* Rename the handlers from _Legacy to regular, because here we can use same handlers
* Fix some packet names and pseudo handlers
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);
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);
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,
{ "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
{ "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
{ "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 };
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
{ "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
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
enum ToClientCommand
{
+ TOCLIENT_ACCESS_DENIED = 0x0A,
+ /*
+ u16 command
+ u16 reason_length
+ wstring reason
+ */
+
TOCLIENT_INIT = 0x10,
/*
Server's reply to TOSERVER_INIT.
TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY = 0x48,
/*
u16 command
- u32 id
+ u16 id
*/
TOCLIENT_HUDADD = 0x49,
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.
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
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
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;
+ }
}
}
}
-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);
}
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
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
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,
{ "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
{ "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
};