From 9a42abe2a7f8d46cb2346629f552be042432bdc8 Mon Sep 17 00:00:00 2001 From: nordsoft Date: Wed, 30 Aug 2023 03:11:46 +0400 Subject: [PATCH] Extended timer info to exhange between client and server --- client/CPlayerInterface.cpp | 9 --- client/CPlayerInterface.h | 3 - client/adventureMap/TurnTimerWidget.cpp | 24 +++---- lib/TurnTimerInfo.h | 5 ++ server/TurnTimerHandler.cpp | 96 ++++++++++++------------- server/TurnTimerHandler.h | 13 +--- 6 files changed, 67 insertions(+), 83 deletions(-) diff --git a/client/CPlayerInterface.cpp b/client/CPlayerInterface.cpp index fa035e9e2..79cef66f6 100644 --- a/client/CPlayerInterface.cpp +++ b/client/CPlayerInterface.cpp @@ -140,7 +140,6 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player): firstCall = 1; //if loading will be overwritten in serialize autosaveCount = 0; isAutoFightOn = false; - timerEnabled = true; duringMovement = false; ignoreEvents = false; numOfMovedArts = 0; @@ -272,8 +271,6 @@ void CPlayerInterface::yourTurn(QueryID queryID) makingTurn = true; adventureInt->onPlayerTurnStarted(playerID); } - - timerEnabled = false; } acceptTurn(queryID); } @@ -326,7 +323,6 @@ void CPlayerInterface::acceptTurn(QueryID queryID) } cb->selectionMade(0, queryID); - timerEnabled = true; } void CPlayerInterface::heroMoved(const TryMoveHero & details, bool verbose) @@ -2127,8 +2123,3 @@ std::optional CPlayerInterface::makeSurrenderRetreatDecision(const { return std::nullopt; } - -bool CPlayerInterface::isTimerEnabled() const -{ - return timerEnabled; -} diff --git a/client/CPlayerInterface.h b/client/CPlayerInterface.h index 157158a71..c5048637f 100644 --- a/client/CPlayerInterface.h +++ b/client/CPlayerInterface.h @@ -57,7 +57,6 @@ namespace boost /// Central class for managing user interface logic class CPlayerInterface : public CGameInterface, public IUpdateable { - bool timerEnabled; bool duringMovement; bool ignoreEvents; size_t numOfMovedArts; @@ -207,8 +206,6 @@ public: // public interface for use by client via LOCPLINT access ///returns true if all events are processed internally bool capturedAllEvents(); - - bool isTimerEnabled() const; CPlayerInterface(PlayerColor Player); ~CPlayerInterface(); diff --git a/client/adventureMap/TurnTimerWidget.cpp b/client/adventureMap/TurnTimerWidget.cpp index 88b1ccd08..bd9606d62 100644 --- a/client/adventureMap/TurnTimerWidget.cpp +++ b/client/adventureMap/TurnTimerWidget.cpp @@ -102,22 +102,27 @@ void TurnTimerWidget::tick(uint32_t msPassed) if(!LOCPLINT || !LOCPLINT->cb) return; - for (PlayerColor p(0); p < PlayerColor::PLAYER_LIMIT; ++p) + for(PlayerColor p(0); p < PlayerColor::PLAYER_LIMIT; ++p) { auto player = p; if(LOCPLINT->battleInt) { if(auto * stack = LOCPLINT->battleInt->stacksController->getActiveStack()) player = stack->getOwner(); + else + continue; + if(p != player) + continue; } - - if(p != player || !LOCPLINT->cb->isPlayerMakingTurn(player)) + else if(!LOCPLINT->cb->isPlayerMakingTurn(player)) continue; auto time = LOCPLINT->cb->getPlayerTurnTime(player); - if(LOCPLINT->isTimerEnabled()) + if(time.isActive) cachedTurnTime -= msPassed; - if(cachedTurnTime < 0) cachedTurnTime = 0; //do not go below zero + + if(cachedTurnTime < 0) + cachedTurnTime = 0; //do not go below zero if(lastPlayer != player) { @@ -140,15 +145,10 @@ void TurnTimerWidget::tick(uint32_t msPassed) auto * playerInfo = LOCPLINT->cb->getPlayer(player); if(player.isValidPlayer() || (playerInfo && playerInfo->isHuman())) { - if(LOCPLINT->battleInt) - { - if(time.isBattleEnabled()) - timeCheckAndUpdate(time.creatureTimer); - } + if(time.isBattle) + timeCheckAndUpdate(time.creatureTimer); else - { timeCheckAndUpdate(time.turnTimer); - } } else timeCheckAndUpdate(0); diff --git a/lib/TurnTimerInfo.h b/lib/TurnTimerInfo.h index f29530726..843e0c0de 100644 --- a/lib/TurnTimerInfo.h +++ b/lib/TurnTimerInfo.h @@ -19,6 +19,9 @@ struct DLL_LINKAGE TurnTimerInfo int battleTimer = 0; //in ms, counts down during battles when creature timer runs out int creatureTimer = 0; //in ms, counts down when player is choosing action in battle + bool isActive = true; //should be paused if set to false + bool isBattle = false; //indicator for current timer mode + bool isEnabled() const; bool isBattleEnabled() const; @@ -29,6 +32,8 @@ struct DLL_LINKAGE TurnTimerInfo h & baseTimer; h & battleTimer; h & creatureTimer; + h & isActive; + h & isBattle; } }; diff --git a/server/TurnTimerHandler.cpp b/server/TurnTimerHandler.cpp index 936b2926b..7473b2f8c 100644 --- a/server/TurnTimerHandler.cpp +++ b/server/TurnTimerHandler.cpp @@ -31,11 +31,11 @@ void TurnTimerHandler::onGameplayStart(PlayerColor player) std::lock_guard guard(mx); if(const auto * si = gameHandler.getStartInfo()) { - timerInfo[player].timer = si->turnTimerInfo; - timerInfo[player].timer.turnTimer = 0; - timerInfo[player].isEnabled = true; - timerInfo[player].isBattle = false; - timerInfo[player].lastUpdate = std::numeric_limits::max(); + timers[player] = si->turnTimerInfo; + timers[player].turnTimer = 0; + timers[player].isActive = true; + timers[player].isBattle = false; + lastUpdate[player] = std::numeric_limits::max(); } } @@ -43,17 +43,16 @@ void TurnTimerHandler::setTimerEnabled(PlayerColor player, bool enabled) { std::lock_guard guard(mx); assert(player.isValidPlayer()); - timerInfo[player].isEnabled = enabled; + timers[player].isActive = enabled; } void TurnTimerHandler::sendTimerUpdate(PlayerColor player) { - auto & info = timerInfo[player]; TurnTimeUpdate ttu; ttu.player = player; - ttu.turnTimer = info.timer; + ttu.turnTimer = timers[player]; gameHandler.sendAndApply(&ttu); - info.lastUpdate = 0; + lastUpdate[player] = 0; } void TurnTimerHandler::onPlayerGetTurn(PlayerColor player) @@ -63,10 +62,10 @@ void TurnTimerHandler::onPlayerGetTurn(PlayerColor player) { if(si->turnTimerInfo.isEnabled()) { - auto & info = timerInfo[player]; + auto & timer = timers[player]; if(si->turnTimerInfo.baseTimer > 0) - info.timer.baseTimer += info.timer.turnTimer; - info.timer.turnTimer = si->turnTimerInfo.turnTimer; + timer.baseTimer += timer.turnTimer; + timer.turnTimer = si->turnTimerInfo.turnTimer; sendTimerUpdate(player); } @@ -91,14 +90,13 @@ bool TurnTimerHandler::timerCountDown(int & timer, int initialTimer, PlayerColor { if(timer > 0) { - auto & info = timerInfo[player]; timer -= waitTime; - info.lastUpdate += waitTime; + lastUpdate[player] += waitTime; int frequency = (timer > turnTimePropagateThreshold && initialTimer - timer > turnTimePropagateThreshold) ? turnTimePropagateFrequency : turnTimePropagateFrequencyCrit; - if(info.lastUpdate >= frequency) + if(lastUpdate[player] >= frequency) sendTimerUpdate(player); return true; @@ -114,16 +112,16 @@ void TurnTimerHandler::onPlayerMakingTurn(PlayerColor player, int waitTime) if(!si || !gs || !si->turnTimerInfo.isEnabled()) return; - auto & info = timerInfo[player]; + auto & timer = timers[player]; const auto * state = gameHandler.getPlayerState(player); - if(state && state->human && info.isEnabled && !info.isBattle && state->status == EPlayerStatus::INGAME) + if(state && state->human && timer.isActive && !timer.isBattle && state->status == EPlayerStatus::INGAME) { - if(!timerCountDown(info.timer.turnTimer, si->turnTimerInfo.turnTimer, player, waitTime)) + if(!timerCountDown(timer.turnTimer, si->turnTimerInfo.turnTimer, player, waitTime)) { - if(info.timer.baseTimer > 0) + if(timer.baseTimer > 0) { - info.timer.turnTimer = info.timer.baseTimer; - info.timer.baseTimer = 0; + timer.turnTimer = timer.baseTimer; + timer.baseTimer = 0; onPlayerMakingTurn(player, 0); } else if(!gameHandler.queries->topQuery(state->color)) //wait for replies to avoid pending queries @@ -164,10 +162,10 @@ void TurnTimerHandler::onBattleStart() { if(i.isValidPlayer()) { - auto & info = timerInfo[i]; - info.isBattle = true; - info.timer.battleTimer = (pvpBattle ? si->turnTimerInfo.battleTimer : 0); - info.timer.creatureTimer = (pvpBattle ? si->turnTimerInfo.creatureTimer : si->turnTimerInfo.battleTimer); + auto & timer = timers[i]; + timer.isBattle = true; + timer.battleTimer = (pvpBattle ? si->turnTimerInfo.battleTimer : 0); + timer.creatureTimer = (pvpBattle ? si->turnTimerInfo.creatureTimer : si->turnTimerInfo.battleTimer); sendTimerUpdate(i); } @@ -191,12 +189,12 @@ void TurnTimerHandler::onBattleEnd() { if(i.isValidPlayer() && !pvpBattle) { - auto & info = timerInfo[i]; - info.isBattle = false; - if(si->turnTimerInfo.baseTimer && info.timer.baseTimer == 0) - info.timer.baseTimer = info.timer.creatureTimer; - else if(si->turnTimerInfo.turnTimer && info.timer.turnTimer == 0) - info.timer.turnTimer = info.timer.creatureTimer; + auto & timer = timers[i]; + timer.isBattle = false; + if(si->turnTimerInfo.baseTimer && timer.baseTimer == 0) + timer.baseTimer = timer.creatureTimer; + else if(si->turnTimerInfo.turnTimer && timer.turnTimer == 0) + timer.turnTimer = timer.creatureTimer; sendTimerUpdate(i); } @@ -215,10 +213,10 @@ void TurnTimerHandler::onBattleNextStack(const CStack & stack) { auto player = stack.getOwner(); - auto & info = timerInfo[player]; - if(info.timer.battleTimer == 0) - info.timer.battleTimer = info.timer.creatureTimer; - info.timer.creatureTimer = si->turnTimerInfo.creatureTimer; + auto & timer = timers[player]; + if(timer.battleTimer == 0) + timer.battleTimer = timer.creatureTimer; + timer.creatureTimer = si->turnTimerInfo.creatureTimer; sendTimerUpdate(player); } @@ -254,16 +252,16 @@ void TurnTimerHandler::onBattleLoop(int waitTime) if(!state || state->status != EPlayerStatus::INGAME || !state->human) return; - auto & info = timerInfo[player]; - if(info.isEnabled && info.isBattle && !timerCountDown(info.timer.creatureTimer, si->turnTimerInfo.creatureTimer, player, waitTime)) + auto & timer = timers[player]; + if(timer.isActive && timer.isBattle && !timerCountDown(timer.creatureTimer, si->turnTimerInfo.creatureTimer, player, waitTime)) { if(isPvpBattle()) { - if(info.timer.battleTimer > 0) + if(timer.battleTimer > 0) { - info.timer.creatureTimer = info.timer.battleTimer; - timerCountDown(info.timer.creatureTimer, info.timer.battleTimer, player, 0); - info.timer.battleTimer = 0; + timer.creatureTimer = timer.battleTimer; + timerCountDown(timer.creatureTimer, timer.battleTimer, player, 0); + timer.battleTimer = 0; } else { @@ -281,17 +279,17 @@ void TurnTimerHandler::onBattleLoop(int waitTime) } else { - if(info.timer.turnTimer > 0) + if(timer.turnTimer > 0) { - info.timer.creatureTimer = info.timer.turnTimer; - timerCountDown(info.timer.creatureTimer, info.timer.turnTimer, player, 0); - info.timer.turnTimer = 0; + timer.creatureTimer = timer.turnTimer; + timerCountDown(timer.creatureTimer, timer.turnTimer, player, 0); + timer.turnTimer = 0; } - else if(info.timer.baseTimer > 0) + else if(timer.baseTimer > 0) { - info.timer.creatureTimer = info.timer.baseTimer; - timerCountDown(info.timer.creatureTimer, info.timer.baseTimer, player, 0); - info.timer.baseTimer = 0; + timer.creatureTimer = timer.baseTimer; + timerCountDown(timer.creatureTimer, timer.baseTimer, player, 0); + timer.baseTimer = 0; } else { diff --git a/server/TurnTimerHandler.h b/server/TurnTimerHandler.h index cdbcb6ca3..5039dc07b 100644 --- a/server/TurnTimerHandler.h +++ b/server/TurnTimerHandler.h @@ -22,20 +22,13 @@ VCMI_LIB_NAMESPACE_END class CGameHandler; class TurnTimerHandler -{ - struct PlayerTimerInfo - { - TurnTimerInfo timer; - bool isEnabled = true; - bool isBattle = false; - int lastUpdate = 0; - }; - +{ CGameHandler & gameHandler; const int turnTimePropagateFrequency = 5000; const int turnTimePropagateFrequencyCrit = 1000; const int turnTimePropagateThreshold = 3000; - std::map timerInfo; + std::map timers; + std::map lastUpdate; std::recursive_mutex mx; void onPlayerMakingTurn(PlayerColor player, int waitTime);