1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-18 12:33:17 +01:00

Make client work

This commit is contained in:
duncanspumpkin
2017-03-25 17:05:18 +00:00
committed by Michał Janiszewski
parent 351b0df76b
commit ae24ded8bf
6 changed files with 83 additions and 53 deletions

View File

@@ -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;
}
}

View File

@@ -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<typename T>
GameActionFactory Register(uint32 id)

View File

@@ -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<money16>();
@@ -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);
}
}

View File

@@ -24,7 +24,7 @@ MemoryStream::MemoryStream(const MemoryStream &copy)
_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());

View File

@@ -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<NetworkPacket> 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<uint16>();
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<uint16>();
test = stream.ReadValue<money16>();
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<uint16>();
test = stream.ReadValue<money16>();
}
void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet)
{

View File

@@ -64,6 +64,7 @@ enum {
#include <openssl/evp.h>
#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 {