From 995d12479b349e44a7c21e9322b391eb0e69451c Mon Sep 17 00:00:00 2001 From: Cyp Date: Sat, 31 Mar 2012 20:34:15 +0200 Subject: [PATCH] Avoid orders given to tanks of wrong player. --- src/multibot.cpp | 10 ++++++++++ src/multigifts.cpp | 12 ++++++++++++ src/multijoin.cpp | 4 ++++ src/multiplay.cpp | 20 ++++++++++++++++++++ src/multiplay.h | 1 + src/multistruct.cpp | 10 ++++++++++ 6 files changed, 57 insertions(+) diff --git a/src/multibot.cpp b/src/multibot.cpp index dce212a07..daadaf434 100644 --- a/src/multibot.cpp +++ b/src/multibot.cpp @@ -217,6 +217,10 @@ bool recvDroidDisEmbark(NETQUEUE queue) debug(LOG_WARNING, "player's %d transport droid %d wasn't found?", player, transporterID); return false; } + if (!canGiveOrdersFor(queue.index, psTransporterDroid->player)) + { + return false; + } // we need to find the droid *in* the transporter psCheckDroid = psTransporterDroid ->psGroup->psList; while (psCheckDroid) @@ -585,6 +589,12 @@ bool recvDroidInfo(NETQUEUE queue) syncDebug("Droid %d missing", info.droidId); continue; // Can't find the droid, so skip this droid. } + if (!canGiveOrdersFor(queue.index, psDroid->player)) + { + debug(LOG_WARNING, "Droid order for wrong player."); + syncDebug("Wrong player."); + continue; + } CHECK_DROID(psDroid); diff --git a/src/multigifts.cpp b/src/multigifts.cpp index 3ff6ee115..7dc7949c7 100644 --- a/src/multigifts.cpp +++ b/src/multigifts.cpp @@ -79,6 +79,13 @@ bool recvGift(NETQUEUE queue) NETuint32_t(&droidID); NETend(); + if (!canGiveOrdersFor(queue.index, from)) + { + debug(LOG_WARNING, "Gift from wrong player."); + syncDebug("Wrong player."); + return false; + } + // Handle the gift depending on what it is switch (type) { @@ -490,6 +497,11 @@ bool recvAlliance(NETQUEUE queue, bool allowAudio) NETint32_t(&value); NETend(); + if (!canGiveOrdersFor(queue.index, from)) + { + return false; + } + switch (state) { case ALLIANCE_NULL: diff --git a/src/multijoin.cpp b/src/multijoin.cpp index c7a16a4f1..2d0ee6d5d 100644 --- a/src/multijoin.cpp +++ b/src/multijoin.cpp @@ -239,6 +239,10 @@ void recvPlayerLeft(NETQUEUE queue) NETbeginDecode(queue, GAME_PLAYER_LEFT); NETuint32_t(&playerIndex); NETend(); + if (queue.index == NET_HOST_ONLY || queue.index == playerIndex) + { + return; + } turnOffMultiMsg(true); clearPlayer(playerIndex, false); // don't do it quietly diff --git a/src/multiplay.cpp b/src/multiplay.cpp index cef9a12fd..a8b5e0658 100644 --- a/src/multiplay.cpp +++ b/src/multiplay.cpp @@ -500,6 +500,12 @@ bool responsibleFor(int player, int playerinquestion) return whosResponsible(playerinquestion) == player; } +bool canGiveOrdersFor(int player, int playerInQuestion) +{ + return playerInQuestion >= 0 && playerInQuestion < MAX_PLAYERS && + (player == playerInQuestion || responsibleFor(player, playerInQuestion) || getDebugMappingStatus()); +} + int scavengerSlot() { // Scavengers used to always be in position 7, when scavengers were only supported in less than 8 player maps. @@ -935,6 +941,12 @@ bool recvResearchStatus(NETQUEUE queue) debug(LOG_ERROR, "Bad GAME_RESEARCHSTATUS received, player is %d, index is %u", (int)player, index); return false; } + if (!canGiveOrdersFor(queue.index, player)) + { + debug(LOG_WARNING, "Droid order for wrong player."); + syncDebug("Wrong player."); + return false; + } int prevResearchState = 0; if (aiCheckAlliances(selectedPlayer, player)) @@ -1421,6 +1433,10 @@ bool recvTemplate(NETQUEUE queue) NETtemplate(&t); NETend(); + if (!canGiveOrdersFor(queue.index, player)) + { + return false; + } t.prefab = false; t.psNext = NULL; @@ -1474,6 +1490,10 @@ static bool recvDestroyTemplate(NETQUEUE queue) NETuint8_t(&player); NETuint32_t(&templateID); NETend(); + if (!canGiveOrdersFor(queue.index, player)) + { + return false; + } ASSERT_OR_RETURN(false, player < MAX_PLAYERS, "invalid player size: %d", player); diff --git a/src/multiplay.h b/src/multiplay.h index a7c8bb81c..a00a05a56 100644 --- a/src/multiplay.h +++ b/src/multiplay.h @@ -153,6 +153,7 @@ extern bool isHumanPlayer(int player); //to tell if the player is a computer extern bool myResponsibility(int player); extern bool responsibleFor(int player, int playerinquestion); extern int whosResponsible(int player); +bool canGiveOrdersFor(int player, int playerInQuestion); int scavengerSlot(); // Returns the player number that scavengers would have if they were enabled. int scavengerPlayer(); // Returns the player number that the scavengers have, or -1 if disabled. extern Vector3i cameraToHome (UDWORD player,bool scroll); diff --git a/src/multistruct.cpp b/src/multistruct.cpp index c0f032b0f..d28f24f63 100644 --- a/src/multistruct.cpp +++ b/src/multistruct.cpp @@ -236,6 +236,11 @@ bool recvLasSat(NETQUEUE queue) psStruct = IdToStruct (id, player); psObj = IdToPointer(targetid, targetplayer); + if (psStruct && !canGiveOrdersFor(queue.index, psStruct->player)) + { + syncDebug("Wrong player."); + return !"Meow"; // Return value meaningless and ignored. + } if (psStruct && psObj && psStruct->pStructureType->psWeapStat[0]->weaponSubClass == WSC_LAS_SAT) { @@ -321,6 +326,11 @@ void recvStructureInfo(NETQUEUE queue) debug(LOG_SYNC, "Couldn't find structure %u to change production.", structId); return; } + if (!canGiveOrdersFor(queue.index, psStruct->player)) + { + syncDebug("Wrong player."); + return; + } CHECK_STRUCTURE(psStruct);