IndexServer Class Reference

#include <index_server.h>

List of all members.

Public Member Functions

 IndexServer ()
 ~IndexServer ()
bool Connect ()
void SetHiddenServer ()
void SendServerStatus ()
void Disconnect ()
std::list< address_pairGetHostList ()

Private Member Functions

void Send (const int &nbr)
void Send (const std::string &str)
int ReceiveInt ()
std::string ReceiveStr ()
bool GetServerList ()
bool GetServerAddress (std::string &address, int &port)
bool ConnectTo (const std::string &address, const int &port)
bool HandShake ()

Private Attributes

TCPsocket socket
IPaddress ip
std::map< std::string, int > server_lst
std::map< std::string, int
>::iterator 
first_server
std::map< std::string, int
>::iterator 
current_server
bool hidden_server
bool connected


Detailed Description

Definition at line 34 of file index_server.h.


Constructor & Destructor Documentation

IndexServer::IndexServer (  ) 

Definition at line 38 of file index_server.cpp.

00039 {
00040   hidden_server = false;
00041   connected = false;
00042   server_lst.clear();
00043   first_server = server_lst.end();
00044   current_server = server_lst.end();
00045 }

IndexServer::~IndexServer (  ) 

Definition at line 47 of file index_server.cpp.

00048 {
00049   server_lst.clear();
00050   if(connected)
00051     Disconnect();
00052 }

Here is the call graph for this function:


Member Function Documentation

bool IndexServer::Connect (  ) 

Definition at line 55 of file index_server.cpp.

00056 {
00057   MSG_DEBUG("index_server", "Connecting..");
00058   assert(!connected);
00059 
00060   if( hidden_server )
00061     return true;
00062 
00063   if( !GetServerList() )
00064     return false;
00065 
00066   std::string addr;
00067   int port;
00068 
00069   // Cycle through the list of server
00070   // Until we find one running
00071   while( GetServerAddress( addr, port) )
00072   {
00073     if( ConnectTo( addr, port) )
00074       return true;
00075   }
00076 
00077   Question question;
00078   question.Set(_("Unable to contact an index server!"),1,0);
00079   question.Ask();
00080 
00081   return false;
00082 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool IndexServer::ConnectTo ( const std::string &  address,
const int &  port 
) [private]

Definition at line 84 of file index_server.cpp.

00085 {
00086   MSG_DEBUG("index_server", "Connecting to %s %i", address.c_str(), port);
00087   Question question;
00088   question.Set(_("Contacting main server..."),1,0);
00089   question.Draw();
00090   AppWormux::GetInstance()->video.Flip();
00091 
00092   network.Init(); // To get SDL_net initialized
00093 
00094   MSG_DEBUG("index_server", "Opening connection");
00095 
00096 //  if( SDLNet_ResolveHost(&ip, "localhost" , port) == -1 )
00097   if( SDLNet_ResolveHost(&ip, address.c_str() , port) == -1 )
00098   {
00099     question.Set(_("Invalid index server adress!"),1,0);
00100     question.Ask();
00101     printf("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
00102     return false;
00103   }
00104 
00105   socket = SDLNet_TCP_Open(&ip);
00106 
00107   if(!socket)
00108   {
00109     printf("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
00110     return false;
00111   }
00112 
00113   connected = true;
00114 
00115   return HandShake();
00116 }

Here is the call graph for this function:

Here is the caller graph for this function:

void IndexServer::Disconnect (  ) 

Definition at line 118 of file index_server.cpp.

00119 {
00120   if( hidden_server )
00121   {
00122     hidden_server = false;
00123     return;
00124   }
00125 
00126   if( !connected )
00127     return;
00128 
00129   MSG_DEBUG("index_server", "Closing connection");
00130   first_server = server_lst.end();
00131   current_server = server_lst.end();
00132 
00133   SDLNet_TCP_Close(socket);
00134   connected = false;
00135 }

Here is the caller graph for this function:

std::list< address_pair > IndexServer::GetHostList (  ) 

Definition at line 315 of file index_server.cpp.

00316 {
00317   Send(TS_MSG_GET_LIST);
00318   int lst_size = ReceiveInt();
00319   std::list<address_pair> lst;
00320   while(lst_size--)
00321   {
00322     IPaddress ip;
00323     ip.host = ReceiveInt();
00324     ip.port = ReceiveInt();
00325     const char* addr = SDLNet_ResolveIP(&ip);
00326     char port[10];
00327     sprintf(port, "%d", ip.port);
00328 
00329     address_pair addr_pair;
00330     addr_pair.second = std::string(port);
00331 
00332     if(addr == NULL)
00333     {
00334       // We can't resolve the hostname, so just show the ip address
00335       unsigned char* str_ip = (unsigned char*)&ip.host;
00336       char formated_ip[16];
00337       snprintf(formated_ip, 16, "%i.%i.%i.%i", (int)str_ip[0],
00338                                            (int)str_ip[1],
00339                                            (int)str_ip[2],
00340                                            (int)str_ip[3]);
00341       addr_pair.first = std::string(formated_ip);
00342     }
00343     else
00344       addr_pair.first = std::string(addr);
00345     lst.push_back(addr_pair);
00346   }
00347   return lst;
00348 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool IndexServer::GetServerAddress ( std::string &  address,
int &  port 
) [private]

Definition at line 196 of file index_server.cpp.

00197 {
00198   MSG_DEBUG("index_server", "Trying a new server");
00199   // Cycle through the server list to find the first one
00200   // accepting connection
00201   if( first_server == server_lst.end() )
00202   {
00203     // First try :
00204     // Randomly select a server in the list
00205     int nbr = randomObj.GetLong( 0, server_lst.size()-1 );
00206     first_server = server_lst.begin();
00207     while(nbr--)
00208       ++first_server;
00209 
00210     assert(first_server != server_lst.end());
00211 
00212     current_server = first_server;
00213 
00214     address = current_server->first;
00215     port = current_server->second;
00216     return true;
00217   }
00218 
00219   ++current_server;
00220   if( current_server == server_lst.end() )
00221     current_server = server_lst.begin();
00222 
00223   address = current_server->first;
00224   port = current_server->second;
00225 
00226   return (current_server != first_server);
00227 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool IndexServer::GetServerList (  )  [private]

Definition at line 146 of file index_server.cpp.

00147 {
00148   MSG_DEBUG("index_server", "Retrieving server list");
00149   // If we already have it, no need to redownload it
00150   if(server_lst.size() != 0)
00151     return true;
00152 
00153   // Download the list of user
00154   const std::string server_file = Config::GetInstance()->GetPersonalDir() + "server_list";
00155 
00156   if( !downloader.Get(server_list_url.c_str(), server_file.c_str()) )
00157     return false;
00158 
00159   // Parse the file
00160   std::ifstream fin;
00161   fin.open(server_file.c_str(), std::ios::in);
00162   if(!fin)
00163         return false;
00164 
00165   /*char * line = NULL;
00166   size_t len = 0;*/
00167   ssize_t read;
00168   std::string line;
00169  
00170   // GNU getline isn't available on *BSD and Win32, so we use a new function, see getline above
00171   while ((read = getline(line, fin)) >= 0)
00172   {
00173     if(line.at(0) == '#' || line.at(0) == '\n' || line.at(0) == '\0')
00174       continue;
00175 
00176     std::string::size_type port_pos = line.find(':', 0);
00177     if(port_pos == std::string::npos)
00178       continue;
00179 
00180     std::string hostname = line.substr(0, port_pos);
00181     std::string portstr = line.substr(port_pos+1);
00182     int port = atoi(portstr.c_str());
00183 
00184     server_lst[ hostname ] = port;
00185   }
00186 
00187   fin.close();
00188 
00189   first_server = server_lst.end();
00190   current_server = server_lst.end();
00191   MSG_DEBUG("index_server", "Server list retrieved. %i servers are running", server_lst.size());
00192 
00193   return (server_lst.size() != 0);
00194 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool IndexServer::HandShake (  )  [private]

Definition at line 283 of file index_server.cpp.

00284 {
00285   Send(TS_MSG_VERSION);
00286   Send(Constants::VERSION);
00287 
00288   int msg = ReceiveInt();
00289   std::string sign;
00290 
00291   if(msg == TS_MSG_VERSION)
00292     sign = ReceiveStr();
00293 
00294   if(msg != TS_MSG_VERSION || sign != "MassMurder!")
00295   {
00296     Question question;
00297     question.Set(_("It doesn't seem to be a valid Wormux server..."),1,0);
00298     question.Ask();
00299     Disconnect();
00300     return false;
00301   }
00302   return true;
00303 }

Here is the call graph for this function:

Here is the caller graph for this function:

int IndexServer::ReceiveInt (  )  [private]

Definition at line 246 of file index_server.cpp.

00247 {
00248   char packet[4];
00249   if( SDLNet_TCP_Recv(socket, packet, sizeof(packet)) < 1 )
00250   {
00251     Disconnect();
00252     return 0;
00253   }
00254 
00255   Uint32 u_nbr = SDLNet_Read32(packet);
00256   int nbr = *((int*)&u_nbr);
00257   return nbr;
00258 }

Here is the call graph for this function:

Here is the caller graph for this function:

std::string IndexServer::ReceiveStr (  )  [private]

Definition at line 260 of file index_server.cpp.

00261 {
00262   int size = ReceiveInt();
00263 
00264   if(!connected)
00265     return "";
00266 
00267   assert(size > 0);
00268   char* str = new char[size+1];
00269 
00270   if( SDLNet_TCP_Recv(socket, str, size) < 1 )
00271   {
00272     Disconnect();
00273     return "";
00274   }
00275 
00276   str[size] = '\0';
00277 
00278   std::string st(str);
00279   delete []str;
00280   return st;
00281 }

Here is the call graph for this function:

Here is the caller graph for this function:

void IndexServer::Send ( const std::string &  str  )  [private]

Definition at line 240 of file index_server.cpp.

00241 {
00242   Send(str.size());
00243   SDLNet_TCP_Send(socket, (void*)str.c_str(), str.size());
00244 }

Here is the call graph for this function:

void IndexServer::Send ( const int &  nbr  )  [private]

Definition at line 230 of file index_server.cpp.

00231 {
00232   char packet[4];
00233   // this is not cute, but we don't want an int -> uint conversion here
00234   Uint32 u_nbr = *((Uint32*)&nbr);
00235 
00236   SDLNet_Write32(u_nbr, packet);
00237   SDLNet_TCP_Send(socket, packet, sizeof(packet));
00238 }

Here is the caller graph for this function:

void IndexServer::SendServerStatus (  ) 

Definition at line 305 of file index_server.cpp.

00306 {
00307   assert(network.IsServer());
00308 
00309   if(hidden_server)
00310     return;
00311   Send(TS_MSG_HOSTING);
00312   Send(network.GetPort());
00313 }

Here is the call graph for this function:

Here is the caller graph for this function:

void IndexServer::SetHiddenServer (  )  [inline]

Definition at line 76 of file index_server.h.

00076 { hidden_server = true; };

Here is the caller graph for this function:


Member Data Documentation

bool IndexServer::connected [private]

Definition at line 50 of file index_server.h.

std::map<std::string, int>::iterator IndexServer::current_server [private]

Definition at line 45 of file index_server.h.

std::map<std::string, int>::iterator IndexServer::first_server [private]

Definition at line 43 of file index_server.h.

bool IndexServer::hidden_server [private]

Definition at line 48 of file index_server.h.

IPaddress IndexServer::ip [private]

Definition at line 38 of file index_server.h.

std::map<std::string, int> IndexServer::server_lst [private]

Definition at line 41 of file index_server.h.

TCPsocket IndexServer::socket [private]

Definition at line 37 of file index_server.h.


The documentation for this class was generated from the following files:
Generated on Mon Jan 1 13:52:07 2007 for Wormux by  doxygen 1.4.7