]> git.lizzy.rs Git - minetest.git/blobdiff - src/server.cpp
Fix android build using hardcoded path for data instead of using the one fetched...
[minetest.git] / src / server.cpp
index 516a9d2f9c32b3a4cd51d04d5bad7b1dad7802ef..262970c09a195bdd96615121d2b0e8e40683097d 100644 (file)
@@ -676,15 +676,15 @@ void Server::AsyncRunStep(bool initial_step)
        {
                float &counter = m_masterserver_timer;
                if(!isSingleplayer() && (!counter || counter >= 300.0) &&
-                               g_settings->getBool("server_announce") == true)
+                               g_settings->getBool("server_announce"))
                {
-                       ServerList::sendAnnounce(!counter ? "start" : "update",
-                                                                               m_clients.getPlayerNames(),
-                                                                               m_uptime.get(),
-                                                                               m_env->getGameTime(),
-                                                                               m_lag,
-                                                                               m_gamespec.id,
-                                                                               m_mods);
+                       ServerList::sendAnnounce(counter ? "update" : "start",
+                                       m_clients.getPlayerNames(),
+                                       m_uptime.get(),
+                                       m_env->getGameTime(),
+                                       m_lag,
+                                       m_gamespec.id,
+                                       m_mods);
                        counter = 0.01;
                }
                counter += dtime;
@@ -714,7 +714,7 @@ void Server::AsyncRunStep(bool initial_step)
 
                        // If definitions and textures have not been sent, don't
                        // send objects either
-                       if (client->getState() < DefinitionsSent)
+                       if (client->getState() < CS_DefinitionsSent)
                                continue;
 
                        Player *player = m_env->getPlayer(client->peer_id);
@@ -1169,10 +1169,15 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id)
        std::string playername = "";
        PlayerSAO *playersao = NULL;
        m_clients.Lock();
-       RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id,InitDone);
-       if (client != NULL) {
-               playername = client->getName();
-               playersao = emergePlayer(playername.c_str(), peer_id);
+       try {
+               RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_InitDone);
+               if (client != NULL) {
+                       playername = client->getName();
+                       playersao = emergePlayer(playername.c_str(), peer_id);
+               }
+       } catch (std::exception &e) {
+               m_clients.Unlock();
+               throw;
        }
        m_clients.Unlock();
 
@@ -1320,10 +1325,10 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                if(datasize < 2+1+PLAYERNAME_SIZE)
                        return;
 
-               RemoteClient* client = getClient(peer_id,Created);
+               RemoteClient* client = getClient(peer_id, CS_Created);
 
                // If net_proto_version is set, this client has already been handled
-               if(client->getState() > Created)
+               if(client->getState() > CS_Created)
                {
                        verbosestream<<"Server: Ignoring multiple TOSERVER_INITs from "
                                        <<addr_s<<" (peer_id="<<peer_id<<")"<<std::endl;
@@ -1448,14 +1453,21 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                /*
                        Set up player
                */
-
-               // Get player name
                char playername[PLAYERNAME_SIZE];
-               for(u32 i=0; i<PLAYERNAME_SIZE-1; i++)
-               {
-                       playername[i] = data[3+i];
+               unsigned int playername_length = 0;
+               for (; playername_length < PLAYERNAME_SIZE; playername_length++ ) {
+                       playername[playername_length] = data[3+playername_length];
+                       if (data[3+playername_length] == 0)
+                               break;
+               }
+
+               if (playername_length == PLAYERNAME_SIZE) {
+                       actionstream<<"Server: Player with name exceeding max length "
+                                       <<"tried to connect from "<<addr_s<<std::endl;
+                       DenyAccess(peer_id, L"Name too long");
+                       return;
                }
-               playername[PLAYERNAME_SIZE-1] = 0;
+
 
                if(playername[0]=='\0')
                {
@@ -1522,7 +1534,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                // Enforce user limit.
                // Don't enforce for users that have some admin right
-               if(m_clients.getClientIDs(Created).size() >= g_settings->getU16("max_users") &&
+               if(m_clients.getClientIDs(CS_Created).size() >= g_settings->getU16("max_users") &&
                                !checkPriv(playername, "server") &&
                                !checkPriv(playername, "ban") &&
                                !checkPriv(playername, "privs") &&
@@ -1605,7 +1617,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                        // Send as reliable
                        m_clients.send(peer_id, 0, reply, true);
-                       m_clients.event(peer_id, Init);
+                       m_clients.event(peer_id, CSE_Init);
                }
 
                return;
@@ -1617,7 +1629,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                verbosestream<<"Server: Got TOSERVER_INIT2 from "
                                <<peer_id<<std::endl;
 
-               m_clients.event(peer_id, GotInit2);
+               m_clients.event(peer_id, CSE_GotInit2);
                u16 protocol_version = m_clients.getProtocolVersion(peer_id);
 
 
@@ -1651,7 +1663,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                // Send node definitions
                SendNodeDef(peer_id, m_nodedef, protocol_version);
 
-               m_clients.event(peer_id, SetDefinitionsSent);
+               m_clients.event(peer_id, CSE_SetDefinitionsSent);
 
                // Send media announcement
                sendMediaAnnouncement(peer_id);
@@ -1666,7 +1678,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                ///// begin compatibility code
                if (protocol_version <= 22) {
-                       m_clients.event(peer_id, SetClientReady);
+                       m_clients.event(peer_id, CSE_SetClientReady);
                        m_script->on_joinplayer(playersao);
                }
                ///// end compatibility code
@@ -1681,8 +1693,8 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                return;
        }
 
-       u8 peer_ser_ver = getClient(peer_id,InitDone)->serialization_version;
-       u16 peer_proto_ver = getClient(peer_id,InitDone)->net_proto_version;
+       u8 peer_ser_ver = getClient(peer_id, CS_InitDone)->serialization_version;
+       u16 peer_proto_ver = getClient(peer_id, CS_InitDone)->net_proto_version;
 
        if(peer_ser_ver == SER_FMT_VER_INVALID)
        {
@@ -1732,21 +1744,27 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                if (playersao == NULL) {
                        errorstream
-                               << "TOSERVER_CLIENT_READY stage 2 client init failed for peer "
+                               << "TOSERVER_CLIENT_READY stage 2 client init failed for peer_id: "
                                << peer_id << std::endl;
+                       m_con.DisconnectPeer(peer_id);
                        return;
                }
 
 
-               if(datasize < 2+8)
+               if(datasize < 2+8) {
+                       errorstream
+                               << "TOSERVER_CLIENT_READY client sent inconsistent data, disconnecting peer_id: "
+                               << peer_id << std::endl;
+                       m_con.DisconnectPeer(peer_id);
                        return;
+               }
 
                m_clients.setClientVersion(
                                peer_id,
                                data[2], data[3], data[4],
                                std::string((char*) &data[8],(u16) data[6]));
 
-               m_clients.event(peer_id, SetClientReady);
+               m_clients.event(peer_id, CSE_SetClientReady);
                m_script->on_joinplayer(playersao);
 
        }
@@ -1778,7 +1796,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                return;
        }
 
-       if (m_clients.getClientState(peer_id) < Active)
+       if (m_clients.getClientState(peer_id) < CS_Active)
        {
                if (command == TOSERVER_PLAYERPOS) return;
 
@@ -1789,18 +1807,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
        }
 
        Player *player = m_env->getPlayer(peer_id);
-       if(player == NULL){
+       if(player == NULL) {
                errorstream<<"Server::ProcessData(): Cancelling: "
                                "No player for peer_id="<<peer_id
-                               <<std::endl;
+                               << " disconnecting peer!" <<std::endl;
+               m_con.DisconnectPeer(peer_id);
                return;
        }
 
        PlayerSAO *playersao = player->getPlayerSAO();
-       if(playersao == NULL){
+       if(playersao == NULL) {
                errorstream<<"Server::ProcessData(): Cancelling: "
                                "No player object for peer_id="<<peer_id
-                               <<std::endl;
+                               << " disconnecting peer!" <<std::endl;
+               m_con.DisconnectPeer(peer_id);
                return;
        }
 
@@ -2537,14 +2557,17 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
                                if(is_valid_dig && n.getContent() != CONTENT_IGNORE)
                                        m_script->node_on_dig(p_under, n, playersao);
 
+                               v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
+                               RemoteClient *client = getClient(peer_id);
                                // Send unusual result (that is, node not being removed)
                                if(m_env->getMap().getNodeNoEx(p_under).getContent() != CONTENT_AIR)
                                {
                                        // Re-send block to revert change on client-side
-                                       RemoteClient *client = getClient(peer_id);
-                                       v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
                                        client->SetBlockNotSent(blockpos);
                                }
+                               else {
+                                       client->ResendBlockIfOnWire(blockpos);
+                               }
                        }
                } // action == 2
 
@@ -2586,15 +2609,21 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
 
                        // If item has node placement prediction, always send the
                        // blocks to make sure the client knows what exactly happened
-                       if(item.getDefinition(m_itemdef).node_placement_prediction != ""){
-                               RemoteClient *client = getClient(peer_id);
-                               v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
+                       RemoteClient *client = getClient(peer_id);
+                       v3s16 blockpos = getNodeBlockPos(floatToInt(pointed_pos_above, BS));
+                       v3s16 blockpos2 = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
+                       if(item.getDefinition(m_itemdef).node_placement_prediction != "") {
                                client->SetBlockNotSent(blockpos);
-                               v3s16 blockpos2 = getNodeBlockPos(floatToInt(pointed_pos_under, BS));
-                               if(blockpos2 != blockpos){
+                               if(blockpos2 != blockpos) {
                                        client->SetBlockNotSent(blockpos2);
                                }
                        }
+                       else {
+                               client->ResendBlockIfOnWire(blockpos);
+                               if(blockpos2 != blockpos) {
+                                       client->ResendBlockIfOnWire(blockpos2);
+                               }
+                       }
                } // action == 3
 
                /*
@@ -2837,7 +2866,7 @@ void Server::deletingPeer(con::Peer *peer, bool timeout)
        verbosestream<<"Server::deletingPeer(): peer->id="
                        <<peer->id<<", timeout="<<timeout<<std::endl;
 
-       m_clients.event(peer->id,Disconnect);
+       m_clients.event(peer->id, CSE_Disconnect);
        con::PeerChange c;
        c.type = con::PEER_REMOVED;
        c.peer_id = peer->id;
@@ -2866,12 +2895,12 @@ bool Server::getClientInfo(
 {
        *state = m_clients.getClientState(peer_id);
        m_clients.Lock();
-       RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id,Invalid);
+       RemoteClient* client = m_clients.lockedGetClientNoEx(peer_id, CS_Invalid);
 
        if (client == NULL) {
                m_clients.Unlock();
                return false;
-               }
+       }
 
        *uptime = client->uptime();
        *ser_vers = client->serialization_version;
@@ -3132,10 +3161,11 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string &formspec,
        std::ostringstream os(std::ios_base::binary);
        u8 buf[12];
 
+
        // Write command
        writeU16(buf, TOCLIENT_SHOW_FORMSPEC);
        os.write((char*)buf, 2);
-       os<<serializeLongString(formspec);
+       os<<serializeLongString(FORMSPEC_VERSION_STRING + formspec);
        os<<serializeString(formname);
 
        // Make data buffer
@@ -3538,7 +3568,7 @@ void Server::SendPlayerInventoryFormspec(u16 peer_id)
 
        std::ostringstream os(std::ios_base::binary);
        writeU16(os, TOCLIENT_INVENTORY_FORMSPEC);
-       os<<serializeLongString(player->inventory_formspec);
+       os<<serializeLongString(FORMSPEC_VERSION_STRING + player->inventory_formspec);
 
        // Make data buffer
        std::string s = os.str();
@@ -3841,10 +3871,10 @@ void Server::SendBlocks(float dtime)
                        i = clients.begin();
                        i != clients.end(); ++i)
                {
-                       RemoteClient *client = m_clients.lockedGetClientNoEx(*i,Active);
+                       RemoteClient *client = m_clients.lockedGetClientNoEx(*i, CS_Active);
 
                        if (client == NULL)
-                               return;
+                               continue;
 
                        total_sending += client->SendingCount();
                        client->GetNextBlocks(m_env,m_emerge, dtime, queue);
@@ -3877,7 +3907,7 @@ void Server::SendBlocks(float dtime)
                        continue;
                }
 
-               RemoteClient *client = m_clients.lockedGetClientNoEx(q.peer_id,Active);
+               RemoteClient *client = m_clients.lockedGetClientNoEx(q.peer_id, CS_Active);
 
                if(!client)
                        continue;
@@ -4268,7 +4298,7 @@ void Server::DenyAccess(u16 peer_id, const std::wstring &reason)
        DSTACK(__FUNCTION_NAME);
 
        SendAccessDenied(peer_id, reason);
-       m_clients.event(peer_id,SetDenied);
+       m_clients.event(peer_id, CSE_SetDenied);
        m_con.DisconnectPeer(peer_id);
 }
 
@@ -4571,8 +4601,13 @@ bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) {
 
        SendHUDSetFlags(player->peer_id, flags, mask);
        player->hud_flags = flags;
+       
+       PlayerSAO* playersao = player->getPlayerSAO();
+       
+       if (playersao == NULL)
+               return false;
 
-       m_script->player_event(player->getPlayerSAO(),"hud_changed");
+       m_script->player_event(playersao, "hud_changed");
        return true;
 }