00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "distant_cpu.h"
00023
00024 #include <SDL_net.h>
00025 #include <SDL_thread.h>
00026 #include "network.h"
00027 #include "../include/action_handler.h"
00028 #include "../map/maps_list.h"
00029 #include "../menu/network_menu.h"
00030 #include "../team/teams_list.h"
00031 #include "../tool/debug.h"
00032 #include "../tool/i18n.h"
00033
00034
00035 DistantComputer::DistantComputer(TCPsocket new_sock)
00036 : sock(new_sock)
00037 {
00038 sock_lock = SDL_CreateMutex();
00039
00040 SDLNet_TCP_AddSocket(network.socket_set, sock);
00041
00042
00043
00044 if( network.IsServer() )
00045 {
00046 Action a(Action::ACTION_SET_MAP, ActiveMap().ReadName());
00047 int size;
00048 char* pack;
00049 a.WritePacket(pack, size);
00050 SendDatas(pack, size);
00051 free(pack);
00052
00053
00054 for(TeamsList::iterator team = teams_list.playing_list.begin();
00055 team != teams_list.playing_list.end();
00056 ++team)
00057 {
00058 Action b(Action::ACTION_NEW_TEAM, (*team)->GetId());
00059 b.Push((*team)->GetPlayerName());
00060 b.Push((int)(*team)->GetNbCharacters());
00061 b.WritePacket(pack, size);
00062 SendDatas(pack, size);
00063 free(pack);
00064 }
00065 }
00066
00067 if(network.network_menu != NULL)
00068 {
00069
00070 network.network_menu->ReceiveMsgCallback(GetAdress() + _(" has joined the party"));
00071 }
00072 }
00073
00074 DistantComputer::~DistantComputer()
00075 {
00076 if(network.network_menu != NULL)
00077 {
00078
00079 network.network_menu->ReceiveMsgCallback( GetAdress() + _(" has left the party"));
00080 }
00081
00082 SDLNet_TCP_DelSocket(network.socket_set, sock);
00083 SDLNet_TCP_Close(sock);
00084
00085 if(network.IsConnected())
00086 for(std::list<std::string>::iterator team = owned_teams.begin();
00087 team != owned_teams.end();
00088 ++team)
00089 {
00090 ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_DEL_TEAM, *team));
00091 }
00092 owned_teams.clear();
00093
00094 SDL_DestroyMutex(sock_lock);
00095 }
00096
00097 bool DistantComputer::SocketReady()
00098 {
00099 return SDLNet_SocketReady(sock);
00100 }
00101
00102 int DistantComputer::ReceiveDatas(char* & buf)
00103 {
00104 SDL_LockMutex(sock_lock);
00105 MSG_DEBUG("network","locked");
00106
00107
00108 Uint32 net_size;
00109 if(SDLNet_TCP_Recv(sock, &net_size, 4) <= 0)
00110 {
00111 SDL_UnlockMutex(sock_lock);
00112 return -1;
00113 }
00114
00115 int size = (int)SDLNet_Read32(&net_size);
00116 assert(size > 0);
00117
00118
00119 buf = (char*)malloc(size);
00120
00121 int total_received = 0;
00122 while(total_received != size)
00123 {
00124 int received = SDLNet_TCP_Recv(sock, buf + total_received, size - total_received);
00125 if(received > 0)
00126 {
00127 MSG_DEBUG("network", "%i received", received);
00128 total_received += received;
00129 }
00130
00131 if(received < 0)
00132 {
00133 assert(false);
00134 std::cerr << "Malformed packet" << std::endl;
00135 total_received = received;
00136 break;
00137 }
00138 }
00139 SDL_UnlockMutex(sock_lock);
00140 MSG_DEBUG("network","unlocked");
00141 return total_received;
00142 }
00143
00144 void DistantComputer::SendDatas(char* packet, int size_tmp)
00145 {
00146 SDL_LockMutex(sock_lock);
00147 MSG_DEBUG("network","locked");
00148 Uint32 size;
00149 SDLNet_Write32(size_tmp, &size);
00150 SDLNet_TCP_Send(sock,&size,4);
00151 SDLNet_TCP_Send(sock,packet, size_tmp);
00152 MSG_DEBUG("network","%i sent", 4 + size_tmp);
00153
00154 SDL_UnlockMutex(sock_lock);
00155 MSG_DEBUG("network","unlocked");
00156 }
00157
00158 std::string DistantComputer::GetAdress()
00159 {
00160 IPaddress* ip = SDLNet_TCP_GetPeerAddress(sock);
00161 std::string address;
00162 const char* resolved_ip = SDLNet_ResolveIP(ip);
00163 if(resolved_ip)
00164 address = resolved_ip;
00165 else
00166 return "Unresolved address";
00167 return address;
00168 }
00169
00170 void DistantComputer::ManageTeam(Action* team)
00171 {
00172 std::string name = team->PopString();
00173 if(team->GetType() == Action::ACTION_NEW_TEAM)
00174 {
00175 owned_teams.push_back(name);
00176
00177 int index = 0;
00178 Team * tmp = teams_list.FindById(name, index);
00179 tmp->SetRemote();
00180
00181 Action* copy = new Action(Action::ACTION_NEW_TEAM, name);
00182 copy->Push( team->PopString() );
00183 copy->Push( team->PopInt() );
00184 ActionHandler::GetInstance()->NewAction(copy, false);
00185 }
00186 else
00187 if(team->GetType() == Action::ACTION_DEL_TEAM)
00188 {
00189 std::list<std::string>::iterator it;
00190 it = find(owned_teams.begin(), owned_teams.end(), name);
00191 std::cout << "ManageTeam : erase " << name << std::endl;
00192 assert(it != owned_teams.end());
00193 owned_teams.erase(it);
00194 ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_DEL_TEAM, name), false);
00195 }
00196 else
00197 assert(false);
00198 }
00199
00200 void DistantComputer::SendChatMessage(Action* a)
00201 {
00202 std::string txt = a->PopString();
00203 if(network.IsServer())
00204 {
00205 ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_CHAT_MESSAGE, nickname + "> "+txt));
00206 }
00207 else
00208 {
00209 ActionHandler::GetInstance()->NewAction(new Action(Action::ACTION_CHAT_MESSAGE, txt), false);
00210 }
00211 }