Index: code/branches/presentationFS15merge/src/libraries/network/MasterServer.cc
===================================================================
--- code/branches/presentationFS15merge/src/libraries/network/MasterServer.cc	(revision 10595)
+++ code/branches/presentationFS15merge/src/libraries/network/MasterServer.cc	(revision 10612)
@@ -34,5 +34,5 @@
 #include "util/Output.h"
 
-namespace orxonox 
+namespace orxonox
 {
   /*** MACROS ***/
@@ -45,9 +45,6 @@
   MasterServer *MasterServer::instance = NULL;
 
-
-
-
   /* command: list servers */
-  void 
+  void
   MasterServer::listServers( void )
   {
@@ -59,6 +56,6 @@
 
     /* loop through list elements */
-    for( i = MasterServer::getInstance()->mainlist.serverlist.begin(); 
-      i != MasterServer::getInstance()->mainlist.serverlist.end(); ++i ) 
+    for( i = MasterServer::getInstance()->mainlist.serverlist.begin();
+      i != MasterServer::getInstance()->mainlist.serverlist.end(); ++i )
     {
       orxout(user_info) << "  " << (*i).ServerInfo.getServerIP() << std::endl;
@@ -70,13 +67,13 @@
   }
 
-  void 
+  void
   MasterServer::delServer( std::string todeladdr )
   {
     /* tell the user we're now removing the entry from the server list */
-    orxout(user_info) << "MS: Deleting server \"" << todeladdr << "\"..." 
+    orxout(user_info) << "MS: Deleting server \"" << todeladdr << "\"..."
       << std::endl;
 
     /* see if we actually have that server on our list */
-    ServerListSearchResult shandle = 
+    ServerListSearchResult shandle =
       MasterServer::getInstance()->mainlist.findServerByAddress(todeladdr);
 
@@ -86,5 +83,5 @@
     }
 
-    /* force-disconnect the server */  
+    /* force-disconnect the server */
     enet_peer_disconnect( shandle.result.peer, 0 );
 
@@ -98,14 +95,14 @@
 
   /* helpers */
-  static void 
+  static void
   helper_output_debug( ENetEvent *event, char *addrconv )
   {
     orxout(verbose, context::master_server)
-      << "A packet of length" 
+      << "A packet of length"
       << event->packet->dataLength
       << " containing "
       << (const char*)event->packet->data
       << " was received from "
-      << addrconv 
+      << addrconv
       << " on channel "
       << event->channelID << endl;
@@ -122,21 +119,21 @@
 
     /* loop through list elements */
-    for( i = mainlist.serverlist.begin(); i 
-        != mainlist.serverlist.end(); ++i ) 
+    for( i = mainlist.serverlist.begin(); i
+        != mainlist.serverlist.end(); ++i )
     {
       /* send this particular server */
       /* build reply string */
-      char *tosend = (char *)calloc( (*i).ServerInfo.getServerIP().length() 
-          + MSPROTO_SERVERLIST_ITEM_LEN + 2,1 );
-      if( !tosend ) 
+      int packetlen = MSPROTO_SERVERLIST_ITEM_LEN + 1 + (*i).ServerInfo.getServerIP().length() + 1 + (*i).ServerInfo.getServerName().length() + 1 + sizeof((*i).ServerInfo.getClientNumber()) + 1;
+      char *tosend = (char *)calloc(packetlen ,1 );
+      if( !tosend )
       { orxout(internal_warning, context::master_server) << "Masterserver.cc: Memory allocation failed." << endl;
         continue;
-      } 
-      sprintf( tosend, "%s %s", MSPROTO_SERVERLIST_ITEM, 
-          (*i).ServerInfo.getServerIP().c_str() );
+      }
+      sprintf( tosend, "%s %s %s %u", MSPROTO_SERVERLIST_ITEM,
+          (*i).ServerInfo.getServerIP().c_str(), (*i).ServerInfo.getServerName().c_str(), (*i).ServerInfo.getClientNumber());
 
       /* create packet from it */
       reply = enet_packet_create( tosend,
-          strlen( tosend ) + 1, 
+          strlen( tosend ) + 1,
           ENET_PACKET_FLAG_RELIABLE);
 
@@ -149,5 +146,5 @@
       /* free the tosend buffer */
       free( tosend );
-    } 
+    }
 
     /* create end-of-list packet */
@@ -163,25 +160,25 @@
   }
 
-  /* maybe the two methods below can be merged into one and 
-   * made to use ENet's RTT functionality to check for disconnected 
+  /* maybe the two methods below can be merged into one and
+   * made to use ENet's RTT functionality to check for disconnected
    * servers.
    */
-  void 
+  void
   MasterServer::helper_cleanupServers( void )
   {
     /* get an iterator */
     std::list<ServerListElem>::iterator i;
-     
+
     if( mainlist.serverlist.size() == 0 )
       return;
 
     /* loop through list elements */
-    for( i = mainlist.serverlist.begin(); i 
-        != mainlist.serverlist.end(); ++i ) 
+    for( i = mainlist.serverlist.begin(); i
+        != mainlist.serverlist.end(); ++i )
     { /* see if we have a disconnected peer */
-      if( (*i).peer && 
+      if( (*i).peer &&
          ((*i).peer->state == ENET_PEER_STATE_DISCONNECTED ||
           (*i).peer->state == ENET_PEER_STATE_ZOMBIE ))
-      { 
+      {
         /* Remove it from the list */
         orxout(internal_warning) << (char*)(*i).peer->data << " timed out.\n";
@@ -190,5 +187,5 @@
         /* stop iterating, we manipulated the list */
         /* TODO note: this only removes one dead server per loop
-         * iteration. not beautiful, but one iteration is ~100ms, 
+         * iteration. not beautiful, but one iteration is ~100ms,
          * so not really relevant for the moment.
          */
@@ -196,5 +193,5 @@
       }
     }
- 
+
   }
 
@@ -204,5 +201,5 @@
   /***** EVENTS *****/
   /* connect event */
-  int 
+  int
   MasterServer::eventConnect( ENetEvent *event )
   { /* check for bad parameters */
@@ -217,11 +214,11 @@
 
     /* output debug info */
-    orxout(verbose, context::master_server) << "A new client connected from " 
-      << addrconv 
-      << " on port " 
+    orxout(verbose, context::master_server) << "A new client connected from "
+      << addrconv
+      << " on port "
       << event->peer->address.port << endl;
 
     /* store string form of address here */
-    event->peer->data = addrconv; 
+    event->peer->data = addrconv;
 
     /* all fine. */
@@ -230,5 +227,5 @@
 
   /* disconnect event */
-  int 
+  int
   MasterServer::eventDisconnect( ENetEvent *event )
   { /* check for bad parameters */
@@ -255,5 +252,5 @@
 
   /* data event */
-  int 
+  int
   MasterServer::eventData( ENetEvent *event )
   { /* validate packet */
@@ -262,8 +259,15 @@
       return -1;
     }
-     
+
     /* generate address in readable form */
     char *addrconv = (char *) calloc( 50, 1 );
     enet_address_get_host_ip( &(event->peer->address), addrconv, 49 );
+    /* convert to string */
+    std::string ip = std::string( addrconv );
+    /* delete addrconv */
+    if( addrconv ) free( addrconv );
+
+    /* pointer to full packet data */
+    char * packetdata = (char *)event->packet->data;
 
     /* output debug info about the data that has come */
@@ -271,49 +275,61 @@
 
     /* GAME SERVER OR CLIENT CONNECTION? */
-    if( !strncmp( (char *)event->packet->data, MSPROTO_GAME_SERVER, 
-      MSPROTO_GAME_SERVER_LEN ) )
+    if( !strncmp(packetdata, MSPROTO_GAME_SERVER, MSPROTO_GAME_SERVER_LEN ) )
     { /* Game server */
 
-      if( !strncmp( (char *)event->packet->data 
-        + MSPROTO_GAME_SERVER_LEN+1, 
-        MSPROTO_REGISTER_SERVER, MSPROTO_REGISTER_SERVER_LEN ) )
+      if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_REGISTER_SERVER, MSPROTO_REGISTER_SERVER_LEN ) )
       { /* register new server */
-        mainlist.addServer( packet::ServerInformation( event ),
-          event->peer );
-        
+        mainlist.addServer( packet::ServerInformation( event ), event->peer );
+
         /* tell people we did so */
-        orxout(internal_info, context::master_server) << "Added new server to list: " << 
+        orxout(internal_info, context::master_server) << "Added new server to list: " <<
           packet::ServerInformation( event ).getServerIP() << endl;
       }
 
-      else if( !strncmp( (char *)event->packet->data
-        + MSPROTO_GAME_SERVER_LEN+1,
-        MSPROTO_SERVERDC, MSPROTO_SERVERDC_LEN ) )
-      {
+      else if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_SERVERDC, MSPROTO_SERVERDC_LEN ) )
+      { /* disconnect server */
+
+        /* remove the server from the list it belongs to */
+        this->mainlist.delServerByAddress( ip );
+
+        /* tell the user */
+        orxout(internal_info, context::master_server) << "Removed server " << ip << " from list." << endl;
+      }
+      /* TODO add hook for disconnect here */
+
+      else if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_SET_NAME, MSPROTO_SET_NAME_LEN ) )
+      { /* save server name */
         /* create string from peer data */
-        std::string name = std::string( addrconv );
+        std::string data (event->packet->data,event->packet->data + event->packet->dataLength );
+        std::string name = data.substr(MSPROTO_GAME_SERVER_LEN+1 + MSPROTO_SET_NAME_LEN + 1);
 
         /* remove the server from the list it belongs to */
-        this->mainlist.delServerByAddress( name );
+        this->mainlist.setNameByAddress( ip, name );
 
         /* tell the user */
-        orxout(internal_info, context::master_server) << "Removed server " << name << " from list." << endl;
-      }
-
-      /* TODO add hook for disconnect here */
-    }
-    else if( !strncmp( (char *)event->packet->data, MSPROTO_CLIENT, 
-      MSPROTO_CLIENT_LEN) )
+        orxout(internal_info, context::master_server) << "Updated server " << ip << " with new name " << name << endl;
+      }
+
+      else if( !strncmp( packetdata + MSPROTO_GAME_SERVER_LEN+1, MSPROTO_SET_CLIENTS, MSPROTO_SET_CLIENTS_LEN ) )
+      { /* save client count from server */
+        /* create string from peer data */
+        std::string data (event->packet->data,event->packet->data + event->packet->dataLength );
+        std::string textform= data.substr(MSPROTO_GAME_SERVER_LEN + 1 + MSPROTO_SET_CLIENTS_LEN + 1);
+        int clientNumber = Ogre::StringConverter::parseInt(textform);
+
+        this->mainlist.setClientsByAddress( ip, clientNumber);
+
+        /* tell the user */
+        orxout(internal_info, context::master_server) << "Updated server " << ip << " with new client number " << clientNumber << endl;
+      }
+    }
+    else if( !strncmp( packetdata, MSPROTO_CLIENT, MSPROTO_CLIENT_LEN) )
     { /* client */
-      if( !strncmp( (char *)event->packet->data + MSPROTO_CLIENT_LEN+1,
-        MSPROTO_REQ_LIST, MSPROTO_REQ_LIST_LEN ) )
+      if( !strncmp( packetdata + MSPROTO_CLIENT_LEN+1, MSPROTO_REQ_LIST, MSPROTO_REQ_LIST_LEN ) )
         /* send server list */
         helper_sendlist( event );
     }
     else
-    { /* bad message, don't do anything. */ } 
-
-    /* delete addrconv */
-    if( addrconv ) free( addrconv );
+    { /* bad message, don't do anything. */ }
 
     /* Clean up the packet now that we're done using it. */
@@ -324,5 +340,5 @@
 
   /**** MAIN ROUTINE *****/
-  int 
+  int
   MasterServer::run()
   {
@@ -330,5 +346,5 @@
     ENetEvent *event = (ENetEvent *)calloc(sizeof(ENetEvent), sizeof(char));
     if( event == NULL )
-    { 
+    {
       orxout(user_error, context::master_server) << "Could not create ENetEvent structure, exiting." << endl;
       exit( EXIT_FAILURE );
@@ -345,9 +361,9 @@
     switch (event->type)
     { /* new connection */
-      case ENET_EVENT_TYPE_CONNECT: 
+      case ENET_EVENT_TYPE_CONNECT:
         eventConnect( event ); break;
 
         /* disconnect */
-      case ENET_EVENT_TYPE_DISCONNECT: 
+      case ENET_EVENT_TYPE_DISCONNECT:
         eventDisconnect( event ); break;
 
@@ -358,6 +374,7 @@
 
     /* done */
+    free(event);
     return 0;
-  } 
+  }
 
   /* constructor */
@@ -380,7 +397,7 @@
     this->address.port = ORX_MSERVER_PORT;
 
-    /* create a host with the above settings (the last two 0 mean: accept 
+    /* create a host with the above settings (the last two 0 mean: accept
      * any input/output bandwidth */
-    this->server = enet_host_create( &this->address, ORX_MSERVER_MAXCONNS, 
+    this->server = enet_host_create( &this->address, ORX_MSERVER_MAXCONNS,
         ORX_MSERVER_MAXCHANS, 0, 0 );
     assert(this->server);
@@ -388,5 +405,5 @@
     /* see if creation worked */
     if( !this->server )
-    { orxout(user_error, context::master_server) << 
+    { orxout(user_error, context::master_server) <<
         "An error occurred while trying to create an ENet server host." << endl;
       exit( EXIT_FAILURE );
