From 9f3fc7201beedc66f974d54415b8e3fedb13ccb3 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Fri, 13 Mar 2015 14:14:48 +0100 Subject: [PATCH] Handle the newly added TOCLIENT_ACCESS_DENIED and TOCLIENT_DELETE_PARTICLESPAWNER * Rename the handlers from _Legacy to regular, because here we can use same handlers * Fix some packet names and pseudo handlers --- src/client.h | 4 +- src/network/clientopcodes.cpp | 43 +++++++------- src/network/networkprotocol.h | 80 ++++++++++++++++++++++++++- src/network/packethandlers/client.cpp | 40 +++++++++++--- src/network/serveropcodes.cpp | 41 +++++++------- 5 files changed, 156 insertions(+), 52 deletions(-) diff --git a/src/client.h b/src/client.h index fd20c627a..a0add689a 100644 --- a/src/client.h +++ b/src/client.h @@ -350,7 +350,7 @@ public: void handleCommand_Null(NetworkPacket* pkt) {}; void handleCommand_Deprecated(NetworkPacket* pkt); void handleCommand_Init(NetworkPacket* pkt); - void handleCommand_AccessDenied_Legacy(NetworkPacket* pkt); + void handleCommand_AccessDenied(NetworkPacket* pkt); void handleCommand_RemoveNode(NetworkPacket* pkt); void handleCommand_AddNode(NetworkPacket* pkt); void handleCommand_BlockData(NetworkPacket* pkt); @@ -379,7 +379,7 @@ public: void handleCommand_ShowFormSpec(NetworkPacket* pkt); void handleCommand_SpawnParticle(NetworkPacket* pkt); void handleCommand_AddParticleSpawner(NetworkPacket* pkt); - void handleCommand_DeleteParticleSpawner_Legacy(NetworkPacket* pkt); + void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt); void handleCommand_HudAdd(NetworkPacket* pkt); void handleCommand_HudRemove(NetworkPacket* pkt); void handleCommand_HudChange(NetworkPacket* pkt); diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp index 2ae00b730..f236b6353 100644 --- a/src/network/clientopcodes.cpp +++ b/src/network/clientopcodes.cpp @@ -24,22 +24,22 @@ const static ToClientCommandHandler null_command_handler = {"TOCLIENT_NULL", TOC const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, - null_command_handler, + null_command_handler, // 0x00 (never use this) + null_command_handler, // 0x01 + null_command_handler, // 0x02 + null_command_handler, // 0x03 + null_command_handler, // 0x04 + null_command_handler, // 0x05 + null_command_handler, // 0x06 + null_command_handler, // 0x07 + null_command_handler, // 0x08 + null_command_handler, // 0x09 + { "TOCLIENT_ACCESS_DENIED", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AccessDenied }, // 0x0A + null_command_handler, // 0x0B + null_command_handler, // 0x0C + null_command_handler, // 0x0D + null_command_handler, // 0x0E + null_command_handler, // 0x0F { "TOCLIENT_INIT", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_Init }, // 0x10 null_command_handler, null_command_handler, @@ -77,7 +77,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_ACTIVE_OBJECT_MESSAGES", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_ActiveObjectMessages }, // 0x32 { "TOCLIENT_HP", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HP }, // 0x33 { "TOCLIENT_MOVE_PLAYER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_MovePlayer }, // 0x34 - { "TOCLIENT_ACCESS_DENIED_LEGACY", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AccessDenied_Legacy }, // 0x35 + { "TOCLIENT_ACCESS_DENIED_LEGACY", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AccessDenied }, // 0x35 { "TOCLIENT_PLAYERITEM", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_PlayerItem }, // 0x36 { "TOCLIENT_DEATHSCREEN", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeathScreen }, // 0x37 { "TOCLIENT_MEDIA", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Media }, // 0x38 @@ -96,7 +96,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_MOVEMENT", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_Movement }, // 0x45 { "TOCLIENT_SPAWN_PARTICLE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_SpawnParticle }, // 0x46 { "TOCLIENT_ADD_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_AddParticleSpawner }, // 0x47 - { "TOCLIENT_DELETE_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeleteParticleSpawner_Legacy }, // 0x48 + { "TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeleteParticleSpawner }, // 0x48 { "TOCLIENT_HUDADD", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudAdd }, // 0x49 { "TOCLIENT_HUDRM", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudRemove }, // 0x4a { "TOCLIENT_HUDCHANGE", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_HudChange }, // 0x4b @@ -107,6 +107,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_OverrideDayNightRatio }, // 0x50 { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_LocalPlayerAnimations }, // 0x51 { "TOCLIENT_EYE_OFFSET", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_EyeOffset }, // 0x52 + { "TOCLIENT_DELETE_PARTICLESPAWNER", TOCLIENT_STATE_CONNECTED, &Client::handleCommand_DeleteParticleSpawner }, // 0x53 }; const static ServerCommandFactory null_command_factory = { "TOSERVER_NULL", 0, false }; @@ -128,8 +129,8 @@ const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES] = null_command_factory, // 0x0c null_command_factory, // 0x0d null_command_factory, // 0x0e - null_command_factory, // 0x0f - { "TOSERVER_INIT", 1, false }, // 0x10 + { "TOSERVER_INIT", 1, false }, // 0x0F + { "TOSERVER_INIT_LEGACY", 1, false }, // 0x10 { "TOSERVER_INIT2", 1, true }, // 0x11 null_command_factory, // 0x12 null_command_factory, // 0x13 @@ -174,7 +175,7 @@ const ServerCommandFactory serverCommandFactoryTable[TOSERVER_NUM_MSG_TYPES] = { "TOSERVER_REMOVED_SOUNDS", 1, true }, // 0x3a { "TOSERVER_NODEMETA_FIELDS", 0, true }, // 0x3b { "TOSERVER_INVENTORY_FIELDS", 0, true }, // 0x3c - null_command_factory, // 0x3d + { "TOSERVER_PASSWORD", 0, true }, // 0x3d null_command_factory, // 0x3e null_command_factory, // 0x3f { "TOSERVER_REQUEST_MEDIA", 1, true }, // 0x40 diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 18905a22b..1e0896ebf 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -108,6 +108,16 @@ with this program; if not, write to the Free Software Foundation, Inc., PROTOCOL_VERSION 24: ContentFeatures version 7 ContentFeatures: change number of special tiles to 6 (CF_SPECIAL_COUNT) + PROTOCOL_VERSION 25: + Rename TOCLIENT_ACCESS_DENIED to TOCLIENT_ACCESS_DENIED_LEGAGY + Rename TOCLIENT_DELETE_PARTICLESPAWNER to TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY + Rename TOSERVER_PASSWORD to TOSERVER_PASSWORD_LEGACY + Rename TOSERVER_INIT to TOSERVER_INIT_LEGACY + Add TOCLIENT_ACCESS_DENIED new opcode (0x0A), using error codes + for standard error, keeping customisation possible. This + permit translation + Add TOCLIENT_DELETE_PARTICLESPAWNER (0x53), fixing the u16 read and + reading u32 */ #define LATEST_PROTOCOL_VERSION 24 @@ -133,6 +143,13 @@ with this program; if not, write to the Free Software Foundation, Inc., enum ToClientCommand { + TOCLIENT_ACCESS_DENIED = 0x0A, + /* + u16 command + u16 reason_length + wstring reason + */ + TOCLIENT_INIT = 0x10, /* Server's reply to TOSERVER_INIT. @@ -460,7 +477,7 @@ enum ToClientCommand TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48, /* u16 command - u32 id + u16 id */ TOCLIENT_HUDADD = 0x49, @@ -557,11 +574,30 @@ enum ToClientCommand v3f1000 third */ - TOCLIENT_NUM_MSG_TYPES = 0x53, + TOCLIENT_DELETE_PARTICLESPAWNER = 0x53, + /* + u16 command + u32 id + */ + + TOCLIENT_NUM_MSG_TYPES = 0x54, }; enum ToServerCommand { + TOSERVER_INIT = 0x0F, + /* + Sent first after connected. + + [0] u16 TOSERVER_INIT + [2] u8 SER_FMT_VER_HIGHEST_READ + [3] u8 compression_modes + [4] std::string player_name + [4+*] std::string password (new in some version) + [4+*+*] u16 minimum supported network protocol version (added sometime) + [4+*+*+2] u16 maximum supported network protocol version (added later than the previous one) + */ + TOSERVER_INIT_LEGACY = 0x10, /* Sent first after connected. @@ -767,6 +803,15 @@ enum ToServerCommand u8[len] field value */ + TOSERVER_PASSWORD = 0x3d, + /* + Sent to change password. + + [0] u16 TOSERVER_PASSWORD + [2] std::string old password + [2+*] std::string new password + */ + TOSERVER_REQUEST_MEDIA = 0x40, /* u16 command @@ -801,4 +846,35 @@ enum ToServerCommand TOSERVER_NUM_MSG_TYPES = 0x44, }; +enum AccessDeniedCode { + SERVER_ACCESSDENIED_WRONG_PASSWORD = 0, + SERVER_ACCESSDENIED_UNEXPECTED_DATA = 1, + SERVER_ACCESSDENIED_SINGLEPLAYER = 2, + SERVER_ACCESSDENIED_WRONG_VERSION = 3, + SERVER_ACCESSDENIED_WRONG_CHARS_IN_NAME = 4, + SERVER_ACCESSDENIED_WRONG_NAME = 5, + SERVER_ACCESSDENIED_TOO_MANY_USERS = 6, + SERVER_ACCESSDENIED_EMPTY_PASSWORD = 7, + SERVER_ACCESSDENIED_ALREADY_CONNECTED = 8, + SERVER_ACCESSDENIED_CUSTOM_STRING = 9, + SERVER_ACCESSDENIED_MAX = 10, +}; + +enum NetProtoCompressionMode { + NETPROTO_COMPRESSION_ZLIB = 0, +}; + +const static std::wstring accessDeniedStrings[SERVER_ACCESSDENIED_MAX] = { + L"Invalid password", + L"Your client sent something server didn't expect. Try reconnecting or updating your client", + L"The server is running in simple singleplayer mode. You cannot connect.", + L"Your client's version is not supported.\nPlease contact server administrator.", + L"Name contains unallowed characters", + L"Name is not allowed", + L"Too many users.", + L"Empty passwords are disallowed. Set a password and try again.", + L"Another client is connected with this name. If your client closed unexpectedly, try again in a minute.", + L"", +}; + #endif diff --git a/src/network/packethandlers/client.cpp b/src/network/packethandlers/client.cpp index 7b3adeda4..ae24157e0 100644 --- a/src/network/packethandlers/client.cpp +++ b/src/network/packethandlers/client.cpp @@ -89,15 +89,32 @@ void Client::handleCommand_Init(NetworkPacket* pkt) m_state = LC_Init; } -void Client::handleCommand_AccessDenied_Legacy(NetworkPacket* pkt) +void Client::handleCommand_AccessDenied(NetworkPacket* pkt) { // The server didn't like our password. Note, this needs // to be processed even if the serialisation format has // not been agreed yet, the same as TOCLIENT_INIT. m_access_denied = true; m_access_denied_reason = L"Unknown"; - if (pkt->getSize() >= 2) { - *pkt >> m_access_denied_reason; + + if (pkt->getCommand() == TOCLIENT_ACCESS_DENIED) { + u8 denyCode = SERVER_ACCESSDENIED_UNEXPECTED_DATA; + if(pkt->getSize() >= 1) { + *pkt >> denyCode; + } + if (denyCode == SERVER_ACCESSDENIED_CUSTOM_STRING) { + *pkt >> m_access_denied_reason; + } + else if (denyCode < SERVER_ACCESSDENIED_MAX) { + m_access_denied_reason = accessDeniedStrings[denyCode]; + } + } + // 13/03/15 Legacy code from 0.4.12 and lesser. must stay 1 year + // for compat with old clients + else { + if (pkt->getSize() >= 2) { + *pkt >> m_access_denied_reason; + } } } @@ -822,15 +839,24 @@ void Client::handleCommand_AddParticleSpawner(NetworkPacket* pkt) } -void Client::handleCommand_DeleteParticleSpawner_Legacy(NetworkPacket* pkt) +void Client::handleCommand_DeleteParticleSpawner(NetworkPacket* pkt) { - u16 id; + u16 legacy_id; + u32 id; + + // Modification set 13/03/15, 1 year of compat for protocol v24 + if (pkt->getCommand() == TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY) { + *pkt >> legacy_id; + } + else { + *pkt >> id; + } - *pkt >> id; ClientEvent event; event.type = CE_DELETE_PARTICLESPAWNER; - event.delete_particlespawner.id = (u32) id; + event.delete_particlespawner.id = + (pkt->getCommand() == TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY ? (u32) legacy_id : id); m_client_event_queue.push(event); } diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp index d3cf5c1b6..cecabf7a8 100644 --- a/src/network/serveropcodes.cpp +++ b/src/network/serveropcodes.cpp @@ -24,7 +24,7 @@ const static ToServerCommandHandler null_command_handler = { "TOSERVER_NULL", TO const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] = { - null_command_handler, // 0x00 + null_command_handler, // 0x00 (never use this) null_command_handler, // 0x01 null_command_handler, // 0x02 null_command_handler, // 0x03 @@ -40,7 +40,7 @@ const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] = null_command_handler, // 0x0d null_command_handler, // 0x0e null_command_handler, // 0x0f - { "TOSERVER_INIT_LEGACY", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_Init_Legacy }, // 0x10 + { "TOSERVER_INIT_LEGACY", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_Init_Legacy }, // 0x10 { "TOSERVER_INIT2", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_Init2 }, // 0x11 null_command_handler, // 0x12 null_command_handler, // 0x13 @@ -98,23 +98,23 @@ const static ClientCommandFactory null_command_factory = { "TOCLIENT_NULL", 0, f const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - null_command_factory, - { "TOCLIENT_INIT", 0, true }, // 0x10 + null_command_factory, // 0x00 + null_command_factory, // 0x01 + null_command_factory, // 0x02 + null_command_factory, // 0x03 + null_command_factory, // 0x04 + null_command_factory, // 0x05 + null_command_factory, // 0x06 + null_command_factory, // 0x07 + null_command_factory, // 0x08 + null_command_factory, // 0x09 + { "TOCLIENT_ACCESS_DENIED", 0, true }, // 0x0A + null_command_factory, // 0x0B + null_command_factory, // 0x0C + null_command_factory, // 0x0D + null_command_factory, // 0x0E + null_command_factory, // 0x0F + { "TOCLIENT_INIT", 0, true }, // 0x10 null_command_factory, null_command_factory, null_command_factory, @@ -151,7 +151,7 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_ACTIVE_OBJECT_MESSAGES", 0, true }, // 0x32 Special packet, sent by 0 (rel) and 1 (unrel) channel { "TOCLIENT_HP", 0, true }, // 0x33 { "TOCLIENT_MOVE_PLAYER", 0, true }, // 0x34 - { "TOCLIENT_ACCESS_DENIED_LEGACY", 0, true }, // 0x35 + { "TOCLIENT_ACCESS_DENIED_LEGACY", 0, true }, // 0x35 { "TOCLIENT_PLAYERITEM", 0, false }, // 0x36 obsolete { "TOCLIENT_DEATHSCREEN", 0, true }, // 0x37 { "TOCLIENT_MEDIA", 2, true }, // 0x38 @@ -181,4 +181,5 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] = { "TOCLIENT_OVERRIDE_DAY_NIGHT_RATIO", 0, true }, // 0x50 { "TOCLIENT_LOCAL_PLAYER_ANIMATIONS", 0, true }, // 0x51 { "TOCLIENT_EYE_OFFSET", 0, true }, // 0x52 + { "TOCLIENT_DELETE_PARTICLESPAWNER", 0, true }, // 0x53 };