From 01e4518c8ef8fdc21ba8825c908695f3a8445d3f Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 1 Sep 2022 23:35:37 -0700 Subject: [PATCH] clean up handler tables --- README.md | 1 + src/ChatCommands.cc | 4 +- src/ChatCommands.hh | 4 +- src/CommandFormats.hh | 8 +- src/ProxyCommands.cc | 1918 +++++++++++++++++++++++++++++++------ src/ProxyCommands.hh | 2 +- src/ProxyServer.cc | 4 +- src/ReceiveCommands.cc | 1057 ++++++++------------ src/ReceiveCommands.hh | 6 +- src/ReceiveSubcommands.cc | 611 ++++++------ src/ReceiveSubcommands.hh | 2 +- src/SendCommands.cc | 2 +- src/Server.cc | 10 +- src/Version.hh | 4 +- 14 files changed, 2373 insertions(+), 1260 deletions(-) diff --git a/README.md b/README.md index 7c4b16a9..590e9a18 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ newserv supports several versions of PSO. Specifically: This project is primarily for my own nostalgia; I offer no guarantees on how or when this project will advance. With that said, feel free to submit GitHub issues if you find bugs or have feature requests. I'd like to make the server as stable and complete as possible, but I can't promise that I'll respond to issues in a timely manner. Current known issues / missing features: +- Support disconnect hooks to clean up state, like if a client disconnects during quest loading or a trade window execution. - Episode 3 battles aren't implemented. - PSOBB is not well-tested and likely will disconnect or misbehave when clients try to use unimplemented features. - Fix some edge cases on the BB proxy server (e.g. make sure Change Ship does the right thing, which is not the same as what it should do on V2/V3). diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index a7615df3..0d3e5fa3 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -933,7 +933,7 @@ struct SplitCommand { // This function is called every time any player sends a chat beginning with a // dollar sign. It is this function's responsibility to see if the chat is a // command, and to execute the command and block the chat if it is. -void process_chat_command(std::shared_ptr s, std::shared_ptr l, +void on_chat_command(std::shared_ptr s, std::shared_ptr l, std::shared_ptr c, const std::u16string& text) { SplitCommand cmd(text); @@ -958,7 +958,7 @@ void process_chat_command(std::shared_ptr s, std::shared_ptr } } -void process_chat_command(std::shared_ptr s, +void on_chat_command(std::shared_ptr s, ProxyServer::LinkedSession& session, const std::u16string& text) { SplitCommand cmd(text); diff --git a/src/ChatCommands.hh b/src/ChatCommands.hh index 61b8796c..107c8c34 100644 --- a/src/ChatCommands.hh +++ b/src/ChatCommands.hh @@ -10,7 +10,7 @@ #include "Client.hh" #include "ProxyServer.hh" -void process_chat_command(std::shared_ptr s, std::shared_ptr l, +void on_chat_command(std::shared_ptr s, std::shared_ptr l, std::shared_ptr c, const std::u16string& text); -void process_chat_command(std::shared_ptr s, +void on_chat_command(std::shared_ptr s, ProxyServer::LinkedSession& session, const std::u16string& text); diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index d0dfc017..5e33b2df 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -1992,7 +1992,7 @@ struct S_ConfirmTournamentEntry_GC_Ep3_CC { // D0 (C->S): Start trade sequence (V3/BB) // The trade window sequence is a bit complicated. The normal flow is: -// - Clients sync trade state with 60xA6 commands (technically 62xA6) +// - Clients sync trade state with 6xA6 commands // - When both have confirmed, one client (the initiator) sends a D0 // - Server sends a D1 to the non-initiator // - Non-initiator sends a D0 @@ -2009,6 +2009,8 @@ struct S_ConfirmTournamentEntry_GC_Ep3_CC { // At any point if an error occurs, either client may send a D4 00, which // cancels the entire sequence. The server should then send D4 00 to both // clients. +// TODO: The server should presumably also send a D4 00 if either client +// disconnects during the sequence. struct SC_TradeItems_D0_D3 { // D0 when sent by client, D3 when sent by server le_uint16_t target_client_id; @@ -2230,8 +2232,8 @@ struct S_Unknown_GC_Ep3_E1 { // header.flag = 00 => request tournament list (server responds with E0) // header.flag = 01 => check tournament // header.flag = 02 => cancel tournament entry -// header.flag = 03 => create tournament spectator team -// header.flag = 04 => join tournament spectator team +// header.flag = 03 => create tournament spectator team (get battle list) +// header.flag = 04 => join tournament spectator team (get team list) // E2 (S->C): Tournament entry list (Episode 3) // Client may send 09 commands if the player presses X. It's not clear what the diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index c0aadf0a..aaed4060 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -107,12 +107,12 @@ struct HandlerResult { : type(type), new_command(new_command), new_flag(new_flag) { } }; -static HandlerResult process_default(shared_ptr, +static HandlerResult on_default(shared_ptr, ProxyServer::LinkedSession&, uint16_t, uint32_t, string&) { return HandlerResult::Type::FORWARD; } -static HandlerResult process_server_97(shared_ptr, +static HandlerResult on_server_97(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t flag, string&) { // Update the newserv client config so we'll know not to show the Programs // menu if they return to newserv @@ -125,7 +125,7 @@ static HandlerResult process_server_97(shared_ptr, return HandlerResult::Type::FORWARD; } -static HandlerResult process_server_gc_9A(shared_ptr, +static HandlerResult on_server_gc_9A(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) { if (!session.license) { return HandlerResult::Type::FORWARD; @@ -159,7 +159,7 @@ static HandlerResult process_server_gc_9A(shared_ptr, return HandlerResult::Type::SUPPRESS; } -static HandlerResult process_server_dc_pc_v3_patch_02_17( +static HandlerResult on_server_dc_pc_v3_patch_02_17( shared_ptr s, ProxyServer::LinkedSession& session, uint16_t command, @@ -320,7 +320,7 @@ static HandlerResult process_server_dc_pc_v3_patch_02_17( } else { // For command 02, send the same as if we had received 9A from the server - return process_server_gc_9A(s, session, command, flag, data); + return on_server_gc_9A(s, session, command, flag, data); } } else if (session.version == GameVersion::XB) { @@ -331,7 +331,7 @@ static HandlerResult process_server_dc_pc_v3_patch_02_17( } } -static HandlerResult process_server_bb_03(shared_ptr s, +static HandlerResult on_server_bb_03(shared_ptr s, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { // Most servers don't include after_message or have a shorter after_message // than newserv does, so don't require it @@ -388,7 +388,7 @@ static HandlerResult process_server_bb_03(shared_ptr s, } } -static HandlerResult process_server_dc_pc_v3_04(shared_ptr, +static HandlerResult on_server_dc_pc_v3_04(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { // Some servers send a short 04 command if they don't use all of the 0x20 // bytes available. We should be prepared to handle that. @@ -443,7 +443,7 @@ static HandlerResult process_server_dc_pc_v3_04(shared_ptr, return session.license ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } -static HandlerResult process_server_dc_pc_v3_06(shared_ptr, +static HandlerResult on_server_dc_pc_v3_06(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { if (session.license) { auto& cmd = check_size_t(data, @@ -457,7 +457,7 @@ static HandlerResult process_server_dc_pc_v3_06(shared_ptr, } template -static HandlerResult process_server_41(shared_ptr, +static HandlerResult on_server_41(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { bool modified = false; if (session.license) { @@ -475,7 +475,7 @@ static HandlerResult process_server_41(shared_ptr, } template -static HandlerResult process_server_81(shared_ptr, +static HandlerResult on_server_81(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { bool modified = false; if (session.license) { @@ -492,7 +492,7 @@ static HandlerResult process_server_81(shared_ptr, return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } -static HandlerResult process_server_88(shared_ptr, +static HandlerResult on_server_88(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t flag, string& data) { bool modified = false; if (session.license) { @@ -509,7 +509,7 @@ static HandlerResult process_server_88(shared_ptr, return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } -static HandlerResult process_server_B2(shared_ptr, +static HandlerResult on_server_B2(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t flag, string& data) { const auto& cmd = check_size_t(data, sizeof(S_ExecuteCode_B2), 0xFFFF); @@ -609,7 +609,7 @@ static HandlerResult process_server_B2(shared_ptr, } } -static HandlerResult process_server_E7(shared_ptr, +static HandlerResult on_server_E7(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { if (session.save_files) { string output_filename = string_printf("player.%" PRId64 ".bin", now()); @@ -620,7 +620,7 @@ static HandlerResult process_server_E7(shared_ptr, } template -static HandlerResult process_server_C4(shared_ptr, +static HandlerResult on_server_C4(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t flag, string& data) { bool modified = false; if (session.license) { @@ -638,7 +638,7 @@ static HandlerResult process_server_C4(shared_ptr, return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } -static HandlerResult process_server_gc_E4(shared_ptr, +static HandlerResult on_server_gc_E4(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { auto& cmd = check_size_t(data); bool modified = false; @@ -651,7 +651,7 @@ static HandlerResult process_server_gc_E4(shared_ptr, return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } -static HandlerResult process_server_bb_22(shared_ptr, +static HandlerResult on_server_bb_22(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { // We use this command (which is sent before the init encryption command) to // detect a particular server behavior that we'll have to work around later. @@ -670,7 +670,7 @@ static HandlerResult process_server_bb_22(shared_ptr, return HandlerResult::Type::FORWARD; } -static HandlerResult process_server_game_19_patch_14(shared_ptr, +static HandlerResult on_server_game_19_patch_14(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { // If the command is shorter than 6 bytes, use the previous server command to // fill it in. This simulates a behavior used by some private servers where a @@ -737,7 +737,7 @@ static HandlerResult process_server_game_19_patch_14(shared_ptr, } } -static HandlerResult process_server_v3_1A_D5(shared_ptr, +static HandlerResult on_server_v3_1A_D5(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) { // If the client is a version that sends close confirmations and the client // has the no-close-confirmation flag set in its newserv client config, send a @@ -749,7 +749,7 @@ static HandlerResult process_server_v3_1A_D5(shared_ptr, return HandlerResult::Type::FORWARD; } -static HandlerResult process_server_60_62_6C_6D_C9_CB(shared_ptr, +static HandlerResult on_server_60_62_6C_6D_C9_CB(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { check_implemented_subcommand(session, data); @@ -800,7 +800,7 @@ static HandlerResult process_server_60_62_6C_6D_C9_CB(shared_ptr, } template -static HandlerResult process_server_44_A6(shared_ptr, +static HandlerResult on_server_44_A6(shared_ptr, ProxyServer::LinkedSession& session, uint16_t command, uint32_t, string& data) { if (session.save_files) { const auto& cmd = check_size_t(data); @@ -827,7 +827,7 @@ static HandlerResult process_server_44_A6(shared_ptr, return HandlerResult::Type::FORWARD; } -static HandlerResult process_server_13_A7(shared_ptr, +static HandlerResult on_server_13_A7(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { if (session.save_files) { const auto& cmd = check_size_t(data); @@ -864,7 +864,7 @@ static HandlerResult process_server_13_A7(shared_ptr, return HandlerResult::Type::FORWARD; } -static HandlerResult process_server_gc_B8(shared_ptr, +static HandlerResult on_server_gc_B8(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { if (session.save_files) { if (data.size() < 4) { @@ -897,7 +897,7 @@ static void update_leader_id(ProxyServer::LinkedSession& session, uint8_t leader } template -static HandlerResult process_server_65_67_68(shared_ptr, +static HandlerResult on_server_65_67_68(shared_ptr, ProxyServer::LinkedSession& session, uint16_t command, uint32_t flag, string& data) { if (command == 0x67) { session.lobby_players.clear(); @@ -952,7 +952,7 @@ static HandlerResult process_server_65_67_68(shared_ptr, } template -static HandlerResult process_server_64(shared_ptr, +static HandlerResult on_server_64(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t flag, string& data) { // We don't need to clear lobby_players here because we always // overwrite all 4 entries for this command @@ -1006,7 +1006,7 @@ static HandlerResult process_server_64(shared_ptr, return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } -static HandlerResult process_server_66_69(shared_ptr, +static HandlerResult on_server_66_69(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { const auto& cmd = check_size_t(data); size_t index = cmd.client_id; @@ -1021,7 +1021,7 @@ static HandlerResult process_server_66_69(shared_ptr, return HandlerResult::Type::FORWARD; } -static HandlerResult process_client_06(shared_ptr s, +static HandlerResult on_client_06(shared_ptr s, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { if (data.size() >= 12) { u16string text; @@ -1045,7 +1045,7 @@ static HandlerResult process_client_06(shared_ptr s, send_chat_message(session.server_channel, text.substr(1)); return HandlerResult::Type::SUPPRESS; } else { - process_chat_command(s, session, text); + on_chat_command(s, session, text); return HandlerResult::Type::SUPPRESS; } @@ -1064,7 +1064,7 @@ static HandlerResult process_client_06(shared_ptr s, } } -static HandlerResult process_client_40(shared_ptr, +static HandlerResult on_client_40(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { bool modified = false; if (session.license) { @@ -1082,7 +1082,7 @@ static HandlerResult process_client_40(shared_ptr, } template -static HandlerResult process_client_81(shared_ptr, +static HandlerResult on_client_81(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { auto& cmd = check_size_t(data); if (session.license) { @@ -1099,7 +1099,7 @@ static HandlerResult process_client_81(shared_ptr, } template -static HandlerResult process_client_60_62_6C_6D_C9_CB(shared_ptr s, +static HandlerResult on_client_60_62_6C_6D_C9_CB(shared_ptr s, ProxyServer::LinkedSession& session, uint16_t command, uint32_t flag, string& data) { if (session.license && !data.empty()) { if (data[0] == 0x06) { @@ -1140,11 +1140,11 @@ static HandlerResult process_client_60_62_6C_6D_C9_CB(shared_ptr s, } } } - return process_client_60_62_6C_6D_C9_CB(s, session, command, flag, data); + return on_client_60_62_6C_6D_C9_CB(s, session, command, flag, data); } template <> -HandlerResult process_client_60_62_6C_6D_C9_CB(shared_ptr, +HandlerResult on_client_60_62_6C_6D_C9_CB(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) { check_implemented_subcommand(session, data); @@ -1165,7 +1165,7 @@ HandlerResult process_client_60_62_6C_6D_C9_CB(shared_ptr, return HandlerResult::Type::FORWARD; } -static HandlerResult process_client_dc_pc_v3_A0_A1(shared_ptr, +static HandlerResult on_client_dc_pc_v3_A0_A1(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) { if (!session.license) { return HandlerResult::Type::FORWARD; @@ -1179,272 +1179,1632 @@ static HandlerResult process_client_dc_pc_v3_A0_A1(shared_ptr, -typedef HandlerResult (*process_command_t)( +typedef HandlerResult (*on_command_t)( shared_ptr s, ProxyServer::LinkedSession& session, uint16_t command, uint32_t flag, string& data); -// The entries in these arrays correspond to the ID of the command received. For -// instance, if a command 6C is received, the function at position 0x6C in the -// array corresponding to the client's version is called. -auto defh = process_default; - -static process_command_t dc_server_handlers[0x100] = { - /* 00 */ defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_dc_pc_v3_04, defh, process_server_dc_pc_v3_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, process_server_13_A7, defh, defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_game_19_patch_14, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ defh, process_server_41, defh, defh, process_server_44_A6, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_64, process_server_65_67_68, process_server_66_69, process_server_65_67_68, process_server_65_67_68, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, process_server_97, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, process_server_44_A6, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t pc_server_handlers[0x100] = { - /* 00 */ defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_dc_pc_v3_04, defh, process_server_dc_pc_v3_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, process_server_13_A7, defh, defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_game_19_patch_14, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ defh, process_server_41, defh, defh, process_server_44_A6, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_64, process_server_65_67_68, process_server_66_69, process_server_65_67_68, process_server_65_67_68, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, process_server_97, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, process_server_44_A6, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t gc_server_handlers[0x100] = { - /* 00 */ defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_dc_pc_v3_04, defh, process_server_dc_pc_v3_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, process_server_13_A7, defh, defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_game_19_patch_14, process_server_v3_1A_D5, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ defh, process_server_41, defh, defh, process_server_44_A6, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_64, process_server_65_67_68, process_server_66_69, process_server_65_67_68, process_server_65_67_68, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, process_server_81, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, process_server_97, defh, defh, process_server_gc_9A, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, process_server_44_A6, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, process_server_B2, defh, defh, defh, defh, defh, process_server_gc_B8, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, process_server_C4, defh, defh, defh, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, process_server_v3_1A_D5, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, process_server_gc_E4, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t xb_server_handlers[0x100] = { - /* 00 */ defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_dc_pc_v3_04, defh, process_server_dc_pc_v3_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, process_server_13_A7, defh, defh, defh, process_server_dc_pc_v3_patch_02_17, defh, process_server_game_19_patch_14, process_server_v3_1A_D5, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ defh, process_server_41, defh, defh, process_server_44_A6, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_64, process_server_65_67_68, process_server_66_69, process_server_65_67_68, process_server_65_67_68, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, process_server_81, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, process_server_97, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, process_server_44_A6, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, process_server_B2, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, process_server_C4, defh, defh, defh, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, process_server_v3_1A_D5, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t bb_server_handlers[0x100] = { - /* 00 */ defh, defh, defh, process_server_bb_03, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, process_server_13_A7, defh, defh, defh, defh, defh, process_server_game_19_patch_14, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, process_server_bb_22, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ defh, process_server_41, defh, defh, process_server_44_A6, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_64, process_server_65_67_68, process_server_66_69, process_server_65_67_68, process_server_65_67_68, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, process_server_44_A6, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, process_server_B2, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, process_server_E7, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t patch_server_handlers[0x100] = { - /* 00 */ defh, defh, process_server_dc_pc_v3_patch_02_17, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, defh, process_server_game_19_patch_14, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, +// [version][command][is_client] +static on_command_t handlers[6][0x100][2] = { + { + // PATCH SERVER CLIENT + /* 00 */ {nullptr, nullptr}, + /* 01 */ {nullptr, nullptr}, + /* 02 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 03 */ {nullptr, nullptr}, + /* 04 */ {nullptr, nullptr}, + /* 05 */ {nullptr, nullptr}, + /* 06 */ {nullptr, nullptr}, + /* 07 */ {nullptr, nullptr}, + /* 08 */ {nullptr, nullptr}, + /* 09 */ {nullptr, nullptr}, + /* 0A */ {nullptr, nullptr}, + /* 0B */ {nullptr, nullptr}, + /* 0C */ {nullptr, nullptr}, + /* 0D */ {nullptr, nullptr}, + /* 0E */ {nullptr, nullptr}, + /* 0F */ {nullptr, nullptr}, + /* 10 */ {nullptr, nullptr}, + /* 11 */ {nullptr, nullptr}, + /* 12 */ {nullptr, nullptr}, + /* 13 */ {nullptr, nullptr}, + /* 14 */ {on_server_game_19_patch_14, nullptr}, + /* 15 */ {nullptr, nullptr}, + /* 16 */ {nullptr, nullptr}, + /* 17 */ {nullptr, nullptr}, + /* 18 */ {nullptr, nullptr}, + /* 19 */ {nullptr, nullptr}, + /* 1A */ {nullptr, nullptr}, + /* 1B */ {nullptr, nullptr}, + /* 1C */ {nullptr, nullptr}, + /* 1D */ {nullptr, nullptr}, + /* 1E */ {nullptr, nullptr}, + /* 1F */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + /* 20 */ {nullptr, nullptr}, + /* 21 */ {nullptr, nullptr}, + /* 22 */ {nullptr, nullptr}, + /* 23 */ {nullptr, nullptr}, + /* 24 */ {nullptr, nullptr}, + /* 25 */ {nullptr, nullptr}, + /* 26 */ {nullptr, nullptr}, + /* 27 */ {nullptr, nullptr}, + /* 28 */ {nullptr, nullptr}, + /* 29 */ {nullptr, nullptr}, + /* 2A */ {nullptr, nullptr}, + /* 2B */ {nullptr, nullptr}, + /* 2C */ {nullptr, nullptr}, + /* 2D */ {nullptr, nullptr}, + /* 2E */ {nullptr, nullptr}, + /* 2F */ {nullptr, nullptr}, + /* 30 */ {nullptr, nullptr}, + /* 31 */ {nullptr, nullptr}, + /* 32 */ {nullptr, nullptr}, + /* 33 */ {nullptr, nullptr}, + /* 34 */ {nullptr, nullptr}, + /* 35 */ {nullptr, nullptr}, + /* 36 */ {nullptr, nullptr}, + /* 37 */ {nullptr, nullptr}, + /* 38 */ {nullptr, nullptr}, + /* 39 */ {nullptr, nullptr}, + /* 3A */ {nullptr, nullptr}, + /* 3B */ {nullptr, nullptr}, + /* 3C */ {nullptr, nullptr}, + /* 3D */ {nullptr, nullptr}, + /* 3E */ {nullptr, nullptr}, + /* 3F */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + /* 40 */ {nullptr, nullptr}, + /* 41 */ {nullptr, nullptr}, + /* 42 */ {nullptr, nullptr}, + /* 43 */ {nullptr, nullptr}, + /* 44 */ {nullptr, nullptr}, + /* 45 */ {nullptr, nullptr}, + /* 46 */ {nullptr, nullptr}, + /* 47 */ {nullptr, nullptr}, + /* 48 */ {nullptr, nullptr}, + /* 49 */ {nullptr, nullptr}, + /* 4A */ {nullptr, nullptr}, + /* 4B */ {nullptr, nullptr}, + /* 4C */ {nullptr, nullptr}, + /* 4D */ {nullptr, nullptr}, + /* 4E */ {nullptr, nullptr}, + /* 4F */ {nullptr, nullptr}, + /* 50 */ {nullptr, nullptr}, + /* 51 */ {nullptr, nullptr}, + /* 52 */ {nullptr, nullptr}, + /* 53 */ {nullptr, nullptr}, + /* 54 */ {nullptr, nullptr}, + /* 55 */ {nullptr, nullptr}, + /* 56 */ {nullptr, nullptr}, + /* 57 */ {nullptr, nullptr}, + /* 58 */ {nullptr, nullptr}, + /* 59 */ {nullptr, nullptr}, + /* 5A */ {nullptr, nullptr}, + /* 5B */ {nullptr, nullptr}, + /* 5C */ {nullptr, nullptr}, + /* 5D */ {nullptr, nullptr}, + /* 5E */ {nullptr, nullptr}, + /* 5F */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + /* 60 */ {nullptr, nullptr}, + /* 61 */ {nullptr, nullptr}, + /* 62 */ {nullptr, nullptr}, + /* 63 */ {nullptr, nullptr}, + /* 64 */ {nullptr, nullptr}, + /* 65 */ {nullptr, nullptr}, + /* 66 */ {nullptr, nullptr}, + /* 67 */ {nullptr, nullptr}, + /* 68 */ {nullptr, nullptr}, + /* 69 */ {nullptr, nullptr}, + /* 6A */ {nullptr, nullptr}, + /* 6B */ {nullptr, nullptr}, + /* 6C */ {nullptr, nullptr}, + /* 6D */ {nullptr, nullptr}, + /* 6E */ {nullptr, nullptr}, + /* 6F */ {nullptr, nullptr}, + /* 70 */ {nullptr, nullptr}, + /* 71 */ {nullptr, nullptr}, + /* 72 */ {nullptr, nullptr}, + /* 73 */ {nullptr, nullptr}, + /* 74 */ {nullptr, nullptr}, + /* 75 */ {nullptr, nullptr}, + /* 76 */ {nullptr, nullptr}, + /* 77 */ {nullptr, nullptr}, + /* 78 */ {nullptr, nullptr}, + /* 79 */ {nullptr, nullptr}, + /* 7A */ {nullptr, nullptr}, + /* 7B */ {nullptr, nullptr}, + /* 7C */ {nullptr, nullptr}, + /* 7D */ {nullptr, nullptr}, + /* 7E */ {nullptr, nullptr}, + /* 7F */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + /* 80 */ {nullptr, nullptr}, + /* 81 */ {nullptr, nullptr}, + /* 82 */ {nullptr, nullptr}, + /* 83 */ {nullptr, nullptr}, + /* 84 */ {nullptr, nullptr}, + /* 85 */ {nullptr, nullptr}, + /* 86 */ {nullptr, nullptr}, + /* 87 */ {nullptr, nullptr}, + /* 88 */ {nullptr, nullptr}, + /* 89 */ {nullptr, nullptr}, + /* 8A */ {nullptr, nullptr}, + /* 8B */ {nullptr, nullptr}, + /* 8C */ {nullptr, nullptr}, + /* 8D */ {nullptr, nullptr}, + /* 8E */ {nullptr, nullptr}, + /* 8F */ {nullptr, nullptr}, + /* 90 */ {nullptr, nullptr}, + /* 91 */ {nullptr, nullptr}, + /* 92 */ {nullptr, nullptr}, + /* 93 */ {nullptr, nullptr}, + /* 94 */ {nullptr, nullptr}, + /* 95 */ {nullptr, nullptr}, + /* 96 */ {nullptr, nullptr}, + /* 97 */ {nullptr, nullptr}, + /* 98 */ {nullptr, nullptr}, + /* 99 */ {nullptr, nullptr}, + /* 9A */ {nullptr, nullptr}, + /* 9B */ {nullptr, nullptr}, + /* 9C */ {nullptr, nullptr}, + /* 9D */ {nullptr, nullptr}, + /* 9E */ {nullptr, nullptr}, + /* 9F */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + /* A0 */ {nullptr, nullptr}, + /* A1 */ {nullptr, nullptr}, + /* A2 */ {nullptr, nullptr}, + /* A3 */ {nullptr, nullptr}, + /* A4 */ {nullptr, nullptr}, + /* A5 */ {nullptr, nullptr}, + /* A6 */ {nullptr, nullptr}, + /* A7 */ {nullptr, nullptr}, + /* A8 */ {nullptr, nullptr}, + /* A9 */ {nullptr, nullptr}, + /* AA */ {nullptr, nullptr}, + /* AB */ {nullptr, nullptr}, + /* AC */ {nullptr, nullptr}, + /* AD */ {nullptr, nullptr}, + /* AE */ {nullptr, nullptr}, + /* AF */ {nullptr, nullptr}, + /* B0 */ {nullptr, nullptr}, + /* B1 */ {nullptr, nullptr}, + /* B2 */ {nullptr, nullptr}, + /* B3 */ {nullptr, nullptr}, + /* B4 */ {nullptr, nullptr}, + /* B5 */ {nullptr, nullptr}, + /* B6 */ {nullptr, nullptr}, + /* B7 */ {nullptr, nullptr}, + /* B8 */ {nullptr, nullptr}, + /* B9 */ {nullptr, nullptr}, + /* BA */ {nullptr, nullptr}, + /* BB */ {nullptr, nullptr}, + /* BC */ {nullptr, nullptr}, + /* BD */ {nullptr, nullptr}, + /* BE */ {nullptr, nullptr}, + /* BF */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + /* C0 */ {nullptr, nullptr}, + /* C1 */ {nullptr, nullptr}, + /* C2 */ {nullptr, nullptr}, + /* C3 */ {nullptr, nullptr}, + /* C4 */ {nullptr, nullptr}, + /* C5 */ {nullptr, nullptr}, + /* C6 */ {nullptr, nullptr}, + /* C7 */ {nullptr, nullptr}, + /* C8 */ {nullptr, nullptr}, + /* C9 */ {nullptr, nullptr}, + /* CA */ {nullptr, nullptr}, + /* CB */ {nullptr, nullptr}, + /* CC */ {nullptr, nullptr}, + /* CD */ {nullptr, nullptr}, + /* CE */ {nullptr, nullptr}, + /* CF */ {nullptr, nullptr}, + /* D0 */ {nullptr, nullptr}, + /* D1 */ {nullptr, nullptr}, + /* D2 */ {nullptr, nullptr}, + /* D3 */ {nullptr, nullptr}, + /* D4 */ {nullptr, nullptr}, + /* D5 */ {nullptr, nullptr}, + /* D6 */ {nullptr, nullptr}, + /* D7 */ {nullptr, nullptr}, + /* D8 */ {nullptr, nullptr}, + /* D9 */ {nullptr, nullptr}, + /* DA */ {nullptr, nullptr}, + /* DB */ {nullptr, nullptr}, + /* DC */ {nullptr, nullptr}, + /* DD */ {nullptr, nullptr}, + /* DE */ {nullptr, nullptr}, + /* DF */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + /* E0 */ {nullptr, nullptr}, + /* E1 */ {nullptr, nullptr}, + /* E2 */ {nullptr, nullptr}, + /* E3 */ {nullptr, nullptr}, + /* E4 */ {nullptr, nullptr}, + /* E5 */ {nullptr, nullptr}, + /* E6 */ {nullptr, nullptr}, + /* E7 */ {nullptr, nullptr}, + /* E8 */ {nullptr, nullptr}, + /* E9 */ {nullptr, nullptr}, + /* EA */ {nullptr, nullptr}, + /* EB */ {nullptr, nullptr}, + /* EC */ {nullptr, nullptr}, + /* ED */ {nullptr, nullptr}, + /* EE */ {nullptr, nullptr}, + /* EF */ {nullptr, nullptr}, + /* F0 */ {nullptr, nullptr}, + /* F1 */ {nullptr, nullptr}, + /* F2 */ {nullptr, nullptr}, + /* F3 */ {nullptr, nullptr}, + /* F4 */ {nullptr, nullptr}, + /* F5 */ {nullptr, nullptr}, + /* F6 */ {nullptr, nullptr}, + /* F7 */ {nullptr, nullptr}, + /* F8 */ {nullptr, nullptr}, + /* F9 */ {nullptr, nullptr}, + /* FA */ {nullptr, nullptr}, + /* FB */ {nullptr, nullptr}, + /* FC */ {nullptr, nullptr}, + /* FD */ {nullptr, nullptr}, + /* FE */ {nullptr, nullptr}, + /* FF */ {nullptr, nullptr}, + // PATCH SERVER CLIENT + }, { + // (DC) SERVER CLIENT + /* 00 */ {nullptr, nullptr}, + /* 01 */ {nullptr, nullptr}, + /* 02 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 03 */ {nullptr, nullptr}, + /* 04 */ {on_server_dc_pc_v3_04, nullptr}, + /* 05 */ {nullptr, nullptr}, + /* 06 */ {on_server_dc_pc_v3_06, on_client_06}, + /* 07 */ {nullptr, nullptr}, + /* 08 */ {nullptr, nullptr}, + /* 09 */ {nullptr, nullptr}, + /* 0A */ {nullptr, nullptr}, + /* 0B */ {nullptr, nullptr}, + /* 0C */ {nullptr, nullptr}, + /* 0D */ {nullptr, nullptr}, + /* 0E */ {nullptr, nullptr}, + /* 0F */ {nullptr, nullptr}, + /* 10 */ {nullptr, nullptr}, + /* 11 */ {nullptr, nullptr}, + /* 12 */ {nullptr, nullptr}, + /* 13 */ {on_server_13_A7, nullptr}, + /* 14 */ {nullptr, nullptr}, + /* 15 */ {nullptr, nullptr}, + /* 16 */ {nullptr, nullptr}, + /* 17 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 18 */ {nullptr, nullptr}, + /* 19 */ {on_server_game_19_patch_14, nullptr}, + /* 1A */ {nullptr, nullptr}, + /* 1B */ {nullptr, nullptr}, + /* 1C */ {nullptr, nullptr}, + /* 1D */ {nullptr, nullptr}, + /* 1E */ {nullptr, nullptr}, + /* 1F */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + /* 20 */ {nullptr, nullptr}, + /* 21 */ {nullptr, nullptr}, + /* 22 */ {nullptr, nullptr}, + /* 23 */ {nullptr, nullptr}, + /* 24 */ {nullptr, nullptr}, + /* 25 */ {nullptr, nullptr}, + /* 26 */ {nullptr, nullptr}, + /* 27 */ {nullptr, nullptr}, + /* 28 */ {nullptr, nullptr}, + /* 29 */ {nullptr, nullptr}, + /* 2A */ {nullptr, nullptr}, + /* 2B */ {nullptr, nullptr}, + /* 2C */ {nullptr, nullptr}, + /* 2D */ {nullptr, nullptr}, + /* 2E */ {nullptr, nullptr}, + /* 2F */ {nullptr, nullptr}, + /* 30 */ {nullptr, nullptr}, + /* 31 */ {nullptr, nullptr}, + /* 32 */ {nullptr, nullptr}, + /* 33 */ {nullptr, nullptr}, + /* 34 */ {nullptr, nullptr}, + /* 35 */ {nullptr, nullptr}, + /* 36 */ {nullptr, nullptr}, + /* 37 */ {nullptr, nullptr}, + /* 38 */ {nullptr, nullptr}, + /* 39 */ {nullptr, nullptr}, + /* 3A */ {nullptr, nullptr}, + /* 3B */ {nullptr, nullptr}, + /* 3C */ {nullptr, nullptr}, + /* 3D */ {nullptr, nullptr}, + /* 3E */ {nullptr, nullptr}, + /* 3F */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + /* 40 */ {nullptr, on_client_40}, + /* 41 */ {on_server_41, nullptr}, + /* 42 */ {nullptr, nullptr}, + /* 43 */ {nullptr, nullptr}, + /* 44 */ {on_server_44_A6, nullptr}, + /* 45 */ {nullptr, nullptr}, + /* 46 */ {nullptr, nullptr}, + /* 47 */ {nullptr, nullptr}, + /* 48 */ {nullptr, nullptr}, + /* 49 */ {nullptr, nullptr}, + /* 4A */ {nullptr, nullptr}, + /* 4B */ {nullptr, nullptr}, + /* 4C */ {nullptr, nullptr}, + /* 4D */ {nullptr, nullptr}, + /* 4E */ {nullptr, nullptr}, + /* 4F */ {nullptr, nullptr}, + /* 50 */ {nullptr, nullptr}, + /* 51 */ {nullptr, nullptr}, + /* 52 */ {nullptr, nullptr}, + /* 53 */ {nullptr, nullptr}, + /* 54 */ {nullptr, nullptr}, + /* 55 */ {nullptr, nullptr}, + /* 56 */ {nullptr, nullptr}, + /* 57 */ {nullptr, nullptr}, + /* 58 */ {nullptr, nullptr}, + /* 59 */ {nullptr, nullptr}, + /* 5A */ {nullptr, nullptr}, + /* 5B */ {nullptr, nullptr}, + /* 5C */ {nullptr, nullptr}, + /* 5D */ {nullptr, nullptr}, + /* 5E */ {nullptr, nullptr}, + /* 5F */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + /* 60 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 61 */ {nullptr, nullptr}, + /* 62 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 63 */ {nullptr, nullptr}, + /* 64 */ {on_server_64, nullptr}, + /* 65 */ {on_server_65_67_68, nullptr}, + /* 66 */ {on_server_66_69, nullptr}, + /* 67 */ {on_server_65_67_68, nullptr}, + /* 68 */ {on_server_65_67_68, nullptr}, + /* 69 */ {on_server_66_69, nullptr}, + /* 6A */ {nullptr, nullptr}, + /* 6B */ {nullptr, nullptr}, + /* 6C */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6D */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6E */ {nullptr, nullptr}, + /* 6F */ {nullptr, nullptr}, + /* 70 */ {nullptr, nullptr}, + /* 71 */ {nullptr, nullptr}, + /* 72 */ {nullptr, nullptr}, + /* 73 */ {nullptr, nullptr}, + /* 74 */ {nullptr, nullptr}, + /* 75 */ {nullptr, nullptr}, + /* 76 */ {nullptr, nullptr}, + /* 77 */ {nullptr, nullptr}, + /* 78 */ {nullptr, nullptr}, + /* 79 */ {nullptr, nullptr}, + /* 7A */ {nullptr, nullptr}, + /* 7B */ {nullptr, nullptr}, + /* 7C */ {nullptr, nullptr}, + /* 7D */ {nullptr, nullptr}, + /* 7E */ {nullptr, nullptr}, + /* 7F */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + /* 80 */ {nullptr, nullptr}, + /* 81 */ {nullptr, nullptr}, + /* 82 */ {nullptr, nullptr}, + /* 83 */ {nullptr, nullptr}, + /* 84 */ {nullptr, nullptr}, + /* 85 */ {nullptr, nullptr}, + /* 86 */ {nullptr, nullptr}, + /* 87 */ {nullptr, nullptr}, + /* 88 */ {on_server_88, nullptr}, + /* 89 */ {nullptr, nullptr}, + /* 8A */ {nullptr, nullptr}, + /* 8B */ {nullptr, nullptr}, + /* 8C */ {nullptr, nullptr}, + /* 8D */ {nullptr, nullptr}, + /* 8E */ {nullptr, nullptr}, + /* 8F */ {nullptr, nullptr}, + /* 90 */ {nullptr, nullptr}, + /* 91 */ {nullptr, nullptr}, + /* 92 */ {nullptr, nullptr}, + /* 93 */ {nullptr, nullptr}, + /* 94 */ {nullptr, nullptr}, + /* 95 */ {nullptr, nullptr}, + /* 96 */ {nullptr, nullptr}, + /* 97 */ {on_server_97, nullptr}, + /* 98 */ {nullptr, nullptr}, + /* 99 */ {nullptr, nullptr}, + /* 9A */ {nullptr, nullptr}, + /* 9B */ {nullptr, nullptr}, + /* 9C */ {nullptr, nullptr}, + /* 9D */ {nullptr, nullptr}, + /* 9E */ {nullptr, nullptr}, + /* 9F */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + /* A0 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A1 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A2 */ {nullptr, nullptr}, + /* A3 */ {nullptr, nullptr}, + /* A4 */ {nullptr, nullptr}, + /* A5 */ {nullptr, nullptr}, + /* A6 */ {on_server_44_A6, nullptr}, + /* A7 */ {on_server_13_A7, nullptr}, + /* A8 */ {nullptr, nullptr}, + /* A9 */ {nullptr, nullptr}, + /* AA */ {nullptr, nullptr}, + /* AB */ {nullptr, nullptr}, + /* AC */ {nullptr, nullptr}, + /* AD */ {nullptr, nullptr}, + /* AE */ {nullptr, nullptr}, + /* AF */ {nullptr, nullptr}, + /* B0 */ {nullptr, nullptr}, + /* B1 */ {nullptr, nullptr}, + /* B2 */ {nullptr, nullptr}, + /* B3 */ {nullptr, nullptr}, + /* B4 */ {nullptr, nullptr}, + /* B5 */ {nullptr, nullptr}, + /* B6 */ {nullptr, nullptr}, + /* B7 */ {nullptr, nullptr}, + /* B8 */ {nullptr, nullptr}, + /* B9 */ {nullptr, nullptr}, + /* BA */ {nullptr, nullptr}, + /* BB */ {nullptr, nullptr}, + /* BC */ {nullptr, nullptr}, + /* BD */ {nullptr, nullptr}, + /* BE */ {nullptr, nullptr}, + /* BF */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + /* C0 */ {nullptr, nullptr}, + /* C1 */ {nullptr, nullptr}, + /* C2 */ {nullptr, nullptr}, + /* C3 */ {nullptr, nullptr}, + /* C4 */ {nullptr, nullptr}, + /* C5 */ {nullptr, nullptr}, + /* C6 */ {nullptr, nullptr}, + /* C7 */ {nullptr, nullptr}, + /* C8 */ {nullptr, nullptr}, + /* C9 */ {nullptr, nullptr}, + /* CA */ {nullptr, nullptr}, + /* CB */ {nullptr, nullptr}, + /* CC */ {nullptr, nullptr}, + /* CD */ {nullptr, nullptr}, + /* CE */ {nullptr, nullptr}, + /* CF */ {nullptr, nullptr}, + /* D0 */ {nullptr, nullptr}, + /* D1 */ {nullptr, nullptr}, + /* D2 */ {nullptr, nullptr}, + /* D3 */ {nullptr, nullptr}, + /* D4 */ {nullptr, nullptr}, + /* D5 */ {nullptr, nullptr}, + /* D6 */ {nullptr, nullptr}, + /* D7 */ {nullptr, nullptr}, + /* D8 */ {nullptr, nullptr}, + /* D9 */ {nullptr, nullptr}, + /* DA */ {nullptr, nullptr}, + /* DB */ {nullptr, nullptr}, + /* DC */ {nullptr, nullptr}, + /* DD */ {nullptr, nullptr}, + /* DE */ {nullptr, nullptr}, + /* DF */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + /* E0 */ {nullptr, nullptr}, + /* E1 */ {nullptr, nullptr}, + /* E2 */ {nullptr, nullptr}, + /* E3 */ {nullptr, nullptr}, + /* E4 */ {nullptr, nullptr}, + /* E5 */ {nullptr, nullptr}, + /* E6 */ {nullptr, nullptr}, + /* E7 */ {nullptr, nullptr}, + /* E8 */ {nullptr, nullptr}, + /* E9 */ {nullptr, nullptr}, + /* EA */ {nullptr, nullptr}, + /* EB */ {nullptr, nullptr}, + /* EC */ {nullptr, nullptr}, + /* ED */ {nullptr, nullptr}, + /* EE */ {nullptr, nullptr}, + /* EF */ {nullptr, nullptr}, + /* F0 */ {nullptr, nullptr}, + /* F1 */ {nullptr, nullptr}, + /* F2 */ {nullptr, nullptr}, + /* F3 */ {nullptr, nullptr}, + /* F4 */ {nullptr, nullptr}, + /* F5 */ {nullptr, nullptr}, + /* F6 */ {nullptr, nullptr}, + /* F7 */ {nullptr, nullptr}, + /* F8 */ {nullptr, nullptr}, + /* F9 */ {nullptr, nullptr}, + /* FA */ {nullptr, nullptr}, + /* FB */ {nullptr, nullptr}, + /* FC */ {nullptr, nullptr}, + /* FD */ {nullptr, nullptr}, + /* FE */ {nullptr, nullptr}, + /* FF */ {nullptr, nullptr}, + // (DC) SERVER CLIENT + }, { + // (PC) SERVER CLIENT + /* 00 */ {nullptr, nullptr}, + /* 01 */ {nullptr, nullptr}, + /* 02 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 03 */ {nullptr, nullptr}, + /* 04 */ {on_server_dc_pc_v3_04, nullptr}, + /* 05 */ {nullptr, nullptr}, + /* 06 */ {on_server_dc_pc_v3_06, on_client_06}, + /* 07 */ {nullptr, nullptr}, + /* 08 */ {nullptr, nullptr}, + /* 09 */ {nullptr, nullptr}, + /* 0A */ {nullptr, nullptr}, + /* 0B */ {nullptr, nullptr}, + /* 0C */ {nullptr, nullptr}, + /* 0D */ {nullptr, nullptr}, + /* 0E */ {nullptr, nullptr}, + /* 0F */ {nullptr, nullptr}, + /* 10 */ {nullptr, nullptr}, + /* 11 */ {nullptr, nullptr}, + /* 12 */ {nullptr, nullptr}, + /* 13 */ {on_server_13_A7, nullptr}, + /* 14 */ {nullptr, nullptr}, + /* 15 */ {nullptr, nullptr}, + /* 16 */ {nullptr, nullptr}, + /* 17 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 18 */ {nullptr, nullptr}, + /* 19 */ {on_server_game_19_patch_14, nullptr}, + /* 1A */ {nullptr, nullptr}, + /* 1B */ {nullptr, nullptr}, + /* 1C */ {nullptr, nullptr}, + /* 1D */ {nullptr, nullptr}, + /* 1E */ {nullptr, nullptr}, + /* 1F */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + /* 20 */ {nullptr, nullptr}, + /* 21 */ {nullptr, nullptr}, + /* 22 */ {nullptr, nullptr}, + /* 23 */ {nullptr, nullptr}, + /* 24 */ {nullptr, nullptr}, + /* 25 */ {nullptr, nullptr}, + /* 26 */ {nullptr, nullptr}, + /* 27 */ {nullptr, nullptr}, + /* 28 */ {nullptr, nullptr}, + /* 29 */ {nullptr, nullptr}, + /* 2A */ {nullptr, nullptr}, + /* 2B */ {nullptr, nullptr}, + /* 2C */ {nullptr, nullptr}, + /* 2D */ {nullptr, nullptr}, + /* 2E */ {nullptr, nullptr}, + /* 2F */ {nullptr, nullptr}, + /* 30 */ {nullptr, nullptr}, + /* 31 */ {nullptr, nullptr}, + /* 32 */ {nullptr, nullptr}, + /* 33 */ {nullptr, nullptr}, + /* 34 */ {nullptr, nullptr}, + /* 35 */ {nullptr, nullptr}, + /* 36 */ {nullptr, nullptr}, + /* 37 */ {nullptr, nullptr}, + /* 38 */ {nullptr, nullptr}, + /* 39 */ {nullptr, nullptr}, + /* 3A */ {nullptr, nullptr}, + /* 3B */ {nullptr, nullptr}, + /* 3C */ {nullptr, nullptr}, + /* 3D */ {nullptr, nullptr}, + /* 3E */ {nullptr, nullptr}, + /* 3F */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + /* 40 */ {nullptr, on_client_40}, + /* 41 */ {on_server_41, nullptr}, + /* 42 */ {nullptr, nullptr}, + /* 43 */ {nullptr, nullptr}, + /* 44 */ {on_server_44_A6, nullptr}, + /* 45 */ {nullptr, nullptr}, + /* 46 */ {nullptr, nullptr}, + /* 47 */ {nullptr, nullptr}, + /* 48 */ {nullptr, nullptr}, + /* 49 */ {nullptr, nullptr}, + /* 4A */ {nullptr, nullptr}, + /* 4B */ {nullptr, nullptr}, + /* 4C */ {nullptr, nullptr}, + /* 4D */ {nullptr, nullptr}, + /* 4E */ {nullptr, nullptr}, + /* 4F */ {nullptr, nullptr}, + /* 50 */ {nullptr, nullptr}, + /* 51 */ {nullptr, nullptr}, + /* 52 */ {nullptr, nullptr}, + /* 53 */ {nullptr, nullptr}, + /* 54 */ {nullptr, nullptr}, + /* 55 */ {nullptr, nullptr}, + /* 56 */ {nullptr, nullptr}, + /* 57 */ {nullptr, nullptr}, + /* 58 */ {nullptr, nullptr}, + /* 59 */ {nullptr, nullptr}, + /* 5A */ {nullptr, nullptr}, + /* 5B */ {nullptr, nullptr}, + /* 5C */ {nullptr, nullptr}, + /* 5D */ {nullptr, nullptr}, + /* 5E */ {nullptr, nullptr}, + /* 5F */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + /* 60 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 61 */ {nullptr, nullptr}, + /* 62 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 63 */ {nullptr, nullptr}, + /* 64 */ {on_server_64, nullptr}, + /* 65 */ {on_server_65_67_68, nullptr}, + /* 66 */ {on_server_66_69, nullptr}, + /* 67 */ {on_server_65_67_68, nullptr}, + /* 68 */ {on_server_65_67_68, nullptr}, + /* 69 */ {on_server_66_69, nullptr}, + /* 6A */ {nullptr, nullptr}, + /* 6B */ {nullptr, nullptr}, + /* 6C */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6D */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6E */ {nullptr, nullptr}, + /* 6F */ {nullptr, nullptr}, + /* 70 */ {nullptr, nullptr}, + /* 71 */ {nullptr, nullptr}, + /* 72 */ {nullptr, nullptr}, + /* 73 */ {nullptr, nullptr}, + /* 74 */ {nullptr, nullptr}, + /* 75 */ {nullptr, nullptr}, + /* 76 */ {nullptr, nullptr}, + /* 77 */ {nullptr, nullptr}, + /* 78 */ {nullptr, nullptr}, + /* 79 */ {nullptr, nullptr}, + /* 7A */ {nullptr, nullptr}, + /* 7B */ {nullptr, nullptr}, + /* 7C */ {nullptr, nullptr}, + /* 7D */ {nullptr, nullptr}, + /* 7E */ {nullptr, nullptr}, + /* 7F */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + /* 80 */ {nullptr, nullptr}, + /* 81 */ {nullptr, nullptr}, + /* 82 */ {nullptr, nullptr}, + /* 83 */ {nullptr, nullptr}, + /* 84 */ {nullptr, nullptr}, + /* 85 */ {nullptr, nullptr}, + /* 86 */ {nullptr, nullptr}, + /* 87 */ {nullptr, nullptr}, + /* 88 */ {on_server_88, nullptr}, + /* 89 */ {nullptr, nullptr}, + /* 8A */ {nullptr, nullptr}, + /* 8B */ {nullptr, nullptr}, + /* 8C */ {nullptr, nullptr}, + /* 8D */ {nullptr, nullptr}, + /* 8E */ {nullptr, nullptr}, + /* 8F */ {nullptr, nullptr}, + /* 90 */ {nullptr, nullptr}, + /* 91 */ {nullptr, nullptr}, + /* 92 */ {nullptr, nullptr}, + /* 93 */ {nullptr, nullptr}, + /* 94 */ {nullptr, nullptr}, + /* 95 */ {nullptr, nullptr}, + /* 96 */ {nullptr, nullptr}, + /* 97 */ {on_server_97, nullptr}, + /* 98 */ {nullptr, nullptr}, + /* 99 */ {nullptr, nullptr}, + /* 9A */ {nullptr, nullptr}, + /* 9B */ {nullptr, nullptr}, + /* 9C */ {nullptr, nullptr}, + /* 9D */ {nullptr, nullptr}, + /* 9E */ {nullptr, nullptr}, + /* 9F */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + /* A0 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A1 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A2 */ {nullptr, nullptr}, + /* A3 */ {nullptr, nullptr}, + /* A4 */ {nullptr, nullptr}, + /* A5 */ {nullptr, nullptr}, + /* A6 */ {on_server_44_A6, nullptr}, + /* A7 */ {on_server_13_A7, nullptr}, + /* A8 */ {nullptr, nullptr}, + /* A9 */ {nullptr, nullptr}, + /* AA */ {nullptr, nullptr}, + /* AB */ {nullptr, nullptr}, + /* AC */ {nullptr, nullptr}, + /* AD */ {nullptr, nullptr}, + /* AE */ {nullptr, nullptr}, + /* AF */ {nullptr, nullptr}, + /* B0 */ {nullptr, nullptr}, + /* B1 */ {nullptr, nullptr}, + /* B2 */ {nullptr, nullptr}, + /* B3 */ {nullptr, nullptr}, + /* B4 */ {nullptr, nullptr}, + /* B5 */ {nullptr, nullptr}, + /* B6 */ {nullptr, nullptr}, + /* B7 */ {nullptr, nullptr}, + /* B8 */ {nullptr, nullptr}, + /* B9 */ {nullptr, nullptr}, + /* BA */ {nullptr, nullptr}, + /* BB */ {nullptr, nullptr}, + /* BC */ {nullptr, nullptr}, + /* BD */ {nullptr, nullptr}, + /* BE */ {nullptr, nullptr}, + /* BF */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + /* C0 */ {nullptr, nullptr}, + /* C1 */ {nullptr, nullptr}, + /* C2 */ {nullptr, nullptr}, + /* C3 */ {nullptr, nullptr}, + /* C4 */ {nullptr, nullptr}, + /* C5 */ {nullptr, nullptr}, + /* C6 */ {nullptr, nullptr}, + /* C7 */ {nullptr, nullptr}, + /* C8 */ {nullptr, nullptr}, + /* C9 */ {nullptr, nullptr}, + /* CA */ {nullptr, nullptr}, + /* CB */ {nullptr, nullptr}, + /* CC */ {nullptr, nullptr}, + /* CD */ {nullptr, nullptr}, + /* CE */ {nullptr, nullptr}, + /* CF */ {nullptr, nullptr}, + /* D0 */ {nullptr, nullptr}, + /* D1 */ {nullptr, nullptr}, + /* D2 */ {nullptr, nullptr}, + /* D3 */ {nullptr, nullptr}, + /* D4 */ {nullptr, nullptr}, + /* D5 */ {nullptr, nullptr}, + /* D6 */ {nullptr, nullptr}, + /* D7 */ {nullptr, nullptr}, + /* D8 */ {nullptr, nullptr}, + /* D9 */ {nullptr, nullptr}, + /* DA */ {nullptr, nullptr}, + /* DB */ {nullptr, nullptr}, + /* DC */ {nullptr, nullptr}, + /* DD */ {nullptr, nullptr}, + /* DE */ {nullptr, nullptr}, + /* DF */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + /* E0 */ {nullptr, nullptr}, + /* E1 */ {nullptr, nullptr}, + /* E2 */ {nullptr, nullptr}, + /* E3 */ {nullptr, nullptr}, + /* E4 */ {nullptr, nullptr}, + /* E5 */ {nullptr, nullptr}, + /* E6 */ {nullptr, nullptr}, + /* E7 */ {nullptr, nullptr}, + /* E8 */ {nullptr, nullptr}, + /* E9 */ {nullptr, nullptr}, + /* EA */ {nullptr, nullptr}, + /* EB */ {nullptr, nullptr}, + /* EC */ {nullptr, nullptr}, + /* ED */ {nullptr, nullptr}, + /* EE */ {nullptr, nullptr}, + /* EF */ {nullptr, nullptr}, + /* F0 */ {nullptr, nullptr}, + /* F1 */ {nullptr, nullptr}, + /* F2 */ {nullptr, nullptr}, + /* F3 */ {nullptr, nullptr}, + /* F4 */ {nullptr, nullptr}, + /* F5 */ {nullptr, nullptr}, + /* F6 */ {nullptr, nullptr}, + /* F7 */ {nullptr, nullptr}, + /* F8 */ {nullptr, nullptr}, + /* F9 */ {nullptr, nullptr}, + /* FA */ {nullptr, nullptr}, + /* FB */ {nullptr, nullptr}, + /* FC */ {nullptr, nullptr}, + /* FD */ {nullptr, nullptr}, + /* FE */ {nullptr, nullptr}, + /* FF */ {nullptr, nullptr}, + // (PC) SERVER CLIENT + }, { + // (GC) SERVER CLIENT + /* 00 */ {nullptr, nullptr}, + /* 01 */ {nullptr, nullptr}, + /* 02 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 03 */ {nullptr, nullptr}, + /* 04 */ {on_server_dc_pc_v3_04, nullptr}, + /* 05 */ {nullptr, nullptr}, + /* 06 */ {on_server_dc_pc_v3_06, on_client_06}, + /* 07 */ {nullptr, nullptr}, + /* 08 */ {nullptr, nullptr}, + /* 09 */ {nullptr, nullptr}, + /* 0A */ {nullptr, nullptr}, + /* 0B */ {nullptr, nullptr}, + /* 0C */ {nullptr, nullptr}, + /* 0D */ {nullptr, nullptr}, + /* 0E */ {nullptr, nullptr}, + /* 0F */ {nullptr, nullptr}, + /* 10 */ {nullptr, nullptr}, + /* 11 */ {nullptr, nullptr}, + /* 12 */ {nullptr, nullptr}, + /* 13 */ {on_server_13_A7, nullptr}, + /* 14 */ {nullptr, nullptr}, + /* 15 */ {nullptr, nullptr}, + /* 16 */ {nullptr, nullptr}, + /* 17 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 18 */ {nullptr, nullptr}, + /* 19 */ {on_server_game_19_patch_14, nullptr}, + /* 1A */ {on_server_v3_1A_D5, nullptr}, + /* 1B */ {nullptr, nullptr}, + /* 1C */ {nullptr, nullptr}, + /* 1D */ {nullptr, nullptr}, + /* 1E */ {nullptr, nullptr}, + /* 1F */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + /* 20 */ {nullptr, nullptr}, + /* 21 */ {nullptr, nullptr}, + /* 22 */ {nullptr, nullptr}, + /* 23 */ {nullptr, nullptr}, + /* 24 */ {nullptr, nullptr}, + /* 25 */ {nullptr, nullptr}, + /* 26 */ {nullptr, nullptr}, + /* 27 */ {nullptr, nullptr}, + /* 28 */ {nullptr, nullptr}, + /* 29 */ {nullptr, nullptr}, + /* 2A */ {nullptr, nullptr}, + /* 2B */ {nullptr, nullptr}, + /* 2C */ {nullptr, nullptr}, + /* 2D */ {nullptr, nullptr}, + /* 2E */ {nullptr, nullptr}, + /* 2F */ {nullptr, nullptr}, + /* 30 */ {nullptr, nullptr}, + /* 31 */ {nullptr, nullptr}, + /* 32 */ {nullptr, nullptr}, + /* 33 */ {nullptr, nullptr}, + /* 34 */ {nullptr, nullptr}, + /* 35 */ {nullptr, nullptr}, + /* 36 */ {nullptr, nullptr}, + /* 37 */ {nullptr, nullptr}, + /* 38 */ {nullptr, nullptr}, + /* 39 */ {nullptr, nullptr}, + /* 3A */ {nullptr, nullptr}, + /* 3B */ {nullptr, nullptr}, + /* 3C */ {nullptr, nullptr}, + /* 3D */ {nullptr, nullptr}, + /* 3E */ {nullptr, nullptr}, + /* 3F */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + /* 40 */ {nullptr, on_client_40}, + /* 41 */ {on_server_41, nullptr}, + /* 42 */ {nullptr, nullptr}, + /* 43 */ {nullptr, nullptr}, + /* 44 */ {on_server_44_A6, nullptr}, + /* 45 */ {nullptr, nullptr}, + /* 46 */ {nullptr, nullptr}, + /* 47 */ {nullptr, nullptr}, + /* 48 */ {nullptr, nullptr}, + /* 49 */ {nullptr, nullptr}, + /* 4A */ {nullptr, nullptr}, + /* 4B */ {nullptr, nullptr}, + /* 4C */ {nullptr, nullptr}, + /* 4D */ {nullptr, nullptr}, + /* 4E */ {nullptr, nullptr}, + /* 4F */ {nullptr, nullptr}, + /* 50 */ {nullptr, nullptr}, + /* 51 */ {nullptr, nullptr}, + /* 52 */ {nullptr, nullptr}, + /* 53 */ {nullptr, nullptr}, + /* 54 */ {nullptr, nullptr}, + /* 55 */ {nullptr, nullptr}, + /* 56 */ {nullptr, nullptr}, + /* 57 */ {nullptr, nullptr}, + /* 58 */ {nullptr, nullptr}, + /* 59 */ {nullptr, nullptr}, + /* 5A */ {nullptr, nullptr}, + /* 5B */ {nullptr, nullptr}, + /* 5C */ {nullptr, nullptr}, + /* 5D */ {nullptr, nullptr}, + /* 5E */ {nullptr, nullptr}, + /* 5F */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + /* 60 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 61 */ {nullptr, nullptr}, + /* 62 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 63 */ {nullptr, nullptr}, + /* 64 */ {on_server_64, nullptr}, + /* 65 */ {on_server_65_67_68, nullptr}, + /* 66 */ {on_server_66_69, nullptr}, + /* 67 */ {on_server_65_67_68, nullptr}, + /* 68 */ {on_server_65_67_68, nullptr}, + /* 69 */ {on_server_66_69, nullptr}, + /* 6A */ {nullptr, nullptr}, + /* 6B */ {nullptr, nullptr}, + /* 6C */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6D */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6E */ {nullptr, nullptr}, + /* 6F */ {nullptr, nullptr}, + /* 70 */ {nullptr, nullptr}, + /* 71 */ {nullptr, nullptr}, + /* 72 */ {nullptr, nullptr}, + /* 73 */ {nullptr, nullptr}, + /* 74 */ {nullptr, nullptr}, + /* 75 */ {nullptr, nullptr}, + /* 76 */ {nullptr, nullptr}, + /* 77 */ {nullptr, nullptr}, + /* 78 */ {nullptr, nullptr}, + /* 79 */ {nullptr, nullptr}, + /* 7A */ {nullptr, nullptr}, + /* 7B */ {nullptr, nullptr}, + /* 7C */ {nullptr, nullptr}, + /* 7D */ {nullptr, nullptr}, + /* 7E */ {nullptr, nullptr}, + /* 7F */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + /* 80 */ {nullptr, nullptr}, + /* 81 */ {on_server_81, on_client_81}, + /* 82 */ {nullptr, nullptr}, + /* 83 */ {nullptr, nullptr}, + /* 84 */ {nullptr, nullptr}, + /* 85 */ {nullptr, nullptr}, + /* 86 */ {nullptr, nullptr}, + /* 87 */ {nullptr, nullptr}, + /* 88 */ {on_server_88, nullptr}, + /* 89 */ {nullptr, nullptr}, + /* 8A */ {nullptr, nullptr}, + /* 8B */ {nullptr, nullptr}, + /* 8C */ {nullptr, nullptr}, + /* 8D */ {nullptr, nullptr}, + /* 8E */ {nullptr, nullptr}, + /* 8F */ {nullptr, nullptr}, + /* 90 */ {nullptr, nullptr}, + /* 91 */ {nullptr, nullptr}, + /* 92 */ {nullptr, nullptr}, + /* 93 */ {nullptr, nullptr}, + /* 94 */ {nullptr, nullptr}, + /* 95 */ {nullptr, nullptr}, + /* 96 */ {nullptr, nullptr}, + /* 97 */ {on_server_97, nullptr}, + /* 98 */ {nullptr, nullptr}, + /* 99 */ {nullptr, nullptr}, + /* 9A */ {on_server_gc_9A, nullptr}, + /* 9B */ {nullptr, nullptr}, + /* 9C */ {nullptr, nullptr}, + /* 9D */ {nullptr, nullptr}, + /* 9E */ {nullptr, nullptr}, + /* 9F */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + /* A0 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A1 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A2 */ {nullptr, nullptr}, + /* A3 */ {nullptr, nullptr}, + /* A4 */ {nullptr, nullptr}, + /* A5 */ {nullptr, nullptr}, + /* A6 */ {on_server_44_A6, nullptr}, + /* A7 */ {on_server_13_A7, nullptr}, + /* A8 */ {nullptr, nullptr}, + /* A9 */ {nullptr, nullptr}, + /* AA */ {nullptr, nullptr}, + /* AB */ {nullptr, nullptr}, + /* AC */ {nullptr, nullptr}, + /* AD */ {nullptr, nullptr}, + /* AE */ {nullptr, nullptr}, + /* AF */ {nullptr, nullptr}, + /* B0 */ {nullptr, nullptr}, + /* B1 */ {nullptr, nullptr}, + /* B2 */ {on_server_B2, nullptr}, + /* B3 */ {nullptr, nullptr}, + /* B4 */ {nullptr, nullptr}, + /* B5 */ {nullptr, nullptr}, + /* B6 */ {nullptr, nullptr}, + /* B7 */ {nullptr, nullptr}, + /* B8 */ {on_server_gc_B8, nullptr}, + /* B9 */ {nullptr, nullptr}, + /* BA */ {nullptr, nullptr}, + /* BB */ {nullptr, nullptr}, + /* BC */ {nullptr, nullptr}, + /* BD */ {nullptr, nullptr}, + /* BE */ {nullptr, nullptr}, + /* BF */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + /* C0 */ {nullptr, nullptr}, + /* C1 */ {nullptr, nullptr}, + /* C2 */ {nullptr, nullptr}, + /* C3 */ {nullptr, nullptr}, + /* C4 */ {on_server_C4, nullptr}, + /* C5 */ {nullptr, nullptr}, + /* C6 */ {nullptr, nullptr}, + /* C7 */ {nullptr, nullptr}, + /* C8 */ {nullptr, nullptr}, + /* C9 */ {on_server_60_62_6C_6D_C9_CB, nullptr}, + /* CA */ {nullptr, nullptr}, + /* CB */ {on_server_60_62_6C_6D_C9_CB, nullptr}, + /* CC */ {nullptr, nullptr}, + /* CD */ {nullptr, nullptr}, + /* CE */ {nullptr, nullptr}, + /* CF */ {nullptr, nullptr}, + /* D0 */ {nullptr, nullptr}, + /* D1 */ {nullptr, nullptr}, + /* D2 */ {nullptr, nullptr}, + /* D3 */ {nullptr, nullptr}, + /* D4 */ {nullptr, nullptr}, + /* D5 */ {on_server_v3_1A_D5, nullptr}, + /* D6 */ {nullptr, nullptr}, + /* D7 */ {nullptr, nullptr}, + /* D8 */ {nullptr, nullptr}, + /* D9 */ {nullptr, nullptr}, + /* DA */ {nullptr, nullptr}, + /* DB */ {nullptr, nullptr}, + /* DC */ {nullptr, nullptr}, + /* DD */ {nullptr, nullptr}, + /* DE */ {nullptr, nullptr}, + /* DF */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + /* E0 */ {nullptr, nullptr}, + /* E1 */ {nullptr, nullptr}, + /* E2 */ {nullptr, nullptr}, + /* E3 */ {nullptr, nullptr}, + /* E4 */ {on_server_gc_E4, nullptr}, + /* E5 */ {nullptr, nullptr}, + /* E6 */ {nullptr, nullptr}, + /* E7 */ {nullptr, nullptr}, + /* E8 */ {nullptr, nullptr}, + /* E9 */ {nullptr, nullptr}, + /* EA */ {nullptr, nullptr}, + /* EB */ {nullptr, nullptr}, + /* EC */ {nullptr, nullptr}, + /* ED */ {nullptr, nullptr}, + /* EE */ {nullptr, nullptr}, + /* EF */ {nullptr, nullptr}, + /* F0 */ {nullptr, nullptr}, + /* F1 */ {nullptr, nullptr}, + /* F2 */ {nullptr, nullptr}, + /* F3 */ {nullptr, nullptr}, + /* F4 */ {nullptr, nullptr}, + /* F5 */ {nullptr, nullptr}, + /* F6 */ {nullptr, nullptr}, + /* F7 */ {nullptr, nullptr}, + /* F8 */ {nullptr, nullptr}, + /* F9 */ {nullptr, nullptr}, + /* FA */ {nullptr, nullptr}, + /* FB */ {nullptr, nullptr}, + /* FC */ {nullptr, nullptr}, + /* FD */ {nullptr, nullptr}, + /* FE */ {nullptr, nullptr}, + /* FF */ {nullptr, nullptr}, + // (GC) SERVER CLIENT + }, { + // (XB) SERVER CLIENT + /* 00 */ {nullptr, nullptr}, + /* 01 */ {nullptr, nullptr}, + /* 02 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 03 */ {nullptr, nullptr}, + /* 04 */ {on_server_dc_pc_v3_04, nullptr}, + /* 05 */ {nullptr, nullptr}, + /* 06 */ {on_server_dc_pc_v3_06, on_client_06}, + /* 07 */ {nullptr, nullptr}, + /* 08 */ {nullptr, nullptr}, + /* 09 */ {nullptr, nullptr}, + /* 0A */ {nullptr, nullptr}, + /* 0B */ {nullptr, nullptr}, + /* 0C */ {nullptr, nullptr}, + /* 0D */ {nullptr, nullptr}, + /* 0E */ {nullptr, nullptr}, + /* 0F */ {nullptr, nullptr}, + /* 10 */ {nullptr, nullptr}, + /* 11 */ {nullptr, nullptr}, + /* 12 */ {nullptr, nullptr}, + /* 13 */ {on_server_13_A7, nullptr}, + /* 14 */ {nullptr, nullptr}, + /* 15 */ {nullptr, nullptr}, + /* 16 */ {nullptr, nullptr}, + /* 17 */ {on_server_dc_pc_v3_patch_02_17, nullptr}, + /* 18 */ {nullptr, nullptr}, + /* 19 */ {on_server_game_19_patch_14, nullptr}, + /* 1A */ {on_server_v3_1A_D5, nullptr}, + /* 1B */ {nullptr, nullptr}, + /* 1C */ {nullptr, nullptr}, + /* 1D */ {nullptr, nullptr}, + /* 1E */ {nullptr, nullptr}, + /* 1F */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + /* 20 */ {nullptr, nullptr}, + /* 21 */ {nullptr, nullptr}, + /* 22 */ {nullptr, nullptr}, + /* 23 */ {nullptr, nullptr}, + /* 24 */ {nullptr, nullptr}, + /* 25 */ {nullptr, nullptr}, + /* 26 */ {nullptr, nullptr}, + /* 27 */ {nullptr, nullptr}, + /* 28 */ {nullptr, nullptr}, + /* 29 */ {nullptr, nullptr}, + /* 2A */ {nullptr, nullptr}, + /* 2B */ {nullptr, nullptr}, + /* 2C */ {nullptr, nullptr}, + /* 2D */ {nullptr, nullptr}, + /* 2E */ {nullptr, nullptr}, + /* 2F */ {nullptr, nullptr}, + /* 30 */ {nullptr, nullptr}, + /* 31 */ {nullptr, nullptr}, + /* 32 */ {nullptr, nullptr}, + /* 33 */ {nullptr, nullptr}, + /* 34 */ {nullptr, nullptr}, + /* 35 */ {nullptr, nullptr}, + /* 36 */ {nullptr, nullptr}, + /* 37 */ {nullptr, nullptr}, + /* 38 */ {nullptr, nullptr}, + /* 39 */ {nullptr, nullptr}, + /* 3A */ {nullptr, nullptr}, + /* 3B */ {nullptr, nullptr}, + /* 3C */ {nullptr, nullptr}, + /* 3D */ {nullptr, nullptr}, + /* 3E */ {nullptr, nullptr}, + /* 3F */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + /* 40 */ {nullptr, on_client_40}, + /* 41 */ {on_server_41, nullptr}, + /* 42 */ {nullptr, nullptr}, + /* 43 */ {nullptr, nullptr}, + /* 44 */ {on_server_44_A6, nullptr}, + /* 45 */ {nullptr, nullptr}, + /* 46 */ {nullptr, nullptr}, + /* 47 */ {nullptr, nullptr}, + /* 48 */ {nullptr, nullptr}, + /* 49 */ {nullptr, nullptr}, + /* 4A */ {nullptr, nullptr}, + /* 4B */ {nullptr, nullptr}, + /* 4C */ {nullptr, nullptr}, + /* 4D */ {nullptr, nullptr}, + /* 4E */ {nullptr, nullptr}, + /* 4F */ {nullptr, nullptr}, + /* 50 */ {nullptr, nullptr}, + /* 51 */ {nullptr, nullptr}, + /* 52 */ {nullptr, nullptr}, + /* 53 */ {nullptr, nullptr}, + /* 54 */ {nullptr, nullptr}, + /* 55 */ {nullptr, nullptr}, + /* 56 */ {nullptr, nullptr}, + /* 57 */ {nullptr, nullptr}, + /* 58 */ {nullptr, nullptr}, + /* 59 */ {nullptr, nullptr}, + /* 5A */ {nullptr, nullptr}, + /* 5B */ {nullptr, nullptr}, + /* 5C */ {nullptr, nullptr}, + /* 5D */ {nullptr, nullptr}, + /* 5E */ {nullptr, nullptr}, + /* 5F */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + /* 60 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 61 */ {nullptr, nullptr}, + /* 62 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 63 */ {nullptr, nullptr}, + /* 64 */ {on_server_64, nullptr}, + /* 65 */ {on_server_65_67_68, nullptr}, + /* 66 */ {on_server_66_69, nullptr}, + /* 67 */ {on_server_65_67_68, nullptr}, + /* 68 */ {on_server_65_67_68, nullptr}, + /* 69 */ {on_server_66_69, nullptr}, + /* 6A */ {nullptr, nullptr}, + /* 6B */ {nullptr, nullptr}, + /* 6C */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6D */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6E */ {nullptr, nullptr}, + /* 6F */ {nullptr, nullptr}, + /* 70 */ {nullptr, nullptr}, + /* 71 */ {nullptr, nullptr}, + /* 72 */ {nullptr, nullptr}, + /* 73 */ {nullptr, nullptr}, + /* 74 */ {nullptr, nullptr}, + /* 75 */ {nullptr, nullptr}, + /* 76 */ {nullptr, nullptr}, + /* 77 */ {nullptr, nullptr}, + /* 78 */ {nullptr, nullptr}, + /* 79 */ {nullptr, nullptr}, + /* 7A */ {nullptr, nullptr}, + /* 7B */ {nullptr, nullptr}, + /* 7C */ {nullptr, nullptr}, + /* 7D */ {nullptr, nullptr}, + /* 7E */ {nullptr, nullptr}, + /* 7F */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + /* 80 */ {nullptr, nullptr}, + /* 81 */ {on_server_81, on_client_81}, + /* 82 */ {nullptr, nullptr}, + /* 83 */ {nullptr, nullptr}, + /* 84 */ {nullptr, nullptr}, + /* 85 */ {nullptr, nullptr}, + /* 86 */ {nullptr, nullptr}, + /* 87 */ {nullptr, nullptr}, + /* 88 */ {on_server_88, nullptr}, + /* 89 */ {nullptr, nullptr}, + /* 8A */ {nullptr, nullptr}, + /* 8B */ {nullptr, nullptr}, + /* 8C */ {nullptr, nullptr}, + /* 8D */ {nullptr, nullptr}, + /* 8E */ {nullptr, nullptr}, + /* 8F */ {nullptr, nullptr}, + /* 90 */ {nullptr, nullptr}, + /* 91 */ {nullptr, nullptr}, + /* 92 */ {nullptr, nullptr}, + /* 93 */ {nullptr, nullptr}, + /* 94 */ {nullptr, nullptr}, + /* 95 */ {nullptr, nullptr}, + /* 96 */ {nullptr, nullptr}, + /* 97 */ {on_server_97, nullptr}, + /* 98 */ {nullptr, nullptr}, + /* 99 */ {nullptr, nullptr}, + /* 9A */ {nullptr, nullptr}, + /* 9B */ {nullptr, nullptr}, + /* 9C */ {nullptr, nullptr}, + /* 9D */ {nullptr, nullptr}, + /* 9E */ {nullptr, nullptr}, + /* 9F */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + /* A0 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A1 */ {nullptr, on_client_dc_pc_v3_A0_A1}, + /* A2 */ {nullptr, nullptr}, + /* A3 */ {nullptr, nullptr}, + /* A4 */ {nullptr, nullptr}, + /* A5 */ {nullptr, nullptr}, + /* A6 */ {on_server_44_A6, nullptr}, + /* A7 */ {on_server_13_A7, nullptr}, + /* A8 */ {nullptr, nullptr}, + /* A9 */ {nullptr, nullptr}, + /* AA */ {nullptr, nullptr}, + /* AB */ {nullptr, nullptr}, + /* AC */ {nullptr, nullptr}, + /* AD */ {nullptr, nullptr}, + /* AE */ {nullptr, nullptr}, + /* AF */ {nullptr, nullptr}, + /* B0 */ {nullptr, nullptr}, + /* B1 */ {nullptr, nullptr}, + /* B2 */ {on_server_B2, nullptr}, + /* B3 */ {nullptr, nullptr}, + /* B4 */ {nullptr, nullptr}, + /* B5 */ {nullptr, nullptr}, + /* B6 */ {nullptr, nullptr}, + /* B7 */ {nullptr, nullptr}, + /* B8 */ {nullptr, nullptr}, + /* B9 */ {nullptr, nullptr}, + /* BA */ {nullptr, nullptr}, + /* BB */ {nullptr, nullptr}, + /* BC */ {nullptr, nullptr}, + /* BD */ {nullptr, nullptr}, + /* BE */ {nullptr, nullptr}, + /* BF */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + /* C0 */ {nullptr, nullptr}, + /* C1 */ {nullptr, nullptr}, + /* C2 */ {nullptr, nullptr}, + /* C3 */ {nullptr, nullptr}, + /* C4 */ {on_server_C4, nullptr}, + /* C5 */ {nullptr, nullptr}, + /* C6 */ {nullptr, nullptr}, + /* C7 */ {nullptr, nullptr}, + /* C8 */ {nullptr, nullptr}, + /* C9 */ {on_server_60_62_6C_6D_C9_CB, nullptr}, + /* CA */ {nullptr, nullptr}, + /* CB */ {on_server_60_62_6C_6D_C9_CB, nullptr}, + /* CC */ {nullptr, nullptr}, + /* CD */ {nullptr, nullptr}, + /* CE */ {nullptr, nullptr}, + /* CF */ {nullptr, nullptr}, + /* D0 */ {nullptr, nullptr}, + /* D1 */ {nullptr, nullptr}, + /* D2 */ {nullptr, nullptr}, + /* D3 */ {nullptr, nullptr}, + /* D4 */ {nullptr, nullptr}, + /* D5 */ {on_server_v3_1A_D5, nullptr}, + /* D6 */ {nullptr, nullptr}, + /* D7 */ {nullptr, nullptr}, + /* D8 */ {nullptr, nullptr}, + /* D9 */ {nullptr, nullptr}, + /* DA */ {nullptr, nullptr}, + /* DB */ {nullptr, nullptr}, + /* DC */ {nullptr, nullptr}, + /* DD */ {nullptr, nullptr}, + /* DE */ {nullptr, nullptr}, + /* DF */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + /* E0 */ {nullptr, nullptr}, + /* E1 */ {nullptr, nullptr}, + /* E2 */ {nullptr, nullptr}, + /* E3 */ {nullptr, nullptr}, + /* E4 */ {nullptr, nullptr}, + /* E5 */ {nullptr, nullptr}, + /* E6 */ {nullptr, nullptr}, + /* E7 */ {nullptr, nullptr}, + /* E8 */ {nullptr, nullptr}, + /* E9 */ {nullptr, nullptr}, + /* EA */ {nullptr, nullptr}, + /* EB */ {nullptr, nullptr}, + /* EC */ {nullptr, nullptr}, + /* ED */ {nullptr, nullptr}, + /* EE */ {nullptr, nullptr}, + /* EF */ {nullptr, nullptr}, + /* F0 */ {nullptr, nullptr}, + /* F1 */ {nullptr, nullptr}, + /* F2 */ {nullptr, nullptr}, + /* F3 */ {nullptr, nullptr}, + /* F4 */ {nullptr, nullptr}, + /* F5 */ {nullptr, nullptr}, + /* F6 */ {nullptr, nullptr}, + /* F7 */ {nullptr, nullptr}, + /* F8 */ {nullptr, nullptr}, + /* F9 */ {nullptr, nullptr}, + /* FA */ {nullptr, nullptr}, + /* FB */ {nullptr, nullptr}, + /* FC */ {nullptr, nullptr}, + /* FD */ {nullptr, nullptr}, + /* FE */ {nullptr, nullptr}, + /* FF */ {nullptr, nullptr}, + // (XB) SERVER CLIENT + }, { + // (BB) SERVER CLIENT + /* 00 */ {nullptr, nullptr}, + /* 01 */ {nullptr, nullptr}, + /* 02 */ {nullptr, nullptr}, + /* 03 */ {on_server_bb_03, nullptr}, + /* 04 */ {nullptr, nullptr}, + /* 05 */ {nullptr, nullptr}, + /* 06 */ {nullptr, on_client_06}, + /* 07 */ {nullptr, nullptr}, + /* 08 */ {nullptr, nullptr}, + /* 09 */ {nullptr, nullptr}, + /* 0A */ {nullptr, nullptr}, + /* 0B */ {nullptr, nullptr}, + /* 0C */ {nullptr, nullptr}, + /* 0D */ {nullptr, nullptr}, + /* 0E */ {nullptr, nullptr}, + /* 0F */ {nullptr, nullptr}, + /* 10 */ {nullptr, nullptr}, + /* 11 */ {nullptr, nullptr}, + /* 12 */ {nullptr, nullptr}, + /* 13 */ {on_server_13_A7, nullptr}, + /* 14 */ {nullptr, nullptr}, + /* 15 */ {nullptr, nullptr}, + /* 16 */ {nullptr, nullptr}, + /* 17 */ {nullptr, nullptr}, + /* 18 */ {nullptr, nullptr}, + /* 19 */ {on_server_game_19_patch_14, nullptr}, + /* 1A */ {nullptr, nullptr}, + /* 1B */ {nullptr, nullptr}, + /* 1C */ {nullptr, nullptr}, + /* 1D */ {nullptr, nullptr}, + /* 1E */ {nullptr, nullptr}, + /* 1F */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + /* 20 */ {nullptr, nullptr}, + /* 21 */ {nullptr, nullptr}, + /* 22 */ {on_server_bb_22, nullptr}, + /* 23 */ {nullptr, nullptr}, + /* 24 */ {nullptr, nullptr}, + /* 25 */ {nullptr, nullptr}, + /* 26 */ {nullptr, nullptr}, + /* 27 */ {nullptr, nullptr}, + /* 28 */ {nullptr, nullptr}, + /* 29 */ {nullptr, nullptr}, + /* 2A */ {nullptr, nullptr}, + /* 2B */ {nullptr, nullptr}, + /* 2C */ {nullptr, nullptr}, + /* 2D */ {nullptr, nullptr}, + /* 2E */ {nullptr, nullptr}, + /* 2F */ {nullptr, nullptr}, + /* 30 */ {nullptr, nullptr}, + /* 31 */ {nullptr, nullptr}, + /* 32 */ {nullptr, nullptr}, + /* 33 */ {nullptr, nullptr}, + /* 34 */ {nullptr, nullptr}, + /* 35 */ {nullptr, nullptr}, + /* 36 */ {nullptr, nullptr}, + /* 37 */ {nullptr, nullptr}, + /* 38 */ {nullptr, nullptr}, + /* 39 */ {nullptr, nullptr}, + /* 3A */ {nullptr, nullptr}, + /* 3B */ {nullptr, nullptr}, + /* 3C */ {nullptr, nullptr}, + /* 3D */ {nullptr, nullptr}, + /* 3E */ {nullptr, nullptr}, + /* 3F */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + /* 40 */ {nullptr, on_client_40}, + /* 41 */ {on_server_41, nullptr}, + /* 42 */ {nullptr, nullptr}, + /* 43 */ {nullptr, nullptr}, + /* 44 */ {on_server_44_A6, nullptr}, + /* 45 */ {nullptr, nullptr}, + /* 46 */ {nullptr, nullptr}, + /* 47 */ {nullptr, nullptr}, + /* 48 */ {nullptr, nullptr}, + /* 49 */ {nullptr, nullptr}, + /* 4A */ {nullptr, nullptr}, + /* 4B */ {nullptr, nullptr}, + /* 4C */ {nullptr, nullptr}, + /* 4D */ {nullptr, nullptr}, + /* 4E */ {nullptr, nullptr}, + /* 4F */ {nullptr, nullptr}, + /* 50 */ {nullptr, nullptr}, + /* 51 */ {nullptr, nullptr}, + /* 52 */ {nullptr, nullptr}, + /* 53 */ {nullptr, nullptr}, + /* 54 */ {nullptr, nullptr}, + /* 55 */ {nullptr, nullptr}, + /* 56 */ {nullptr, nullptr}, + /* 57 */ {nullptr, nullptr}, + /* 58 */ {nullptr, nullptr}, + /* 59 */ {nullptr, nullptr}, + /* 5A */ {nullptr, nullptr}, + /* 5B */ {nullptr, nullptr}, + /* 5C */ {nullptr, nullptr}, + /* 5D */ {nullptr, nullptr}, + /* 5E */ {nullptr, nullptr}, + /* 5F */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + /* 60 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 61 */ {nullptr, nullptr}, + /* 62 */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 63 */ {nullptr, nullptr}, + /* 64 */ {on_server_64, nullptr}, + /* 65 */ {on_server_65_67_68, nullptr}, + /* 66 */ {on_server_66_69, nullptr}, + /* 67 */ {on_server_65_67_68, nullptr}, + /* 68 */ {on_server_65_67_68, nullptr}, + /* 69 */ {on_server_66_69, nullptr}, + /* 6A */ {nullptr, nullptr}, + /* 6B */ {nullptr, nullptr}, + /* 6C */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6D */ {on_server_60_62_6C_6D_C9_CB, on_client_60_62_6C_6D_C9_CB}, + /* 6E */ {nullptr, nullptr}, + /* 6F */ {nullptr, nullptr}, + /* 70 */ {nullptr, nullptr}, + /* 71 */ {nullptr, nullptr}, + /* 72 */ {nullptr, nullptr}, + /* 73 */ {nullptr, nullptr}, + /* 74 */ {nullptr, nullptr}, + /* 75 */ {nullptr, nullptr}, + /* 76 */ {nullptr, nullptr}, + /* 77 */ {nullptr, nullptr}, + /* 78 */ {nullptr, nullptr}, + /* 79 */ {nullptr, nullptr}, + /* 7A */ {nullptr, nullptr}, + /* 7B */ {nullptr, nullptr}, + /* 7C */ {nullptr, nullptr}, + /* 7D */ {nullptr, nullptr}, + /* 7E */ {nullptr, nullptr}, + /* 7F */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + /* 80 */ {nullptr, nullptr}, + /* 81 */ {nullptr, nullptr}, + /* 82 */ {nullptr, nullptr}, + /* 83 */ {nullptr, nullptr}, + /* 84 */ {nullptr, nullptr}, + /* 85 */ {nullptr, nullptr}, + /* 86 */ {nullptr, nullptr}, + /* 87 */ {nullptr, nullptr}, + /* 88 */ {on_server_88, nullptr}, + /* 89 */ {nullptr, nullptr}, + /* 8A */ {nullptr, nullptr}, + /* 8B */ {nullptr, nullptr}, + /* 8C */ {nullptr, nullptr}, + /* 8D */ {nullptr, nullptr}, + /* 8E */ {nullptr, nullptr}, + /* 8F */ {nullptr, nullptr}, + /* 90 */ {nullptr, nullptr}, + /* 91 */ {nullptr, nullptr}, + /* 92 */ {nullptr, nullptr}, + /* 93 */ {nullptr, nullptr}, + /* 94 */ {nullptr, nullptr}, + /* 95 */ {nullptr, nullptr}, + /* 96 */ {nullptr, nullptr}, + /* 97 */ {nullptr, nullptr}, + /* 98 */ {nullptr, nullptr}, + /* 99 */ {nullptr, nullptr}, + /* 9A */ {nullptr, nullptr}, + /* 9B */ {nullptr, nullptr}, + /* 9C */ {nullptr, nullptr}, + /* 9D */ {nullptr, nullptr}, + /* 9E */ {nullptr, nullptr}, + /* 9F */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + /* A0 */ {nullptr, nullptr}, + /* A1 */ {nullptr, nullptr}, + /* A2 */ {nullptr, nullptr}, + /* A3 */ {nullptr, nullptr}, + /* A4 */ {nullptr, nullptr}, + /* A5 */ {nullptr, nullptr}, + /* A6 */ {on_server_44_A6, nullptr}, + /* A7 */ {on_server_13_A7, nullptr}, + /* A8 */ {nullptr, nullptr}, + /* A9 */ {nullptr, nullptr}, + /* AA */ {nullptr, nullptr}, + /* AB */ {nullptr, nullptr}, + /* AC */ {nullptr, nullptr}, + /* AD */ {nullptr, nullptr}, + /* AE */ {nullptr, nullptr}, + /* AF */ {nullptr, nullptr}, + /* B0 */ {nullptr, nullptr}, + /* B1 */ {nullptr, nullptr}, + /* B2 */ {on_server_B2, nullptr}, + /* B3 */ {nullptr, nullptr}, + /* B4 */ {nullptr, nullptr}, + /* B5 */ {nullptr, nullptr}, + /* B6 */ {nullptr, nullptr}, + /* B7 */ {nullptr, nullptr}, + /* B8 */ {nullptr, nullptr}, + /* B9 */ {nullptr, nullptr}, + /* BA */ {nullptr, nullptr}, + /* BB */ {nullptr, nullptr}, + /* BC */ {nullptr, nullptr}, + /* BD */ {nullptr, nullptr}, + /* BE */ {nullptr, nullptr}, + /* BF */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + /* C0 */ {nullptr, nullptr}, + /* C1 */ {nullptr, nullptr}, + /* C2 */ {nullptr, nullptr}, + /* C3 */ {nullptr, nullptr}, + /* C4 */ {nullptr, nullptr}, + /* C5 */ {nullptr, nullptr}, + /* C6 */ {nullptr, nullptr}, + /* C7 */ {nullptr, nullptr}, + /* C8 */ {nullptr, nullptr}, + /* C9 */ {nullptr, nullptr}, + /* CA */ {nullptr, nullptr}, + /* CB */ {nullptr, nullptr}, + /* CC */ {nullptr, nullptr}, + /* CD */ {nullptr, nullptr}, + /* CE */ {nullptr, nullptr}, + /* CF */ {nullptr, nullptr}, + /* D0 */ {nullptr, nullptr}, + /* D1 */ {nullptr, nullptr}, + /* D2 */ {nullptr, nullptr}, + /* D3 */ {nullptr, nullptr}, + /* D4 */ {nullptr, nullptr}, + /* D5 */ {nullptr, nullptr}, + /* D6 */ {nullptr, nullptr}, + /* D7 */ {nullptr, nullptr}, + /* D8 */ {nullptr, nullptr}, + /* D9 */ {nullptr, nullptr}, + /* DA */ {nullptr, nullptr}, + /* DB */ {nullptr, nullptr}, + /* DC */ {nullptr, nullptr}, + /* DD */ {nullptr, nullptr}, + /* DE */ {nullptr, nullptr}, + /* DF */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + /* E0 */ {nullptr, nullptr}, + /* E1 */ {nullptr, nullptr}, + /* E2 */ {nullptr, nullptr}, + /* E3 */ {nullptr, nullptr}, + /* E4 */ {nullptr, nullptr}, + /* E5 */ {nullptr, nullptr}, + /* E6 */ {nullptr, nullptr}, + /* E7 */ {on_server_E7, nullptr}, + /* E8 */ {nullptr, nullptr}, + /* E9 */ {nullptr, nullptr}, + /* EA */ {nullptr, nullptr}, + /* EB */ {nullptr, nullptr}, + /* EC */ {nullptr, nullptr}, + /* ED */ {nullptr, nullptr}, + /* EE */ {nullptr, nullptr}, + /* EF */ {nullptr, nullptr}, + /* F0 */ {nullptr, nullptr}, + /* F1 */ {nullptr, nullptr}, + /* F2 */ {nullptr, nullptr}, + /* F3 */ {nullptr, nullptr}, + /* F4 */ {nullptr, nullptr}, + /* F5 */ {nullptr, nullptr}, + /* F6 */ {nullptr, nullptr}, + /* F7 */ {nullptr, nullptr}, + /* F8 */ {nullptr, nullptr}, + /* F9 */ {nullptr, nullptr}, + /* FA */ {nullptr, nullptr}, + /* FB */ {nullptr, nullptr}, + /* FC */ {nullptr, nullptr}, + /* FD */ {nullptr, nullptr}, + /* FE */ {nullptr, nullptr}, + /* FF */ {nullptr, nullptr}, + // (BB) SERVER CLIENT + }, }; - - -static process_command_t dc_client_handlers[0x100] = { - /* 00 */ defh, defh, defh, defh, defh, defh, process_client_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ process_client_40, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_client_60_62_6C_6D_C9_CB, defh, process_client_60_62_6C_6D_C9_CB, defh, defh, defh, defh, defh, defh, defh, defh, defh, process_client_60_62_6C_6D_C9_CB, process_client_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ process_client_dc_pc_v3_A0_A1, process_client_dc_pc_v3_A0_A1, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t pc_client_handlers[0x100] = { - /* 00 */ defh, defh, defh, defh, defh, defh, process_client_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ process_client_40, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_client_60_62_6C_6D_C9_CB, defh, process_client_60_62_6C_6D_C9_CB, defh, defh, defh, defh, defh, defh, defh, defh, defh, process_client_60_62_6C_6D_C9_CB, process_client_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ process_client_dc_pc_v3_A0_A1, process_client_dc_pc_v3_A0_A1, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t gc_client_handlers[0x100] = { - /* 00 */ defh, defh, defh, defh, defh, defh, process_client_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ process_client_40, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_client_60_62_6C_6D_C9_CB, defh, process_client_60_62_6C_6D_C9_CB, defh, defh, defh, defh, defh, defh, defh, defh, defh, process_client_60_62_6C_6D_C9_CB, process_client_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, process_client_81, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ process_client_dc_pc_v3_A0_A1, process_client_dc_pc_v3_A0_A1, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t xb_client_handlers[0x100] = { - /* 00 */ defh, defh, defh, defh, defh, defh, process_client_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ process_client_40, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_client_60_62_6C_6D_C9_CB, defh, process_client_60_62_6C_6D_C9_CB, defh, defh, defh, defh, defh, defh, defh, defh, defh, process_client_60_62_6C_6D_C9_CB, process_client_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, process_client_81, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ process_client_dc_pc_v3_A0_A1, process_client_dc_pc_v3_A0_A1, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t bb_client_handlers[0x100] = { - /* 00 */ defh, defh, defh, defh, defh, defh, process_client_06, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ process_client_40, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ process_client_60_62_6C_6D_C9_CB, defh, process_client_60_62_6C_6D_C9_CB, defh, defh, defh, defh, defh, defh, defh, defh, defh, process_client_60_62_6C_6D_C9_CB, process_client_60_62_6C_6D_C9_CB, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; -static process_command_t patch_client_handlers[0x100] = { - /* 00 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 10 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 20 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 30 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 40 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 50 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 60 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* A0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* D0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* E0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, - /* F0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, -}; - - - -static process_command_t* server_handlers[] = { - dc_server_handlers, - pc_server_handlers, - patch_server_handlers, - gc_server_handlers, - xb_server_handlers, - bb_server_handlers}; -static process_command_t* client_handlers[] = { - dc_client_handlers, - pc_client_handlers, - patch_client_handlers, - gc_client_handlers, - xb_client_handlers, - bb_client_handlers}; - -static process_command_t get_handler(GameVersion version, bool from_server, uint8_t command) { +static on_command_t get_handler(GameVersion version, bool from_server, uint8_t command) { size_t version_index = static_cast(version); - if (version_index >= 6) { + if (version_index >= sizeof(handlers) / sizeof(handlers[0])) { throw logic_error("invalid game version on proxy server"); } - return (from_server ? server_handlers : client_handlers)[version_index][command]; + auto ret = handlers[version_index][command][!from_server]; + return ret ? ret : on_default; } -void process_proxy_command( +void on_proxy_command( shared_ptr s, ProxyServer::LinkedSession& session, bool from_server, uint16_t command, uint32_t flag, string& data) { - auto fn = get_handler(session.version, from_server, command); try { + auto fn = get_handler(session.version, from_server, command); auto res = fn(s, session, command, flag, data); if (res.type == HandlerResult::Type::FORWARD) { forward_command(session, !from_server, command, flag, data, false); diff --git a/src/ProxyCommands.hh b/src/ProxyCommands.hh index 542758f1..c4045f99 100644 --- a/src/ProxyCommands.hh +++ b/src/ProxyCommands.hh @@ -9,7 +9,7 @@ -void process_proxy_command( +void on_proxy_command( std::shared_ptr s, ProxyServer::LinkedSession& session, bool from_server, diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index 3bf1a188..10d20a4c 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -689,7 +689,7 @@ void ProxyServer::LinkedSession::send_to_game_server(const char* error_message) this->client_channel.send(0x04, 0x00, &update_client_config_cmd, sizeof(update_client_config_cmd)); static const vector version_to_port_name({ - "console-login", "pc-login", "bb-patch", "console-login", "console-login", "bb-init"}); + "bb-patch", "console-login", "pc-login", "console-login", "console-login", "bb-init"}); const auto& port_name = version_to_port_name.at(static_cast( this->version)); @@ -745,7 +745,7 @@ void ProxyServer::LinkedSession::on_input(Channel& ch, uint16_t command, uint32_ size_t bytes_to_save = min(data.size(), sizeof(session->prev_server_command_bytes)); memcpy(session->prev_server_command_bytes, data.data(), bytes_to_save); } - process_proxy_command( + on_proxy_command( session->server->state, *session, is_server_stream, diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 68ff5a8d..d0471561 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -66,7 +66,7 @@ vector quest_download_menu({ //////////////////////////////////////////////////////////////////////////////// -void process_connect(std::shared_ptr s, std::shared_ptr c) { +void on_connect(std::shared_ptr s, std::shared_ptr c) { switch (c->server_behavior) { case ServerBehavior::PC_CONSOLE_DETECT: { uint16_t pc_port = s->name_to_port_config.at("pc-login")->port; @@ -97,9 +97,9 @@ void process_connect(std::shared_ptr s, std::shared_ptr c) } } -void process_login_complete(shared_ptr s, shared_ptr c) { +void on_login_complete(shared_ptr s, shared_ptr c) { // On the BB data server, this function is called only on the last connection - // (when we should send ths ship select menu). + // (when we should send the ship select menu). if ((c->server_behavior == ServerBehavior::LOGIN_SERVER) || (c->server_behavior == ServerBehavior::DATA_SERVER_BB)) { // On the login server, send the events/songs, ep3 updates, and the main @@ -138,14 +138,12 @@ void process_login_complete(shared_ptr s, shared_ptr c) { -void process_disconnect(shared_ptr s, shared_ptr c) { - // if the client was in a lobby, remove them and notify the other clients +void on_disconnect(shared_ptr s, shared_ptr c) { + // If the client was in a lobby, remove them and notify the other clients if (c->lobby_id) { s->remove_client_from_lobby(c); } - // TODO: Make a timer event for each connected player that saves their data - // periodically, not only when they disconnect // TODO: Track play time somewhere for BB players // c->game_data.player()->disp.play_time += ((now() - c->play_time_begin) / 1000000); @@ -171,7 +169,7 @@ static void set_console_client_flags( c->flags |= flags_for_version(c->version(), sub_version); } -void process_verify_license_v3(shared_ptr s, shared_ptr c, +static void on_verify_license_v3(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // DB const auto& cmd = check_size_t(data); @@ -212,7 +210,7 @@ void process_verify_license_v3(shared_ptr s, shared_ptr c, } } -void process_login_0_dc_pc_v3(shared_ptr s, shared_ptr c, +static void on_login_0_dc_pc_v3(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 90 const auto& cmd = check_size_t(data); c->channel.version = GameVersion::DC; @@ -244,13 +242,13 @@ void process_login_0_dc_pc_v3(shared_ptr s, shared_ptr c, } } -void process_login_2_dc(shared_ptr, shared_ptr c, +static void on_login_2_dc(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // 92 check_size_t(data); send_command(c, 0x92, 0x01); } -void process_login_3_dc_pc_v3(shared_ptr s, shared_ptr c, +static void on_login_3_dc_pc_v3(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 93 const auto& cmd = check_size_t(data, sizeof(C_LoginV1_DC_93), sizeof(C_LoginExtendedV1_DC_93)); @@ -289,10 +287,10 @@ void process_login_3_dc_pc_v3(shared_ptr s, shared_ptr c, send_update_client_config(c); - process_login_complete(s, c); + on_login_complete(s, c); } -void process_login_a_dc_pc_v3(shared_ptr s, shared_ptr c, +static void on_login_a_dc_pc_v3(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 9A const auto& cmd = check_size_t(data); set_console_client_flags(c, cmd.sub_version); @@ -348,7 +346,7 @@ void process_login_a_dc_pc_v3(shared_ptr s, shared_ptr c, } } -void process_login_c_dc_pc_v3(shared_ptr s, shared_ptr c, +static void on_login_c_dc_pc_v3(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 9C const auto& cmd = check_size_t(data); @@ -410,7 +408,7 @@ void process_login_c_dc_pc_v3(shared_ptr s, shared_ptr c, } } -void process_login_d_e_dc_pc_v3(shared_ptr s, shared_ptr c, +static void on_login_d_e_dc_pc_v3(shared_ptr s, shared_ptr c, uint16_t command, uint32_t, const string& data) { // 9D 9E const C_Login_DC_PC_GC_9D* base_cmd; if (command == 0x9D) { @@ -521,10 +519,10 @@ void process_login_d_e_dc_pc_v3(shared_ptr s, shared_ptr c, send_update_client_config(c); - process_login_complete(s, c); + on_login_complete(s, c); } -void process_login_bb(shared_ptr s, shared_ptr c, +static void on_login_bb(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 93 const auto& cmd = check_size_t(data, sizeof(C_Login_BB_93) - 8, sizeof(C_Login_BB_93)); @@ -599,7 +597,7 @@ void process_login_bb(shared_ptr s, shared_ptr c, break; case ClientStateBB::SHIP_SELECT: - process_login_complete(s, c); + on_login_complete(s, c); break; case ClientStateBB::IN_GAME: @@ -610,7 +608,7 @@ void process_login_bb(shared_ptr s, shared_ptr c, } } -void process_return_client_config(shared_ptr, shared_ptr c, +static void on_return_client_config(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // 9F if (c->version() == GameVersion::BB) { const auto& cfg = check_size_t(data); @@ -621,13 +619,13 @@ void process_return_client_config(shared_ptr, shared_ptr c, } } -void process_client_checksum(shared_ptr, shared_ptr c, +static void on_client_checksum(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // 96 check_size_t(data); send_server_time(c); } -void process_server_time_request(shared_ptr s, shared_ptr c, +static void on_server_time_request(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // B1 check_size_v(data.size(), 0); send_server_time(c); @@ -642,7 +640,7 @@ void process_server_time_request(shared_ptr s, shared_ptr c // responds after saving. if (c->should_send_to_lobby_server) { static const vector version_to_port_name({ - "console-lobby", "pc-lobby", "bb-lobby", "console-lobby", "console-lobby", "bb-lobby"}); + "bb-lobby", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}); const auto& port_name = version_to_port_name.at(static_cast(c->version())); send_reconnect(c, s->connect_address_for_client(c), s->name_to_port_config.at(port_name)->port); @@ -651,11 +649,7 @@ void process_server_time_request(shared_ptr s, shared_ptr c -//////////////////////////////////////////////////////////////////////////////// -// Ep3 commands. Note that these commands are not at all functional. The command -// handlers that partially worked were lost in a dead hard drive, unfortunately. - -void process_ep3_meseta_transaction(shared_ptr, +static void on_ep3_meseta_transaction(shared_ptr, shared_ptr c, uint16_t command, uint32_t, const string& data) { const auto& in_cmd = check_size_t(data); @@ -663,7 +657,7 @@ void process_ep3_meseta_transaction(shared_ptr, send_command(c, command, 0x03, &out_cmd, sizeof(out_cmd)); } -void process_ep3_menu_challenge(shared_ptr, shared_ptr c, +static void on_ep3_counter_state(shared_ptr, shared_ptr c, uint16_t, uint32_t flag, const string& data) { // DC check_size_v(data.size(), 0); if (flag != 0) { @@ -671,7 +665,7 @@ void process_ep3_menu_challenge(shared_ptr, shared_ptr c, } } -void process_ep3_server_data_request(shared_ptr s, shared_ptr c, +static void on_ep3_server_data_request(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // CA check_size_v(data.size(), 8, 0xFFFF); const PSOSubcommand* cmds = reinterpret_cast(data.data()); @@ -764,26 +758,17 @@ void process_ep3_server_data_request(shared_ptr s, shared_ptr, shared_ptr c, +static void on_ep3_tournament_control(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string&) { // E2 - // The client will get stuck here unless we send something. An 01 (lobby - // message box) seems to get them unstuck. + // The client will set their interaction mode expecting a menu to be sent, but + // since we don't implement tournaments, they will get stuck here unless we + // send something. An 01 (lobby message box) seems to work fine. send_lobby_message_box(c, u"$C6Tournaments are\nnot supported."); - - // In case we ever implement this (doubtful), the flag values are: - // 00 - list tournaments - // 01 - check tournament entry status - // 02 - cancel tournament entry - // 03 - create tournament spectator team (presumably get battle list, like get team list) - // 04 - join tournament spectator team (presumably also get battle list) } -//////////////////////////////////////////////////////////////////////////////// -// menu commands - -void process_message_box_closed(shared_ptr s, shared_ptr c, +static void on_message_box_closed(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // D6 check_size_v(data.size(), 0); if (c->flags & Client::Flag::IN_INFORMATION_MENU) { @@ -796,7 +781,7 @@ void process_message_box_closed(shared_ptr s, shared_ptr c, } } -void process_menu_item_info_request(shared_ptr s, shared_ptr c, +static void on_menu_item_info_request(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 09 const auto& cmd = check_size_t(data); @@ -814,7 +799,7 @@ void process_menu_item_info_request(shared_ptr s, shared_ptrinformation_menu_for_version(c->version())->at(cmd.item_id + 1).description.c_str()); } catch (const out_of_range&) { send_ship_info(c, u"$C4Missing information\nmenu item"); @@ -828,7 +813,7 @@ void process_menu_item_info_request(shared_ptr s, shared_ptrproxy_destinations_menu_for_version(c->version()); - // we use item_id + 1 here because "go back" is the first item + // We use item_id + 1 here because "go back" is the first item send_ship_info(c, menu.at(cmd.item_id + 1).description.c_str()); } catch (const out_of_range&) { send_ship_info(c, u"$C4Missing proxy\ndestination"); @@ -936,7 +921,7 @@ void process_menu_item_info_request(shared_ptr s, shared_ptr s, shared_ptr s, shared_ptr c, +static void on_menu_selection(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 10 bool uses_unicode = ((c->version() == GameVersion::PC) || (c->version() == GameVersion::BB)); @@ -998,7 +983,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, send_update_client_config(c); } else { static const vector version_to_port_name({ - "console-lobby", "pc-lobby", "bb-lobby", "console-lobby", "console-lobby", "bb-lobby"}); + "bb-lobby", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}); const auto& port_name = version_to_port_name.at(static_cast(c->version())); send_reconnect(c, s->connect_address_for_client(c), s->name_to_port_config.at(port_name)->port); @@ -1027,8 +1012,9 @@ void process_menu_selection(shared_ptr s, shared_ptr c, } else { // Episode 3 has only download quests, not online quests, so this // is always the download quest menu. (Episode 3 does actually - // have online quests, but they don't use the file download - // paradigm that all other versions use.) + // have online quests, but they're served via a server data + // request instead of the file download paradigm that all other + // versions use.) send_quest_menu(c, MenuID::QUEST, quests, true); } } else { @@ -1089,13 +1075,13 @@ void process_menu_selection(shared_ptr s, shared_ptr c, send_message_box(c, u"$C6No such destination exists."); c->should_disconnect = true; } else { - // TODO: We can probably avoid using client config and reconnecting the - // client here; it's likely we could build a way to just directly link - // the client to the proxy server instead (would have to provide + // TODO: We can probably avoid using client config and reconnecting + // the client here; it's likely we could build a way to just directly + // link the client to the proxy server instead (would have to provide // license/char name/etc. for remote auth) static const vector version_to_port_name({ - "dc-proxy", "pc-proxy", "", "gc-proxy", "xb-proxy", "bb-proxy"}); + "", "dc-proxy", "pc-proxy", "gc-proxy", "xb-proxy", "bb-proxy"}); const auto& port_name = version_to_port_name.at(static_cast(c->version())); uint16_t local_port = s->name_to_port_config.at(port_name)->port; @@ -1182,7 +1168,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, break; } - // Hack: assume the menu to be sent is the download quest menu if the + // Hack: Assume the menu to be sent is the download quest menu if the // client is not in any lobby send_quest_menu(c, MenuID::QUEST, quests, !c->lobby_id); break; @@ -1205,7 +1191,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, if (c->lobby_id) { l = s->find_lobby(c->lobby_id); if (!l->is_game()) { - send_lobby_message_box(c, u"$C6Quests cannot be loaded\nin lobbies."); + send_lobby_message_box(c, u"$C6Quests cannot be\nloaded in lobbies."); break; } } @@ -1238,8 +1224,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, // TODO: It looks like blasting all the chunks to the client at once // can cause GC clients to crash in rare cases. Find a way to slow // this down (perhaps by only sending each new chunk when they - // acknowledge the previous chunk with a 44 [first chunk] or 13 [later - // chunks] command). + // acknowledge the previous chunk with a 13 command). send_quest_file(l->clients[x], bin_basename + ".bin", bin_basename, *bin_contents, QuestFileType::ONLINE); send_quest_file(l->clients[x], dat_basename + ".dat", dat_basename, @@ -1303,8 +1288,8 @@ void process_menu_selection(shared_ptr s, shared_ptr c, c->loading_dol_file = s->dol_file_index->item_id_to_file.at(item_id); // Send the first function call, which triggers the process of loading a - // DOL file. This function call determines the necessary base address - // for loading the file. + // DOL file. The result of this function call determines the necessary + // base address for loading the file. send_function_call( c, s->function_code_index->name_to_function.at("ReadMemoryWord"), @@ -1318,7 +1303,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, } } -void process_change_lobby(shared_ptr s, shared_ptr c, +static void on_change_lobby(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 84 const auto& cmd = check_size_t(data); @@ -1327,9 +1312,8 @@ void process_change_lobby(shared_ptr s, shared_ptr c, return; } - // If the client isn't in any lobby, then they just left a game. Ignore their - // selection and add them to any lobby with room. If they're already in a - // lobby, then they used the lobby teleporter - add them to a specific lobby. + // If the client isn't in any lobby, then they just left a game. Add them to + // the lobby they requested, but fall back to another lobby if it's full. if (c->lobby_id == 0) { c->preferred_lobby_id = cmd.item_id; s->add_client_to_available_lobby(c); @@ -1356,25 +1340,23 @@ void process_change_lobby(shared_ptr s, shared_ptr c, } } -void process_game_list_request(shared_ptr s, shared_ptr c, +static void on_game_list_request(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 08 check_size_v(data.size(), 0); send_game_menu(c, s); } -void process_information_menu_request_dc_pc(shared_ptr s, +static void on_info_menu_request_dc_pc(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 1F check_size_v(data.size(), 0); send_menu(c, u"Information", MenuID::INFORMATION, *s->information_menu_for_version(c->version()), true); } -void process_change_ship(shared_ptr s, shared_ptr c, +static void on_change_ship(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string&) { // A0 - // The client actually sends data in this command... looks like nothing - // important (player_tag and guild_card_number are the only discernable - // things, which we already know). We intentionally don't call check_size - // here, but instead just ignore the data. + // The client sends data in this command, but none of it is important. We + // intentionally don't call check_size here, but just ignore the data. // Delete the player from the lobby they're in (but only visible to themself). // This makes it safe to allow the player to choose download quests from the @@ -1387,21 +1369,20 @@ void process_change_ship(shared_ptr s, shared_ptr c, send_message_box(c, u""); static const vector version_to_port_name({ - "console-login", "pc-login", "bb-patch", "console-login", "console-login", "bb-init"}); + "bb-patch", "console-login", "pc-login", "console-login", "console-login", "bb-init"}); const auto& port_name = version_to_port_name.at(static_cast(c->version())); send_reconnect(c, s->connect_address_for_client(c), s->name_to_port_config.at(port_name)->port); } -void process_change_block(shared_ptr s, shared_ptr c, +static void on_change_block(shared_ptr s, shared_ptr c, uint16_t command, uint32_t flag, const string& data) { // A1 // newserv doesn't have blocks; treat block change the same as ship change - process_change_ship(s, c, command, flag, data); + on_change_ship(s, c, command, flag, data); } -//////////////////////////////////////////////////////////////////////////////// -// DOL loading commands + static void send_dol_file_chunk(shared_ptr s, shared_ptr c, uint32_t start_addr) { @@ -1423,7 +1404,7 @@ static void send_dol_file_chunk(shared_ptr s, shared_ptr c, send_ship_info(c, decode_sjis(info)); } -void process_function_call_result(shared_ptr s, shared_ptr c, +static void on_function_call_result(shared_ptr s, shared_ptr c, uint16_t, uint32_t flag, const string& data) { // B3 const auto& cmd = check_size_t(data); if (flag == 0) { @@ -1451,10 +1432,9 @@ void process_function_call_result(shared_ptr s, shared_ptr } } -//////////////////////////////////////////////////////////////////////////////// -// Quest commands -void process_quest_list_request(shared_ptr s, shared_ptr c, + +static void on_quest_list_request(shared_ptr s, shared_ptr c, uint16_t, uint32_t flag, const string& data) { // A2 check_size_v(data.size(), 0); @@ -1494,7 +1474,7 @@ void process_quest_list_request(shared_ptr s, shared_ptr c, } } -void process_quest_barrier(shared_ptr s, shared_ptr c, +static void on_quest_barrier(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // AC check_size_v(data.size(), 0); @@ -1511,9 +1491,9 @@ void process_quest_barrier(shared_ptr s, shared_ptr c, } c->flags &= ~Client::Flag::LOADING_QUEST; - // check if any client is still loading - // TODO: we need to handle clients disconnecting while loading. probably - // process_client_disconnect needs to check for this case or something + // Check if any client is still loading + // TODO: We need to handle clients disconnecting while loading. Probably + // on_client_disconnect needs to check for this case... size_t x; for (x = 0; x < l->max_clients; x++) { if (!l->clients[x]) { @@ -1524,13 +1504,13 @@ void process_quest_barrier(shared_ptr s, shared_ptr c, } } - // if they're all done, start the quest + // If they're all done, start the quest if (x == l->max_clients) { send_command(l, 0xAC, 0x00); } } -void process_update_quest_statistics(shared_ptr s, +static void on_update_quest_statistics(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // AA const auto& cmd = check_size_t(data); @@ -1552,7 +1532,7 @@ void process_update_quest_statistics(shared_ptr s, send_command_t(c, 0xAB, 0x00, response); } -void process_gba_file_request(shared_ptr, shared_ptr c, +static void on_gba_file_request(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // D7 string filename(data); strip_trailing_zeroes(filename); @@ -1565,14 +1545,9 @@ void process_gba_file_request(shared_ptr, shared_ptr c, -//////////////////////////////////////////////////////////////////////////////// -// player data commands - -void process_player_data(shared_ptr s, shared_ptr c, +static void on_player_data(shared_ptr s, shared_ptr c, uint16_t command, uint32_t flag, const string& data) { // 61 98 - // Note: we add extra buffer on the end when checking sizes because the - // autoreply text is a variable length switch (c->version()) { case GameVersion::DC: case GameVersion::PC: { @@ -1658,10 +1633,9 @@ void process_player_data(shared_ptr s, shared_ptr c, } } -//////////////////////////////////////////////////////////////////////////////// -// subcommands -void process_game_command(shared_ptr s, shared_ptr c, + +static void on_game_command(shared_ptr s, shared_ptr c, uint16_t command, uint32_t flag, const string& data) { // 60 62 6C 6D C9 CB (C9 CB are ep3 only) check_size_v(data.size(), 4, 0xFFFF); @@ -1670,13 +1644,12 @@ void process_game_command(shared_ptr s, shared_ptr c, return; } - process_subcommand(s, l, c, command, flag, data); + on_subcommand(s, l, c, command, flag, data); } -//////////////////////////////////////////////////////////////////////////////// -// chat commands -void process_chat_generic(shared_ptr s, shared_ptr c, + +static void on_chat_generic(shared_ptr s, shared_ptr c, const u16string& text) { // 06 u16string processed_text = remove_language_marker(text); @@ -1693,7 +1666,7 @@ void process_chat_generic(shared_ptr s, shared_ptr c, if (processed_text[1] == L'$') { processed_text = processed_text.substr(1); } else { - process_chat_command(s, l, c, processed_text); + on_chat_command(s, l, c, processed_text); return; } } @@ -1711,31 +1684,30 @@ void process_chat_generic(shared_ptr s, shared_ptr c, } } -void process_chat_pc_bb(shared_ptr s, shared_ptr c, +static void on_chat_pc_bb(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 06 const auto& cmd = check_size_t(data, sizeof(C_Chat_06), 0xFFFF); u16string text(cmd.text.pcbb, (data.size() - sizeof(C_Chat_06)) / sizeof(char16_t)); strip_trailing_zeroes(text); - process_chat_generic(s, c, text); + on_chat_generic(s, c, text); } -void process_chat_dc_v3(shared_ptr s, shared_ptr c, +static void on_chat_dc_v3(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data, sizeof(C_Chat_06), 0xFFFF); u16string decoded_s = decode_sjis(cmd.text.dcv3, data.size() - sizeof(C_Chat_06)); - process_chat_generic(s, c, decoded_s); + on_chat_generic(s, c, decoded_s); } -//////////////////////////////////////////////////////////////////////////////// -// BB commands -void process_key_config_request_bb(shared_ptr, shared_ptr c, + +static void on_key_config_request_bb(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); send_team_and_key_config_bb(c); } -void process_player_preview_request_bb(shared_ptr, shared_ptr c, +static void on_player_preview_request_bb(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); @@ -1766,7 +1738,7 @@ void process_player_preview_request_bb(shared_ptr, shared_ptr, shared_ptr c, +static void on_client_checksum_bb(shared_ptr, shared_ptr c, uint16_t command, uint32_t, const string& data) { constexpr size_t max_count = sizeof(GuildCardFileBB::entries) / sizeof(GuildCardEntryBB); constexpr size_t max_blocked = sizeof(GuildCardFileBB::blocked) / sizeof(GuildCardBB); @@ -1905,7 +1877,7 @@ void process_client_checksum_bb(shared_ptr, shared_ptr c, } } -void process_guild_card_data_request_bb(shared_ptr, shared_ptr c, +static void on_guild_card_data_request_bb(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); if (cmd.cont) { @@ -1913,7 +1885,7 @@ void process_guild_card_data_request_bb(shared_ptr, shared_ptr, shared_ptr c, +static void on_stream_file_request_bb(shared_ptr, shared_ptr c, uint16_t command, uint32_t flag, const string& data) { check_size_v(data.size(), 0); @@ -1926,7 +1898,7 @@ void process_stream_file_request_bb(shared_ptr, shared_ptr } } -void process_create_character_bb(shared_ptr s, shared_ptr c, +static void on_create_character_bb(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); @@ -1964,7 +1936,7 @@ void process_create_character_bb(shared_ptr s, shared_ptr c send_approve_player_choice_bb(c); } -void process_change_account_data_bb(shared_ptr, shared_ptr c, +static void on_change_account_data_bb(shared_ptr, shared_ptr c, uint16_t command, uint32_t, const string& data) { const auto* cmd = reinterpret_cast(data.data()); @@ -2002,7 +1974,7 @@ void process_change_account_data_bb(shared_ptr, shared_ptr } } -void process_return_player_data_bb(shared_ptr, shared_ptr c, +static void on_return_player_data_bb(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // 00E7 const auto& cmd = check_size_t(data); @@ -2012,19 +1984,18 @@ void process_return_player_data_bb(shared_ptr, shared_ptr c c->game_data.player()->quest_data2 = cmd.quest_data2; } -void process_update_key_config_bb(shared_ptr, shared_ptr c, +static void on_update_key_config_bb(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // Some clients have only a uint32_t at the end for team rewards auto& cmd = check_size_t(data, sizeof(KeyAndTeamConfigBB) - 4, sizeof(KeyAndTeamConfigBB)); c->game_data.account()->key_config = cmd; - // TODO: We should send a response here, but I don't know which one! + // TODO: We should probably send a response here, but I don't know which one! } -//////////////////////////////////////////////////////////////////////////////// -// Lobby commands -void process_change_arrow_color(shared_ptr s, shared_ptr c, + +static void on_change_arrow_color(shared_ptr s, shared_ptr c, uint16_t, uint32_t flag, const string& data) { // 89 check_size_v(data.size(), 0); @@ -2035,7 +2006,7 @@ void process_change_arrow_color(shared_ptr s, shared_ptr c, } } -void process_card_search(shared_ptr s, shared_ptr c, +static void on_card_search(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 40 const auto& cmd = check_size_t(data); try { @@ -2045,13 +2016,13 @@ void process_card_search(shared_ptr s, shared_ptr c, } catch (const out_of_range&) { } } -void process_choice_search(shared_ptr, shared_ptr c, +static void on_choice_search(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string&) { // C0 // TODO: Implement choice search. send_text_message(c, u"$C6Choice Search is\nnot supported"); } -void process_simple_mail(shared_ptr s, shared_ptr c, +static void on_simple_mail(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 81 u16string message; uint32_t to_guild_card_number; @@ -2106,17 +2077,14 @@ void process_simple_mail(shared_ptr s, shared_ptr c, -//////////////////////////////////////////////////////////////////////////////// -// Info board commands - -void process_info_board_request(shared_ptr s, shared_ptr c, +static void on_info_board_request(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // D8 check_size_v(data.size(), 0); send_info_board(c, s->find_lobby(c->lobby_id)); } template -void process_write_info_board_t(shared_ptr, shared_ptr c, +void on_write_info_board_t(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // D9 check_size_v(data.size(), 0, c->game_data.player()->info_board.size() * sizeof(CharT)); c->game_data.player()->info_board.assign( @@ -2125,7 +2093,7 @@ void process_write_info_board_t(shared_ptr, shared_ptr c, } template -void process_set_auto_reply_t(shared_ptr, shared_ptr c, +void on_set_auto_reply_t(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // C7 check_size_v(data.size(), 0, c->game_data.player()->auto_reply.size() * sizeof(CharT)); c->game_data.player()->auto_reply.assign( @@ -2133,13 +2101,13 @@ void process_set_auto_reply_t(shared_ptr, shared_ptr c, data.size() / sizeof(CharT)); } -void process_disable_auto_reply(shared_ptr, shared_ptr c, +static void on_disable_auto_reply(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // C8 check_size_v(data.size(), 0); c->game_data.player()->auto_reply.clear(0); } -void process_set_blocked_senders_list(shared_ptr, shared_ptr c, +static void on_set_blocked_senders_list(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // C6 if (c->version() == GameVersion::BB) { const auto& cmd = check_size_t(data); @@ -2152,9 +2120,6 @@ void process_set_blocked_senders_list(shared_ptr, shared_ptr create_game_generic(shared_ptr s, shared_ptr c, const std::u16string& name, @@ -2166,9 +2131,9 @@ static shared_ptr create_game_generic(shared_ptr s, // A player's actual level is their displayed level - 1, so the minimums for // Episode 1 (for example) are actually 1, 20, 40, 80. static const uint32_t default_minimum_levels[3][4] = { - {0, 19, 39, 79}, // episode 1 - {0, 29, 49, 89}, // episode 2 - {0, 39, 79, 109}}; // episode 4 + {0, 19, 39, 79}, // Episode 1 + {0, 29, 49, 89}, // Episode 2 + {0, 39, 79, 109}}; // Episode 4 bool is_ep3 = (flags & Lobby::Flag::EPISODE_3_ONLY); if (episode == 0) { @@ -2221,7 +2186,7 @@ static shared_ptr create_game_generic(shared_ptr s, game->max_level = 0xFFFFFFFF; if (game->version == GameVersion::BB) { - // TODO: cache these somewhere so we don't read the file every time, lolz + // TODO: Cache these somewhere so we don't read the file every time game->rare_item_set.reset(new RareItemSet("system/blueburst/ItemRT.rel", game->episode - 1, game->difficulty, game->section_id)); @@ -2284,7 +2249,7 @@ static shared_ptr create_game_generic(shared_ptr s, return game; } -void process_create_game_pc(shared_ptr s, shared_ptr c, +static void on_create_game_pc(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // C1 const auto& cmd = check_size_t(data); @@ -2298,7 +2263,7 @@ void process_create_game_pc(shared_ptr s, shared_ptr c, create_game_generic(s, c, cmd.name, cmd.password, 1, cmd.difficulty, flags); } -void process_create_game_dc_v3(shared_ptr s, shared_ptr c, +static void on_create_game_dc_v3(shared_ptr s, shared_ptr c, uint16_t command, uint32_t, const string& data) { // 0C C1 EC (EC Ep3 only) const auto& cmd = check_size_t(data); @@ -2333,7 +2298,7 @@ void process_create_game_dc_v3(shared_ptr s, shared_ptr c, s, c, name.c_str(), password.c_str(), episode, cmd.difficulty, flags); } -void process_create_game_bb(shared_ptr s, shared_ptr c, +static void on_create_game_bb(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // C1 const auto& cmd = check_size_t(data); @@ -2351,7 +2316,7 @@ void process_create_game_bb(shared_ptr s, shared_ptr c, s, c, cmd.name, cmd.password, cmd.episode, cmd.difficulty, flags); } -void process_lobby_name_request(shared_ptr s, shared_ptr c, +static void on_lobby_name_request(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 8A check_size_v(data.size(), 0); auto l = s->find_lobby(c->lobby_id); @@ -2361,7 +2326,7 @@ void process_lobby_name_request(shared_ptr s, shared_ptr c, send_lobby_name(c, l->name.c_str()); } -void process_client_ready(shared_ptr s, shared_ptr c, +static void on_client_ready(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // 6F check_size_v(data.size(), 0); @@ -2381,10 +2346,9 @@ void process_client_ready(shared_ptr s, shared_ptr c, } } -//////////////////////////////////////////////////////////////////////////////// -// Trade window commands -void process_trade_start(shared_ptr s, shared_ptr c, + +static void on_trade_start(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // D0 auto& cmd = check_size_t(data); @@ -2416,13 +2380,15 @@ void process_trade_start(shared_ptr s, shared_ptr c, // other player does not have a pending trade, assume this is the first half // of the trade sequence, and send a D1 only to the target player (to request // its D0 command). + // See the description of the D0 command in CommandFormats.hh for more + // information on how this sequence is supposed to work. send_command(target_c, 0xD1, 0x00); if (target_c->game_data.pending_item_trade) { send_command(c, 0xD1, 0x00); } } -void process_trade_execute(shared_ptr s, shared_ptr c, +static void on_trade_execute(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // D2 check_size_v(data.size(), 0); @@ -2453,7 +2419,7 @@ void process_trade_execute(shared_ptr s, shared_ptr c, } } -void process_trade_error(shared_ptr s, shared_ptr c, +static void on_trade_error(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // D4 check_size_v(data.size(), 0); @@ -2484,12 +2450,13 @@ void process_trade_error(shared_ptr s, shared_ptr c, send_command(target_c, 0xD4, 0x00); } -//////////////////////////////////////////////////////////////////////////////// -// Team commands -void process_team_command_bb(shared_ptr, shared_ptr c, + +static void on_team_command_bb(shared_ptr, shared_ptr c, uint16_t command, uint32_t, const string&) { // EA + // TODO: Implement teams. This command has a very large number of subcommands + // (up to 20EA!). if (command == 0x01EA) { send_lobby_message_box(c, u"$C6Teams are not supported."); } else if (command == 0x14EA) { @@ -2499,10 +2466,9 @@ void process_team_command_bb(shared_ptr, shared_ptr c, } } -//////////////////////////////////////////////////////////////////////////////// -// Patch server commands -void process_encryption_ok_patch(shared_ptr, shared_ptr c, + +static void on_connected_patch(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { check_size_v(data.size(), 0); send_command(c, 0x04, 0x00); // This requests the user's login information @@ -2539,7 +2505,7 @@ static void change_to_directory_patch( } } -void process_login_patch(shared_ptr s, shared_ptr c, +static void on_login_patch(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { const auto& cmd = check_size_t(data); @@ -2606,7 +2572,7 @@ void process_login_patch(shared_ptr s, shared_ptr c, } } -void process_file_checksum_result_patch(shared_ptr, +static void on_checksum_patch(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string& data) { // 0F auto& cmd = check_size_t(data); auto& req = c->patch_file_checksum_requests.at(cmd.request_id); @@ -2615,7 +2581,7 @@ void process_file_checksum_result_patch(shared_ptr, req.response_received = true; } -void process_file_checksum_results_done_patch(shared_ptr, +static void on_checksums_done_patch(shared_ptr, shared_ptr c, uint16_t, uint32_t, const string&) { // 10 S_StartFileDownloads_Patch_11 start_cmd = {0, 0}; @@ -2644,13 +2610,12 @@ void process_file_checksum_results_done_patch(shared_ptr, send_command(c, 0x12, 0x00); } -//////////////////////////////////////////////////////////////////////////////// -// Command pointer arrays -void process_ignored_command(shared_ptr, shared_ptr, + +static void on_ignored_command(shared_ptr, shared_ptr, uint16_t, uint32_t, const string&) { } -void process_unimplemented_command(shared_ptr, +static void on_unimplemented_command(shared_ptr, shared_ptr c, uint16_t command, uint32_t flag, const string& data) { c->log.warning("Unknown command: size=%04zX command=%04hX flag=%08" PRIX32, data.size(), command, flag); @@ -2659,501 +2624,281 @@ void process_unimplemented_command(shared_ptr, -typedef void (*process_command_t)(shared_ptr s, shared_ptr c, +typedef void (*on_command_t)(shared_ptr s, shared_ptr c, uint16_t command, uint32_t flag, const string& data); -// The entries in these arrays correspond to the ID of the command received. For -// instance, if a command 6C is received, the function at position 0x6C in the -// array corresponding to the client's version is called. -static process_command_t dc_handlers[0x100] = { - // 00 - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, process_chat_dc_v3, nullptr, - process_game_list_request, process_menu_item_info_request, nullptr, nullptr, - process_create_game_dc_v3, nullptr, nullptr, nullptr, - - // 10 - process_menu_selection, nullptr, nullptr, process_ignored_command, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, nullptr, process_information_menu_request_dc_pc, - - // 20 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 30 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 40 - process_card_search, nullptr, nullptr, nullptr, - process_ignored_command, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 50 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 60 - process_game_command, process_player_data, process_game_command, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - process_game_command, process_game_command, nullptr, process_client_ready, - - // 70 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 80 - nullptr, process_simple_mail, nullptr, nullptr, - process_change_lobby, nullptr, nullptr, nullptr, - nullptr, process_change_arrow_color, process_lobby_name_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 90 - process_login_0_dc_pc_v3, nullptr, process_login_2_dc, process_login_3_dc_pc_v3, - nullptr, nullptr, process_client_checksum, nullptr, - process_player_data, process_ignored_command, process_login_a_dc_pc_v3, nullptr, - process_login_c_dc_pc_v3, process_login_d_e_dc_pc_v3, nullptr, nullptr, - - // A0 - process_change_ship, process_change_block, process_quest_list_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // B0 - nullptr, process_server_time_request, nullptr, process_function_call_result, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // C0 - process_choice_search, process_create_game_dc_v3, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // D0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // E0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // F0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, +// Command handler table, indexed by command number and game version. Null +// entries in this table cause on_unimplemented_command to be called, which +// disconnects the client. +static on_command_t handlers[0x100][6] = { + // PATCH DC PC GC XB BB + /* 00 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 00 */ + /* 01 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 01 */ + /* 02 */ {on_connected_patch, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 02 */ + /* 03 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 03 */ + /* 04 */ {on_login_patch, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 04 */ + /* 05 */ {nullptr, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, }, /* 05 */ + /* 06 */ {nullptr, on_chat_dc_v3, on_chat_pc_bb, on_chat_dc_v3, on_chat_dc_v3, on_chat_pc_bb, }, /* 06 */ + /* 07 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 07 */ + /* 08 */ {nullptr, on_game_list_request, on_game_list_request, on_game_list_request, on_game_list_request, on_game_list_request, }, /* 08 */ + /* 09 */ {nullptr, on_menu_item_info_request, on_menu_item_info_request, on_menu_item_info_request, on_menu_item_info_request, on_menu_item_info_request, }, /* 09 */ + /* 0A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 0A */ + /* 0B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 0B */ + /* 0C */ {nullptr, on_create_game_dc_v3, nullptr, nullptr, nullptr, nullptr, }, /* 0C */ + /* 0D */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 0D */ + /* 0E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 0E */ + /* 0F */ {on_checksum_patch, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 0F */ + /* 10 */ {on_checksums_done_patch, on_menu_selection, on_menu_selection, on_menu_selection, on_menu_selection, on_menu_selection, }, /* 10 */ + /* 11 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 11 */ + /* 12 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 12 */ + /* 13 */ {nullptr, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, }, /* 13 */ + /* 14 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 14 */ + /* 15 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 15 */ + /* 16 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 16 */ + /* 17 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 17 */ + /* 18 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 18 */ + /* 19 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 19 */ + /* 1A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 1A */ + /* 1B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 1B */ + /* 1C */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 1C */ + /* 1D */ {nullptr, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, }, /* 1D */ + /* 1E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 1E */ + /* 1F */ {nullptr, on_info_menu_request_dc_pc, on_info_menu_request_dc_pc, nullptr, nullptr, nullptr, }, /* 1F */ + // PATCH DC PC GC XB BB + /* 20 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 20 */ + /* 21 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 21 */ + /* 22 */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_ignored_command, }, /* 22 */ + /* 23 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 23 */ + /* 24 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 24 */ + /* 25 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 25 */ + /* 26 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 26 */ + /* 27 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 27 */ + /* 28 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 28 */ + /* 29 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 29 */ + /* 2A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 2A */ + /* 2B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 2B */ + /* 2C */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 2C */ + /* 2D */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 2D */ + /* 2E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 2E */ + /* 2F */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 2F */ + /* 30 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 30 */ + /* 31 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 31 */ + /* 32 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 32 */ + /* 33 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 33 */ + /* 34 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 34 */ + /* 35 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 35 */ + /* 36 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 36 */ + /* 37 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 37 */ + /* 38 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 38 */ + /* 39 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 39 */ + /* 3A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 3A */ + /* 3B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 3B */ + /* 3C */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 3C */ + /* 3D */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 3D */ + /* 3E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 3E */ + /* 3F */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 3F */ + // PATCH DC PC GC XB BB + /* 40 */ {nullptr, on_card_search, on_card_search, on_card_search, on_card_search, on_card_search, }, /* 40 */ + /* 41 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 41 */ + /* 42 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 42 */ + /* 43 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 43 */ + /* 44 */ {nullptr, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, }, /* 44 */ + /* 45 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 45 */ + /* 46 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 46 */ + /* 47 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 47 */ + /* 48 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 48 */ + /* 49 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 49 */ + /* 4A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 4A */ + /* 4B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 4B */ + /* 4C */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 4C */ + /* 4D */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 4D */ + /* 4E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 4E */ + /* 4F */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 4F */ + /* 50 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 50 */ + /* 51 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 51 */ + /* 52 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 52 */ + /* 53 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 53 */ + /* 54 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 54 */ + /* 55 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 55 */ + /* 56 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 56 */ + /* 57 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 57 */ + /* 58 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 58 */ + /* 59 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 59 */ + /* 5A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 5A */ + /* 5B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 5B */ + /* 5C */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 5C */ + /* 5D */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 5D */ + /* 5E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 5E */ + /* 5F */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 5F */ + // PATCH DC PC GC XB BB + /* 60 */ {nullptr, on_game_command, on_game_command, on_game_command, on_game_command, on_game_command, }, /* 60 */ + /* 61 */ {nullptr, on_player_data, on_player_data, on_player_data, on_player_data, on_player_data, }, /* 61 */ + /* 62 */ {nullptr, on_game_command, on_game_command, on_game_command, on_game_command, on_game_command, }, /* 62 */ + /* 63 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 63 */ + /* 64 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 64 */ + /* 65 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 65 */ + /* 66 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 66 */ + /* 67 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 67 */ + /* 68 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 68 */ + /* 69 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 69 */ + /* 6A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 6A */ + /* 6B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 6B */ + /* 6C */ {nullptr, on_game_command, on_game_command, on_game_command, on_game_command, on_game_command, }, /* 6C */ + /* 6D */ {nullptr, on_game_command, on_game_command, on_game_command, on_game_command, on_game_command, }, /* 6D */ + /* 6E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 6E */ + /* 6F */ {nullptr, on_client_ready, on_client_ready, on_client_ready, on_client_ready, on_client_ready, }, /* 6F */ + /* 70 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 70 */ + /* 71 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 71 */ + /* 72 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 72 */ + /* 73 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 73 */ + /* 74 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 74 */ + /* 75 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 75 */ + /* 76 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 76 */ + /* 77 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 77 */ + /* 78 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 78 */ + /* 79 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 79 */ + /* 7A */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 7A */ + /* 7B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 7B */ + /* 7C */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 7C */ + /* 7D */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 7D */ + /* 7E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 7E */ + /* 7F */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 7F */ + // PATCH DC PC GC XB BB + /* 80 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 80 */ + /* 81 */ {nullptr, on_simple_mail, on_simple_mail, on_simple_mail, on_simple_mail, on_simple_mail, }, /* 81 */ + /* 82 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 82 */ + /* 83 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 83 */ + /* 84 */ {nullptr, on_change_lobby, on_change_lobby, on_change_lobby, on_change_lobby, on_change_lobby, }, /* 84 */ + /* 85 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 85 */ + /* 86 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 86 */ + /* 87 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 87 */ + /* 88 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 88 */ + /* 89 */ {nullptr, on_change_arrow_color, on_change_arrow_color, on_change_arrow_color, on_change_arrow_color, on_change_arrow_color, }, /* 89 */ + /* 8A */ {nullptr, on_lobby_name_request, on_lobby_name_request, on_lobby_name_request, on_lobby_name_request, on_lobby_name_request, }, /* 8A */ + /* 8B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 8B */ + /* 8C */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 8C */ + /* 8D */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 8D */ + /* 8E */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 8E */ + /* 8F */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 8F */ + /* 90 */ {nullptr, on_login_0_dc_pc_v3, nullptr, on_login_0_dc_pc_v3, nullptr, nullptr, }, /* 90 */ + /* 91 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 91 */ + /* 92 */ {nullptr, on_login_2_dc, nullptr, nullptr, nullptr, nullptr, }, /* 92 */ + /* 93 */ {nullptr, on_login_3_dc_pc_v3, nullptr, on_login_3_dc_pc_v3, nullptr, on_login_bb, }, /* 93 */ + /* 94 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 94 */ + /* 95 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 95 */ + /* 96 */ {nullptr, on_client_checksum, on_client_checksum, on_client_checksum, on_client_checksum, nullptr, }, /* 96 */ + /* 97 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 97 */ + /* 98 */ {nullptr, on_player_data, on_player_data, on_player_data, on_player_data, on_player_data, }, /* 98 */ + /* 99 */ {nullptr, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, }, /* 99 */ + /* 9A */ {nullptr, on_login_a_dc_pc_v3, on_login_a_dc_pc_v3, on_login_a_dc_pc_v3, nullptr, nullptr, }, /* 9A */ + /* 9B */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* 9B */ + /* 9C */ {nullptr, on_login_c_dc_pc_v3, on_login_c_dc_pc_v3, on_login_c_dc_pc_v3, on_login_c_dc_pc_v3, nullptr, }, /* 9C */ + /* 9D */ {nullptr, on_login_d_e_dc_pc_v3, on_login_d_e_dc_pc_v3, on_login_d_e_dc_pc_v3, on_login_d_e_dc_pc_v3, nullptr, }, /* 9D */ + /* 9E */ {nullptr, nullptr, on_login_d_e_dc_pc_v3, on_login_d_e_dc_pc_v3, on_login_d_e_dc_pc_v3, nullptr, }, /* 9E */ + /* 9F */ {nullptr, nullptr, nullptr, on_return_client_config, on_return_client_config, nullptr, }, /* 9F */ + // PATCH DC PC GC XB BB + /* A0 */ {nullptr, on_change_ship, on_change_ship, on_change_ship, on_change_ship, on_change_ship, }, /* A0 */ + /* A1 */ {nullptr, on_change_block, on_change_block, on_change_block, on_change_block, on_change_block, }, /* A1 */ + /* A2 */ {nullptr, on_quest_list_request, on_quest_list_request, on_quest_list_request, on_quest_list_request, on_quest_list_request, }, /* A2 */ + /* A3 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* A3 */ + /* A4 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* A4 */ + /* A5 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* A5 */ + /* A6 */ {nullptr, nullptr, nullptr, on_ignored_command, on_ignored_command, nullptr, }, /* A6 */ + /* A7 */ {nullptr, nullptr, nullptr, on_ignored_command, on_ignored_command, nullptr, }, /* A7 */ + /* A8 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* A8 */ + /* A9 */ {nullptr, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, on_ignored_command, }, /* A9 */ + /* AA */ {nullptr, nullptr, on_update_quest_statistics, on_update_quest_statistics, on_update_quest_statistics, on_update_quest_statistics, }, /* AA */ + /* AB */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* AB */ + /* AC */ {nullptr, nullptr, nullptr, on_quest_barrier, on_quest_barrier, on_quest_barrier, }, /* AC */ + /* AD */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* AD */ + /* AE */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* AE */ + /* AF */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* AF */ + /* B0 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* B0 */ + /* B1 */ {nullptr, on_server_time_request, on_server_time_request, on_server_time_request, on_server_time_request, nullptr, }, /* B1 */ + /* B2 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* B2 */ + /* B3 */ {nullptr, on_function_call_result, on_function_call_result, on_function_call_result, on_function_call_result, on_function_call_result, }, /* B3 */ + /* B4 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* B4 */ + /* B5 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* B5 */ + /* B6 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* B6 */ + /* B7 */ {nullptr, nullptr, nullptr, on_ignored_command, nullptr, nullptr, }, /* B7 */ + /* B8 */ {nullptr, nullptr, nullptr, on_ignored_command, nullptr, nullptr, }, /* B8 */ + /* B9 */ {nullptr, nullptr, nullptr, on_ignored_command, nullptr, nullptr, }, /* B9 */ + /* BA */ {nullptr, nullptr, nullptr, on_ep3_meseta_transaction, nullptr, nullptr, }, /* BA */ + /* BB */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* BB */ + /* BC */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* BC */ + /* BD */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* BD */ + /* BE */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* BE */ + /* BF */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* BF */ + // PATCH DC PC GC XB BB + /* C0 */ {nullptr, on_choice_search, nullptr, on_choice_search, on_choice_search, nullptr, }, /* C0 */ + /* C1 */ {nullptr, on_create_game_dc_v3, on_create_game_pc, on_create_game_dc_v3, on_create_game_dc_v3, on_create_game_bb, }, /* C1 */ + /* C2 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* C2 */ + /* C3 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* C3 */ + /* C4 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* C4 */ + /* C5 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* C5 */ + /* C6 */ {nullptr, nullptr, on_set_blocked_senders_list, on_set_blocked_senders_list, on_set_blocked_senders_list, on_set_blocked_senders_list, }, /* C6 */ + /* C7 */ {nullptr, nullptr, on_set_auto_reply_t, on_set_auto_reply_t, on_set_auto_reply_t, on_set_auto_reply_t, }, /* C7 */ + /* C8 */ {nullptr, nullptr, on_disable_auto_reply, on_disable_auto_reply, on_disable_auto_reply, on_disable_auto_reply, }, /* C8 */ + /* C9 */ {nullptr, nullptr, nullptr, on_game_command, nullptr, nullptr, }, /* C9 */ + /* CA */ {nullptr, nullptr, nullptr, on_ep3_server_data_request, nullptr, nullptr, }, /* CA */ + /* CB */ {nullptr, nullptr, nullptr, on_game_command, nullptr, nullptr, }, /* CB */ + /* CC */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* CC */ + /* CD */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* CD */ + /* CE */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* CE */ + /* CF */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* CF */ + /* D0 */ {nullptr, nullptr, nullptr, on_trade_start, on_trade_start, on_trade_start, }, /* D0 */ + /* D1 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* D1 */ + /* D2 */ {nullptr, nullptr, nullptr, on_trade_execute, on_trade_execute, on_trade_execute, }, /* D2 */ + /* D3 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* D3 */ + /* D4 */ {nullptr, nullptr, nullptr, on_trade_error, on_trade_error, on_trade_error, }, /* D4 */ + /* D5 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* D5 */ + /* D6 */ {nullptr, nullptr, nullptr, on_message_box_closed, on_message_box_closed, nullptr, }, /* D6 */ + /* D7 */ {nullptr, nullptr, nullptr, on_gba_file_request, on_gba_file_request, nullptr, }, /* D7 */ + /* D8 */ {nullptr, nullptr, on_info_board_request, on_info_board_request, on_info_board_request, on_info_board_request, }, /* D8 */ + /* D9 */ {nullptr, nullptr, on_write_info_board_t, on_write_info_board_t, on_write_info_board_t, on_write_info_board_t,}, /* D9 */ + /* DA */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* DA */ + /* DB */ {nullptr, nullptr, nullptr, on_verify_license_v3, on_verify_license_v3, nullptr, }, /* DB */ + /* DC */ {nullptr, nullptr, nullptr, on_ep3_counter_state, nullptr, on_guild_card_data_request_bb, }, /* DC */ + /* DD */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* DD */ + /* DE */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* DE */ + /* DF */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* DF */ + // PATCH DC PC GC XB BB + /* E0 */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_key_config_request_bb, }, /* E0 */ + /* E1 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* E1 */ + /* E2 */ {nullptr, nullptr, nullptr, on_ep3_tournament_control, nullptr, on_update_key_config_bb, }, /* E2 */ + /* E3 */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_player_preview_request_bb, }, /* E3 */ + /* E4 */ {nullptr, nullptr, nullptr, on_ignored_command, nullptr, nullptr, }, /* E4 */ + /* E5 */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_create_character_bb, }, /* E5 */ + /* E6 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* E6 */ + /* E7 */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_return_player_data_bb, }, /* E7 */ + /* E8 */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_client_checksum_bb, }, /* E8 */ + /* E9 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* E9 */ + /* EA */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_team_command_bb, }, /* EA */ + /* EB */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_stream_file_request_bb, }, /* EB */ + /* EC */ {nullptr, nullptr, nullptr, on_create_game_dc_v3, nullptr, on_ignored_command, }, /* EC */ + /* ED */ {nullptr, nullptr, nullptr, nullptr, nullptr, on_change_account_data_bb, }, /* ED */ + /* EE */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* EE */ + /* EF */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* EF */ + /* F0 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F0 */ + /* F1 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F1 */ + /* F2 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F2 */ + /* F3 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F3 */ + /* F4 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F4 */ + /* F5 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F5 */ + /* F6 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F6 */ + /* F7 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F7 */ + /* F8 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F8 */ + /* F9 */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* F9 */ + /* FA */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* FA */ + /* FB */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* FB */ + /* FC */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* FC */ + /* FD */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* FD */ + /* FE */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* FE */ + /* FF */ {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, /* FF */ + // PATCH DC PC GC XB BB }; -static process_command_t pc_handlers[0x100] = { - // 00 - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, process_chat_pc_bb, nullptr, - process_game_list_request, process_menu_item_info_request, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 10 - process_menu_selection, nullptr, nullptr, process_ignored_command, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, nullptr, process_information_menu_request_dc_pc, - - // 20 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 30 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 40 - process_card_search, nullptr, nullptr, nullptr, - process_ignored_command, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 50 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 60 - process_game_command, process_player_data, process_game_command, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - process_game_command, process_game_command, nullptr, process_client_ready, - - // 70 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 80 - nullptr, process_simple_mail, nullptr, nullptr, - process_change_lobby, nullptr, nullptr, nullptr, - nullptr, process_change_arrow_color, process_lobby_name_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 90 - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, process_client_checksum, nullptr, - process_player_data, process_ignored_command, process_login_a_dc_pc_v3, nullptr, - process_login_c_dc_pc_v3, process_login_d_e_dc_pc_v3, process_login_d_e_dc_pc_v3, nullptr, - - // A0 - process_change_ship, process_change_block, process_quest_list_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, process_update_quest_statistics, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // B0 - nullptr, process_server_time_request, nullptr, process_function_call_result, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // C0 - nullptr, process_create_game_pc, nullptr, nullptr, - nullptr, nullptr, process_set_blocked_senders_list, process_set_auto_reply_t, - process_disable_auto_reply, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // D0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - process_info_board_request, process_write_info_board_t, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // E0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // F0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, -}; - -static process_command_t gc_handlers[0x100] = { - // 00 - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, process_chat_dc_v3, nullptr, - process_game_list_request, process_menu_item_info_request, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 10 - process_menu_selection, nullptr, nullptr, process_ignored_command, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, nullptr, nullptr, - - // 20 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 30 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 40 - process_card_search, nullptr, nullptr, nullptr, - process_ignored_command, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 50 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 60 - process_game_command, process_player_data, process_game_command, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - process_game_command, process_game_command, nullptr, process_client_ready, - - // 70 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 80 - nullptr, process_simple_mail, nullptr, nullptr, - process_change_lobby, nullptr, nullptr, nullptr, - nullptr, process_change_arrow_color, process_lobby_name_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 90 - process_login_0_dc_pc_v3, nullptr, nullptr, process_login_3_dc_pc_v3, - nullptr, nullptr, process_client_checksum, nullptr, - process_player_data, process_ignored_command, process_login_a_dc_pc_v3, nullptr, - process_login_c_dc_pc_v3, process_login_d_e_dc_pc_v3, process_login_d_e_dc_pc_v3, process_return_client_config, - - // A0 - process_change_ship, process_change_block, process_quest_list_request, nullptr, - nullptr, nullptr, process_ignored_command, process_ignored_command, - nullptr, process_ignored_command, process_update_quest_statistics, nullptr, - process_quest_barrier, nullptr, nullptr, nullptr, - - // B0 - nullptr, process_server_time_request, nullptr, process_function_call_result, - nullptr, nullptr, nullptr, process_ignored_command, - process_ignored_command, process_ignored_command, process_ep3_meseta_transaction, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // C0 - process_choice_search, process_create_game_dc_v3, nullptr, nullptr, - nullptr, nullptr, process_set_blocked_senders_list, process_set_auto_reply_t, - process_disable_auto_reply, process_game_command, process_ep3_server_data_request, process_game_command, - nullptr, nullptr, nullptr, nullptr, - - // D0 - process_trade_start, nullptr, process_trade_execute, nullptr, - process_trade_error, nullptr, process_message_box_closed, process_gba_file_request, - process_info_board_request, process_write_info_board_t, nullptr, process_verify_license_v3, - process_ep3_menu_challenge, nullptr, nullptr, nullptr, - - // E0 - nullptr, nullptr, process_ep3_tournament_control, nullptr, - process_ignored_command, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - process_create_game_dc_v3, nullptr, nullptr, nullptr, - - // F0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, -}; - -static process_command_t xb_handlers[0x100] = { - // 00 - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, process_chat_dc_v3, nullptr, - process_game_list_request, process_menu_item_info_request, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 10 - process_menu_selection, nullptr, nullptr, process_ignored_command, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, nullptr, nullptr, - - // 20 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 30 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 40 - process_card_search, nullptr, nullptr, nullptr, - process_ignored_command, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 50 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 60 - process_game_command, process_player_data, process_game_command, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - process_game_command, process_game_command, nullptr, process_client_ready, - - // 70 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 80 - nullptr, process_simple_mail, nullptr, nullptr, - process_change_lobby, nullptr, nullptr, nullptr, - nullptr, process_change_arrow_color, process_lobby_name_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 90 - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, process_client_checksum, nullptr, - process_player_data, process_ignored_command, nullptr, nullptr, - process_login_c_dc_pc_v3, process_login_d_e_dc_pc_v3, process_login_d_e_dc_pc_v3, process_return_client_config, - - // A0 - process_change_ship, process_change_block, process_quest_list_request, nullptr, - nullptr, nullptr, process_ignored_command, process_ignored_command, - nullptr, process_ignored_command, process_update_quest_statistics, nullptr, - process_quest_barrier, nullptr, nullptr, nullptr, - - // B0 - nullptr, process_server_time_request, nullptr, process_function_call_result, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // C0 - process_choice_search, process_create_game_dc_v3, nullptr, nullptr, - nullptr, nullptr, process_set_blocked_senders_list, process_set_auto_reply_t, - process_disable_auto_reply, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // D0 - process_trade_start, nullptr, process_trade_execute, nullptr, - process_trade_error, nullptr, process_message_box_closed, process_gba_file_request, - process_info_board_request, process_write_info_board_t, nullptr, process_verify_license_v3, - nullptr, nullptr, nullptr, nullptr, - - // E0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // F0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, -}; - -static process_command_t bb_handlers[0x100] = { - // 00 - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, process_chat_pc_bb, nullptr, - process_game_list_request, process_menu_item_info_request, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 10 - process_menu_selection, nullptr, nullptr, process_ignored_command, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, nullptr, nullptr, - - // 20 - nullptr, nullptr, process_ignored_command, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 30 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 40 - process_card_search, nullptr, nullptr, nullptr, - process_ignored_command, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 50 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 60 - process_game_command, process_player_data, process_game_command, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - process_game_command, process_game_command, nullptr, process_client_ready, - - // 70 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - - // 80 - nullptr, process_simple_mail, nullptr, nullptr, - process_change_lobby, nullptr, nullptr, nullptr, - nullptr, process_change_arrow_color, process_lobby_name_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 90 - nullptr, nullptr, nullptr, process_login_bb, - nullptr, nullptr, nullptr, nullptr, - process_player_data, process_ignored_command, nullptr, nullptr, - nullptr, nullptr, nullptr, process_return_client_config, - - // A0 - process_change_ship, process_change_block, process_quest_list_request, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, process_ignored_command, process_update_quest_statistics, nullptr, - process_quest_barrier, nullptr, nullptr, nullptr, - - // B0 - nullptr, nullptr, nullptr, process_function_call_result, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // C0 - nullptr, process_create_game_bb, nullptr, nullptr, - nullptr, nullptr, process_set_blocked_senders_list, process_set_auto_reply_t, - process_disable_auto_reply, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // D0 - process_trade_start, nullptr, process_trade_execute, nullptr, - process_trade_error, nullptr, nullptr, nullptr, - process_info_board_request, process_write_info_board_t, nullptr, nullptr, - process_guild_card_data_request_bb, nullptr, nullptr, nullptr, - - // E0 - process_key_config_request_bb, nullptr, process_update_key_config_bb, process_player_preview_request_bb, - nullptr, process_create_character_bb, nullptr, process_return_player_data_bb, - process_client_checksum_bb, nullptr, process_team_command_bb, process_stream_file_request_bb, - process_ignored_command, process_change_account_data_bb, nullptr, nullptr, - - // F0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, -}; - -static process_command_t patch_handlers[0x100] = { - // 00 - nullptr, nullptr, process_encryption_ok_patch, nullptr, - process_login_patch, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, process_file_checksum_result_patch, - - // 10 - process_file_checksum_results_done_patch, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, - - // 20 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // 30 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // 40 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // 50 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // 60 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // 70 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // 80 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // 90 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // A0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // B0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // C0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // D0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // E0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - // F0 - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, -}; - -static process_command_t* handlers[6] = { - dc_handlers, pc_handlers, patch_handlers, gc_handlers, xb_handlers, bb_handlers}; - -void check_unlicensed_command(GameVersion version, uint8_t command) { +static void check_unlicensed_command(GameVersion version, uint8_t command) { switch (version) { case GameVersion::DC: // newserv doesn't actually know that DC clients are DC until it receives @@ -3192,7 +2937,7 @@ void check_unlicensed_command(GameVersion version, uint8_t command) { } } -void process_command(shared_ptr s, shared_ptr c, +void on_command(shared_ptr s, shared_ptr c, uint16_t command, uint32_t flag, const string& data) { string encoded_name; auto player = c->game_data.player(false); @@ -3208,10 +2953,10 @@ void process_command(shared_ptr s, shared_ptr c, check_unlicensed_command(c->version(), command); } - auto fn = handlers[static_cast(c->version())][command & 0xFF]; + auto fn = handlers[command & 0xFF][static_cast(c->version())]; if (fn) { fn(s, c, command, flag, data); } else { - process_unimplemented_command(s, c, command, flag, data); + on_unimplemented_command(s, c, command, flag, data); } } diff --git a/src/ReceiveCommands.hh b/src/ReceiveCommands.hh index b84d74f9..61ccb6f2 100644 --- a/src/ReceiveCommands.hh +++ b/src/ReceiveCommands.hh @@ -6,8 +6,8 @@ -void process_connect(std::shared_ptr s, std::shared_ptr c); -void process_disconnect(std::shared_ptr s, +void on_connect(std::shared_ptr s, std::shared_ptr c); +void on_disconnect(std::shared_ptr s, std::shared_ptr c); -void process_command(std::shared_ptr s, std::shared_ptr c, +void on_command(std::shared_ptr s, std::shared_ptr c, uint16_t command, uint32_t flag, const std::string& data); diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 6494a8ef..54f3816e 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -107,7 +107,7 @@ static void forward_subcommand(shared_ptr l, shared_ptr c, //////////////////////////////////////////////////////////////////////////////// // Chat commands and the like -static void process_subcommand_send_guild_card(shared_ptr, +static void on_subcommand_send_guild_card(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (!command_is_private(command) || !l || (flag >= l->max_clients) || @@ -144,7 +144,7 @@ static void process_subcommand_send_guild_card(shared_ptr, } // client sends a symbol chat -static void process_subcommand_symbol_chat(shared_ptr, +static void on_subcommand_symbol_chat(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, 0x08, 0xFFFF); @@ -156,7 +156,7 @@ static void process_subcommand_symbol_chat(shared_ptr, } // client sends a word select chat -static void process_subcommand_word_select(shared_ptr, +static void on_subcommand_word_select(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, 0x20, 0xFFFF); @@ -180,7 +180,7 @@ static void process_subcommand_word_select(shared_ptr, } // client is done loading into a lobby (we use this to trigger arrow updates) -static void process_subcommand_set_player_visibility(shared_ptr, +static void on_subcommand_set_player_visibility(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto& p = check_size_sc(data, 4); @@ -200,7 +200,7 @@ static void process_subcommand_set_player_visibility(shared_ptr, // Game commands used by cheat mechanisms // need to process changing areas since we keep track of where players are -static void process_subcommand_change_area(shared_ptr, +static void on_subcommand_change_area(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, 0x08, 0xFFFF); @@ -212,7 +212,7 @@ static void process_subcommand_change_area(shared_ptr, } // when a player is hit by an enemy, heal them if infinite HP is enabled -static void process_subcommand_hit_by_enemy(shared_ptr, +static void on_subcommand_hit_by_enemy(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, 0x04, 0xFFFF); @@ -226,7 +226,7 @@ static void process_subcommand_hit_by_enemy(shared_ptr, } // when a player casts a tech, restore TP if infinite TP is enabled -static void process_subcommand_use_technique(shared_ptr, +static void on_subcommand_use_technique(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, 0x04, 0xFFFF); @@ -239,7 +239,7 @@ static void process_subcommand_use_technique(shared_ptr, } } -static void process_subcommand_switch_state_changed(shared_ptr, +static void on_subcommand_switch_state_changed(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { auto& cmd = check_size_t(data); @@ -262,7 +262,7 @@ static void process_subcommand_switch_state_changed(shared_ptr, //////////////////////////////////////////////////////////////////////////////// template -void process_subcommand_movement(shared_ptr, +void on_subcommand_movement(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data); @@ -280,7 +280,7 @@ void process_subcommand_movement(shared_ptr, //////////////////////////////////////////////////////////////////////////////// // Item commands -static void process_subcommand_player_drop_item(shared_ptr, +static void on_subcommand_player_drop_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data); @@ -301,7 +301,7 @@ static void process_subcommand_player_drop_item(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_create_inventory_item(shared_ptr, +static void on_subcommand_create_inventory_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data, @@ -332,7 +332,7 @@ static void process_subcommand_create_inventory_item(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_drop_partial_stack(shared_ptr, +static void on_subcommand_drop_partial_stack(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data, @@ -364,7 +364,7 @@ static void process_subcommand_drop_partial_stack(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_drop_partial_stack_bb(shared_ptr, +static void on_subcommand_drop_partial_stack_bb(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (l->version == GameVersion::BB) { @@ -405,7 +405,7 @@ static void process_subcommand_drop_partial_stack_bb(shared_ptr, } } -static void process_subcommand_buy_shop_item(shared_ptr, +static void on_subcommand_buy_shop_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data); @@ -433,7 +433,7 @@ static void process_subcommand_buy_shop_item(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_box_or_enemy_item_drop(shared_ptr, +static void on_subcommand_box_or_enemy_item_drop(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data, @@ -460,7 +460,7 @@ static void process_subcommand_box_or_enemy_item_drop(shared_ptr, } -static void process_subcommand_pick_up_item(shared_ptr, +static void on_subcommand_pick_up_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { auto* cmd = check_size_sc(data); @@ -488,7 +488,7 @@ static void process_subcommand_pick_up_item(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_pick_up_item_request(shared_ptr, +static void on_subcommand_pick_up_item_request(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { // This is handled by the server on BB, and by the leader on other versions @@ -515,7 +515,7 @@ static void process_subcommand_pick_up_item_request(shared_ptr, } } -static void process_subcommand_equip_unequip_item(shared_ptr, +static void on_subcommand_equip_unequip_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data); @@ -540,7 +540,7 @@ static void process_subcommand_equip_unequip_item(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_use_item(shared_ptr, +static void on_subcommand_use_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data); @@ -560,7 +560,7 @@ static void process_subcommand_use_item(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_open_shop_bb_or_unknown_ep3(shared_ptr, +static void on_subcommand_open_shop_bb_or_unknown_ep3(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (l->flags & Lobby::Flag::EPISODE_3_ONLY) { @@ -598,14 +598,14 @@ static void process_subcommand_open_shop_bb_or_unknown_ep3(shared_ptr, +static void on_subcommand_open_bank_bb(shared_ptr, shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string&) { if ((l->version == GameVersion::BB) && l->is_game()) { send_bank(c); } } -static void process_subcommand_bank_action_bb(shared_ptr, +static void on_subcommand_bank_action_bb(shared_ptr, shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string& data) { if (l->version == GameVersion::BB) { const auto* cmd = check_size_sc(data); @@ -655,7 +655,7 @@ static void process_subcommand_bank_action_bb(shared_ptr, } // player sorts the items in their inventory -static void process_subcommand_sort_inventory_bb(shared_ptr, +static void on_subcommand_sort_inventory_bb(shared_ptr, shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string& data) { if (l->version == GameVersion::BB) { @@ -763,7 +763,7 @@ static bool drop_item( return true; } -static void process_subcommand_enemy_drop_item_request(shared_ptr, +static void on_subcommand_enemy_drop_item_request(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (!l->is_game()) { @@ -778,7 +778,7 @@ static void process_subcommand_enemy_drop_item_request(shared_ptr, } } -static void process_subcommand_box_drop_item_request(shared_ptr, +static void on_subcommand_box_drop_item_request(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (!l->is_game()) { @@ -791,7 +791,7 @@ static void process_subcommand_box_drop_item_request(shared_ptr, } } -static void process_subcommand_phase_setup(shared_ptr, +static void on_subcommand_phase_setup(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); @@ -838,7 +838,7 @@ static void process_subcommand_phase_setup(shared_ptr, } // enemy hit by player -static void process_subcommand_enemy_hit(shared_ptr, +static void on_subcommand_enemy_hit(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (l->version == GameVersion::BB) { @@ -861,7 +861,7 @@ static void process_subcommand_enemy_hit(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_enemy_killed(shared_ptr s, +static void on_subcommand_enemy_killed(shared_ptr s, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { forward_subcommand(l, c, command, flag, data); @@ -931,7 +931,7 @@ static void process_subcommand_enemy_killed(shared_ptr s, } } -static void process_subcommand_destroy_inventory_item(shared_ptr, +static void on_subcommand_destroy_inventory_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data); @@ -950,7 +950,7 @@ static void process_subcommand_destroy_inventory_item(shared_ptr, } } -static void process_subcommand_destroy_ground_item(shared_ptr, +static void on_subcommand_destroy_ground_item(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* cmd = check_size_sc(data); @@ -965,7 +965,7 @@ static void process_subcommand_destroy_ground_item(shared_ptr, } } -static void process_subcommand_identify_item_bb(shared_ptr, +static void on_subcommand_identify_item_bb(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (l->version == GameVersion::BB) { @@ -1000,7 +1000,7 @@ static void process_subcommand_identify_item_bb(shared_ptr, } } -static void process_subcommand_accept_identify_item_bb(shared_ptr, +static void on_subcommand_accept_identify_item_bb(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { @@ -1026,7 +1026,7 @@ static void process_subcommand_accept_identify_item_bb(shared_ptr, } } -static void process_subcommand_sell_item_at_shop_bb(shared_ptr, +static void on_subcommand_sell_item_at_shop_bb(shared_ptr, shared_ptr l, shared_ptr, uint8_t, uint8_t, const string&) { if (l->version == GameVersion::BB) { @@ -1043,7 +1043,7 @@ static void process_subcommand_sell_item_at_shop_bb(shared_ptr, } } -static void process_subcommand_buy_shop_item_bb(shared_ptr, +static void on_subcommand_buy_shop_item_bb(shared_ptr, shared_ptr l, shared_ptr, uint8_t, uint8_t, const string&) { if (l->version == GameVersion::BB) { @@ -1060,7 +1060,7 @@ static void process_subcommand_buy_shop_item_bb(shared_ptr, } } -static void process_subcommand_medical_center_bb(shared_ptr, +static void on_subcommand_medical_center_bb(shared_ptr, shared_ptr l, shared_ptr c, uint8_t, uint8_t, const string&) { if (l->version == GameVersion::BB) { @@ -1073,14 +1073,14 @@ static void process_subcommand_medical_center_bb(shared_ptr, //////////////////////////////////////////////////////////////////////////////// -static void process_subcommand_forward_check_size(shared_ptr, +static void on_subcommand_forward_check_size(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_forward_check_game(shared_ptr, +static void on_subcommand_forward_check_game(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (!l->is_game()) { @@ -1089,7 +1089,7 @@ static void process_subcommand_forward_check_game(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_forward_check_game_loading(shared_ptr, +static void on_subcommand_forward_check_game_loading(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (!l->is_game() || !l->any_client_loading()) { @@ -1098,7 +1098,7 @@ static void process_subcommand_forward_check_game_loading(shared_ptr, +static void on_subcommand_forward_check_size_client(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); @@ -1108,7 +1108,7 @@ static void process_subcommand_forward_check_size_client(shared_ptr forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_forward_check_size_game(shared_ptr, +static void on_subcommand_forward_check_size_game(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); @@ -1118,7 +1118,7 @@ static void process_subcommand_forward_check_size_game(shared_ptr, forward_subcommand(l, c, command, flag, data); } -static void process_subcommand_forward_check_size_ep3_lobby(shared_ptr, +static void on_subcommand_forward_check_size_ep3_lobby(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); @@ -1128,7 +1128,7 @@ static void process_subcommand_forward_check_size_ep3_lobby(shared_ptr, +static void on_subcommand_forward_check_size_ep3_game(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); @@ -1138,7 +1138,7 @@ static void process_subcommand_forward_check_size_ep3_game(shared_ptr, +static void on_subcommand_invalid(shared_ptr, shared_ptr, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); @@ -1149,7 +1149,7 @@ static void process_subcommand_invalid(shared_ptr, } } -static void process_subcommand_unimplemented(shared_ptr, +static void on_subcommand_unimplemented(shared_ptr, shared_ptr, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { const auto* p = check_size_sc(data, sizeof(PSOSubcommand), 0xFFFF); @@ -1170,273 +1170,278 @@ typedef void (*subcommand_handler_t)(shared_ptr s, const string& data); subcommand_handler_t subcommand_handlers[0x100] = { - /* 00 */ process_subcommand_invalid, - /* 01 */ process_subcommand_unimplemented, - /* 02 */ process_subcommand_unimplemented, - /* 03 */ process_subcommand_unimplemented, - /* 04 */ process_subcommand_unimplemented, - /* 05 */ process_subcommand_switch_state_changed, - /* 06 */ process_subcommand_send_guild_card, - /* 07 */ process_subcommand_symbol_chat, - /* 08 */ process_subcommand_unimplemented, - /* 09 */ process_subcommand_unimplemented, - /* 0A */ process_subcommand_enemy_hit, - /* 0B */ process_subcommand_forward_check_size_game, - /* 0C */ process_subcommand_forward_check_size_game, // Add condition (poison/slow/etc.) - /* 0D */ process_subcommand_forward_check_size_game, // Remove condition (poison/slow/etc.) - /* 0E */ process_subcommand_unimplemented, - /* 0F */ process_subcommand_unimplemented, - /* 10 */ process_subcommand_unimplemented, - /* 11 */ process_subcommand_unimplemented, - /* 12 */ process_subcommand_forward_check_size_game, // Dragon actions - /* 13 */ process_subcommand_forward_check_size_game, // De Rol Le actions - /* 14 */ process_subcommand_forward_check_size_game, - /* 15 */ process_subcommand_forward_check_size_game, // Vol Opt actions - /* 16 */ process_subcommand_forward_check_size_game, // Vol Opt actions - /* 17 */ process_subcommand_forward_check_size_game, - /* 18 */ process_subcommand_forward_check_size_game, - /* 19 */ process_subcommand_forward_check_size_game, // Dark Falz actions - /* 1A */ process_subcommand_unimplemented, - /* 1B */ process_subcommand_unimplemented, - /* 1C */ process_subcommand_forward_check_size_game, - /* 1D */ process_subcommand_unimplemented, - /* 1E */ process_subcommand_unimplemented, - /* 1F */ process_subcommand_forward_check_size, - /* 20 */ process_subcommand_forward_check_size, - /* 21 */ process_subcommand_change_area, // Inter-level warp - /* 22 */ process_subcommand_forward_check_size_client, // Set player visibility - /* 23 */ process_subcommand_set_player_visibility, // Set player visibility - /* 24 */ process_subcommand_forward_check_size_game, - /* 25 */ process_subcommand_equip_unequip_item, // Equip item - /* 26 */ process_subcommand_equip_unequip_item, // Unequip item - /* 27 */ process_subcommand_use_item, - /* 28 */ process_subcommand_forward_check_size_game, // Feed MAG - /* 29 */ process_subcommand_destroy_inventory_item, // Delete item (via bank deposit / sale / feeding MAG) - /* 2A */ process_subcommand_player_drop_item, - /* 2B */ process_subcommand_create_inventory_item, // Create inventory item (e.g. from tekker or bank withdrawal) - /* 2C */ process_subcommand_forward_check_size, // Talk to NPC - /* 2D */ process_subcommand_forward_check_size, // Done talking to NPC - /* 2E */ process_subcommand_unimplemented, - /* 2F */ process_subcommand_hit_by_enemy, - /* 30 */ process_subcommand_forward_check_size_game, // Level up - /* 31 */ process_subcommand_forward_check_size_game, // Medical center - /* 32 */ process_subcommand_forward_check_size_game, // Medical center - /* 33 */ process_subcommand_forward_check_size_game, // Moon atomizer/Reverser - /* 34 */ process_subcommand_unimplemented, - /* 35 */ process_subcommand_unimplemented, - /* 36 */ process_subcommand_forward_check_game, - /* 37 */ process_subcommand_forward_check_size_game, // Photon blast - /* 38 */ process_subcommand_unimplemented, - /* 39 */ process_subcommand_forward_check_size_game, // Photon blast ready - /* 3A */ process_subcommand_forward_check_size_game, - /* 3B */ process_subcommand_forward_check_size, - /* 3C */ process_subcommand_unimplemented, - /* 3D */ process_subcommand_unimplemented, - /* 3E */ process_subcommand_movement, // Stop moving - /* 3F */ process_subcommand_movement, // Set position (e.g. when materializing after warp) - /* 40 */ process_subcommand_movement, // Walk - /* 41 */ process_subcommand_unimplemented, - /* 42 */ process_subcommand_movement, // Run - /* 43 */ process_subcommand_forward_check_size_client, - /* 44 */ process_subcommand_forward_check_size_client, - /* 45 */ process_subcommand_forward_check_size_client, - /* 46 */ process_subcommand_forward_check_size_client, - /* 47 */ process_subcommand_forward_check_size_client, - /* 48 */ process_subcommand_use_technique, - /* 49 */ process_subcommand_forward_check_size_client, - /* 4A */ process_subcommand_forward_check_size_client, - /* 4B */ process_subcommand_hit_by_enemy, - /* 4C */ process_subcommand_hit_by_enemy, - /* 4D */ process_subcommand_forward_check_size_client, - /* 4E */ process_subcommand_forward_check_size_client, - /* 4F */ process_subcommand_forward_check_size_client, - /* 50 */ process_subcommand_forward_check_size_client, - /* 51 */ process_subcommand_unimplemented, - /* 52 */ process_subcommand_forward_check_size, // Toggle shop/bank interaction - /* 53 */ process_subcommand_forward_check_size_game, - /* 54 */ process_subcommand_unimplemented, - /* 55 */ process_subcommand_forward_check_size_client, // Intra-map warp - /* 56 */ process_subcommand_forward_check_size_client, - /* 57 */ process_subcommand_forward_check_size_client, - /* 58 */ process_subcommand_forward_check_size_game, - /* 59 */ process_subcommand_pick_up_item, // Item picked up - /* 5A */ process_subcommand_pick_up_item_request, // Request to pick up item - /* 5B */ process_subcommand_unimplemented, - /* 5C */ process_subcommand_unimplemented, - /* 5D */ process_subcommand_drop_partial_stack, // Drop meseta or stacked item - /* 5E */ process_subcommand_buy_shop_item, // Buy item at shop - /* 5F */ process_subcommand_box_or_enemy_item_drop, // Drop item from box/enemy - /* 60 */ process_subcommand_enemy_drop_item_request, // Request for item drop (handled by the server on BB) - /* 61 */ process_subcommand_forward_check_size_game, // Feed mag - /* 62 */ process_subcommand_unimplemented, - /* 63 */ process_subcommand_destroy_ground_item, // Destroy an item on the ground (used when too many items have been dropped) - /* 64 */ process_subcommand_unimplemented, - /* 65 */ process_subcommand_unimplemented, - /* 66 */ process_subcommand_forward_check_size_game, // Use star atomizer - /* 67 */ process_subcommand_forward_check_size_game, // Create enemy set - /* 68 */ process_subcommand_forward_check_size_game, // Telepipe/Ryuker - /* 69 */ process_subcommand_forward_check_size_game, - /* 6A */ process_subcommand_forward_check_size_game, - /* 6B */ process_subcommand_forward_check_game_loading, - /* 6C */ process_subcommand_forward_check_game_loading, - /* 6D */ process_subcommand_forward_check_game_loading, - /* 6E */ process_subcommand_forward_check_game_loading, - /* 6F */ process_subcommand_forward_check_game_loading, - /* 70 */ process_subcommand_forward_check_game_loading, - /* 71 */ process_subcommand_forward_check_game_loading, - /* 72 */ process_subcommand_forward_check_game_loading, - /* 73 */ process_subcommand_invalid, - /* 74 */ process_subcommand_word_select, - /* 75 */ process_subcommand_phase_setup, - /* 76 */ process_subcommand_forward_check_size_game, // Enemy killed - /* 77 */ process_subcommand_forward_check_size_game, // Sync quest data - /* 78 */ process_subcommand_unimplemented, - /* 79 */ process_subcommand_forward_check_size, // Lobby 14/15 soccer game - /* 7A */ process_subcommand_unimplemented, - /* 7B */ process_subcommand_unimplemented, - /* 7C */ process_subcommand_forward_check_size_game, - /* 7D */ process_subcommand_forward_check_size_game, - /* 7E */ process_subcommand_unimplemented, - /* 7F */ process_subcommand_unimplemented, - /* 80 */ process_subcommand_forward_check_size_game, // Trigger trap - /* 81 */ process_subcommand_unimplemented, - /* 82 */ process_subcommand_unimplemented, - /* 83 */ process_subcommand_forward_check_size_game, // Place trap - /* 84 */ process_subcommand_forward_check_size_game, - /* 85 */ process_subcommand_forward_check_size_game, - /* 86 */ process_subcommand_forward_check_size_game, // Hit destructible wall - /* 87 */ process_subcommand_unimplemented, - /* 88 */ process_subcommand_forward_check_size_game, - /* 89 */ process_subcommand_forward_check_size_game, - /* 8A */ process_subcommand_unimplemented, - /* 8B */ process_subcommand_unimplemented, - /* 8C */ process_subcommand_unimplemented, - /* 8D */ process_subcommand_forward_check_size_client, - /* 8E */ process_subcommand_unimplemented, - /* 8F */ process_subcommand_unimplemented, - /* 90 */ process_subcommand_unimplemented, - /* 91 */ process_subcommand_forward_check_size_game, - /* 92 */ process_subcommand_unimplemented, - /* 93 */ process_subcommand_forward_check_size_game, // Timed switch activated - /* 94 */ process_subcommand_forward_check_size_game, // Warp (the $warp chat command is implemented using this) - /* 95 */ process_subcommand_unimplemented, - /* 96 */ process_subcommand_unimplemented, - /* 97 */ process_subcommand_unimplemented, - /* 98 */ process_subcommand_unimplemented, - /* 99 */ process_subcommand_unimplemented, - /* 9A */ process_subcommand_forward_check_size_game, // Update player stat ($infhp/$inftp are implemented using this command) - /* 9B */ process_subcommand_unimplemented, - /* 9C */ process_subcommand_forward_check_size_game, - /* 9D */ process_subcommand_unimplemented, - /* 9E */ process_subcommand_unimplemented, - /* 9F */ process_subcommand_forward_check_size_game, // Gal Gryphon actions - /* A0 */ process_subcommand_forward_check_size_game, // Gal Gryphon actions - /* A1 */ process_subcommand_forward_check_size_game, // Part of revive process. Occurs right after revive command, function unclear. - /* A2 */ process_subcommand_box_drop_item_request, // Request for item drop from box (handled by server on BB) - /* A3 */ process_subcommand_forward_check_size_game, // Episode 2 boss actions - /* A4 */ process_subcommand_forward_check_size_game, // Olga Flow phase 1 actions - /* A5 */ process_subcommand_forward_check_size_game, // Olga Flow phase 2 actions - /* A6 */ process_subcommand_forward_check_size, // Trade proposal - /* A7 */ process_subcommand_unimplemented, - /* A8 */ process_subcommand_forward_check_size_game, // Gol Dragon actions - /* A9 */ process_subcommand_forward_check_size_game, // Barba Ray actions - /* AA */ process_subcommand_forward_check_size_game, // Episode 2 boss actions - /* AB */ process_subcommand_forward_check_size_client, // Create lobby chair - /* AC */ process_subcommand_unimplemented, - /* AD */ process_subcommand_forward_check_size_game, // Olga Flow phase 2 subordinate boss actions - /* AE */ process_subcommand_forward_check_size_client, - /* AF */ process_subcommand_forward_check_size_client, // Turn in lobby chair - /* B0 */ process_subcommand_forward_check_size_client, // Move in lobby chair - /* B1 */ process_subcommand_unimplemented, - /* B2 */ process_subcommand_unimplemented, - /* B3 */ process_subcommand_unimplemented, - /* B4 */ process_subcommand_forward_check_size_ep3_game, - /* B5 */ process_subcommand_open_shop_bb_or_unknown_ep3, // BB shop request - /* B6 */ process_subcommand_unimplemented, // BB shop contents (server->client only) - /* B7 */ process_subcommand_buy_shop_item_bb, - /* B8 */ process_subcommand_identify_item_bb, - /* B9 */ process_subcommand_unimplemented, - /* BA */ process_subcommand_accept_identify_item_bb, - /* BB */ process_subcommand_open_bank_bb, - /* BC */ process_subcommand_unimplemented, // BB bank contents (server->client only) - /* BD */ process_subcommand_bank_action_bb, - /* BE */ process_subcommand_unimplemented, // BB create inventory item (server->client only) - /* BF */ process_subcommand_forward_check_size_ep3_lobby, // Ep3 change music, also BB give EXP (BB usage is server->client only) - /* C0 */ process_subcommand_sell_item_at_shop_bb, - /* C1 */ process_subcommand_unimplemented, - /* C2 */ process_subcommand_unimplemented, - /* C3 */ process_subcommand_drop_partial_stack_bb, // Split stacked item - not sent if entire stack is dropped - /* C4 */ process_subcommand_sort_inventory_bb, - /* C5 */ process_subcommand_medical_center_bb, - /* C6 */ process_subcommand_unimplemented, - /* C7 */ process_subcommand_unimplemented, - /* C8 */ process_subcommand_enemy_killed, - /* C9 */ process_subcommand_unimplemented, - /* CA */ process_subcommand_unimplemented, - /* CB */ process_subcommand_unimplemented, - /* CC */ process_subcommand_unimplemented, - /* CD */ process_subcommand_unimplemented, - /* CE */ process_subcommand_unimplemented, - /* CF */ process_subcommand_forward_check_size_game, - /* D0 */ process_subcommand_unimplemented, - /* D1 */ process_subcommand_unimplemented, - /* D2 */ process_subcommand_unimplemented, - /* D3 */ process_subcommand_unimplemented, - /* D4 */ process_subcommand_unimplemented, - /* D5 */ process_subcommand_unimplemented, - /* D6 */ process_subcommand_unimplemented, - /* D7 */ process_subcommand_unimplemented, - /* D8 */ process_subcommand_unimplemented, - /* D9 */ process_subcommand_unimplemented, - /* DA */ process_subcommand_unimplemented, - /* DB */ process_subcommand_unimplemented, - /* DC */ process_subcommand_unimplemented, - /* DD */ process_subcommand_unimplemented, - /* DE */ process_subcommand_unimplemented, - /* DF */ process_subcommand_unimplemented, - /* E0 */ process_subcommand_unimplemented, - /* E1 */ process_subcommand_unimplemented, - /* E2 */ process_subcommand_unimplemented, - /* E3 */ process_subcommand_unimplemented, - /* E4 */ process_subcommand_unimplemented, - /* E5 */ process_subcommand_unimplemented, - /* E6 */ process_subcommand_unimplemented, - /* E7 */ process_subcommand_unimplemented, - /* E8 */ process_subcommand_unimplemented, - /* E9 */ process_subcommand_unimplemented, - /* EA */ process_subcommand_unimplemented, - /* EB */ process_subcommand_unimplemented, - /* EC */ process_subcommand_unimplemented, - /* ED */ process_subcommand_unimplemented, - /* EE */ process_subcommand_unimplemented, - /* EF */ process_subcommand_unimplemented, - /* F0 */ process_subcommand_unimplemented, - /* F1 */ process_subcommand_unimplemented, - /* F2 */ process_subcommand_unimplemented, - /* F3 */ process_subcommand_unimplemented, - /* F4 */ process_subcommand_unimplemented, - /* F5 */ process_subcommand_unimplemented, - /* F6 */ process_subcommand_unimplemented, - /* F7 */ process_subcommand_unimplemented, - /* F8 */ process_subcommand_unimplemented, - /* F9 */ process_subcommand_unimplemented, - /* FA */ process_subcommand_unimplemented, - /* FB */ process_subcommand_unimplemented, - /* FC */ process_subcommand_unimplemented, - /* FD */ process_subcommand_unimplemented, - /* FE */ process_subcommand_unimplemented, - /* FF */ process_subcommand_unimplemented, + /* 00 */ on_subcommand_invalid, + /* 01 */ nullptr, + /* 02 */ nullptr, + /* 03 */ nullptr, + /* 04 */ nullptr, + /* 05 */ on_subcommand_switch_state_changed, + /* 06 */ on_subcommand_send_guild_card, + /* 07 */ on_subcommand_symbol_chat, + /* 08 */ nullptr, + /* 09 */ nullptr, + /* 0A */ on_subcommand_enemy_hit, + /* 0B */ on_subcommand_forward_check_size_game, + /* 0C */ on_subcommand_forward_check_size_game, // Add condition (poison/slow/etc.) + /* 0D */ on_subcommand_forward_check_size_game, // Remove condition (poison/slow/etc.) + /* 0E */ nullptr, + /* 0F */ nullptr, + /* 10 */ nullptr, + /* 11 */ nullptr, + /* 12 */ on_subcommand_forward_check_size_game, // Dragon actions + /* 13 */ on_subcommand_forward_check_size_game, // De Rol Le actions + /* 14 */ on_subcommand_forward_check_size_game, + /* 15 */ on_subcommand_forward_check_size_game, // Vol Opt actions + /* 16 */ on_subcommand_forward_check_size_game, // Vol Opt actions + /* 17 */ on_subcommand_forward_check_size_game, + /* 18 */ on_subcommand_forward_check_size_game, + /* 19 */ on_subcommand_forward_check_size_game, // Dark Falz actions + /* 1A */ nullptr, + /* 1B */ nullptr, + /* 1C */ on_subcommand_forward_check_size_game, + /* 1D */ nullptr, + /* 1E */ nullptr, + /* 1F */ on_subcommand_forward_check_size, + /* 20 */ on_subcommand_forward_check_size, + /* 21 */ on_subcommand_change_area, // Inter-level warp + /* 22 */ on_subcommand_forward_check_size_client, // Set player visibility + /* 23 */ on_subcommand_set_player_visibility, // Set player visibility + /* 24 */ on_subcommand_forward_check_size_game, + /* 25 */ on_subcommand_equip_unequip_item, // Equip item + /* 26 */ on_subcommand_equip_unequip_item, // Unequip item + /* 27 */ on_subcommand_use_item, + /* 28 */ on_subcommand_forward_check_size_game, // Feed MAG + /* 29 */ on_subcommand_destroy_inventory_item, // Delete item (via bank deposit / sale / feeding MAG) + /* 2A */ on_subcommand_player_drop_item, + /* 2B */ on_subcommand_create_inventory_item, // Create inventory item (e.g. from tekker or bank withdrawal) + /* 2C */ on_subcommand_forward_check_size, // Talk to NPC + /* 2D */ on_subcommand_forward_check_size, // Done talking to NPC + /* 2E */ nullptr, + /* 2F */ on_subcommand_hit_by_enemy, + /* 30 */ on_subcommand_forward_check_size_game, // Level up + /* 31 */ on_subcommand_forward_check_size_game, // Medical center + /* 32 */ on_subcommand_forward_check_size_game, // Medical center + /* 33 */ on_subcommand_forward_check_size_game, // Moon atomizer/Reverser + /* 34 */ nullptr, + /* 35 */ nullptr, + /* 36 */ on_subcommand_forward_check_game, + /* 37 */ on_subcommand_forward_check_size_game, // Photon blast + /* 38 */ nullptr, + /* 39 */ on_subcommand_forward_check_size_game, // Photon blast ready + /* 3A */ on_subcommand_forward_check_size_game, + /* 3B */ on_subcommand_forward_check_size, + /* 3C */ nullptr, + /* 3D */ nullptr, + /* 3E */ on_subcommand_movement, // Stop moving + /* 3F */ on_subcommand_movement, // Set position (e.g. when materializing after warp) + /* 40 */ on_subcommand_movement, // Walk + /* 41 */ nullptr, + /* 42 */ on_subcommand_movement, // Run + /* 43 */ on_subcommand_forward_check_size_client, + /* 44 */ on_subcommand_forward_check_size_client, + /* 45 */ on_subcommand_forward_check_size_client, + /* 46 */ on_subcommand_forward_check_size_client, + /* 47 */ on_subcommand_forward_check_size_client, + /* 48 */ on_subcommand_use_technique, + /* 49 */ on_subcommand_forward_check_size_client, + /* 4A */ on_subcommand_forward_check_size_client, + /* 4B */ on_subcommand_hit_by_enemy, + /* 4C */ on_subcommand_hit_by_enemy, + /* 4D */ on_subcommand_forward_check_size_client, + /* 4E */ on_subcommand_forward_check_size_client, + /* 4F */ on_subcommand_forward_check_size_client, + /* 50 */ on_subcommand_forward_check_size_client, + /* 51 */ nullptr, + /* 52 */ on_subcommand_forward_check_size, // Toggle shop/bank interaction + /* 53 */ on_subcommand_forward_check_size_game, + /* 54 */ nullptr, + /* 55 */ on_subcommand_forward_check_size_client, // Intra-map warp + /* 56 */ on_subcommand_forward_check_size_client, + /* 57 */ on_subcommand_forward_check_size_client, + /* 58 */ on_subcommand_forward_check_size_game, + /* 59 */ on_subcommand_pick_up_item, // Item picked up + /* 5A */ on_subcommand_pick_up_item_request, // Request to pick up item + /* 5B */ nullptr, + /* 5C */ nullptr, + /* 5D */ on_subcommand_drop_partial_stack, // Drop meseta or stacked item + /* 5E */ on_subcommand_buy_shop_item, // Buy item at shop + /* 5F */ on_subcommand_box_or_enemy_item_drop, // Drop item from box/enemy + /* 60 */ on_subcommand_enemy_drop_item_request, // Request for item drop (handled by the server on BB) + /* 61 */ on_subcommand_forward_check_size_game, // Feed mag + /* 62 */ nullptr, + /* 63 */ on_subcommand_destroy_ground_item, // Destroy an item on the ground (used when too many items have been dropped) + /* 64 */ nullptr, + /* 65 */ nullptr, + /* 66 */ on_subcommand_forward_check_size_game, // Use star atomizer + /* 67 */ on_subcommand_forward_check_size_game, // Create enemy set + /* 68 */ on_subcommand_forward_check_size_game, // Telepipe/Ryuker + /* 69 */ on_subcommand_forward_check_size_game, + /* 6A */ on_subcommand_forward_check_size_game, + /* 6B */ on_subcommand_forward_check_game_loading, + /* 6C */ on_subcommand_forward_check_game_loading, + /* 6D */ on_subcommand_forward_check_game_loading, + /* 6E */ on_subcommand_forward_check_game_loading, + /* 6F */ on_subcommand_forward_check_game_loading, + /* 70 */ on_subcommand_forward_check_game_loading, + /* 71 */ on_subcommand_forward_check_game_loading, + /* 72 */ on_subcommand_forward_check_game_loading, + /* 73 */ on_subcommand_invalid, + /* 74 */ on_subcommand_word_select, + /* 75 */ on_subcommand_phase_setup, + /* 76 */ on_subcommand_forward_check_size_game, // Enemy killed + /* 77 */ on_subcommand_forward_check_size_game, // Sync quest data + /* 78 */ nullptr, + /* 79 */ on_subcommand_forward_check_size, // Lobby 14/15 soccer game + /* 7A */ nullptr, + /* 7B */ nullptr, + /* 7C */ on_subcommand_forward_check_size_game, + /* 7D */ on_subcommand_forward_check_size_game, + /* 7E */ nullptr, + /* 7F */ nullptr, + /* 80 */ on_subcommand_forward_check_size_game, // Trigger trap + /* 81 */ nullptr, + /* 82 */ nullptr, + /* 83 */ on_subcommand_forward_check_size_game, // Place trap + /* 84 */ on_subcommand_forward_check_size_game, + /* 85 */ on_subcommand_forward_check_size_game, + /* 86 */ on_subcommand_forward_check_size_game, // Hit destructible wall + /* 87 */ nullptr, + /* 88 */ on_subcommand_forward_check_size_game, + /* 89 */ on_subcommand_forward_check_size_game, + /* 8A */ nullptr, + /* 8B */ nullptr, + /* 8C */ nullptr, + /* 8D */ on_subcommand_forward_check_size_client, + /* 8E */ nullptr, + /* 8F */ nullptr, + /* 90 */ nullptr, + /* 91 */ on_subcommand_forward_check_size_game, + /* 92 */ nullptr, + /* 93 */ on_subcommand_forward_check_size_game, // Timed switch activated + /* 94 */ on_subcommand_forward_check_size_game, // Warp (the $warp chat command is implemented using this) + /* 95 */ nullptr, + /* 96 */ nullptr, + /* 97 */ nullptr, + /* 98 */ nullptr, + /* 99 */ nullptr, + /* 9A */ on_subcommand_forward_check_size_game, // Update player stat ($infhp/$inftp are implemented using this command) + /* 9B */ nullptr, + /* 9C */ on_subcommand_forward_check_size_game, + /* 9D */ nullptr, + /* 9E */ nullptr, + /* 9F */ on_subcommand_forward_check_size_game, // Gal Gryphon actions + /* A0 */ on_subcommand_forward_check_size_game, // Gal Gryphon actions + /* A1 */ on_subcommand_forward_check_size_game, // Part of revive process. Occurs right after revive command, function unclear. + /* A2 */ on_subcommand_box_drop_item_request, // Request for item drop from box (handled by server on BB) + /* A3 */ on_subcommand_forward_check_size_game, // Episode 2 boss actions + /* A4 */ on_subcommand_forward_check_size_game, // Olga Flow phase 1 actions + /* A5 */ on_subcommand_forward_check_size_game, // Olga Flow phase 2 actions + /* A6 */ on_subcommand_forward_check_size, // Trade proposal + /* A7 */ nullptr, + /* A8 */ on_subcommand_forward_check_size_game, // Gol Dragon actions + /* A9 */ on_subcommand_forward_check_size_game, // Barba Ray actions + /* AA */ on_subcommand_forward_check_size_game, // Episode 2 boss actions + /* AB */ on_subcommand_forward_check_size_client, // Create lobby chair + /* AC */ nullptr, + /* AD */ on_subcommand_forward_check_size_game, // Olga Flow phase 2 subordinate boss actions + /* AE */ on_subcommand_forward_check_size_client, + /* AF */ on_subcommand_forward_check_size_client, // Turn in lobby chair + /* B0 */ on_subcommand_forward_check_size_client, // Move in lobby chair + /* B1 */ nullptr, + /* B2 */ nullptr, + /* B3 */ nullptr, + /* B4 */ on_subcommand_forward_check_size_ep3_game, + /* B5 */ on_subcommand_open_shop_bb_or_unknown_ep3, // BB shop request + /* B6 */ nullptr, // BB shop contents (server->client only) + /* B7 */ on_subcommand_buy_shop_item_bb, + /* B8 */ on_subcommand_identify_item_bb, + /* B9 */ nullptr, + /* BA */ on_subcommand_accept_identify_item_bb, + /* BB */ on_subcommand_open_bank_bb, + /* BC */ nullptr, // BB bank contents (server->client only) + /* BD */ on_subcommand_bank_action_bb, + /* BE */ nullptr, // BB create inventory item (server->client only) + /* BF */ on_subcommand_forward_check_size_ep3_lobby, // Ep3 change music, also BB give EXP (BB usage is server->client only) + /* C0 */ on_subcommand_sell_item_at_shop_bb, + /* C1 */ nullptr, + /* C2 */ nullptr, + /* C3 */ on_subcommand_drop_partial_stack_bb, // Split stacked item - not sent if entire stack is dropped + /* C4 */ on_subcommand_sort_inventory_bb, + /* C5 */ on_subcommand_medical_center_bb, + /* C6 */ nullptr, + /* C7 */ nullptr, + /* C8 */ on_subcommand_enemy_killed, + /* C9 */ nullptr, + /* CA */ nullptr, + /* CB */ nullptr, + /* CC */ nullptr, + /* CD */ nullptr, + /* CE */ nullptr, + /* CF */ on_subcommand_forward_check_size_game, + /* D0 */ nullptr, + /* D1 */ nullptr, + /* D2 */ nullptr, + /* D3 */ nullptr, + /* D4 */ nullptr, + /* D5 */ nullptr, + /* D6 */ nullptr, + /* D7 */ nullptr, + /* D8 */ nullptr, + /* D9 */ nullptr, + /* DA */ nullptr, + /* DB */ nullptr, + /* DC */ nullptr, + /* DD */ nullptr, + /* DE */ nullptr, + /* DF */ nullptr, + /* E0 */ nullptr, + /* E1 */ nullptr, + /* E2 */ nullptr, + /* E3 */ nullptr, + /* E4 */ nullptr, + /* E5 */ nullptr, + /* E6 */ nullptr, + /* E7 */ nullptr, + /* E8 */ nullptr, + /* E9 */ nullptr, + /* EA */ nullptr, + /* EB */ nullptr, + /* EC */ nullptr, + /* ED */ nullptr, + /* EE */ nullptr, + /* EF */ nullptr, + /* F0 */ nullptr, + /* F1 */ nullptr, + /* F2 */ nullptr, + /* F3 */ nullptr, + /* F4 */ nullptr, + /* F5 */ nullptr, + /* F6 */ nullptr, + /* F7 */ nullptr, + /* F8 */ nullptr, + /* F9 */ nullptr, + /* FA */ nullptr, + /* FB */ nullptr, + /* FC */ nullptr, + /* FD */ nullptr, + /* FE */ nullptr, + /* FF */ nullptr, }; -void process_subcommand(shared_ptr s, shared_ptr l, +void on_subcommand(shared_ptr s, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const string& data) { if (data.empty()) { throw runtime_error("game command is empty"); } uint8_t which = static_cast(data[0]); - subcommand_handlers[which](s, l, c, command, flag, data); + auto fn = subcommand_handlers[which]; + if (fn) { + fn(s, l, c, command, flag, data); + } else { + on_subcommand_unimplemented(s, l, c, command, flag, data); + } } bool subcommand_is_implemented(uint8_t which) { - return subcommand_handlers[which] != process_subcommand_unimplemented; + return subcommand_handlers[which] != nullptr; } diff --git a/src/ReceiveSubcommands.hh b/src/ReceiveSubcommands.hh index 60f19a46..6c9aa383 100644 --- a/src/ReceiveSubcommands.hh +++ b/src/ReceiveSubcommands.hh @@ -8,7 +8,7 @@ -void process_subcommand(std::shared_ptr s, +void on_subcommand(std::shared_ptr s, std::shared_ptr l, std::shared_ptr c, uint8_t command, uint8_t flag, const std::string& data); diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 52144ff5..544942c9 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -698,7 +698,7 @@ void send_card_search_result_t( shared_ptr result, shared_ptr result_lobby) { static const vector version_to_port_name({ - "console-lobby", "pc-lobby", "bb-lobby", "console-lobby", "console-lobby", "bb-lobby"}); + "bb-lobby", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}); const auto& port_name = version_to_port_name.at(static_cast(c->version())); S_GuildCardSearchResult cmd; diff --git a/src/Server.cc b/src/Server.cc index 85571fb8..6a3ef81a 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -42,11 +42,11 @@ void Server::disconnect_client(shared_ptr c) { c->channel.disconnect(); try { - process_disconnect(this->state, c); + on_disconnect(this->state, c); } catch (const exception& e) { server_log.warning("Error during client disconnect cleanup: %s", e.what()); } - // c is destroyed here (process_disconnect should remove any other references + // c is destroyed here (on_disconnect should remove any other references // to it, e.g. from Lobby objects) } @@ -90,7 +90,7 @@ void Server::on_listen_accept(struct evconnlistener* listener, c->id, fd, listen_fd, listening_socket->addr_str.c_str()); try { - process_connect(this->state, c); + on_connect(this->state, c); } catch (const exception& e) { server_log.warning("Error during client initialization: %s", e.what()); this->disconnect_client(c); @@ -123,7 +123,7 @@ void Server::connect_client( remote_sin->sin_port = htons(client_port); try { - process_connect(this->state, c); + on_connect(this->state, c); } catch (const exception& e) { server_log.error("Error during client initialization: %s", e.what()); this->disconnect_client(c); @@ -145,7 +145,7 @@ void Server::on_client_input(Channel& ch, uint16_t command, uint32_t flag, std:: server->disconnect_client(c); } else { try { - process_command(server->state, c, command, flag, data); + on_command(server->state, c, command, flag, data); } catch (const exception& e) { server_log.warning("Error processing client command: %s", e.what()); c->should_disconnect = true; diff --git a/src/Version.hh b/src/Version.hh index b8566b12..8be4dbd2 100644 --- a/src/Version.hh +++ b/src/Version.hh @@ -5,9 +5,9 @@ enum class GameVersion { - DC = 0, + PATCH = 0, + DC, PC, - PATCH, GC, XB, BB,