fixed erroneus handling of many players with no peer existing at same time
authorPerttu Ahola <celeron55@gmail.com>
Mon, 17 Jan 2011 22:26:09 +0000 (00:26 +0200)
committerPerttu Ahola <celeron55@gmail.com>
Mon, 17 Jan 2011 22:26:09 +0000 (00:26 +0200)
src/server.cpp
src/server.h

index 17004a803480cc853a96aaceeac46da1139d4803..d962c4811a9a508dd8bd71b0cf718e251d6d6ff7 100644 (file)
@@ -1567,9 +1567,18 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                playername[playername_size-1] = 0;
                
                // Get player
-               Player *player = emergePlayer(playername, "");
+               Player *player = emergePlayer(playername, "", peer_id);
                //Player *player = m_env.getPlayer(peer_id);
 
+               // If failed, cancel
+               if(player == NULL)
+               {
+                       derr_server<<DTIME<<"Server: peer_id="<<peer_id
+                                       <<": failed to emerge player"<<std::endl;
+                       return;
+               }
+
+               /*
                // If a client is already connected to the player, cancel
                if(player->peer_id != 0)
                {
@@ -1579,9 +1588,9 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                        <<player->peer_id<<")"<<std::endl;
                        return;
                }
-
                // Set client of player
                player->peer_id = peer_id;
+               */
 
                // Check if player doesn't exist
                if(player == NULL)
@@ -3091,7 +3100,8 @@ RemoteClient* Server::getClient(u16 peer_id)
        return n->getValue();
 }
 
-Player *Server::emergePlayer(const char *name, const char *password)
+Player *Server::emergePlayer(const char *name, const char *password,
+               u16 peer_id)
 {
        /*
                Try to get an existing player
@@ -3099,9 +3109,25 @@ Player *Server::emergePlayer(const char *name, const char *password)
        Player *player = m_env.getPlayer(name);
        if(player != NULL)
        {
+               // If player is already connected, cancel
+               if(player->peer_id != 0)
+               {
+                       dstream<<"emergePlayer(): Player already connected"<<std::endl;
+                       return NULL;
+               }
                // Got one.
                return player;
        }
+
+       /*
+               If player with the wanted peer_id already exists, cancel.
+       */
+       if(m_env.getPlayer(peer_id) != NULL)
+       {
+               dstream<<"emergePlayer(): Player with wrong name but same"
+                               " peer_id already exists"<<std::endl;
+               return NULL;
+       }
        
        /*
                Create a new player
@@ -3109,7 +3135,8 @@ Player *Server::emergePlayer(const char *name, const char *password)
        {
                player = new ServerRemotePlayer();
                //player->peer_id = c.peer_id;
-               player->peer_id = PEER_ID_INEXISTENT;
+               //player->peer_id = PEER_ID_INEXISTENT;
+               player->peer_id = peer_id;
                player->updateName(name);
 
                /*
index 4bdaa84550a7e7261e0a8d4db8d3d7ed9f0d6717..9c655b9abf6c9690bab1d7170662216d5ba61a38 100644 (file)
@@ -437,11 +437,14 @@ private:
        // When called, connection mutex should be locked
        RemoteClient* getClient(u16 peer_id);
 
-       // Gets a player from memory or creates one.
-       // Caller should check isClientConnected() and set it appropriately.
-       // 
-       // Call with env and con locked.
-       Player *emergePlayer(const char *name, const char *password);
+       /*
+               Get a player from memory or creates one.
+               If player is already connected, return NULL
+
+               Call with env and con locked.
+       */
+       Player *emergePlayer(const char *name, const char *password,
+                       u16 peer_id);
 
        /*
                Update water pressure.