1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-17 20:13:07 +01:00

Put action files in headers instead of cpps.

Added callbacks for GameActions and network support for them.
Refactored GameAction registration due static library issues.
Moved all C functions into a single file.
This commit is contained in:
ZehM4tt
2017-07-17 21:27:21 +02:00
committed by Michał Janiszewski
parent 1b2a61c6ba
commit fbd793083c
9 changed files with 196 additions and 100 deletions

View File

@@ -52,8 +52,21 @@ namespace GameActions
return factory;
}
void Initialize()
{
static bool initialized = false;
if (initialized)
return;
Register();
initialized = true;
}
IGameAction * Create(uint32 id)
{
Initialize();
IGameAction * result = nullptr;
if (id < Util::CountOf(_actions))
{
@@ -109,10 +122,8 @@ namespace GameActions
return result;
}
GameActionResult Execute(IGameAction * action)
GameActionResult Execute(const IGameAction * action)
{
log_info("[%s] GameAction::Execute\n", network_get_mode() == NETWORK_MODE_CLIENT ? "cl" : "sv");
Guard::ArgumentNotNull(action);
uint16 actionFlags = action->GetActionFlags();
@@ -127,6 +138,8 @@ namespace GameActions
// As a client we have to wait or send it first.
if (!(actionFlags & GA_FLAGS::CLIENT_ONLY) && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NETWORKED))
{
log_info("[%s] GameAction::Execute\n", "cl");
network_send_game_action(action);
return result;
@@ -138,12 +151,15 @@ namespace GameActions
// at the beginning of the frame, so we have to put them into the queue.
if (!(actionFlags & GA_FLAGS::CLIENT_ONLY) && !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NETWORKED))
{
log_info("[%s] GameAction::Execute\n", "sv-cl");
network_enqueue_game_action(action);
return result;
}
}
log_info("[%s] GameAction::Execute\n", "sv");
// Execute the action, changing the game state
result = action->Execute();
@@ -174,12 +190,11 @@ namespace GameActions
}
// Call callback for asynchronous events
/*
if (callback != nullptr)
const std::function<void()>& cb = action->GetCallback();
if (cb)
{
callback(result);
cb();
}
*/
if (result.Error != GA_ERROR::OK && !(flags & GAME_COMMAND_FLAG_GHOST))
{

View File

@@ -16,6 +16,10 @@
#pragma once
extern "C" {
#include "../platform/platform.h"
}
#include "IGameAction.h"
typedef IGameAction *(*GameActionFactory)();
@@ -31,9 +35,11 @@ public:
private:
uint32 _playerId; // Callee
uint32 _flags; // GAME_COMMAND_FLAGS
uint32 _networkId;
std::function<void()> _callback;
public:
GameAction() : _playerId(0), _flags(0)
GameAction() : _playerId(0), _flags(0), _networkId(0)
{
}
@@ -73,8 +79,29 @@ public:
return Type;
}
virtual void SetCallback(const std::function<void()>& cb)
{
_callback = cb;
}
virtual const std::function<void()>& GetCallback() const
{
return _callback;
}
virtual void SetNetworkId(uint32_t id)
{
_networkId = id;
}
virtual uint32 GetNetworkId() const
{
return _networkId;
}
virtual void Serialise(DataSerialiser& stream)
{
stream << _networkId;
stream << _flags;
stream << _playerId;
}
@@ -92,10 +119,13 @@ public:
namespace GameActions
{
GameActionFactory Register(uint32 id, GameActionFactory action);
void Initialize();
void Register();
IGameAction * Create(uint32 id);
GameActionResult Query(const IGameAction * action);
GameActionResult Execute(IGameAction * action);
GameActionResult Execute(const IGameAction * action);
GameActionFactory Register(uint32 id, GameActionFactory action);
template<typename T>
static GameActionFactory Register()

View File

@@ -0,0 +1,87 @@
#include "PlaceParkEntranceAction.hpp"
#include "SetParkEntranceFeeAction.hpp"
extern "C"
{
#pragma region PlaceParkEntranceAction
money32 place_park_entrance(sint16 x, sint16 y, sint16 z, uint8 direction)
{
auto gameAction = PlaceParkEntranceAction();
gameAction.x = x;
gameAction.y = y;
gameAction.z = z;
gameAction.direction = direction;
auto result = GameActions::Execute(&gameAction);
if (result.Error == GA_ERROR::OK)
{
return 0;
}
else
{
return MONEY32_UNDEFINED;
}
}
/**
*
* rct2: 0x006666E7
*/
void game_command_place_park_entrance(sint32* eax,
sint32* ebx,
sint32* ecx,
sint32* edx,
sint32* esi,
sint32* edi,
sint32* ebp)
{
Guard::Assert(false, "GAME_COMMAND_PLACE_PARK_ENTRANCE DEPRECIATED");
}
/**
*
* rct2: 0x00666F4E
*/
money32 park_entrance_place_ghost(sint32 x, sint32 y, sint32 z, sint32 direction)
{
park_entrance_remove_ghost();
auto gameAction = PlaceParkEntranceAction();
gameAction.x = x;
gameAction.y = y;
gameAction.z = z;
gameAction.direction = direction;
gameAction.SetFlags(GAME_COMMAND_FLAG_GHOST);
auto result = GameActions::Execute(&gameAction);
if (result.Error == GA_ERROR::OK)
{
gParkEntranceGhostPosition.x = x;
gParkEntranceGhostPosition.y = y;
gParkEntranceGhostPosition.z = z;
gParkEntranceGhostDirection = direction;
gParkEntranceGhostExists = true;
}
return result.Cost;
}
#pragma endregion
#pragma region SetParkEntranceFeeAction
void park_set_entrance_fee(money32 value)
{
auto gameAction = SetParkEntranceFeeAction();
gameAction.Fee = (money16)value;
gameAction.SetCallback([]()
{
log_info("GameAction Callback executed");
});
GameActions::Execute(&gameAction);
}
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);
}
#pragma endregion
}

View File

@@ -0,0 +1,13 @@
#include "GameAction.h"
#include "PlaceParkEntranceAction.hpp"
#include "SetParkEntranceFeeAction.hpp"
namespace GameActions {
void Register()
{
Register<SetParkEntranceFeeAction>();
Register<PlaceParkEntranceAction>();
}
}

View File

@@ -101,6 +101,12 @@ public:
virtual void SetPlayer(uint32 playerId) abstract;
virtual uint32 GetPlayer() const abstract;
virtual void SetCallback(const std::function<void()>& cb) abstract;
virtual const std::function<void()>& GetCallback() const abstract;
virtual void SetNetworkId(uint32_t id) abstract;
virtual uint32 GetNetworkId() const abstract;
/**
* Writes or reads the game action directly to the given stream. Used for
* sending across the network in multiplayer.

View File

@@ -18,6 +18,8 @@
#include "../localisation/string_ids.h"
#include "GameAction.h"
#pragma once
extern "C"
{
#include "../cheats.h"
@@ -203,68 +205,3 @@ public:
return GameActionResult();
}
};
static auto Factory UNUSED_ATTR = GameActions::Register<PlaceParkEntranceAction>();
extern "C"
{
money32 place_park_entrance(sint16 x, sint16 y, sint16 z, uint8 direction)
{
auto gameAction = PlaceParkEntranceAction();
gameAction.x = x;
gameAction.y = y;
gameAction.z = z;
gameAction.direction = direction;
auto result = GameActions::Execute(&gameAction);
if (result.Error == GA_ERROR::OK)
{
return 0;
}
else
{
return MONEY32_UNDEFINED;
}
}
/**
*
* rct2: 0x006666E7
*/
void game_command_place_park_entrance(sint32* eax,
sint32* ebx,
sint32* ecx,
sint32* edx,
sint32* esi,
sint32* edi,
sint32* ebp)
{
Guard::Assert(false, "GAME_COMMAND_PLACE_PARK_ENTRANCE DEPRECIATED");
}
/**
*
* rct2: 0x00666F4E
*/
money32 park_entrance_place_ghost(sint32 x, sint32 y, sint32 z, sint32 direction)
{
park_entrance_remove_ghost();
auto gameAction = PlaceParkEntranceAction();
gameAction.x = x;
gameAction.y = y;
gameAction.z = z;
gameAction.direction = direction;
gameAction.SetFlags(GAME_COMMAND_FLAG_GHOST);
auto result = GameActions::Execute(&gameAction);
if (result.Error == GA_ERROR::OK)
{
gParkEntranceGhostPosition.x = x;
gParkEntranceGhostPosition.y = y;
gParkEntranceGhostPosition.z = z;
gParkEntranceGhostDirection = direction;
gParkEntranceGhostExists = true;
}
return result.Cost;
}
}

View File

@@ -14,6 +14,8 @@
*****************************************************************************/
#pragma endregion
#pragma once
#include "../core/MemoryStream.h"
#include "../localisation/string_ids.h"
#include "GameAction.h"
@@ -58,21 +60,3 @@ public:
}
};
static auto Factory UNUSED_ATTR = GameActions::Register<SetParkEntranceFeeAction>();
extern "C"
{
void park_set_entrance_fee(money32 value)
{
auto gameAction = SetParkEntranceFeeAction();
gameAction.Fee = (money16)value;
GameActions::Execute(&gameAction);
}
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);
}
}

View File

@@ -94,7 +94,8 @@ Network::Network()
status = NETWORK_STATUS_NONE;
last_tick_sent_time = 0;
last_ping_sent_time = 0;
_commandIndex = 0;
_commandId = 0;
_actionId = 0;
client_command_handlers.resize(NETWORK_COMMAND_MAX, 0);
client_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Client_Handle_AUTH;
client_command_handlers[NETWORK_COMMAND_MAP] = &Network::Client_Handle_MAP;
@@ -1151,6 +1152,16 @@ void Network::Client_Send_GAME_ACTION(const IGameAction *action)
{
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
uint32_t networkId = 0;
networkId = ++_actionId;
// I know its ugly, want basic functionality for now.
const_cast<IGameAction*>(action)->SetNetworkId(networkId);
if(action->GetCallback())
{
_gameActionCallbacks.insert(std::make_pair(networkId, action->GetCallback()));
}
DataSerialiser stream(true);
action->Serialise(stream);
@@ -1472,12 +1483,14 @@ void Network::EnqueueGameAction(const IGameAction *action)
action->Serialise(dsOut);
IGameAction *ga = GameActions::Create(action->GetType());
ga->SetCallback(action->GetCallback());
stream.SetPosition(0);
DataSerialiser dsIn(false, stream);
ga->Serialise(dsIn);
GameCommand gc(gCurrentTicks, ga);
gc.commandIndex = _commandIndex++;
gc.commandIndex = _commandId++;
game_command_queue.insert(gc);
}
@@ -2100,7 +2113,7 @@ void Network::Client_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket
packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> playerid >> callback;
GameCommand gc(tick, args, playerid, callback);
gc.commandIndex = _commandIndex++;
gc.commandIndex = _commandId++;
game_command_queue.insert(gc);
}
@@ -2124,8 +2137,16 @@ void Network::Client_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa
}
action->Serialise(ds);
auto itr = _gameActionCallbacks.find(action->GetNetworkId());
if (itr != _gameActionCallbacks.end())
{
action->SetCallback(itr->second);
_gameActionCallbacks.erase(itr);
}
GameCommand gc(tick, action);
gc.commandIndex = _commandIndex++;
gc.commandIndex = _commandId++;
game_command_queue.insert(gc);
}
@@ -2200,7 +2221,7 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa
ga->SetPlayer(connection.Player->Id);
GameCommand gc(tick, ga);
gc.commandIndex = _commandIndex++;
gc.commandIndex = _commandId++;
game_command_queue.insert(gc);
}
@@ -2265,7 +2286,7 @@ void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket
}
GameCommand gc = GameCommand(tick, args, playerid, callback);
gc.commandIndex = _commandIndex++;
gc.commandIndex = _commandId++;
game_command_queue.insert(gc);
}

View File

@@ -62,6 +62,7 @@ typedef struct IGameAction IGameAction;
#include <memory>
#include <string>
#include <vector>
#include <functional>
#include <map>
#include <openssl/evp.h>
#include "../core/Json.hpp"
@@ -168,6 +169,7 @@ public:
std::vector<std::unique_ptr<NetworkGroup>> group_list;
NetworkKey _key;
std::vector<uint8> _challenge;
std::map<uint32, std::function<void()>> _gameActionCallbacks;
NetworkUserManager _userManager;
std::string ServerName;
@@ -263,7 +265,8 @@ private:
uint32 server_connect_time = 0;
uint8 default_group = 0;
uint32 game_commands_processed_this_tick = 0;
uint32 _commandIndex;
uint32 _commandId;
uint32 _actionId;
std::string _chatLogPath;
std::string _chatLogFilenameFormat = "%Y%m%d-%H%M%S.txt";
std::string _serverLogPath;