diff options
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/clientopcodes.cpp | 10 | ||||
-rw-r--r-- | src/network/clientpackethandler.cpp | 93 | ||||
-rw-r--r-- | src/network/networkprotocol.h | 37 | ||||
-rw-r--r-- | src/network/serveropcodes.cpp | 10 | ||||
-rw-r--r-- | src/network/serverpackethandler.cpp | 117 |
5 files changed, 238 insertions, 29 deletions
diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp index fa63fba65..bc5bd37dd 100644 --- a/src/network/clientopcodes.cpp +++ b/src/network/clientopcodes.cpp @@ -111,8 +111,8 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_CLOUD_PARAMS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_CloudParams }, // 0x54 { "TOCLIENT_FADE_SOUND", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_FadeSound }, // 0x55 { "TOCLIENT_UPDATE_PLAYER_LIST", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_UpdatePlayerList }, // 0x56 - null_command_handler, - null_command_handler, + { "TOCLIENT_MODCHANNEL_MSG", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ModChannelMsg }, // 0x57 + { "TOCLIENT_MODCHANNEL_SIGNAL", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ModChannelSignal }, // 0x58 null_command_handler, null_command_handler, null_command_handler, @@ -150,9 +150,9 @@ const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES] = null_command_factory, // 0x14 null_command_factory, // 0x15 null_command_factory, // 0x16 - null_command_factory, // 0x17 - null_command_factory, // 0x18 - null_command_factory, // 0x19 + { "TOSERVER_MODCHANNEL_JOIN", 0, true }, // 0x17 + { "TOSERVER_MODCHANNEL_LEAVE", 0, true }, // 0x18 + { "TOSERVER_MODCHANNEL_MSG", 0, true }, // 0x19 null_command_factory, // 0x1a null_command_factory, // 0x1b null_command_factory, // 0x1c diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 3ff23453d..b5e2203c8 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "map.h" #include "mapsector.h" #include "minimap.h" +#include "modchannels.h" #include "nodedef.h" #include "serialization.h" #include "server.h" @@ -1330,3 +1331,95 @@ void Client::handleCommand_CSMFlavourLimits(NetworkPacket *pkt) { *pkt >> m_csm_flavour_limits >> m_csm_noderange_limit; } + +/* + * Mod channels + */ + +void Client::handleCommand_ModChannelMsg(NetworkPacket *pkt) +{ + std::string channel_name, sender, channel_msg; + *pkt >> channel_name >> sender >> channel_msg; + + verbosestream << "Mod channel message received from server " << pkt->getPeerId() + << " on channel " << channel_name << ". sender: `" << sender << "`, message: " + << channel_msg << std::endl; + + if (!m_modchannel_mgr->channelRegistered(channel_name)) { + verbosestream << "Server sent us messages on unregistered channel " + << channel_name << ", ignoring." << std::endl; + return; + } + + m_script->on_modchannel_message(channel_name, sender, channel_msg); +} + +void Client::handleCommand_ModChannelSignal(NetworkPacket *pkt) +{ + u8 signal_tmp; + ModChannelSignal signal; + std::string channel; + + *pkt >> signal_tmp >> channel; + + signal = (ModChannelSignal)signal_tmp; + + bool valid_signal = true; + // @TODO: send Signal to Lua API + switch (signal) { + case MODCHANNEL_SIGNAL_JOIN_OK: + m_modchannel_mgr->setChannelState(channel, MODCHANNEL_STATE_READ_WRITE); + infostream << "Server ack our mod channel join on channel `" << channel + << "`, joining." << std::endl; + break; + case MODCHANNEL_SIGNAL_JOIN_FAILURE: + // Unable to join, remove channel + m_modchannel_mgr->leaveChannel(channel, 0); + infostream << "Server refused our mod channel join on channel `" << channel + << "`" << std::endl; + break; + case MODCHANNEL_SIGNAL_LEAVE_OK: +#ifndef NDEBUG + infostream << "Server ack our mod channel leave on channel " << channel + << "`, leaving." << std::endl; +#endif + break; + case MODCHANNEL_SIGNAL_LEAVE_FAILURE: + infostream << "Server refused our mod channel leave on channel `" << channel + << "`" << std::endl; + break; + case MODCHANNEL_SIGNAL_CHANNEL_NOT_REGISTERED: +#ifndef NDEBUG + // Generally unused, but ensure we don't do an implementation error + infostream << "Server tells us we sent a message on channel `" << channel + << "` but we are not registered. Message was dropped." << std::endl; +#endif + break; + case MODCHANNEL_SIGNAL_SET_STATE: { + u8 state; + *pkt >> state; + + if (state == MODCHANNEL_STATE_INIT || state >= MODCHANNEL_STATE_MAX) { + infostream << "Received wrong channel state " << state + << ", ignoring." << std::endl; + return; + } + + m_modchannel_mgr->setChannelState(channel, (ModChannelState) state); + infostream << "Server sets mod channel `" << channel + << "` in read-only mode." << std::endl; + break; + } + default: +#ifndef NDEBUG + warningstream << "Received unhandled mod channel signal ID " + << signal << ", ignoring." << std::endl; +#endif + valid_signal = false; + break; + } + + // If signal is valid, forward it to client side mods + if (valid_signal) + m_script->on_modchannel_signal(channel, signal); +} diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index f4258e9cd..28132396b 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -180,6 +180,7 @@ with this program; if not, write to the Free Software Foundation, Inc., Backwards compatibility drop Add 'can_zoom' to player object properties Add glow to object properties + Mod channels */ #define LATEST_PROTOCOL_VERSION 36 @@ -611,6 +612,22 @@ enum ToClientCommand u8[len] player name */ + TOCLIENT_MODCHANNEL_MSG = 0x57, + /* + u16 channel name length + std::string channel name + u16 channel name sender + std::string channel name + u16 message length + std::string message + */ + TOCLIENT_MODCHANNEL_SIGNAL = 0x58, + /* + u8 signal id + u16 channel name length + std::string channel name + */ + TOCLIENT_SRP_BYTES_S_B = 0x60, /* Belonging to AUTH_MECHANISM_SRP. @@ -645,6 +662,26 @@ enum ToServerCommand [0] u16 TOSERVER_INIT2 */ + TOSERVER_MODCHANNEL_JOIN = 0x17, + /* + u16 channel name length + std::string channel name + */ + + TOSERVER_MODCHANNEL_LEAVE = 0x18, + /* + u16 channel name length + std::string channel name + */ + + TOSERVER_MODCHANNEL_MSG = 0x19, + /* + u16 channel name length + std::string channel name + u16 message length + std::string message + */ + TOSERVER_GETBLOCK = 0x20, // Obsolete TOSERVER_ADDNODE = 0x21, // Obsolete TOSERVER_REMOVENODE = 0x22, // Obsolete diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp index 8c6d159cd..6dcf9c93a 100644 --- a/src/network/serveropcodes.cpp +++ b/src/network/serveropcodes.cpp @@ -47,9 +47,9 @@ const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] = null_command_handler, // 0x14 null_command_handler, // 0x15 null_command_handler, // 0x16 - null_command_handler, // 0x17 - null_command_handler, // 0x18 - null_command_handler, // 0x19 + { "TOSERVER_MODCHANNEL_JOIN", TOSERVER_STATE_INGAME, &Server::handleCommand_ModChannelJoin }, // 0x17 + { "TOSERVER_MODCHANNEL_LEAVE", TOSERVER_STATE_INGAME, &Server::handleCommand_ModChannelLeave }, // 0x18 + { "TOSERVER_MODCHANNEL_MSG", TOSERVER_STATE_INGAME, &Server::handleCommand_ModChannelMsg }, // 0x19 null_command_handler, // 0x1a null_command_handler, // 0x1b null_command_handler, // 0x1c @@ -200,8 +200,8 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_CLOUD_PARAMS", 0, true }, // 0x54 { "TOCLIENT_FADE_SOUND", 0, true }, // 0x55 { "TOCLIENT_UPDATE_PLAYER_LIST", 0, true }, // 0x56 - null_command_factory, - null_command_factory, + { "TOCLIENT_MODCHANNEL_MSG", 0, true}, // 0x57 + { "TOCLIENT_MODCHANNEL_SIGNAL", 0, true}, // 0x58 null_command_factory, null_command_factory, null_command_factory, diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index c4c0c9d0d..7d2f6009f 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -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" @@ -363,7 +364,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 +373,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 +504,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 +513,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 +565,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 +574,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 +746,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 +774,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 +783,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 +840,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 +893,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 +902,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 +920,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 +973,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 +982,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; } @@ -1411,7 +1412,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 +1421,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 +1463,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 +1472,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 +1734,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()); +} |