mirror of https://github.com/OpenRCT2/OpenRCT2.git
Implement game action logging. (#8138)
This commit is contained in:
parent
e043af4be2
commit
1abb31a159
|
@ -44,7 +44,7 @@ public:
|
|||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _bannerIndex << _name;
|
||||
stream << DS_TAG(_bannerIndex) << DS_TAG(_name);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _climate;
|
||||
stream << DS_TAG(_climate);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _x << _y << _z;
|
||||
stream << DS_TAG(_x) << DS_TAG(_y) << DS_TAG(_z);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -140,6 +140,57 @@ namespace GameActions
|
|||
return result;
|
||||
}
|
||||
|
||||
static const char* GetRealm()
|
||||
{
|
||||
if (network_get_mode() == NETWORK_MODE_CLIENT)
|
||||
return "cl";
|
||||
else if (network_get_mode() == NETWORK_MODE_SERVER)
|
||||
return "sv";
|
||||
return "";
|
||||
}
|
||||
|
||||
struct ActionLogContext_t
|
||||
{
|
||||
MemoryStream output;
|
||||
};
|
||||
|
||||
static void LogActionBegin(ActionLogContext_t& ctx, const GameAction* action)
|
||||
{
|
||||
MemoryStream& output = ctx.output;
|
||||
|
||||
char temp[128] = {};
|
||||
snprintf(temp, sizeof(temp), "[%s] Game Action %08X (", GetRealm(), action->GetType());
|
||||
|
||||
output.Write(temp, strlen(temp));
|
||||
|
||||
DataSerialiser ds(true, ctx.output, true); // Logging mode.
|
||||
|
||||
// Write all parameters into output as text.
|
||||
action->Serialise(ds);
|
||||
}
|
||||
|
||||
static void LogActionFinish(ActionLogContext_t& ctx, const GameAction* action, const GameActionResult::Ptr& result)
|
||||
{
|
||||
MemoryStream& output = ctx.output;
|
||||
|
||||
char temp[128] = {};
|
||||
|
||||
if (result->Error != GA_ERROR::OK)
|
||||
{
|
||||
snprintf(temp, sizeof(temp), ") Failed, %u", (uint32_t)result->Error);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(temp, sizeof(temp), ") OK");
|
||||
}
|
||||
|
||||
output.Write(temp, strlen(temp) + 1);
|
||||
|
||||
const char* text = (const char*)output.GetData();
|
||||
log_info(text);
|
||||
network_append_server_log(text);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Execute(const GameAction* action)
|
||||
{
|
||||
Guard::ArgumentNotNull(action);
|
||||
|
@ -176,11 +227,14 @@ namespace GameActions
|
|||
}
|
||||
}
|
||||
|
||||
log_verbose("[%s] GameAction::Execute\n", "sv");
|
||||
ActionLogContext_t logContext;
|
||||
LogActionBegin(logContext, action);
|
||||
|
||||
// Execute the action, changing the game state
|
||||
result = action->Execute();
|
||||
|
||||
LogActionFinish(logContext, action, result);
|
||||
|
||||
gCommandPosition.x = result->Position.x;
|
||||
gCommandPosition.y = result->Position.y;
|
||||
gCommandPosition.z = result->Position.z;
|
||||
|
@ -197,13 +251,12 @@ namespace GameActions
|
|||
{
|
||||
if (network_get_mode() == NETWORK_MODE_SERVER && result->Error == GA_ERROR::OK)
|
||||
{
|
||||
const uint32_t playerId = action->GetPlayer();
|
||||
const uint32_t playerIndex = network_get_player_index(playerId);
|
||||
NetworkPlayerId_t playerId = action->GetPlayer();
|
||||
|
||||
network_set_player_last_action(playerIndex, action->GetType());
|
||||
network_set_player_last_action(network_get_player_index(playerId.id), action->GetType());
|
||||
if (result->Cost != 0)
|
||||
{
|
||||
network_add_player_money_spent(playerIndex, result->Cost);
|
||||
network_add_player_money_spent(playerId.id, result->Cost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -230,4 +283,5 @@ namespace GameActions
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace GameActions
|
||||
|
|
|
@ -90,8 +90,8 @@ public:
|
|||
private:
|
||||
uint32_t const _type;
|
||||
|
||||
uint32_t _playerId = 0; // Callee
|
||||
uint32_t _flags = 0; // GAME_COMMAND_FLAGS
|
||||
NetworkPlayerId_t _playerId = { 0 }; // Callee
|
||||
uint32_t _flags = 0; // GAME_COMMAND_FLAGS
|
||||
uint32_t _networkId = 0;
|
||||
Callback_t _callback;
|
||||
|
||||
|
@ -103,12 +103,12 @@ public:
|
|||
|
||||
virtual ~GameAction() = default;
|
||||
|
||||
uint32_t GetPlayer() const
|
||||
NetworkPlayerId_t GetPlayer() const
|
||||
{
|
||||
return _playerId;
|
||||
}
|
||||
|
||||
void SetPlayer(uint32_t playerId)
|
||||
void SetPlayer(NetworkPlayerId_t playerId)
|
||||
{
|
||||
_playerId = playerId;
|
||||
}
|
||||
|
@ -174,9 +174,7 @@ public:
|
|||
|
||||
virtual void Serialise(DataSerialiser& stream)
|
||||
{
|
||||
stream << _networkId;
|
||||
stream << _flags;
|
||||
stream << _playerId;
|
||||
stream << DS_TAG(_networkId) << DS_TAG(_flags) << DS_TAG(_playerId);
|
||||
}
|
||||
|
||||
// Helper function, allows const Objects to still serialize into DataSerialiser while being const.
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _spriteIndex << _name;
|
||||
stream << DS_TAG(_spriteIndex) << DS_TAG(_name);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -56,7 +56,7 @@ private:
|
|||
uint16_t _z;
|
||||
bool _initialPlacement;
|
||||
uint8_t _direction;
|
||||
uint8_t _rideIndex;
|
||||
NetworkRideId_t _rideIndex;
|
||||
uint8_t _mode;
|
||||
|
||||
public:
|
||||
|
@ -64,7 +64,7 @@ public:
|
|||
{
|
||||
}
|
||||
MazeSetTrackAction(
|
||||
uint16_t x, uint16_t y, uint16_t z, bool initialPlacement, uint8_t direction, uint8_t rideIndex, uint8_t mode)
|
||||
uint16_t x, uint16_t y, uint16_t z, bool initialPlacement, uint8_t direction, NetworkRideId_t rideIndex, uint8_t mode)
|
||||
: _x(x)
|
||||
, _y(y)
|
||||
, _z(z)
|
||||
|
@ -79,7 +79,8 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _x << _y << _z << _initialPlacement << _direction << _rideIndex << _mode;
|
||||
stream << DS_TAG(_x) << DS_TAG(_y) << DS_TAG(_z) << DS_TAG(_initialPlacement) << DS_TAG(_direction)
|
||||
<< DS_TAG(_rideIndex) << DS_TAG(_mode);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _type << _item << _numWeeks;
|
||||
stream << DS_TAG(_type) << DS_TAG(_item) << DS_TAG(_numWeeks);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -40,7 +40,7 @@ public:
|
|||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _value;
|
||||
stream << DS_TAG(_value);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _name;
|
||||
stream << DS_TAG(_name);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
@ -85,13 +85,6 @@ public:
|
|||
user_string_free(gParkName);
|
||||
gParkName = newNameId;
|
||||
|
||||
// Log park rename command if we are in multiplayer and logging is enabled
|
||||
if ((network_get_mode() == NETWORK_MODE_CLIENT || network_get_mode() == NETWORK_MODE_SERVER)
|
||||
&& gConfigNetwork.log_server_actions)
|
||||
{
|
||||
LogAction(oldName);
|
||||
}
|
||||
|
||||
scrolling_text_invalidate();
|
||||
gfx_invalidate_screen();
|
||||
|
||||
|
@ -105,16 +98,4 @@ private:
|
|||
format_string(buffer, sizeof(buffer), gParkName, &gParkNameArgs);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void LogAction(const std::string& oldName) const
|
||||
{
|
||||
// Get player name
|
||||
auto playerIndex = network_get_player_index(GetPlayer());
|
||||
auto playerName = network_get_player_name(playerIndex);
|
||||
|
||||
char logMessage[256];
|
||||
const char* args[3] = { playerName, oldName.c_str(), _name.c_str() };
|
||||
format_string(logMessage, sizeof(logMessage), STR_LOG_PARK_NAME, (void*)args);
|
||||
network_append_server_log(logMessage);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _priorities << _fundingAmount;
|
||||
stream << DS_TAG(_priorities) << DS_TAG(_fundingAmount);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -51,7 +51,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _x << _y << _z << _direction;
|
||||
stream << DS_TAG(_x) << DS_TAG(_y) << DS_TAG(_z) << DS_TAG(_direction);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _location.x << _location.y << _location.z << _location.direction;
|
||||
stream << DS_TAG(_location.x) << DS_TAG(_location.y) << DS_TAG(_location.z) << DS_TAG(_location.direction);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -64,14 +64,13 @@ public:
|
|||
uint16_t GetActionFlags() const override
|
||||
{
|
||||
return GameAction::GetActionFlags() | GA_FLAGS::ALLOW_WHILE_PAUSED;
|
||||
;
|
||||
}
|
||||
|
||||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _rideType << _subType << _colour1 << _colour2;
|
||||
stream << DS_TAG(_rideType) << DS_TAG(_subType) << DS_TAG(_colour1) << DS_TAG(_colour2);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -31,7 +31,7 @@ using namespace OpenRCT2;
|
|||
struct RideDemolishAction : public GameActionBase<GAME_COMMAND_DEMOLISH_RIDE, GameActionResult>
|
||||
{
|
||||
private:
|
||||
int32_t _rideIndex = -1;
|
||||
NetworkRideId_t _rideIndex{ -1 };
|
||||
uint8_t _modifyType = RIDE_MODIFY_DEMOLISH;
|
||||
|
||||
public:
|
||||
|
@ -48,7 +48,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _rideIndex << _modifyType;
|
||||
stream << DS_TAG(_rideIndex) << DS_TAG(_modifyType);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
struct RideSetNameAction : public GameActionBase<GAME_COMMAND_SET_RIDE_NAME, GameActionResult>
|
||||
{
|
||||
private:
|
||||
int32_t _rideIndex = -1;
|
||||
NetworkRideId_t _rideIndex{ -1 };
|
||||
std::string _name;
|
||||
|
||||
public:
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _rideIndex << _name;
|
||||
stream << DS_TAG(_rideIndex) << DS_TAG(_name);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -30,7 +30,7 @@ static rct_string_id _StatusErrorTitles[] = {
|
|||
struct RideSetStatusAction : public GameActionBase<GAME_COMMAND_SET_RIDE_STATUS, GameActionResult>
|
||||
{
|
||||
private:
|
||||
int32_t _rideIndex = -1;
|
||||
NetworkRideId_t _rideIndex{ -1 };
|
||||
uint8_t _status = RIDE_STATUS_CLOSED;
|
||||
|
||||
public:
|
||||
|
@ -52,7 +52,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _rideIndex << _status;
|
||||
stream << DS_TAG(_rideIndex) << DS_TAG(_status);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _fee;
|
||||
stream << DS_TAG(_fee);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _bannerIndex << _name;
|
||||
stream << DS_TAG(_bannerIndex) << DS_TAG(_name);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -44,7 +44,7 @@ public:
|
|||
void Serialise(DataSerialiser& stream) override
|
||||
{
|
||||
GameAction::Serialise(stream);
|
||||
stream << _staffType << _colour;
|
||||
stream << DS_TAG(_staffType) << DS_TAG(_colour);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -47,7 +47,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _spriteIndex << _name;
|
||||
stream << DS_TAG(_spriteIndex) << DS_TAG(_name);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
{
|
||||
GameAction::Serialise(stream);
|
||||
|
||||
stream << _location.x << _location.y << _location.z << _location.direction;
|
||||
stream << DS_TAG(_location.x) << DS_TAG(_location.y) << DS_TAG(_location.z) << DS_TAG(_location.direction);
|
||||
}
|
||||
|
||||
GameActionResult::Ptr Query() const override
|
||||
|
|
|
@ -17,18 +17,21 @@ class DataSerialiser
|
|||
{
|
||||
private:
|
||||
MemoryStream _stream;
|
||||
MemoryStream* _activeStream;
|
||||
bool _isSaving;
|
||||
IStream* _activeStream = nullptr;
|
||||
bool _isSaving = false;
|
||||
bool _isLogging = false;
|
||||
|
||||
public:
|
||||
DataSerialiser(bool isSaving)
|
||||
: _isSaving(isSaving)
|
||||
, _isLogging(false)
|
||||
{
|
||||
_activeStream = &_stream;
|
||||
}
|
||||
|
||||
DataSerialiser(bool isSaving, MemoryStream& stream)
|
||||
DataSerialiser(bool isSaving, IStream& stream, bool isLogging = false)
|
||||
: _isSaving(isSaving)
|
||||
, _isLogging(isLogging)
|
||||
{
|
||||
_activeStream = &stream;
|
||||
}
|
||||
|
@ -50,10 +53,35 @@ public:
|
|||
|
||||
template<typename T> DataSerialiser& operator<<(T& data)
|
||||
{
|
||||
if (_isSaving)
|
||||
DataSerializerTraits<T>::encode(_activeStream, data);
|
||||
if (!_isLogging)
|
||||
{
|
||||
if (_isSaving)
|
||||
DataSerializerTraits<T>::encode(_activeStream, data);
|
||||
else
|
||||
DataSerializerTraits<T>::decode(_activeStream, data);
|
||||
}
|
||||
else
|
||||
DataSerializerTraits<T>::decode(_activeStream, data);
|
||||
{
|
||||
DataSerializerTraits<T>::log(_activeStream, data);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T> DataSerialiser& operator<<(DataSerialiserTag<T> data)
|
||||
{
|
||||
if (!_isLogging)
|
||||
{
|
||||
if (_isSaving)
|
||||
DataSerializerTraits<DataSerialiserTag<T>>::encode(_activeStream, data);
|
||||
else
|
||||
DataSerializerTraits<DataSerialiserTag<T>>::decode(_activeStream, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataSerializerTraits<DataSerialiserTag<T>>::log(_activeStream, data);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014-2018 OpenRCT2 developers
|
||||
*
|
||||
* For a complete list of all authors, please refer to contributors.md
|
||||
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
|
||||
*
|
||||
* OpenRCT2 is licensed under the GNU General Public License version 3.
|
||||
*****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
template<typename T> class DataSerialiserTag
|
||||
{
|
||||
public:
|
||||
DataSerialiserTag(const char* name, T& data)
|
||||
: _name(name)
|
||||
, _data(data)
|
||||
{
|
||||
}
|
||||
|
||||
const char* Name() const
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
T& Data() const
|
||||
{
|
||||
return _data;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* _name = nullptr;
|
||||
T& _data;
|
||||
};
|
||||
|
||||
template<typename T> inline DataSerialiserTag<T> CreateDataSerialiserTag(const char* name, T& data)
|
||||
{
|
||||
DataSerialiserTag<T> r(name, data);
|
||||
return r;
|
||||
}
|
||||
|
||||
#define DS_TAG(var) CreateDataSerialiserTag(#var, var)
|
|
@ -9,13 +9,21 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "../localisation/Localisation.h"
|
||||
#include "../network/NetworkTypes.h"
|
||||
#include "../network/network.h"
|
||||
#include "../ride/Ride.h"
|
||||
#include "DataSerialiserTag.h"
|
||||
#include "Endianness.h"
|
||||
#include "MemoryStream.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
template<typename T> struct DataSerializerTraits
|
||||
{
|
||||
static void encode(IStream* stream, const T& v) = delete;
|
||||
static void decode(IStream* stream, T& val) = delete;
|
||||
static void log(IStream* stream, T& val) = delete;
|
||||
};
|
||||
|
||||
template<typename T> struct DataSerializerTraitsIntegral
|
||||
|
@ -31,10 +39,41 @@ template<typename T> struct DataSerializerTraitsIntegral
|
|||
stream->Read(&temp);
|
||||
val = ByteSwapBE(temp);
|
||||
}
|
||||
static void log(IStream* stream, T& val)
|
||||
{
|
||||
char temp[32] = {};
|
||||
if constexpr (sizeof(T) == 1)
|
||||
snprintf(temp, sizeof(temp), "%02X", val);
|
||||
else if constexpr (sizeof(T) == 2)
|
||||
snprintf(temp, sizeof(temp), "%04X", val);
|
||||
else if constexpr (sizeof(T) == 4)
|
||||
snprintf(temp, sizeof(temp), "%08X", val);
|
||||
else if constexpr (sizeof(T) == 8)
|
||||
snprintf(temp, sizeof(temp), "%16X", val);
|
||||
else
|
||||
static_assert("Invalid size");
|
||||
|
||||
stream->Write(temp, strlen(temp));
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct DataSerializerTraits<bool> : public DataSerializerTraitsIntegral<bool>
|
||||
template<> struct DataSerializerTraits<bool>
|
||||
{
|
||||
static void encode(IStream* stream, const bool& val)
|
||||
{
|
||||
stream->Write(&val);
|
||||
}
|
||||
static void decode(IStream* stream, bool& val)
|
||||
{
|
||||
stream->Read(&val);
|
||||
}
|
||||
static void log(IStream* stream, bool& val)
|
||||
{
|
||||
if (val)
|
||||
stream->Write("true", 4);
|
||||
else
|
||||
stream->Write("false", 5);
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct DataSerializerTraits<uint8_t> : public DataSerializerTraitsIntegral<uint8_t>
|
||||
|
@ -81,4 +120,102 @@ template<> struct DataSerializerTraits<std::string>
|
|||
|
||||
Memory::FreeArray(str, len);
|
||||
}
|
||||
static void log(IStream* stream, const std::string& str)
|
||||
{
|
||||
stream->Write("\"");
|
||||
stream->Write(str.data(), str.size());
|
||||
stream->Write("\"");
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct DataSerializerTraits<NetworkPlayerId_t>
|
||||
{
|
||||
static void encode(IStream* stream, const NetworkPlayerId_t& val)
|
||||
{
|
||||
uint32_t temp = ByteSwapBE(val.id);
|
||||
stream->Write(&temp);
|
||||
}
|
||||
static void decode(IStream* stream, NetworkPlayerId_t& val)
|
||||
{
|
||||
uint32_t temp;
|
||||
stream->Read(&temp);
|
||||
val.id = ByteSwapBE(temp);
|
||||
}
|
||||
static void log(IStream* stream, NetworkPlayerId_t& val)
|
||||
{
|
||||
char playerId[28] = {};
|
||||
snprintf(playerId, sizeof(playerId), "%u", val.id);
|
||||
|
||||
stream->Write(playerId, strlen(playerId));
|
||||
|
||||
int32_t playerIndex = network_get_player_index(val.id);
|
||||
if (playerIndex != -1)
|
||||
{
|
||||
const char* playerName = network_get_player_name(playerIndex);
|
||||
if (playerName != nullptr)
|
||||
{
|
||||
stream->Write(" \"", 2);
|
||||
stream->Write(playerName, strlen(playerName));
|
||||
stream->Write("\"", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct DataSerializerTraits<NetworkRideId_t>
|
||||
{
|
||||
static void encode(IStream* stream, const NetworkRideId_t& val)
|
||||
{
|
||||
uint32_t temp = ByteSwapBE(val.id);
|
||||
stream->Write(&temp);
|
||||
}
|
||||
static void decode(IStream* stream, NetworkRideId_t& val)
|
||||
{
|
||||
uint32_t temp;
|
||||
stream->Read(&temp);
|
||||
val.id = ByteSwapBE(temp);
|
||||
}
|
||||
static void log(IStream* stream, NetworkRideId_t& val)
|
||||
{
|
||||
char rideId[28] = {};
|
||||
snprintf(rideId, sizeof(rideId), "%u", val.id);
|
||||
|
||||
stream->Write(rideId, strlen(rideId));
|
||||
|
||||
Ride* ride = get_ride(val.id);
|
||||
if (ride)
|
||||
{
|
||||
char rideName[256] = {};
|
||||
format_string(rideName, 256, ride->name, &ride->name_arguments);
|
||||
|
||||
stream->Write(" \"", 2);
|
||||
stream->Write(rideName, strlen(rideName));
|
||||
stream->Write("\"", 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct DataSerializerTraits<DataSerialiserTag<T>>
|
||||
{
|
||||
static void encode(IStream* stream, const DataSerialiserTag<T>& tag)
|
||||
{
|
||||
DataSerializerTraits<T> s;
|
||||
s.encode(stream, tag.Data());
|
||||
}
|
||||
static void decode(IStream* stream, DataSerialiserTag<T>& tag)
|
||||
{
|
||||
DataSerializerTraits<T> s;
|
||||
s.decode(stream, tag.Data());
|
||||
}
|
||||
static void log(IStream* stream, DataSerialiserTag<T>& tag)
|
||||
{
|
||||
const char* name = tag.Name();
|
||||
stream->Write(name, strlen(name));
|
||||
stream->Write(" = ", 3);
|
||||
|
||||
DataSerializerTraits<T> s;
|
||||
s.log(stream, tag.Data());
|
||||
|
||||
stream->Write("; ", 2);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2635,7 +2635,7 @@ void Network::Client_Handle_GAME_ACTION([[maybe_unused]] NetworkConnection& conn
|
|||
}
|
||||
action->Serialise(ds);
|
||||
|
||||
if (player_id == action->GetPlayer())
|
||||
if (player_id == action->GetPlayer().id)
|
||||
{
|
||||
// Only execute callbacks that belong to us,
|
||||
// clients can have identical network ids assigned.
|
||||
|
@ -2721,7 +2721,7 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa
|
|||
|
||||
ga->Serialise(stream);
|
||||
// Set player to sender, should be 0 if sent from client.
|
||||
ga->SetPlayer(connection.Player->Id);
|
||||
ga->SetPlayer(NetworkPlayerId_t{ connection.Player->Id });
|
||||
|
||||
game_command_queue.emplace(tick, std::move(ga), _commandId++);
|
||||
}
|
||||
|
@ -3143,7 +3143,7 @@ uint32_t network_get_player_commands_ran(uint32_t index)
|
|||
return gNetwork.player_list[index]->CommandsRan;
|
||||
}
|
||||
|
||||
int32_t network_get_player_index(uint8_t id)
|
||||
int32_t network_get_player_index(uint32_t id)
|
||||
{
|
||||
auto it = gNetwork.GetPlayerIteratorByID(id);
|
||||
if (it == gNetwork.player_list.end())
|
||||
|
@ -3915,7 +3915,7 @@ uint32_t network_get_player_commands_ran(uint32_t index)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
int32_t network_get_player_index(uint8_t id)
|
||||
int32_t network_get_player_index(uint32_t id)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -68,3 +68,30 @@ enum NETWORK_COMMAND
|
|||
NETWORK_COMMAND_MAX,
|
||||
NETWORK_COMMAND_INVALID = -1
|
||||
};
|
||||
|
||||
// Structure is used for networking specific fields with meaning,
|
||||
// this structure can be used in combination with DataSerialiser
|
||||
// to provide extra details with template specialization.
|
||||
#pragma pack(push, 1)
|
||||
template<typename T, size_t _TypeID> struct NetworkObjectId_t
|
||||
{
|
||||
NetworkObjectId_t(T v)
|
||||
: id(v)
|
||||
{
|
||||
}
|
||||
NetworkObjectId_t()
|
||||
: id(T(-1))
|
||||
{
|
||||
}
|
||||
operator T() const
|
||||
{
|
||||
return id;
|
||||
}
|
||||
T id;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
// NOTE: When adding new types make sure to have no duplicate _TypeID's otherwise
|
||||
// there is no way to specialize templates if they have the exact symbol.
|
||||
using NetworkPlayerId_t = NetworkObjectId_t<int32_t, 0>;
|
||||
using NetworkRideId_t = NetworkObjectId_t<int32_t, 1>;
|
||||
|
|
|
@ -57,7 +57,7 @@ void network_set_player_last_action(uint32_t index, int32_t command);
|
|||
LocationXYZ16 network_get_player_last_action_coord(uint32_t index);
|
||||
void network_set_player_last_action_coord(uint32_t index, LocationXYZ16 coord);
|
||||
uint32_t network_get_player_commands_ran(uint32_t index);
|
||||
int32_t network_get_player_index(uint8_t id);
|
||||
int32_t network_get_player_index(uint32_t id);
|
||||
uint8_t network_get_player_group(uint32_t index);
|
||||
void network_set_player_group(uint32_t index, uint32_t groupindex);
|
||||
int32_t network_get_group_index(uint8_t id);
|
||||
|
|
Loading…
Reference in New Issue