From ae24ded8bf8b3681099475792ad44369d68039c7 Mon Sep 17 00:00:00 2001 From: duncanspumpkin Date: Sat, 25 Mar 2017 17:05:18 +0000 Subject: [PATCH] Make client work --- src/openrct2/actions/GameAction.cpp | 9 +- src/openrct2/actions/GameAction.h | 4 +- .../actions/SetParkEntranceFeeAction.cpp | 9 +- src/openrct2/core/MemoryStream.cpp | 2 +- src/openrct2/network/Network.cpp | 100 ++++++++++-------- src/openrct2/network/network.h | 12 +++ 6 files changed, 83 insertions(+), 53 deletions(-) diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index 0a0595b66a..086fd693ac 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -108,7 +108,7 @@ namespace GameActions return result; } - void Execute(const IGameAction * action, GameActionCallback callback) + GameActionResult Execute(const IGameAction * action, GameActionCallback callback, uint16 flags) { Guard::ArgumentNotNull(action); @@ -120,12 +120,12 @@ namespace GameActions if (network_get_mode() != NETWORK_MODE_NONE) { // Action has come from server. - if (!(actionFlags & GA_FLAGS::CLIENT_ONLY) && !(actionFlags & GA_FLAGS::GHOST)) + if (!(actionFlags & GA_FLAGS::CLIENT_ONLY) && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & 0x80)) { MemoryStream stream; - stream.WriteValue(action->GetFlags()); + stream.WriteValue(flags); action->Serialise(&stream); - network_send_game_action((uint8*)stream.GetData(), stream.GetLength(), 0); + network_send_game_action((uint8*)stream.GetData(), stream.GetLength(), action->GetType()); } } @@ -167,5 +167,6 @@ namespace GameActions Memory::Copy(gCommonFormatArgs, result.ErrorMessageArgs, sizeof(result.ErrorMessageArgs)); window_error_open(result.ErrorTitle, result.ErrorMessage); } + return result; } } diff --git a/src/openrct2/actions/GameAction.h b/src/openrct2/actions/GameAction.h index cee63174a6..8a6f018779 100644 --- a/src/openrct2/actions/GameAction.h +++ b/src/openrct2/actions/GameAction.h @@ -48,7 +48,6 @@ namespace GA_FLAGS { constexpr uint16 ALLOW_WHILE_PAUSED = 1 << 0; constexpr uint16 CLIENT_ONLY = 1 << 1; - constexpr uint16 GHOST = 1 << 2; } /** @@ -82,6 +81,7 @@ interface IGameAction */ virtual uint16 GetFlags() const abstract; + virtual uint32 GetType() const abstract; /** * Reads the game action directly from the given stream. Used for * sending across the network in multiplayer. @@ -113,7 +113,7 @@ namespace GameActions GameActionFactory Register(uint32 id, GameActionFactory action); IGameAction * Create(uint32 id); GameActionResult Query(const IGameAction * action); - void Execute(const IGameAction * action, GameActionCallback callback = nullptr); + GameActionResult Execute(const IGameAction * action, GameActionCallback callback = nullptr, uint16 flags = 0); template GameActionFactory Register(uint32 id) diff --git a/src/openrct2/actions/SetParkEntranceFeeAction.cpp b/src/openrct2/actions/SetParkEntranceFeeAction.cpp index df6fd507c7..582249023f 100644 --- a/src/openrct2/actions/SetParkEntranceFeeAction.cpp +++ b/src/openrct2/actions/SetParkEntranceFeeAction.cpp @@ -35,6 +35,11 @@ public: return GA_FLAGS::ALLOW_WHILE_PAUSED; } + uint32 GetType() const override + { + return GAME_COMMAND_SET_PARK_ENTRANCE_FEE; + } + void Deserialise(IStream * stream) override { Fee = stream->ReadValue(); @@ -76,13 +81,13 @@ extern "C" { auto gameAction = SetParkEntranceFeeAction(); gameAction.Fee = (money16)value; - GameActions::Execute(&gameAction); + GameActions::Execute(&gameAction, nullptr, 0); } 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); + GameActions::Execute(&gameAction, nullptr, 0); } } diff --git a/src/openrct2/core/MemoryStream.cpp b/src/openrct2/core/MemoryStream.cpp index 01877e30f3..b5a2551780 100644 --- a/src/openrct2/core/MemoryStream.cpp +++ b/src/openrct2/core/MemoryStream.cpp @@ -24,7 +24,7 @@ MemoryStream::MemoryStream(const MemoryStream ©) _dataCapacity = copy._dataCapacity; _dataSize = copy._dataSize; - if (_access == MEMORY_ACCESS::OWNER) + if (_access & MEMORY_ACCESS::OWNER) { _data = Memory::Duplicate(copy._data, _dataCapacity); _position = (void*)((uintptr_t)_data + copy.GetPosition()); diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp index cb34d88347..60e8106028 100644 --- a/src/openrct2/network/Network.cpp +++ b/src/openrct2/network/Network.cpp @@ -1127,7 +1127,7 @@ void Network::Client_Send_GAME_ACTION(const uint8 * buffer, uint64 size, uint32 void Network::Server_Send_GAME_ACTION(const uint8 * buffer, uint64 size, uint32 type) { std::unique_ptr packet(NetworkPacket::Allocate()); - *packet << (uint32)NETWORK_COMMAND_GAME_ACTION << (uint32)gCurrentTicks << type; + *packet << (uint32)NETWORK_COMMAND_GAME_ACTION << (uint32)gCurrentTicks << type << gNetwork.GetPlayerID(); packet->Write(buffer, size); SendPacketToClients(*packet); } @@ -1355,44 +1355,61 @@ void Network::ProcessGameCommandQueue() if (game_command_queue.begin()->tick != gCurrentTicks) break; } - - if (GetPlayerID() == gc.playerid) { - game_command_callback = game_command_callback_get_callback(gc.callback); - } - - game_command_playerid = gc.playerid; - - sint32 command = gc.esi; - sint32 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) - { - game_commands_processed_this_tick++; - 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) { - - if (command == GAME_COMMAND_PLACE_SCENERY) { - player->LastPlaceSceneryTime = player->LastActionTime; + if (gc.actionType != 0xFFFFFFFF) { + IGameAction * action = GameActions::Create(gc.actionType); + uint16 flags = gc.parameters->ReadValue(); + action->Deserialise(gc.parameters); + delete gc.parameters; + GameActionResult result = GameActions::Execute(action, nullptr, flags | 0x80); + if (result.Error != GA_ERROR::OK) + { + game_commands_processed_this_tick++; + NetworkPlayer* player = GetPlayerByID(gc.playerid); + if (player) { + player->LastAction = NetworkActions::FindCommand(gc.actionType); + player->LastActionTime = platform_get_ticks(); + player->AddMoneySpent(result.Cost); } - 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); } } + else { + if (GetPlayerID() == gc.playerid) { + game_command_callback = game_command_callback_get_callback(gc.callback); + } + game_command_playerid = gc.playerid; + + sint32 command = gc.esi; + sint32 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) + { + game_commands_processed_this_tick++; + 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) { + + 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); + } + } + } game_command_queue.erase(game_command_queue.begin()); } @@ -2040,33 +2057,28 @@ void Network::Client_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket void Network::Client_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet) { uint32 tick; - uint16 flags; uint32 type; - money16 test; - packet >> tick >> type; + uint8 playerid; + packet >> tick >> type >> playerid; MemoryStream stream; for (int i = packet.BytesRead; i < packet.Size; ++i) { stream.WriteValue(((uint8*)packet.GetData())[i]); } stream.SetPosition(0); - flags = stream.ReadValue(); - test = stream.ReadValue(); + GameCommand gc = GameCommand(tick, type, stream, playerid); + game_command_queue.insert(gc); } void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet) { uint32 tick; - uint16 flags; uint32 type; - money16 test; packet >> tick >> type; MemoryStream stream; for (int i = packet.BytesRead; i < packet.Size; ++i) { stream.WriteValue(((uint8*)packet.GetData())[i]); } stream.SetPosition(0); - flags = stream.ReadValue(); - test = stream.ReadValue(); } void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet) { diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 6511d34fa8..cf6d905d9d 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -64,6 +64,7 @@ enum { #include #include "../core/Json.hpp" #include "../core/Nullable.hpp" +#include "../core/MemoryStream.h" #include "NetworkConnection.h" #include "NetworkGroup.h" #include "NetworkKey.h" @@ -191,9 +192,20 @@ private: GameCommand(uint32 t, uint32* args, uint8 p, uint8 cb) { 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; + actionType = 0xFFFFFFFF; } + + GameCommand(uint32 t, uint32 aType, MemoryStream const &stream, uint8 p) + { + tick = t; playerid = p; actionType = aType; + // Note this will leak memory. Do something about this + parameters = new MemoryStream(stream); + } + uint32 tick; uint32 eax, ebx, ecx, edx, esi, edi, ebp; + uint32 actionType = 0xFFFFFFFF; + MemoryStream *parameters; uint8 playerid; uint8 callback; bool operator<(const GameCommand& comp) const {