src/network/distant_cpu.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *  Wormux is a convivial mass murder game.
00003  *  Copyright (C) 2001-2004 Lawrence Azzoug.
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
00018  ******************************************************************************
00019  * Distant Computer handling
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   // If we are the server, we have to tell this new computer
00043   // what teams / maps have already been selected
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     // Teams infos of already connected computers
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     // Display a message in the network menu
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     // Display a message in the network menu
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   // Firstly, we read the size of the incoming packet
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   // Now we read the packet
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 }

Generated on Mon Jan 1 13:10:58 2007 for Wormux by  doxygen 1.4.7