]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/network/serverpackethandler.cpp
Allow overriding tool capabilities through itemstack metadata
[dragonfireclient.git] / src / network / serverpackethandler.cpp
index 07de20d60113e59519171e3ce10a03f1485340f7..b248b867bc85ae8a5b3b1c368c1d988ae66f3a6f 100644 (file)
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "content_sao.h"
 #include "emerge.h"
 #include "mapblock.h"
+#include "modchannels.h"
 #include "nodedef.h"
 #include "remoteplayer.h"
 #include "rollback_interface.h"
@@ -141,7 +142,8 @@ void Server::handleCommand_Init(NetworkPacket* pkt)
 
        client->net_proto_version = net_proto_version;
 
-       if (g_settings->getBool("strict_protocol_version_checking") ||
+       if ((g_settings->getBool("strict_protocol_version_checking") &&
+                       net_proto_version != LATEST_PROTOCOL_VERSION) ||
                        net_proto_version < SERVER_PROTOCOL_VERSION_MIN ||
                        net_proto_version > SERVER_PROTOCOL_VERSION_MAX) {
                actionstream << "Server: A mismatched client tried to connect from "
@@ -355,7 +357,7 @@ void Server::handleCommand_RequestMedia(NetworkPacket* pkt)
 
 void Server::handleCommand_ClientReady(NetworkPacket* pkt)
 {
-       u16 peer_id = pkt->getPeerId();
+       session_t peer_id = pkt->getPeerId();
 
        PlayerSAO* playersao = StageTwoClientInit(peer_id);
 
@@ -363,7 +365,7 @@ void Server::handleCommand_ClientReady(NetworkPacket* pkt)
                actionstream
                        << "TOSERVER_CLIENT_READY stage 2 client init failed for peer_id: "
                        << peer_id << std::endl;
-               m_con->DisconnectPeer(peer_id);
+               DisconnectPeer(peer_id);
                return;
        }
 
@@ -372,7 +374,7 @@ void Server::handleCommand_ClientReady(NetworkPacket* pkt)
                errorstream
                        << "TOSERVER_CLIENT_READY client sent inconsistent data, disconnecting peer_id: "
                        << peer_id << std::endl;
-               m_con->DisconnectPeer(peer_id);
+               DisconnectPeer(peer_id);
                return;
        }
 
@@ -503,7 +505,7 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -512,7 +514,7 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player object for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -564,7 +566,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -573,7 +575,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player object for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -745,7 +747,7 @@ void Server::handleCommand_ChatMessage(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -773,7 +775,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -782,7 +784,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player object for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -839,7 +841,7 @@ void Server::handleCommand_Password(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -892,7 +894,7 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -901,7 +903,7 @@ void Server::handleCommand_PlayerItem(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player object for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -919,7 +921,7 @@ void Server::handleCommand_Respawn(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -972,7 +974,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -981,7 +983,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player object for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -1124,8 +1126,8 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                        playersao->noCheatDigStart(p_under);
                }
                else if (pointed.type == POINTEDTHING_OBJECT) {
-                       // Skip if object has been removed
-                       if (pointed_object->m_removed)
+                       // Skip if object can't be interacted with anymore
+                       if (pointed_object->isGone())
                                return;
 
                        actionstream<<player->getName()<<" punches object "
@@ -1208,9 +1210,10 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                                // If can't dig, try hand
                                if (!params.diggable) {
                                        InventoryList *hlist = playersao->getInventory()->getList("hand");
-                                       const ItemDefinition &hand =
-                                               hlist ? hlist->getItem(0).getDefinition(m_itemdef) : m_itemdef->get("");
-                                       const ToolCapabilities *tp = hand.tool_capabilities;
+                                       const ToolCapabilities *tp = hlist
+                                               ? &hlist->getItem(0).getToolCapabilities(m_itemdef)
+                                               : m_itemdef->get("").tool_capabilities;
+
                                        if (tp)
                                                params = getDigParams(m_nodedef->get(n).groups, tp);
                                }
@@ -1283,8 +1286,8 @@ void Server::handleCommand_Interact(NetworkPacket* pkt)
                if (pointed.type == POINTEDTHING_OBJECT) {
                        // Right click object
 
-                       // Skip if object has been removed
-                       if (pointed_object->m_removed)
+                       // Skip if object can't be interacted with anymore
+                       if (pointed_object->isGone())
                                return;
 
                        actionstream << player->getName() << " right-clicks object "
@@ -1411,7 +1414,7 @@ void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -1420,7 +1423,7 @@ void Server::handleCommand_NodeMetaFields(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player object for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!"  << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -1462,7 +1465,7 @@ void Server::handleCommand_InventoryFields(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -1471,7 +1474,7 @@ void Server::handleCommand_InventoryFields(NetworkPacket* pkt)
                errorstream << "Server::ProcessData(): Canceling: "
                                "No player object for peer_id=" << pkt->getPeerId()
                                << " disconnecting peer!" << std::endl;
-               m_con->DisconnectPeer(pkt->getPeerId());
+               DisconnectPeer(pkt->getPeerId());
                return;
        }
 
@@ -1733,3 +1736,81 @@ void Server::handleCommand_SrpBytesM(NetworkPacket* pkt)
 
        acceptAuth(pkt->getPeerId(), wantSudo);
 }
+
+/*
+ * Mod channels
+ */
+
+void Server::handleCommand_ModChannelJoin(NetworkPacket *pkt)
+{
+       std::string channel_name;
+       *pkt >> channel_name;
+
+       NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_SIGNAL, 1 + 2 + channel_name.size(),
+               pkt->getPeerId());
+
+       // Send signal to client to notify join succeed or not
+       if (g_settings->getBool("enable_mod_channels") &&
+                       m_modchannel_mgr->joinChannel(channel_name, pkt->getPeerId())) {
+               resp_pkt << (u8) MODCHANNEL_SIGNAL_JOIN_OK;
+               infostream << "Peer " << pkt->getPeerId() << " joined channel " << channel_name
+                               << std::endl;
+       }
+       else {
+               resp_pkt << (u8)MODCHANNEL_SIGNAL_JOIN_FAILURE;
+               infostream << "Peer " << pkt->getPeerId() << " tried to join channel "
+                       << channel_name << ", but was already registered." << std::endl;
+       }
+       resp_pkt << channel_name;
+       Send(&resp_pkt);
+}
+
+void Server::handleCommand_ModChannelLeave(NetworkPacket *pkt)
+{
+       std::string channel_name;
+       *pkt >> channel_name;
+
+       NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_SIGNAL, 1 + 2 + channel_name.size(),
+               pkt->getPeerId());
+
+       // Send signal to client to notify join succeed or not
+       if (g_settings->getBool("enable_mod_channels") &&
+                       m_modchannel_mgr->leaveChannel(channel_name, pkt->getPeerId())) {
+               resp_pkt << (u8)MODCHANNEL_SIGNAL_LEAVE_OK;
+               infostream << "Peer " << pkt->getPeerId() << " left channel " << channel_name
+                               << std::endl;
+       } else {
+               resp_pkt << (u8) MODCHANNEL_SIGNAL_LEAVE_FAILURE;
+               infostream << "Peer " << pkt->getPeerId() << " left channel " << channel_name
+                               << ", but was not registered." << std::endl;
+       }
+       resp_pkt << channel_name;
+       Send(&resp_pkt);
+}
+
+void Server::handleCommand_ModChannelMsg(NetworkPacket *pkt)
+{
+       std::string channel_name, channel_msg;
+       *pkt >> channel_name >> channel_msg;
+
+       verbosestream << "Mod channel message received from peer " << pkt->getPeerId()
+                       << " on channel " << channel_name << " message: " << channel_msg << std::endl;
+
+       // If mod channels are not enabled, discard message
+       if (!g_settings->getBool("enable_mod_channels")) {
+               return;
+       }
+
+       // If channel not registered, signal it and ignore message
+       if (!m_modchannel_mgr->channelRegistered(channel_name)) {
+               NetworkPacket resp_pkt(TOCLIENT_MODCHANNEL_SIGNAL, 1 + 2 + channel_name.size(),
+                       pkt->getPeerId());
+               resp_pkt << (u8)MODCHANNEL_SIGNAL_CHANNEL_NOT_REGISTERED << channel_name;
+               Send(&resp_pkt);
+               return;
+       }
+
+       // @TODO: filter, rate limit
+
+       broadcastModChannelMessage(channel_name, channel_msg, pkt->getPeerId());
+}