1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Attempt to fix data raced in battle on server

This commit is contained in:
Ivan Savenko 2023-08-07 17:03:39 +03:00
parent b167aeafd8
commit d7cbe4ecde

View File

@ -40,6 +40,7 @@
#include "../lib/CCreatureHandler.h"
#include "../lib/gameState/CGameState.h"
#include "../lib/CStack.h"
#include "../lib/UnlockGuard.h"
#include "../lib/GameSettings.h"
#include "../lib/battle/BattleInfo.h"
#include "../lib/CondSh.h"
@ -76,6 +77,7 @@
#define COMPLAIN_RETF(txt, FORMAT) {complain(boost::str(boost::format(txt) % FORMAT)); return false;}
CondSh<bool> battleMadeAction(false);
boost::recursive_mutex battleActionMutex;
CondSh<BattleResult *> battleResult(nullptr);
template <typename T> class CApplyOnGH;
@ -4394,6 +4396,8 @@ void CGameHandler::updateGateState()
bool CGameHandler::makeBattleAction(BattleAction &ba)
{
boost::unique_lock lock(battleActionMutex);
bool ok = true;
battle::Target target = ba.getTarget(gs->curB);
@ -4817,6 +4821,8 @@ bool CGameHandler::makeBattleAction(BattleAction &ba)
bool CGameHandler::makeCustomAction(BattleAction & ba)
{
boost::unique_lock lock(battleActionMutex);
switch(ba.actionType)
{
case EActionType::HERO_SPELL:
@ -6048,6 +6054,8 @@ bool CGameHandler::swapStacks(const StackLocation & sl1, const StackLocation & s
void CGameHandler::runBattle()
{
boost::unique_lock lock(battleActionMutex);
setBattle(gs->curB);
assert(gs->curB);
//TODO: pre-tactic stuff, call scripts etc.
@ -6066,7 +6074,10 @@ void CGameHandler::runBattle()
//tactic round
{
while ((lobby->state != EServerState::SHUTDOWN) && gs->curB->tacticDistance && !battleResult.get())
{
auto unlockGuard = vstd::makeUnlockGuard(battleActionMutex);
boost::this_thread::sleep(boost::posix_time::milliseconds(50));
}
}
//initial stacks appearance triggers, e.g. built-in bonus spells
@ -6389,7 +6400,10 @@ void CGameHandler::runBattle()
battleMadeAction.data = false;
while ((lobby->state != EServerState::SHUTDOWN) && !actionWasMade())
{
battleMadeAction.cond.wait(lock);
{
auto unlockGuard = vstd::makeUnlockGuard(battleActionMutex);
battleMadeAction.cond.wait(lock);
}
if (battleGetStackByID(nextId, false) != next)
next = nullptr; //it may be removed, while we wait
}