diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index f2de568ea7..722bb89017 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -81,7 +81,7 @@ namespace GameActions return false; } - GameActionResult Query(const IGameAction * action) + GameActionResult Query(const IGameAction * action, uint32 flags) { Guard::ArgumentNotNull(action); @@ -94,7 +94,7 @@ namespace GameActions } else { - result = action->Query(); + result = action->Query(flags); if (result.Error == GA_ERROR::OK) { if (!CheckActionAffordability(&result)) @@ -108,24 +108,21 @@ namespace GameActions return result; } - GameActionResult Execute(const IGameAction * action, GameActionCallback callback, uint16 flags) + GameActionResult Execute(const IGameAction * action, uint32 flags, GameActionCallback callback) { Guard::ArgumentNotNull(action); uint16 actionFlags = action->GetFlags(); - GameActionResult result = Query(action); + GameActionResult result = Query(action, flags); if (result.Error == GA_ERROR::OK) { // Networked games send actions to the server to be run if (network_get_mode() != NETWORK_MODE_NONE) { // Action has come from server. - if (!(actionFlags & GA_FLAGS::CLIENT_ONLY) && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & 0x80)) + if (!(actionFlags & GA_FLAGS::CLIENT_ONLY) && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NETWORKED)) { - MemoryStream stream; - stream.WriteValue(flags); - action->Serialise(&stream); - network_send_game_action((uint8*)stream.GetData(), stream.GetLength(), action->GetType()); + network_send_game_action(action, flags); 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 = 0; @@ -137,7 +134,7 @@ namespace GameActions } // Execute the action, changing the game state - result = action->Execute(); + result = action->Execute(flags); // Update money balance if (!(gParkFlags & PARK_FLAGS_NO_MONEY) && result.Cost != 0) diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index 8a6f018779..a9362ea014 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -97,12 +97,12 @@ interface IGameAction /** * Query the result of the game action without changing the game state. */ - virtual GameActionResult Query() const abstract; + virtual GameActionResult Query(uint32 flags = 0) const abstract; /** * Apply the game action and change the game state. */ - virtual GameActionResult Execute() const abstract; + virtual GameActionResult Execute(uint32 flags = 0) const abstract; }; typedef IGameAction *(*GameActionFactory)(); @@ -112,8 +112,8 @@ namespace GameActions { GameActionFactory Register(uint32 id, GameActionFactory action); IGameAction * Create(uint32 id); - GameActionResult Query(const IGameAction * action); - GameActionResult Execute(const IGameAction * action, GameActionCallback callback = nullptr, uint16 flags = 0); + GameActionResult Query(const IGameAction * action, uint32 flags = 0); + GameActionResult Execute(const IGameAction * action, uint32 flags = 0, GameActionCallback callback = nullptr); template GameActionFactory Register(uint32 id) diff --git a/src/openrct2/actions/SetParkEntranceFeeAction.cpp b/src/openrct2/actions/SetParkEntranceFeeAction.cpp index 582249023f..e49f609098 100644 --- a/src/openrct2/actions/SetParkEntranceFeeAction.cpp +++ b/src/openrct2/actions/SetParkEntranceFeeAction.cpp @@ -50,7 +50,7 @@ public: stream->WriteValue(Fee); } - GameActionResult Query() const override + GameActionResult Query(uint32 flags = 0) const override { bool noMoney = (gParkFlags & PARK_FLAGS_NO_MONEY) != 0; bool forceFreeEntry = (gParkFlags & PARK_FLAGS_PARK_FREE_ENTRY) && !gCheatsUnlockAllPrices; @@ -65,7 +65,7 @@ public: return GameActionResult(); } - GameActionResult Execute() const override + GameActionResult Execute(uint32 flags = 0) const override { gParkEntranceFee = Fee; window_invalidate_by_class(WC_PARK_INFORMATION); @@ -81,13 +81,13 @@ extern "C" { auto gameAction = SetParkEntranceFeeAction(); gameAction.Fee = (money16)value; - GameActions::Execute(&gameAction, nullptr, 0); + GameActions::Execute(&gameAction, 0, nullptr); } void game_command_set_park_entrance_fee(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp) { auto gameAction = SetParkEntranceFeeAction(); gameAction.Fee = (*edi & 0xFFFF); - GameActions::Execute(&gameAction, nullptr, 0); + GameActions::Execute(&gameAction, 0, nullptr); } } diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index 27262d6ce7..68a0e8e0ba 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -1116,19 +1116,23 @@ void Network::Server_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx SendPacketToClients(*packet, false, true); } -void Network::Client_Send_GAME_ACTION(const uint8 * buffer, uint64 size, uint32 type) +void Network::Client_Send_GAME_ACTION(const IGameAction *action, uint32 flags = 0) { std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << (uint32)NETWORK_COMMAND_GAME_ACTION << (uint32)gCurrentTicks << (uint32)type; - packet->Write(buffer, size); + *packet << (uint32)NETWORK_COMMAND_GAME_ACTION << (uint32)gCurrentTicks << action->GetType() << flags; + MemoryStream stream; + action->Serialise(&stream); + packet->Write((uint8*)stream.GetData(), stream.GetLength()); server_connection.QueuePacket(std::move(packet)); } -void Network::Server_Send_GAME_ACTION(const uint8 * buffer, uint64 size, uint32 type) +void Network::Server_Send_GAME_ACTION(const IGameAction *action, uint32 flags = 0) { std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << (uint32)NETWORK_COMMAND_GAME_ACTION << (uint32)gCurrentTicks << type << gNetwork.GetPlayerID(); - packet->Write(buffer, size); + *packet << (uint32)NETWORK_COMMAND_GAME_ACTION << (uint32)gCurrentTicks << action->GetType() << gNetwork.GetPlayerID() << flags; + MemoryStream stream; + action->Serialise(&stream); + packet->Write((uint8*)stream.GetData(), stream.GetLength()); SendPacketToClients(*packet); } @@ -1357,10 +1361,10 @@ void Network::ProcessGameCommandQueue() } if (gc.actionType != 0xFFFFFFFF) { IGameAction * action = GameActions::Create(gc.actionType); - uint16 flags = gc.parameters->ReadValue(); + uint32 flags = gc.parameters->ReadValue(); action->Deserialise(gc.parameters); delete gc.parameters; - GameActionResult result = GameActions::Execute(action, nullptr, flags | 0x80); + GameActionResult result = GameActions::Execute(action, flags | GAME_COMMAND_FLAG_NETWORKED); if (result.Error != GA_ERROR::OK) { game_commands_processed_this_tick++; @@ -2133,9 +2137,9 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa game_command_playerid = connection.Player->Id; // Run game command, and if it is successful send to clients auto ga = GameActions::Create(commandType); - uint16 flags = stream.ReadValue(); + uint32 flags = stream.ReadValue(); ga->Deserialise(&stream); - auto result = GameActions::Execute(ga, nullptr, 0x80 | flags); + auto result = GameActions::Execute(ga, GAME_COMMAND_FLAG_NETWORKED | flags); if (result.Error != GA_ERROR::OK) { return; } @@ -2151,7 +2155,7 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa connection.Player->LastDemolishRideTime = connection.Player->LastActionTime; } - Server_Send_GAME_ACTION((uint8*)stream.GetData(), stream.GetLength(), commandType); + Server_Send_GAME_ACTION(ga, flags); } void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet) @@ -3001,14 +3005,14 @@ void network_send_chat(const char* text) } } -void network_send_game_action(const uint8 * buffer, uint64 size, uint32 type) +void network_send_game_action(const IGameAction *action, uint32 flags = 0) { switch (gNetwork.GetMode()) { case NETWORK_MODE_SERVER: - gNetwork.Server_Send_GAME_ACTION(buffer, size, type); + gNetwork.Server_Send_GAME_ACTION(action, flags); break; case NETWORK_MODE_CLIENT: - gNetwork.Client_Send_GAME_ACTION(buffer, size, type); + gNetwork.Client_Send_GAME_ACTION(action, flags); break; } } diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index cf6d905d9d..f540cfabc0 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -44,6 +44,8 @@ enum { #include "../Version.h" #include "NetworkTypes.h" +typedef struct IGameAction IGameAction; + #ifndef DISABLE_NETWORK // This define specifies which version of network stream current build uses. @@ -142,8 +144,8 @@ public: void Server_Send_CHAT(const char* text); void Client_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 callback); void Server_Send_GAMECMD(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 playerid, uint8 callback); - void Client_Send_GAME_ACTION(const uint8 * buffer, uint64 size, uint32 type); - void Server_Send_GAME_ACTION(const uint8 * buffer, uint64 size, uint32 type); + void Client_Send_GAME_ACTION(const IGameAction *action, uint32 flags); + void Server_Send_GAME_ACTION(const IGameAction *action, uint32 flags); void Server_Send_TICK(); void Server_Send_PLAYERLIST(); void Client_Send_PING(); @@ -336,7 +338,7 @@ sint32 network_get_pickup_peep_old_x(uint8 playerid); void network_send_map(); void network_send_chat(const char* text); void network_send_gamecmd(uint32 eax, uint32 ebx, uint32 ecx, uint32 edx, uint32 esi, uint32 edi, uint32 ebp, uint8 callback); -void network_send_game_action(const uint8 * buffer, uint64 size, uint32 type); +void network_send_game_action(const IGameAction *action, uint32 flags); void network_send_password(const char* password); void network_set_password(const char* password);