1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-23 06:44:38 +01:00

Merge pull request #9453 from duncanspumpkin/remove_gc

Remove Networked Game Commands
This commit is contained in:
Michael Steenbeek
2019-07-14 14:46:46 +02:00
committed by GitHub
8 changed files with 4 additions and 323 deletions

View File

@@ -74,7 +74,6 @@ float gDayNightCycle = 0;
bool gInUpdateCode = false;
bool gInMapInitCode = false;
int32_t gGameCommandNestLevel;
bool gGameCommandIsNetworked;
std::string gCurrentLoadedPath;
bool gLoadKeepWindowsOpen = false;
@@ -85,23 +84,6 @@ uint8_t gUnk141F568;
uint32_t gCurrentTicks;
uint32_t gCurrentRealTimeTicks;
// clang-format off
GAME_COMMAND_CALLBACK_POINTER * game_command_callback = nullptr;
static GAME_COMMAND_CALLBACK_POINTER * const game_command_callback_table[] = {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr
};
// clang-format on
int32_t game_command_playerid = -1;
rct_string_id gGameCommandErrorTitle;
rct_string_id gGameCommandErrorText;
uint8_t gErrorType;
@@ -109,27 +91,6 @@ rct_string_id gErrorStringId;
using namespace OpenRCT2;
int32_t game_command_callback_get_index(GAME_COMMAND_CALLBACK_POINTER* callback)
{
for (uint32_t i = 0; i < std::size(game_command_callback_table); i++)
{
if (game_command_callback_table[i] == callback)
{
return i;
}
}
return 0;
}
GAME_COMMAND_CALLBACK_POINTER* game_command_callback_get_callback(uint32_t index)
{
if (index < std::size(game_command_callback_table))
{
return game_command_callback_table[index];
}
return nullptr;
}
void game_increase_game_speed()
{
gGameSpeed = std::min(gConfigGeneral.debugging_tools ? 5 : 4, gGameSpeed + 1);
@@ -402,27 +363,11 @@ int32_t game_do_command_p(
if (gGameCommandNestLevel == 0)
{
gGameCommandErrorText = STR_NONE;
gGameCommandIsNetworked = (flags & GAME_COMMAND_FLAG_NETWORKED) != 0;
}
// Increment nest count
gGameCommandNestLevel++;
if (game_command_playerid == -1)
{
game_command_playerid = network_get_current_player_id();
}
// Log certain commands if we are in multiplayer and logging is enabled
bool serverLog = (network_get_mode() == NETWORK_MODE_SERVER) && gGameCommandNestLevel == 1
&& gConfigNetwork.log_server_actions;
bool clientLog = (network_get_mode() == NETWORK_MODE_CLIENT) && (flags & GAME_COMMAND_FLAG_NETWORKED)
&& gGameCommandNestLevel == 1 && gConfigNetwork.log_server_actions;
if (serverLog || clientLog)
{
game_log_multiplayer_command(command, eax, ebx, ecx, edx, edi, ebp);
}
*ebx &= ~GAME_COMMAND_FLAG_APPLY;
// Make sure the camera position won't change if the command skips setting them.
@@ -456,23 +401,6 @@ int32_t game_do_command_p(
return cost;
}
if (network_get_mode() != NETWORK_MODE_NONE && !(flags & GAME_COMMAND_FLAG_NETWORKED)
&& !(flags & GAME_COMMAND_FLAG_GHOST) && !(flags & GAME_COMMAND_FLAG_NO_SPEND)
&& gGameCommandNestLevel == 1) /* Send only top-level commands */
{
network_send_gamecmd(
*eax, *ebx, *ecx, *edx, *esi, *edi, *ebp, game_command_callback_get_index(game_command_callback));
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 = nullptr;
// Decrement nest count
gGameCommandNestLevel--;
return cost;
}
}
// Second call to actually perform the operation
new_game_command_table[command](eax, ebx, ecx, edx, esi, edi, ebp);
@@ -489,26 +417,11 @@ int32_t game_do_command_p(
if (recordCommand && gGameCommandNestLevel == 1)
{
int32_t callback = game_command_callback_get_index(game_command_callback);
replayManager->AddGameCommand(
gCurrentTicks, *eax, original_ebx, *ecx, original_edx, original_esi, original_edi, original_ebp,
callback);
gCurrentTicks, *eax, original_ebx, *ecx, original_edx, original_esi, original_edi, original_ebp, 0);
}
}
// Do the callback (required for multiplayer to work correctly), but only for top level commands
if (gGameCommandNestLevel == 1)
{
if (game_command_callback && !(flags & GAME_COMMAND_FLAG_GHOST))
{
game_command_callback(*eax, *ebx, *ecx, *edx, *esi, *edi, *ebp);
game_command_callback = nullptr;
}
}
game_command_playerid = -1;
*edx = *ebx;
if (*edx != MONEY32_UNDEFINED && *edx < cost)
@@ -532,13 +445,6 @@ int32_t game_do_command_p(
}
}
if (network_get_mode() == NETWORK_MODE_SERVER && !(flags & GAME_COMMAND_FLAG_NETWORKED)
&& !(flags & GAME_COMMAND_FLAG_GHOST))
{
network_set_player_last_action(network_get_player_index(network_get_current_player_id()), command);
network_add_player_money_spent(network_get_current_player_id(), cost);
}
// Start autosave timer after game command
if (gLastAutoSaveUpdate == AUTOSAVE_PAUSE)
gLastAutoSaveUpdate = platform_get_ticks();
@@ -552,9 +458,6 @@ int32_t game_do_command_p(
// Decrement nest count
gGameCommandNestLevel--;
// Clear the game command callback to prevent the next command triggering it
game_command_callback = nullptr;
// Show error window
if (gGameCommandNestLevel == 0 && (flags & GAME_COMMAND_FLAG_APPLY) && gUnk141F568 == gUnk13CA740
&& !(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && !(flags & GAME_COMMAND_FLAG_NETWORKED)
@@ -566,34 +469,6 @@ int32_t game_do_command_p(
return MONEY32_UNDEFINED;
}
void game_log_multiplayer_command(int command, const int* eax, const int* ebx, const int* ecx, int* edx, int* edi, int* ebp)
{
// Get player name
const char* player_name = "localhost";
int player_index = network_get_player_index(game_command_playerid);
if (player_index != -1)
{
player_name = network_get_player_name(player_index);
}
char log_msg[256];
if (command == GAME_COMMAND_DEMOLISH_RIDE && (*ebp == 1 || *ebp == 0))
{ // ebp is 1 if command comes from ride window prompt, so we don't log "demolishing" ride previews
// Get ride name
Ride* ride = get_ride(*edx);
char ride_name[128];
format_string(ride_name, 128, ride->name, &ride->name_arguments);
char* args[2] = {
(char*)player_name,
ride_name,
};
format_string(log_msg, 256, STR_LOG_DEMOLISH_RIDE, args);
network_append_server_log(log_msg);
}
}
void pause_toggle()
{
gGamePaused ^= GAME_PAUSED_NORMAL;

View File

@@ -130,13 +130,6 @@ enum
using GAME_COMMAND_POINTER = void(
int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);
using GAME_COMMAND_CALLBACK_POINTER = void(
int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int32_t esi, int32_t edi, int32_t ebp);
extern GAME_COMMAND_CALLBACK_POINTER* game_command_callback;
int32_t game_command_callback_get_index(GAME_COMMAND_CALLBACK_POINTER* callback);
GAME_COMMAND_CALLBACK_POINTER* game_command_callback_get_callback(uint32_t index);
extern int32_t game_command_playerid;
extern rct_string_id gGameCommandErrorTitle;
extern rct_string_id gGameCommandErrorText;
@@ -156,7 +149,6 @@ extern float gDayNightCycle;
extern bool gInUpdateCode;
extern bool gInMapInitCode;
extern int32_t gGameCommandNestLevel;
extern bool gGameCommandIsNetworked;
extern std::string gCurrentLoadedPath;
extern bool gLoadKeepWindowsOpen;
@@ -175,8 +167,6 @@ int32_t game_do_command(int32_t eax, int32_t ebx, int32_t ecx, int32_t edx, int3
int32_t game_do_command_p(
uint32_t command, int32_t* eax, int32_t* ebx, int32_t* ecx, int32_t* edx, int32_t* esi, int32_t* edi, int32_t* ebp);
void game_log_multiplayer_command(int command, const int* eax, const int* ebx, const int* ecx, int* edx, int* edi, int* ebp);
void game_load_or_quit_no_save_prompt();
void load_from_sv6(const char* path);
void game_load_init();

View File

@@ -180,11 +180,6 @@ public:
void Server_Send_MAP(NetworkConnection* connection = nullptr);
void Client_Send_CHAT(const char* text);
void Server_Send_CHAT(const char* text);
void Client_Send_GAMECMD(
uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback);
void Server_Send_GAMECMD(
uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t playerid,
uint8_t callback);
void Client_Send_GAME_ACTION(const GameAction* action);
void Server_Send_GAME_ACTION(const GameAction* action);
void Server_Send_TICK();
@@ -244,15 +239,7 @@ private:
GameCommand(uint32_t t, uint32_t* args, uint8_t p, uint8_t cb, uint32_t id)
{
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;
action = nullptr;
commandIndex = id;
}
@@ -269,10 +256,8 @@ private:
}
uint32_t tick = 0;
uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0, esi = 0, edi = 0, ebp = 0;
GameAction::Ptr action;
uint8_t playerid = 0;
uint8_t callback = 0;
uint32_t commandIndex = 0;
bool operator<(const GameCommand& comp) const
{
@@ -350,8 +335,6 @@ private:
void Client_Handle_MAP(NetworkConnection& connection, NetworkPacket& packet);
void Client_Handle_CHAT(NetworkConnection& connection, NetworkPacket& packet);
void Server_Handle_CHAT(NetworkConnection& connection, NetworkPacket& packet);
void Client_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet);
void Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet);
void Client_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet);
void Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPacket& packet);
void Client_Handle_TICK(NetworkConnection& connection, NetworkPacket& packet);
@@ -392,7 +375,6 @@ Network::Network()
client_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Client_Handle_AUTH;
client_command_handlers[NETWORK_COMMAND_MAP] = &Network::Client_Handle_MAP;
client_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Client_Handle_CHAT;
client_command_handlers[NETWORK_COMMAND_GAMECMD] = &Network::Client_Handle_GAMECMD;
client_command_handlers[NETWORK_COMMAND_GAME_ACTION] = &Network::Client_Handle_GAME_ACTION;
client_command_handlers[NETWORK_COMMAND_TICK] = &Network::Client_Handle_TICK;
client_command_handlers[NETWORK_COMMAND_PLAYERLIST] = &Network::Client_Handle_PLAYERLIST;
@@ -410,7 +392,6 @@ Network::Network()
server_command_handlers.resize(NETWORK_COMMAND_MAX, nullptr);
server_command_handlers[NETWORK_COMMAND_AUTH] = &Network::Server_Handle_AUTH;
server_command_handlers[NETWORK_COMMAND_CHAT] = &Network::Server_Handle_CHAT;
server_command_handlers[NETWORK_COMMAND_GAMECMD] = &Network::Server_Handle_GAMECMD;
server_command_handlers[NETWORK_COMMAND_GAME_ACTION] = &Network::Server_Handle_GAME_ACTION;
server_command_handlers[NETWORK_COMMAND_PING] = &Network::Server_Handle_PING;
server_command_handlers[NETWORK_COMMAND_GAMEINFO] = &Network::Server_Handle_GAMEINFO;
@@ -1674,26 +1655,6 @@ void Network::Server_Send_CHAT(const char* text)
SendPacketToClients(*packet);
}
void Network::Client_Send_GAMECMD(
uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback)
{
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32_t)NETWORK_COMMAND_GAMECMD << gCurrentTicks << eax << (ebx | GAME_COMMAND_FLAG_NETWORKED) << ecx << edx
<< esi << edi << ebp << callback;
_serverConnection->QueuePacket(std::move(packet));
}
void Network::Server_Send_GAMECMD(
uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t playerid,
uint8_t callback)
{
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
*packet << (uint32_t)NETWORK_COMMAND_GAMECMD << gCurrentTicks << eax << (ebx | GAME_COMMAND_FLAG_NETWORKED) << ecx << edx
<< esi << edi << ebp << playerid << callback;
SendPacketToClients(*packet, false, true);
}
void Network::Client_Send_GAME_ACTION(const GameAction* action)
{
std::unique_ptr<NetworkPacket> packet(NetworkPacket::Allocate());
@@ -2105,7 +2066,7 @@ void Network::ProcessGameCommands()
// the command is useless so lets not keep it.
log_warning(
"Discarding game command from tick behind current tick, CMD: %08X, CMD Tick: %08X, Current Tick: %08X\n",
gc.esi, gc.tick, gCurrentTicks);
gc.commandIndex, gc.tick, gCurrentTicks);
game_command_queue.erase(game_command_queue.begin());
@@ -2143,49 +2104,6 @@ void Network::ProcessGameCommands()
Server_Send_PLAYERINFO(action->GetPlayer());
}
}
else
{
if (GetPlayerID() == gc.playerid)
{
game_command_callback = game_command_callback_get_callback(gc.callback);
}
game_command_playerid = gc.playerid;
int32_t command = gc.esi;
int32_t 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)
{
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)
{
// Note these are currently not reached as both commands are ported to GameActions
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);
Server_Send_PLAYERINFO(gc.playerid);
}
}
}
game_command_queue.erase(game_command_queue.begin());
}
}
@@ -3026,17 +2944,6 @@ void Network::Server_Handle_CHAT(NetworkConnection& connection, NetworkPacket& p
}
}
void Network::Client_Handle_GAMECMD([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet)
{
uint32_t tick;
uint32_t args[7];
uint8_t playerid;
uint8_t callback;
packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> playerid >> callback;
game_command_queue.emplace(tick, args, playerid, callback, _commandId++);
}
void Network::Client_Handle_GAME_ACTION([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet)
{
uint32_t tick;
@@ -3143,66 +3050,6 @@ void Network::Server_Handle_GAME_ACTION(NetworkConnection& connection, NetworkPa
game_command_queue.emplace(tick, std::move(ga), _commandId++);
}
void Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& packet)
{
uint32_t tick;
uint32_t args[7];
uint8_t playerid;
uint8_t callback;
if (!connection.Player)
{
return;
}
playerid = connection.Player->Id;
packet >> tick >> args[0] >> args[1] >> args[2] >> args[3] >> args[4] >> args[5] >> args[6] >> callback;
int32_t commandCommand = args[4];
uint32_t ticks = platform_get_ticks(); // tick count is different by time last_action_time is set, keep same value.
// Check if player's group permission allows command to run
NetworkGroup* group = GetGroupByID(connection.Player->Group);
if (!group || !group->CanPerformCommand(commandCommand))
{
Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_PERMISSION_DENIED);
return;
}
// In case someone modifies the code / memory to enable cluster build,
// require a small delay in between placing scenery to provide some security, as
// cluster mode is a for loop that runs the place_scenery code multiple times.
if (commandCommand == GAME_COMMAND_PLACE_SCENERY)
{
if (ticks - connection.Player->LastPlaceSceneryTime < ACTION_COOLDOWN_TIME_PLACE_SCENERY &&
// In case platform_get_ticks() wraps after ~49 days, ignore larger logged times.
ticks > connection.Player->LastPlaceSceneryTime)
{
if (!(group->CanPerformCommand(MISC_COMMAND_TOGGLE_SCENERY_CLUSTER)))
{
Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE);
return;
}
}
}
// This is to prevent abuse of demolishing rides. Anyone that is not the server
// host will have to wait a small amount of time in between deleting rides.
else if (commandCommand == GAME_COMMAND_DEMOLISH_RIDE)
{
if (ticks - connection.Player->LastDemolishRideTime < ACTION_COOLDOWN_TIME_DEMOLISH_RIDE &&
// In case platform_get_ticks() wraps after ~49 days, ignore larger logged times.
ticks > connection.Player->LastDemolishRideTime)
{
Server_Send_SHOWERROR(connection, STR_CANT_DO_THIS, STR_NETWORK_ACTION_RATE_LIMIT_MESSAGE);
return;
}
}
game_command_queue.emplace(tick, args, playerid, callback, _commandId++);
}
void Network::Client_Handle_TICK([[maybe_unused]] NetworkConnection& connection, NetworkPacket& packet)
{
uint32_t srand0;
@@ -4006,20 +3853,6 @@ void network_enqueue_game_action(const GameAction* action)
gNetwork.EnqueueGameAction(action);
}
void network_send_gamecmd(
uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback)
{
switch (gNetwork.GetMode())
{
case NETWORK_MODE_SERVER:
gNetwork.Server_Send_GAMECMD(eax, ebx, ecx, edx, esi, edi, ebp, gNetwork.GetPlayerID(), callback);
break;
case NETWORK_MODE_CLIENT:
gNetwork.Client_Send_GAMECMD(eax, ebx, ecx, edx, esi, edi, ebp, callback);
break;
}
}
void network_send_password(const std::string& password)
{
utf8 keyPath[MAX_PATH];
@@ -4175,10 +4008,6 @@ void network_request_gamestate_snapshot()
void network_enqueue_game_action(const GameAction* action)
{
}
void network_send_gamecmd(
uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback)
{
}
void network_send_game_action(const GameAction* action)
{
}

View File

@@ -191,7 +191,6 @@ void NetworkConnection::RecordPacketStats(const NetworkPacket& packet, bool send
switch (packet.GetCommand())
{
case NETWORK_COMMAND_GAMECMD:
case NETWORK_COMMAND_GAME_ACTION:
trafficGroup = NETWORK_STATISTICS_GROUP_COMMANDS;
break;

View File

@@ -52,8 +52,7 @@ enum NETWORK_COMMAND
NETWORK_COMMAND_AUTH,
NETWORK_COMMAND_MAP,
NETWORK_COMMAND_CHAT,
NETWORK_COMMAND_GAMECMD,
NETWORK_COMMAND_TICK,
NETWORK_COMMAND_TICK = 4,
NETWORK_COMMAND_PLAYERLIST,
NETWORK_COMMAND_PING,
NETWORK_COMMAND_PINGLIST,

View File

@@ -93,8 +93,6 @@ int32_t network_get_pickup_peep_old_x(uint8_t playerid);
void network_send_map();
void network_send_chat(const char* text);
void network_send_gamecmd(
uint32_t eax, uint32_t ebx, uint32_t ecx, uint32_t edx, uint32_t esi, uint32_t edi, uint32_t ebp, uint8_t callback);
void network_send_game_action(const GameAction* action);
void network_enqueue_game_action(const GameAction* action);
void network_send_password(const std::string& password);

View File

@@ -5222,7 +5222,7 @@ static void loc_6B51C0(const Ride* ride)
*/
static void ride_scroll_to_track_error(CoordsXYE* trackElement)
{
if (!gGameCommandIsNetworked && gUnk141F568 == gUnk13CA740)
if (gUnk141F568 == gUnk13CA740)
{
rct_window* w = window_get_main();
if (w != nullptr)

View File

@@ -2075,15 +2075,6 @@ static money32 place_maze_design(uint8_t flags, Ride* ride, uint16_t mazeEntry,
if (flags & GAME_COMMAND_FLAG_APPLY)
{
if (gGameCommandNestLevel == 1 && !(flags & GAME_COMMAND_FLAG_GHOST))
{
LocationXYZ16 coord;
coord.x = x + 8;
coord.y = y + 8;
coord.z = z;
network_set_player_last_action_coord(network_get_player_index(game_command_playerid), coord);
}
// Place track element
int32_t fx = floor2(x, 32);
int32_t fy = floor2(y, 32);