diff --git a/src/openrct2/actions/GameAction.cpp b/src/openrct2/actions/GameAction.cpp index 51c3175228..2b0bc1e174 100644 --- a/src/openrct2/actions/GameAction.cpp +++ b/src/openrct2/actions/GameAction.cpp @@ -475,7 +475,8 @@ namespace GameActions NetworkPlayerId_t playerId = action->GetPlayer(); int32_t playerIndex = network_get_player_index(playerId.id); - Guard::Assert(playerIndex != -1); + Guard::Assert( + playerIndex != -1, "Unable to find player %u for game action %u", playerId, action->GetType()); network_set_player_last_action(playerIndex, action->GetType()); if (result->Cost != 0) diff --git a/src/openrct2/core/Guard.hpp b/src/openrct2/core/Guard.hpp index a41572cf1a..7b72aa068b 100644 --- a/src/openrct2/core/Guard.hpp +++ b/src/openrct2/core/Guard.hpp @@ -68,6 +68,12 @@ namespace Guard Assert(argument >= min && argument <= max, message, args); va_end(args); } + + template static void IndexInRange(size_t index, const T& container) + { + Guard::Assert(index >= container.size(), "Index %zu out of bounds (%zu)", index, container.size()); + } + } // namespace Guard #define GUARD_LINE "Location: %s:%d", __func__, __LINE__ diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 5ad0703477..5f6889a955 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -3329,26 +3329,36 @@ int32_t network_get_num_players() const char* network_get_player_name(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return static_cast(gNetwork.player_list[index]->Name.c_str()); } uint32_t network_get_player_flags(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return gNetwork.player_list[index]->Flags; } int32_t network_get_player_ping(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return gNetwork.player_list[index]->Ping; } int32_t network_get_player_id(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return gNetwork.player_list[index]->Id; } money32 network_get_player_money_spent(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return gNetwork.player_list[index]->MoneySpent; } @@ -3374,11 +3384,15 @@ std::string network_get_player_public_key_hash(uint32_t id) void network_add_player_money_spent(uint32_t index, money32 cost) { + Guard::IndexInRange(index, gNetwork.player_list); + gNetwork.player_list[index]->AddMoneySpent(cost); } int32_t network_get_player_last_action(uint32_t index, int32_t time) { + Guard::IndexInRange(index, gNetwork.player_list); + if (time && platform_get_ticks() > gNetwork.player_list[index]->LastActionTime + time) { return -999; @@ -3388,17 +3402,23 @@ int32_t network_get_player_last_action(uint32_t index, int32_t time) void network_set_player_last_action(uint32_t index, int32_t command) { + Guard::IndexInRange(index, gNetwork.player_list); + gNetwork.player_list[index]->LastAction = NetworkActions::FindCommand(command); gNetwork.player_list[index]->LastActionTime = platform_get_ticks(); } CoordsXYZ network_get_player_last_action_coord(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return gNetwork.player_list[index]->LastActionCoord; } void network_set_player_last_action_coord(uint32_t index, const CoordsXYZ& coord) { + Guard::IndexInRange(index, gNetwork.player_list); + if (index < gNetwork.player_list.size()) { gNetwork.player_list[index]->LastActionCoord = coord; @@ -3407,6 +3427,8 @@ void network_set_player_last_action_coord(uint32_t index, const CoordsXYZ& coord uint32_t network_get_player_commands_ran(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return gNetwork.player_list[index]->CommandsRan; } @@ -3422,11 +3444,16 @@ int32_t network_get_player_index(uint32_t id) uint8_t network_get_player_group(uint32_t index) { + Guard::IndexInRange(index, gNetwork.player_list); + return gNetwork.player_list[index]->Group; } void network_set_player_group(uint32_t index, uint32_t groupindex) { + Guard::IndexInRange(index, gNetwork.player_list); + Guard::IndexInRange(groupindex, gNetwork.group_list); + gNetwork.player_list[index]->Group = gNetwork.group_list[groupindex]->Id; } @@ -3442,6 +3469,8 @@ int32_t network_get_group_index(uint8_t id) uint8_t network_get_group_id(uint32_t index) { + Guard::IndexInRange(index, gNetwork.group_list); + return gNetwork.group_list[index]->Id; } @@ -3728,11 +3757,15 @@ rct_string_id network_get_action_name_string_id(uint32_t index) int32_t network_can_perform_action(uint32_t groupindex, uint32_t index) { + Guard::IndexInRange(groupindex, gNetwork.group_list); + return gNetwork.group_list[groupindex]->CanPerformAction(index); } int32_t network_can_perform_command(uint32_t groupindex, int32_t index) { + Guard::IndexInRange(groupindex, gNetwork.group_list); + return gNetwork.group_list[groupindex]->CanPerformCommand(index); }