diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 235a88968a..83f1751f2c 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -74,7 +74,6 @@ float gDayNightCycle = 0; bool gInUpdateCode = false; bool gInMapInitCode = false; int32_t gGameCommandNestLevel; -bool gGameCommandIsNetworked; std::string gCurrentLoadedPath; bool gLoadKeepWindowsOpen = false; @@ -85,23 +84,6 @@ uint8_t gUnk141F568; uint32_t gCurrentTicks; uint32_t gCurrentRealTimeTicks; -// clang-format off -GAME_COMMAND_CALLBACK_POINTER * game_command_callback = nullptr; -static GAME_COMMAND_CALLBACK_POINTER * const game_command_callback_table[] = { - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr, - nullptr -}; -// clang-format on -int32_t game_command_playerid = -1; - rct_string_id gGameCommandErrorTitle; rct_string_id gGameCommandErrorText; uint8_t gErrorType; @@ -109,27 +91,6 @@ rct_string_id gErrorStringId; using namespace OpenRCT2; -int32_t game_command_callback_get_index(GAME_COMMAND_CALLBACK_POINTER* callback) -{ - for (uint32_t i = 0; i < std::size(game_command_callback_table); i++) - { - if (game_command_callback_table[i] == callback) - { - return i; - } - } - return 0; -} - -GAME_COMMAND_CALLBACK_POINTER* game_command_callback_get_callback(uint32_t index) -{ - if (index < std::size(game_command_callback_table)) - { - return game_command_callback_table[index]; - } - return nullptr; -} - void game_increase_game_speed() { gGameSpeed = std::min(gConfigGeneral.debugging_tools ? 5 : 4, gGameSpeed + 1); @@ -402,27 +363,11 @@ int32_t game_do_command_p( if (gGameCommandNestLevel == 0) { gGameCommandErrorText = STR_NONE; - gGameCommandIsNetworked = (flags & GAME_COMMAND_FLAG_NETWORKED) != 0; } // Increment nest count gGameCommandNestLevel++; - if (game_command_playerid == -1) - { - game_command_playerid = network_get_current_player_id(); - } - - // Log certain commands if we are in multiplayer and logging is enabled - bool serverLog = (network_get_mode() == NETWORK_MODE_SERVER) && gGameCommandNestLevel == 1 - && gConfigNetwork.log_server_actions; - bool clientLog = (network_get_mode() == NETWORK_MODE_CLIENT) && (flags & GAME_COMMAND_FLAG_NETWORKED) - && gGameCommandNestLevel == 1 && gConfigNetwork.log_server_actions; - if (serverLog || clientLog) - { - game_log_multiplayer_command(command, eax, ebx, ecx, edx, edi, ebp); - } - *ebx &= ~GAME_COMMAND_FLAG_APPLY; // Make sure the camera position won't change if the command skips setting them. @@ -456,23 +401,6 @@ int32_t game_do_command_p( return cost; } - if (network_get_mode() != NETWORK_MODE_NONE && !(flags & GAME_COMMAND_FLAG_NETWORKED) - && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NO_SPEND) - && gGameCommandNestLevel == 1) /* Send only top-level commands */ - { - network_send_gamecmd( - *eax, *ebx, *ecx, *edx, *esi, *edi, *ebp, game_command_callback_get_index(game_command_callback)); - if (network_get_mode() == NETWORK_MODE_CLIENT) - { - // Client sent the command to the server, do not run it locally, just return. It will run when server - // sends it. - game_command_callback = nullptr; - // Decrement nest count - gGameCommandNestLevel--; - return cost; - } - } - // Second call to actually perform the operation new_game_command_table[command](eax, ebx, ecx, edx, esi, edi, ebp); @@ -489,26 +417,11 @@ int32_t game_do_command_p( if (recordCommand && gGameCommandNestLevel == 1) { - int32_t callback = game_command_callback_get_index(game_command_callback); - replayManager->AddGameCommand( - gCurrentTicks, *eax, original_ebx, *ecx, original_edx, original_esi, original_edi, original_ebp, - callback); + gCurrentTicks, *eax, original_ebx, *ecx, original_edx, original_esi, original_edi, original_ebp, 0); } } - // Do the callback (required for multiplayer to work correctly), but only for top level commands - if (gGameCommandNestLevel == 1) - { - if (game_command_callback && !(flags & GAME_COMMAND_FLAG_GHOST)) - { - game_command_callback(*eax, *ebx, *ecx, *edx, *esi, *edi, *ebp); - game_command_callback = nullptr; - } - } - - game_command_playerid = -1; - *edx = *ebx; if (*edx != MONEY32_UNDEFINED && *edx < cost) @@ -532,13 +445,6 @@ int32_t game_do_command_p( } } - if (network_get_mode() == NETWORK_MODE_SERVER && !(flags & GAME_COMMAND_FLAG_NETWORKED) - && !(flags & GAME_COMMAND_FLAG_GHOST)) - { - network_set_player_last_action(network_get_player_index(network_get_current_player_id()), command); - network_add_player_money_spent(network_get_current_player_id(), cost); - } - // Start autosave timer after game command if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE) gLastAutoSaveUpdate = platform_get_ticks(); @@ -552,9 +458,6 @@ int32_t game_do_command_p( // Decrement nest count gGameCommandNestLevel--; - // Clear the game command callback to prevent the next command triggering it - game_command_callback = nullptr; - // Show error window if (gGameCommandNestLevel == 0 && (flags & GAME_COMMAND_FLAG_APPLY) && gUnk141F568 == gUnk13CA740 && !(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && !(flags & GAME_COMMAND_FLAG_NETWORKED) @@ -566,34 +469,6 @@ int32_t game_do_command_p( return MONEY32_UNDEFINED; } -void game_log_multiplayer_command(int command, const int* eax, const int* ebx, const int* ecx, int* edx, int* edi, int* ebp) -{ - // Get player name - const char* player_name = "localhost"; - - int player_index = network_get_player_index(game_command_playerid); - if (player_index != -1) - { - player_name = network_get_player_name(player_index); - } - - char log_msg[256]; - if (command == GAME_COMMAND_DEMOLISH_RIDE && (*ebp == 1 || *ebp == 0)) - { // ebp is 1 if command comes from ride window prompt, so we don't log "demolishing" ride previews - // Get ride name - Ride* ride = get_ride(*edx); - char ride_name[128]; - format_string(ride_name, 128, ride->name, &ride->name_arguments); - - char* args[2] = { - (char*)player_name, - ride_name, - }; - format_string(log_msg, 256, STR_LOG_DEMOLISH_RIDE, args); - network_append_server_log(log_msg); - } -} - void pause_toggle() { gGamePaused ^= GAME_PAUSED_NORMAL; diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 12e733ad51..bb90be3e74 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -130,13 +130,6 @@ enum using GAME_COMMAND_POINTER = void( int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -using GAME_COMMAND_CALLBACK_POINTER = void( - int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int32_t esi, int32_t edi, int32_t ebp); - -extern GAME_COMMAND_CALLBACK_POINTER* game_command_callback; -int32_t game_command_callback_get_index(GAME_COMMAND_CALLBACK_POINTER* callback); -GAME_COMMAND_CALLBACK_POINTER* game_command_callback_get_callback(uint32_t index); -extern int32_t game_command_playerid; extern rct_string_id gGameCommandErrorTitle; extern rct_string_id gGameCommandErrorText; @@ -156,7 +149,6 @@ extern float gDayNightCycle; extern bool gInUpdateCode; extern bool gInMapInitCode; extern int32_t gGameCommandNestLevel; -extern bool gGameCommandIsNetworked; extern std::string gCurrentLoadedPath; extern bool gLoadKeepWindowsOpen; @@ -175,8 +167,6 @@ int32_t game_do_command(int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int3 int32_t game_do_command_p( uint32_t command, int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp); -void game_log_multiplayer_command(int command, const int* eax, const int* ebx, const int* ecx, int* edx, int* edi, int* ebp); - void game_load_or_quit_no_save_prompt(); void load_from_sv6(const char* path); void game_load_init(); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 188cf85737..80e2d32d51 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -180,11 +180,6 @@ public: void Server_Send_MAP(NetworkConnection* connection = nullptr); void Client_Send_CHAT(const char* text); void Server_Send_CHAT(const char* text); - void Client_Send_GAMECMD( - uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback); - void Server_Send_GAMECMD( - uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t playerid, - uint8_t callback); void Client_Send_GAME_ACTION(const GameAction* action); void Server_Send_GAME_ACTION(const GameAction* action); void Server_Send_TICK(); @@ -244,15 +239,7 @@ private: GameCommand(uint32_t t, uint32_t* args, uint8_t p, uint8_t cb, uint32_t id) { tick = t; - eax = args[0]; - ebx = args[1]; - ecx = args[2]; - edx = args[3]; - esi = args[4]; - edi = args[5]; - ebp = args[6]; playerid = p; - callback = cb; action = nullptr; commandIndex = id; } @@ -269,10 +256,8 @@ private: } uint32_t tick = 0; - uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0; GameAction::Ptr action; uint8_t playerid = 0; - uint8_t callback = 0; uint32_t commandIndex = 0; bool operator<(const GameCommand& comp) const { @@ -350,8 +335,6 @@ private: void Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_CHAT(NetworkConnection& connection, NetworkPacket& packet); void Server_Handle_CHAT(NetworkConnection& connection, NetworkPacket& packet); - void Client_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet); - void Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet); void Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet); void Client_Handle_TICK(NetworkConnection& connection, NetworkPacket& packet); @@ -392,7 +375,6 @@ Network::Network() client_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Client_Handle_AUTH; client_command_handlers[NETWORK_COMMAND_MAP] = &Network::Client_Handle_MAP; client_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Client_Handle_CHAT; - client_command_handlers[NETWORK_COMMAND_GAMECMD] = &Network::Client_Handle_GAMECMD; client_command_handlers[NETWORK_COMMAND_GAME_ACTION] = &Network::Client_Handle_GAME_ACTION; client_command_handlers[NETWORK_COMMAND_TICK] = &Network::Client_Handle_TICK; client_command_handlers[NETWORK_COMMAND_PLAYERLIST] = &Network::Client_Handle_PLAYERLIST; @@ -410,7 +392,6 @@ Network::Network() server_command_handlers.resize(NETWORK_COMMAND_MAX, nullptr); server_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Server_Handle_AUTH; server_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Server_Handle_CHAT; - server_command_handlers[NETWORK_COMMAND_GAMECMD] = &Network::Server_Handle_GAMECMD; server_command_handlers[NETWORK_COMMAND_GAME_ACTION] = &Network::Server_Handle_GAME_ACTION; server_command_handlers[NETWORK_COMMAND_PING] = &Network::Server_Handle_PING; server_command_handlers[NETWORK_COMMAND_GAMEINFO] = &Network::Server_Handle_GAMEINFO; @@ -1674,26 +1655,6 @@ void Network::Server_Send_CHAT(const char* text) SendPacketToClients(*packet); } -void Network::Client_Send_GAMECMD( - uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback) -{ - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << (uint32_t)NETWORK_COMMAND_GAMECMD << gCurrentTicks << eax << (ebx | GAME_COMMAND_FLAG_NETWORKED) << ecx << edx - << esi << edi << ebp << callback; - - _serverConnection->QueuePacket(std::move(packet)); -} - -void Network::Server_Send_GAMECMD( - uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t playerid, - uint8_t callback) -{ - std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << (uint32_t)NETWORK_COMMAND_GAMECMD << gCurrentTicks << eax << (ebx | GAME_COMMAND_FLAG_NETWORKED) << ecx << edx - << esi << edi << ebp << playerid << callback; - SendPacketToClients(*packet, false, true); -} - void Network::Client_Send_GAME_ACTION(const GameAction* action) { std::unique_ptr packet(NetworkPacket::Allocate()); @@ -2105,7 +2066,7 @@ void Network::ProcessGameCommands() // the command is useless so lets not keep it. log_warning( "Discarding game command from tick behind current tick, CMD: %08X, CMD Tick: %08X, Current Tick: %08X\n", - gc.esi, gc.tick, gCurrentTicks); + gc.commandIndex, gc.tick, gCurrentTicks); game_command_queue.erase(game_command_queue.begin()); @@ -2143,49 +2104,6 @@ void Network::ProcessGameCommands() Server_Send_PLAYERINFO(action->GetPlayer()); } } - else - { - if (GetPlayerID() == gc.playerid) - { - game_command_callback = game_command_callback_get_callback(gc.callback); - } - - game_command_playerid = gc.playerid; - - int32_t command = gc.esi; - int32_t flags = gc.ebx; - if (mode == NETWORK_MODE_SERVER) - flags |= GAME_COMMAND_FLAG_NETWORKED; - - money32 cost = game_do_command(gc.eax, flags, gc.ecx, gc.edx, gc.esi, gc.edi, gc.ebp); - - if (cost != MONEY32_UNDEFINED) - { - NetworkPlayer* player = GetPlayerByID(gc.playerid); - if (!player) - return; - - player->LastAction = NetworkActions::FindCommand(command); - player->LastActionTime = platform_get_ticks(); - player->AddMoneySpent(cost); - - if (mode == NETWORK_MODE_SERVER) - { - // Note these are currently not reached as both commands are ported to GameActions - if (command == GAME_COMMAND_PLACE_SCENERY) - { - player->LastPlaceSceneryTime = player->LastActionTime; - } - else if (command == GAME_COMMAND_DEMOLISH_RIDE) - { - player->LastDemolishRideTime = player->LastActionTime; - } - - Server_Send_GAMECMD(gc.eax, gc.ebx, gc.ecx, gc.edx, gc.esi, gc.edi, gc.ebp, gc.playerid, gc.callback); - Server_Send_PLAYERINFO(gc.playerid); - } - } - } game_command_queue.erase(game_command_queue.begin()); } } @@ -3026,17 +2944,6 @@ void Network::Server_Handle_CHAT(NetworkConnection& connection, NetworkPacket& p } } -void Network::Client_Handle_GAMECMD([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) -{ - uint32_t tick; - uint32_t args[7]; - uint8_t playerid; - uint8_t callback; - packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> playerid >> callback; - - game_command_queue.emplace(tick, args, playerid, callback, _commandId++); -} - void Network::Client_Handle_GAME_ACTION([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) { uint32_t tick; @@ -3143,66 +3050,6 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa game_command_queue.emplace(tick, std::move(ga), _commandId++); } -void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet) -{ - uint32_t tick; - uint32_t args[7]; - uint8_t playerid; - uint8_t callback; - - if (!connection.Player) - { - return; - } - - playerid = connection.Player->Id; - - packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> callback; - - int32_t commandCommand = args[4]; - - uint32_t ticks = platform_get_ticks(); // tick count is different by time last_action_time is set, keep same value. - - // Check if player's group permission allows command to run - NetworkGroup* group = GetGroupByID(connection.Player->Group); - if (!group || !group->CanPerformCommand(commandCommand)) - { - Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_PERMISSION_DENIED); - return; - } - - // In case someone modifies the code / memory to enable cluster build, - // require a small delay in between placing scenery to provide some security, as - // cluster mode is a for loop that runs the place_scenery code multiple times. - if (commandCommand == GAME_COMMAND_PLACE_SCENERY) - { - if (ticks - connection.Player->LastPlaceSceneryTime < ACTION_COOLDOWN_TIME_PLACE_SCENERY && - // In case platform_get_ticks() wraps after ~49 days, ignore larger logged times. - ticks > connection.Player->LastPlaceSceneryTime) - { - if (!(group->CanPerformCommand(MISC_COMMAND_TOGGLE_SCENERY_CLUSTER))) - { - Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE); - return; - } - } - } - // This is to prevent abuse of demolishing rides. Anyone that is not the server - // host will have to wait a small amount of time in between deleting rides. - else if (commandCommand == GAME_COMMAND_DEMOLISH_RIDE) - { - if (ticks - connection.Player->LastDemolishRideTime < ACTION_COOLDOWN_TIME_DEMOLISH_RIDE && - // In case platform_get_ticks() wraps after ~49 days, ignore larger logged times. - ticks > connection.Player->LastDemolishRideTime) - { - Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE); - return; - } - } - - game_command_queue.emplace(tick, args, playerid, callback, _commandId++); -} - void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet) { uint32_t srand0; @@ -4006,20 +3853,6 @@ void network_enqueue_game_action(const GameAction* action) gNetwork.EnqueueGameAction(action); } -void network_send_gamecmd( - uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback) -{ - switch (gNetwork.GetMode()) - { - case NETWORK_MODE_SERVER: - gNetwork.Server_Send_GAMECMD(eax, ebx, ecx, edx, esi, edi, ebp, gNetwork.GetPlayerID(), callback); - break; - case NETWORK_MODE_CLIENT: - gNetwork.Client_Send_GAMECMD(eax, ebx, ecx, edx, esi, edi, ebp, callback); - break; - } -} - void network_send_password(const std::string& password) { utf8 keyPath[MAX_PATH]; @@ -4175,10 +4008,6 @@ void network_request_gamestate_snapshot() void network_enqueue_game_action(const GameAction* action) { } -void network_send_gamecmd( - uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback) -{ -} void network_send_game_action(const GameAction* action) { } diff --git a/src/openrct2/network/NetworkConnection.cpp b/src/openrct2/network/NetworkConnection.cpp index 2f8c14725d..da9ab8d6cd 100644 --- a/src/openrct2/network/NetworkConnection.cpp +++ b/src/openrct2/network/NetworkConnection.cpp @@ -191,7 +191,6 @@ void NetworkConnection::RecordPacketStats(const NetworkPacket& packet, bool send switch (packet.GetCommand()) { - case NETWORK_COMMAND_GAMECMD: case NETWORK_COMMAND_GAME_ACTION: trafficGroup = NETWORK_STATISTICS_GROUP_COMMANDS; break; diff --git a/src/openrct2/network/NetworkTypes.h b/src/openrct2/network/NetworkTypes.h index 7a99db8022..4feb491b2c 100644 --- a/src/openrct2/network/NetworkTypes.h +++ b/src/openrct2/network/NetworkTypes.h @@ -52,8 +52,7 @@ enum NETWORK_COMMAND NETWORK_COMMAND_AUTH, NETWORK_COMMAND_MAP, NETWORK_COMMAND_CHAT, - NETWORK_COMMAND_GAMECMD, - NETWORK_COMMAND_TICK, + NETWORK_COMMAND_TICK = 4, NETWORK_COMMAND_PLAYERLIST, NETWORK_COMMAND_PING, NETWORK_COMMAND_PINGLIST, diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 12f946d475..12edc97dd3 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -93,8 +93,6 @@ int32_t network_get_pickup_peep_old_x(uint8_t playerid); void network_send_map(); void network_send_chat(const char* text); -void network_send_gamecmd( - uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback); void network_send_game_action(const GameAction* action); void network_enqueue_game_action(const GameAction* action); void network_send_password(const std::string& password); diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 809fdd468c..6691f26256 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -5222,7 +5222,7 @@ static void loc_6B51C0(const Ride* ride) */ static void ride_scroll_to_track_error(CoordsXYE* trackElement) { - if (!gGameCommandIsNetworked && gUnk141F568 == gUnk13CA740) + if (gUnk141F568 == gUnk13CA740) { rct_window* w = window_get_main(); if (w != nullptr) diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index bf44eb5ece..9b735dbc87 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -2075,15 +2075,6 @@ static money32 place_maze_design(uint8_t flags, Ride* ride, uint16_t mazeEntry, if (flags & GAME_COMMAND_FLAG_APPLY) { - if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST)) - { - LocationXYZ16 coord; - coord.x = x + 8; - coord.y = y + 8; - coord.z = z; - network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord); - } - // Place track element int32_t fx = floor2(x, 32); int32_t fy = floor2(y, 32);