From 3fb0d2fb65c968f91c333a1d31d2d7a1a02ab7d1 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 15 Jan 2011 03:28:19 +0200 Subject: [PATCH] Players are left on server while server is running. No passwords yet. --- src/client.cpp | 6 +- src/connection.cpp | 18 +- src/connection.h | 2 +- src/environment.cpp | 33 ++++ src/environment.h | 2 + src/player.cpp | 2 +- src/player.h | 16 +- src/server.cpp | 401 +++++++++++++++++++++++++++----------------- src/server.h | 6 + 9 files changed, 312 insertions(+), 174 deletions(-) diff --git a/src/client.cpp b/src/client.cpp index 103f20c3c..3853c25e5 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -568,7 +568,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id) our_peer_id = m_con.GetPeerID(); } // Cancel if we don't have a peer id - if(our_peer_id == PEER_ID_NEW){ + if(our_peer_id == PEER_ID_INEXISTENT){ dout_client<peer_id == PEER_ID_NEW) + if(myplayer->peer_id == PEER_ID_INEXISTENT) myplayer->peer_id = our_peer_id; // Check that an existing peer_id is the same as the connection's assert(myplayer->peer_id == our_peer_id); diff --git a/src/connection.cpp b/src/connection.cpp index 6c37ff63b..e890a12a1 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -497,7 +497,7 @@ Connection::Connection( m_protocol_id = protocol_id; m_max_packet_size = max_packet_size; m_timeout = timeout; - m_peer_id = PEER_ID_NEW; + m_peer_id = PEER_ID_INEXISTENT; //m_waiting_new_peer_id = false; m_indentation = 0; m_peerhandler = peerhandler; @@ -534,8 +534,8 @@ void Connection::Connect(Address address) m_socket.Bind(0); - // Send a dummy packet to server with peer_id = PEER_ID_NEW - m_peer_id = PEER_ID_NEW; + // Send a dummy packet to server with peer_id = PEER_ID_INEXISTENT + m_peer_id = PEER_ID_INEXISTENT; SharedBuffer data(0); Send(PEER_ID_SERVER, 0, data, true); @@ -568,7 +568,7 @@ bool Connection::Connected() if(node == NULL) return false; - if(m_peer_id == PEER_ID_NEW) + if(m_peer_id == PEER_ID_INEXISTENT) return false; return true; @@ -643,7 +643,7 @@ SharedBuffer Channel::ProcessPacket( con->PrintInfo(); dout_con<<"Got new peer id: "<GetPeerID() != PEER_ID_NEW) + if(con->GetPeerID() != PEER_ID_INEXISTENT) { con->PrintInfo(derr_con); derr_con<<"WARNING: Not changing" @@ -951,7 +951,7 @@ u32 Connection::Receive(u16 &peer_id, u8 *data, u32 datasize) throw InvalidIncomingDataException("Channel doesn't exist"); } - if(peer_id == PEER_ID_NEW) + if(peer_id == PEER_ID_INEXISTENT) { /* Somebody is trying to send stuff to us with no peer id. @@ -994,7 +994,7 @@ u32 Connection::Receive(u16 &peer_id, u8 *data, u32 datasize) /* The peer was not found in our lists. Add it. */ - if(peer_id == PEER_ID_NEW) + if(peer_id == PEER_ID_INEXISTENT) { // Somebody wants to make a new connection @@ -1016,7 +1016,7 @@ u32 Connection::Receive(u16 &peer_id, u8 *data, u32 datasize) } PrintInfo(); - dout_con<<"Receive(): Got a packet with peer_id=PEER_ID_NEW," + dout_con<<"Receive(): Got a packet with peer_id=PEER_ID_INEXISTENT," " giving peer_id="<::Iterator i = m_players.begin(); + i != m_players.end(); i++) + { + Player *player = *i; + if(strcmp(player->getName(), name) == 0) + return player; + } + return NULL; +} + core::list Environment::getPlayers() { return m_players; } +core::list Environment::getPlayers(bool ignore_disconnected) +{ + core::list newlist; + for(core::list::Iterator + i = m_players.begin(); + i != m_players.end(); i++) + { + Player *player = *i; + + if(ignore_disconnected) + { + // Ignore disconnected players + if(player->peer_id == 0) + continue; + } + + newlist.push_back(player); + } + return newlist; +} + void Environment::printPlayers(std::ostream &o) { o<<"Players in environment:"< getPlayers(); + core::list getPlayers(bool ignore_disconnected); void printPlayers(std::ostream &o); #ifndef SERVER diff --git a/src/player.cpp b/src/player.cpp index c0dad697d..37fcda991 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Player::Player(): touching_ground(false), in_water(false), - peer_id(PEER_ID_NEW), + peer_id(PEER_ID_INEXISTENT), m_speed(0,0,0), m_position(0,0,0) { diff --git a/src/player.h b/src/player.h index fc87a5edd..9330bdd54 100644 --- a/src/player.h +++ b/src/player.h @@ -96,9 +96,10 @@ public: virtual bool isLocal() const = 0; virtual void updateLight(u8 light_at_pos) {}; - - virtual bool isClientConnected() { return false; } - virtual void setClientConnected(bool) {} + + // NOTE: Use peer_id == 0 for disconnected + /*virtual bool isClientConnected() { return false; } + virtual void setClientConnected(bool) {}*/ bool touching_ground; bool in_water; @@ -118,8 +119,9 @@ protected: class ServerRemotePlayer : public Player { public: - ServerRemotePlayer(bool client_connected): - m_client_connected(client_connected) + /*ServerRemotePlayer(bool client_connected): + m_client_connected(client_connected)*/ + ServerRemotePlayer() { } virtual ~ServerRemotePlayer() @@ -135,7 +137,7 @@ public: { } - virtual bool isClientConnected() + /*virtual bool isClientConnected() { return m_client_connected; } @@ -145,7 +147,7 @@ public: } // This - bool m_client_connected; + bool m_client_connected;*/ private: }; diff --git a/src/server.cpp b/src/server.cpp index 38c421e41..2f285b6e9 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -294,6 +294,8 @@ void RemoteClient::GetNextBlocks(Server *server, float dtime, Player *player = server->m_env.getPlayer(peer_id); + assert(player != NULL); + v3f playerpos = player->getPosition(); v3f playerspeed = player->getSpeed(); @@ -604,8 +606,9 @@ void RemoteClient::SendObjectData( /* Get and write player data */ - - core::list players = server->m_env.getPlayers(); + + // Get connected players + core::list players = server->m_env.getPlayers(true); // Write player count u16 playercount = players.size(); @@ -656,6 +659,8 @@ void RemoteClient::SendObjectData( Player *player = server->m_env.getPlayer(peer_id); + assert(player); + v3f playerpos = player->getPosition(); v3f playerspeed = player->getSpeed(); @@ -847,7 +852,8 @@ PlayerInfo::PlayerInfo() void PlayerInfo::PrintLine(std::ostream *s) { - (*s)<getKey(); - - // Delete player + /*// Delete player + // NOTE: These are removed by env destructor { + u16 peer_id = i.getNode()->getKey(); JMutexAutoLock envlock(m_env_mutex); m_env.removePlayer(peer_id); - } + }*/ // Delete client delete i.getNode()->getValue(); @@ -1419,20 +1425,44 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) /* Set up player */ + + // Get player name + const u32 playername_size = 20; + char playername[playername_size]; + for(u32 i=0; ipeer_id != 0) + { + derr_server<peer_id = peer_id; // Check if player doesn't exist if(player == NULL) throw con::InvalidIncomingDataException ("Server::ProcessData(): INIT: Player doesn't exist"); - // update name if it was supplied + /*// update name if it was supplied if(datasize >= 20+3) { data[20+3-1] = 0; player->updateName((const char*)&data[3]); - } + }*/ // Now answer with a TOCLIENT_INIT @@ -1488,9 +1518,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id) assert(client->peer_id == i.getNode()->getKey()); if(client->serialization_version == SER_FMT_VER_INVALID) continue; + // Get player + Player *player = m_env.getPlayer(client->peer_id); // Get name of player std::wstring name = L"unknown"; - Player *player = m_env.getPlayer(client->peer_id); if(player != NULL) name = narrow_to_wide(player->getName()); // Add name to information string @@ -2394,15 +2425,17 @@ core::list Server::getPlayerInfo() PlayerInfo info; Player *player = *i; + try{ con::Peer *peer = m_con.GetPeer(player->peer_id); + // Copy info from peer to info struct info.id = peer->id; info.address = peer->address; info.avg_rtt = peer->avg_rtt; } catch(con::PeerNotFoundException &e) { - // Outdated peer info + // Set dummy peer info info.id = 0; info.address = Address(0,0,0,0,0); info.avg_rtt = 0.0; @@ -2470,7 +2503,8 @@ void Server::SendPlayerInfos() //JMutexAutoLock envlock(m_env_mutex); - core::list players = m_env.getPlayers(); + // Get connected players + core::list players = m_env.getPlayers(true); u32 player_count = players.getSize(); u32 datasize = 2+(2+PLAYERNAME_SIZE)*player_count; @@ -2922,6 +2956,200 @@ RemoteClient* Server::getClient(u16 peer_id) return n->getValue(); } +Player *Server::emergePlayer(const char *name, const char *password) +{ + /* + Try to get an existing player + */ + Player *player = m_env.getPlayer(name); + if(player != NULL) + { + // Got one. + return player; + } + + /* + Create a new player + */ + { + player = new ServerRemotePlayer(); + //player->peer_id = c.peer_id; + player->peer_id = PEER_ID_INEXISTENT; + player->updateName(name); + + /* + Set player position + */ +#if 0 + // We're going to throw the player to this position + //v2s16 nodepos(29990,29990); + //v2s16 nodepos(9990,9990); + v2s16 nodepos(0,0); + v2s16 sectorpos = getNodeSectorPos(nodepos); + // Get sector + m_env.getMap().emergeSector(sectorpos); + // Get ground height at point + f32 groundheight = m_env.getMap().getGroundHeight(nodepos, true); + // The sector should have been generated -> groundheight exists + assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE); + // Don't go underwater + if(groundheight < WATER_LEVEL) + groundheight = WATER_LEVEL; +#endif + +#if 1 + v2s16 nodepos; + f32 groundheight = 0; + // Try to find a good place a few times + for(s32 i=0; i<100; i++) + { + s32 range = 1 + i*5; + // We're going to try to throw the player to this position + nodepos = v2s16(-range/2 + (myrand()%range), + -range/2 + (myrand()%range)); + v2s16 sectorpos = getNodeSectorPos(nodepos); + // Get sector + m_env.getMap().emergeSector(sectorpos); + // Get ground height at point + groundheight = m_env.getMap().getGroundHeight(nodepos, true); + // The sector should have been generated -> groundheight exists + assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE); + // Don't go underwater + if(groundheight < WATER_LEVEL) + continue; + // Don't go inside ground + try{ + v3s16 footpos(nodepos.X, groundheight+1, nodepos.Y); + v3s16 headpos(nodepos.X, groundheight+2, nodepos.Y); + if(m_env.getMap().getNode(footpos).d != CONTENT_AIR + || m_env.getMap().getNode(headpos).d != CONTENT_AIR) + { + // In ground + continue; + } + }catch(InvalidPositionException &e) + { + // Ignore invalid position + continue; + } + // Found a good place + break; + } +#endif + + player->setPosition(intToFloat(v3s16( + nodepos.X, + groundheight + 1, + nodepos.Y + ))); + + /* + Add player to environment + */ + + m_env.addPlayer(player); + + /* + Add stuff to inventory + */ + + if(g_settings.getBool("creative_mode")) + { + // Give some good picks + { + InventoryItem *item = new ToolItem("STPick", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("MesePick", 0); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + + /* + Give materials + */ + assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE); + + // add torch first + InventoryItem *item = new MaterialItem(CONTENT_TORCH, 1); + player->inventory.addItem("main", item); + + // Then others + for(u16 i=0; iinventory.addItem("main", item); + } + // Sign + { + InventoryItem *item = new MapBlockObjectItem("Sign Example text"); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + } + else + { + /*{ + InventoryItem *item = new MaterialItem(CONTENT_MESE, 6); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new MaterialItem(CONTENT_COALSTONE, 6); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new MaterialItem(CONTENT_WOOD, 6); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new CraftItem("Stick", 4); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("WPick", 32000); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + } + { + InventoryItem *item = new ToolItem("STPick", 32000); + void* r = player->inventory.addItem("main", item); + assert(r == NULL); + }*/ + /*// Give some lights + { + InventoryItem *item = new MaterialItem(CONTENT_TORCH, 999); + bool r = player->inventory.addItem("main", item); + assert(r == true); + } + // and some signs + for(u16 i=0; i<4; i++) + { + InventoryItem *item = new MapBlockObjectItem("Sign Example text"); + bool r = player->inventory.addItem("main", item); + assert(r == true); + }*/ + /*// Give some other stuff + { + InventoryItem *item = new MaterialItem(CONTENT_TREE, 999); + bool r = player->inventory.addItem("main", item); + assert(r == true); + }*/ + } + + return player; + } +} + void Server::UpdateBlockWaterPressure(MapBlock *block, core::map &modified_blocks) { @@ -2966,145 +3194,6 @@ void Server::handlePeerChange(PeerChange &c) client->peer_id = c.peer_id; m_clients.insert(client->peer_id, client); - // Create player - { - Player *player = m_env.getPlayer(c.peer_id); - - // The player shouldn't already exist - assert(player == NULL); - - player = new ServerRemotePlayer(true); - player->peer_id = c.peer_id; - - /* - Set player position - */ - - // We're going to throw the player to this position - //v2s16 nodepos(29990,29990); - //v2s16 nodepos(9990,9990); - v2s16 nodepos(0,0); - v2s16 sectorpos = getNodeSectorPos(nodepos); - // Get zero sector (it could have been unloaded to disk) - m_env.getMap().emergeSector(sectorpos); - // Get ground height at origin - f32 groundheight = m_env.getMap().getGroundHeight(nodepos, true); - // The sector should have been generated -> groundheight exists - assert(groundheight > GROUNDHEIGHT_VALID_MINVALUE); - // Don't go underwater - if(groundheight < WATER_LEVEL) - groundheight = WATER_LEVEL; - - player->setPosition(intToFloat(v3s16( - nodepos.X, - groundheight + 1, - nodepos.Y - ))); - - /* - Add player to environment - */ - - m_env.addPlayer(player); - - /* - Add stuff to inventory - */ - - if(g_settings.getBool("creative_mode")) - { - // Give some good picks - { - InventoryItem *item = new ToolItem("STPick", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("MesePick", 0); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - - /* - Give materials - */ - assert(USEFUL_CONTENT_COUNT <= PLAYER_INVENTORY_SIZE); - - // add torch first - InventoryItem *item = new MaterialItem(CONTENT_TORCH, 1); - player->inventory.addItem("main", item); - - // Then others - for(u16 i=0; iinventory.addItem("main", item); - } - // Sign - { - InventoryItem *item = new MapBlockObjectItem("Sign Example text"); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - } - else - { - /*{ - InventoryItem *item = new MaterialItem(CONTENT_MESE, 6); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new MaterialItem(CONTENT_COALSTONE, 6); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new MaterialItem(CONTENT_WOOD, 6); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new CraftItem("Stick", 4); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("WPick", 32000); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - } - { - InventoryItem *item = new ToolItem("STPick", 32000); - void* r = player->inventory.addItem("main", item); - assert(r == NULL); - }*/ - /*// Give some lights - { - InventoryItem *item = new MaterialItem(CONTENT_TORCH, 999); - bool r = player->inventory.addItem("main", item); - assert(r == true); - } - // and some signs - for(u16 i=0; i<4; i++) - { - InventoryItem *item = new MapBlockObjectItem("Sign Example text"); - bool r = player->inventory.addItem("main", item); - assert(r == true); - }*/ - /*// Give some other stuff - { - InventoryItem *item = new MaterialItem(CONTENT_TREE, 999); - bool r = player->inventory.addItem("main", item); - assert(r == true); - }*/ - } - } - } // PEER_ADDED else if(c.type == PEER_REMOVED) { @@ -3133,9 +3222,15 @@ void Server::handlePeerChange(PeerChange &c) message += L" (timed out)"; } - // Delete player + /*// Delete player { m_env.removePlayer(c.peer_id); + }*/ + + // Set player client disconnected + { + Player *player = m_env.getPlayer(c.peer_id); + player->peer_id = 0; } // Delete client diff --git a/src/server.h b/src/server.h index b716a7df1..099be9e14 100644 --- a/src/server.h +++ b/src/server.h @@ -425,6 +425,12 @@ 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); + /* Update water pressure. This also adds suitable nodes to active_nodes.