From e4c6c795525457ac7a1aeafbedc1d7d472832bb2 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 5 Jan 2016 18:30:39 +0000 Subject: [PATCH] fix #2650: validate game commands sent from clients in multiplayer --- distribution/changelog.txt | 1 + src/game.c | 2 +- src/network/network.cpp | 7 +++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/distribution/changelog.txt b/distribution/changelog.txt index dc24bc75c6..89d5017616 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -9,6 +9,7 @@ - Feature: Integrate RCT1 style scenario select with optional unlock progression. - Fix: [#2126] Ferris Wheels set to "backward rotation" stop working (original bug) - Fix: [#2449] Turning off Day/Night Circle while it is night doesn't reset back to day +- Fix: [#2650] Server did not validate actions send from clients (caused error box and desynchronisation) 0.0.3.1-beta (2015-12-04) ------------------------------------------------------------------------ diff --git a/src/game.c b/src/game.c index 294dacae7b..2fd5066c5f 100644 --- a/src/game.c +++ b/src/game.c @@ -543,7 +543,7 @@ int game_do_command_p(int command, int *eax, int *ebx, int *ecx, int *edx, int * RCT2_GLOBAL(0x009A8C28, uint8)--; // Show error window - if (RCT2_GLOBAL(0x009A8C28, uint8) == 0 && (flags & GAME_COMMAND_FLAG_APPLY) && RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8) && !(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED)) + if (RCT2_GLOBAL(0x009A8C28, uint8) == 0 && (flags & GAME_COMMAND_FLAG_APPLY) && RCT2_GLOBAL(0x0141F568, uint8) == RCT2_GLOBAL(0x013CA740, uint8) && !(flags & GAME_COMMAND_FLAG_ALLOW_DURING_PAUSED) && !(flags & GAME_COMMAND_FLAG_NETWORKED)) window_error_open(RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TITLE, uint16), RCT2_GLOBAL(RCT2_ADDRESS_GAME_COMMAND_ERROR_TEXT, uint16)); return MONEY32_UNDEFINED; diff --git a/src/network/network.cpp b/src/network/network.cpp index d3e65468b6..1754518530 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -1415,8 +1415,11 @@ int Network::Server_Handle_GAMECMD(NetworkConnection& connection, NetworkPacket& if (commandCommand != GAME_COMMAND_TOGGLE_PAUSE && commandCommand != GAME_COMMAND_LOAD_OR_QUIT ) { - Server_Send_GAMECMD(args[0], args[1], args[2], args[3], args[4], args[5], args[6], playerid, callback); - game_do_command(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); + // Run game command, and if it is successful send to clients + money32 cost = game_do_command(args[0], args[1] | GAME_COMMAND_FLAG_NETWORKED, args[2], args[3], args[4], args[5], args[6]); + if (cost != MONEY32_UNDEFINED) { + Server_Send_GAMECMD(args[0], args[1], args[2], args[3], args[4], args[5], args[6], playerid, callback); + } } return 1;