From 1d76f456ad5d8660073dfbfb24e1bae596a8d8cb Mon Sep 17 00:00:00 2001 From: Michael <13953785+Laserlicht@users.noreply.github.com> Date: Mon, 14 Aug 2023 00:08:48 +0200 Subject: [PATCH] change servercode to make it more robust --- client/CServerHandler.cpp | 6 ++-- client/CServerHandler.h | 4 +-- lib/NetPacksLobby.h | 6 ++-- server/CVCMIServer.cpp | 56 ++++++++++++++++++++++++++++++++++ server/CVCMIServer.h | 3 ++ server/NetPacksLobbyServer.cpp | 15 +++++++-- 6 files changed, 80 insertions(+), 10 deletions(-) diff --git a/client/CServerHandler.cpp b/client/CServerHandler.cpp index 112af7f6c..e73ad9863 100644 --- a/client/CServerHandler.cpp +++ b/client/CServerHandler.cpp @@ -86,6 +86,8 @@ template class CApplyOnLobby : public CBaseForLobbyApply public: bool applyOnLobbyHandler(CServerHandler * handler, void * pack) const override { + boost::unique_lock un(*CPlayerInterface::pim); + T * ptr = static_cast(pack); ApplyOnLobbyHandlerNetPackVisitor visitor(*handler); @@ -454,11 +456,11 @@ void CServerHandler::setPlayer(PlayerColor color) const sendLobbyPack(lsp); } -void CServerHandler::setPlayerOption(ui8 what, si8 dir, PlayerColor player) const +void CServerHandler::setPlayerOption(ui8 what, si16 value, PlayerColor player) const { LobbyChangePlayerOption lcpo; lcpo.what = what; - lcpo.direction = dir; + lcpo.value = value; lcpo.color = player; sendLobbyPack(lcpo); } diff --git a/client/CServerHandler.h b/client/CServerHandler.h index e8b20117d..394599c60 100644 --- a/client/CServerHandler.h +++ b/client/CServerHandler.h @@ -62,7 +62,7 @@ public: virtual void setCampaignBonus(int bonusId) const = 0; virtual void setMapInfo(std::shared_ptr to, std::shared_ptr mapGenOpts = {}) const = 0; virtual void setPlayer(PlayerColor color) const = 0; - virtual void setPlayerOption(ui8 what, si8 dir, PlayerColor player) const = 0; + virtual void setPlayerOption(ui8 what, si16 value, PlayerColor player) const = 0; virtual void setDifficulty(int to) const = 0; virtual void setTurnLength(int npos) const = 0; virtual void sendMessage(const std::string & txt) const = 0; @@ -140,7 +140,7 @@ public: void setCampaignBonus(int bonusId) const override; void setMapInfo(std::shared_ptr to, std::shared_ptr mapGenOpts = {}) const override; void setPlayer(PlayerColor color) const override; - void setPlayerOption(ui8 what, si8 dir, PlayerColor player) const override; + void setPlayerOption(ui8 what, si16 value, PlayerColor player) const override; void setDifficulty(int to) const override; void setTurnLength(int npos) const override; void sendMessage(const std::string & txt) const override; diff --git a/lib/NetPacksLobby.h b/lib/NetPacksLobby.h index 47cad0e7f..6fce191c2 100644 --- a/lib/NetPacksLobby.h +++ b/lib/NetPacksLobby.h @@ -211,9 +211,9 @@ struct DLL_LINKAGE LobbySetCampaignBonus : public CLobbyPackToServer struct DLL_LINKAGE LobbyChangePlayerOption : public CLobbyPackToServer { - enum EWhat : ui8 {UNKNOWN, TOWN, HERO, BONUS}; + enum EWhat : ui8 {UNKNOWN, TOWN, HERO, BONUS, TOWN_ID, HERO_ID, BONUS_ID}; ui8 what = UNKNOWN; - si8 direction = 0; //-1 or +1 + si16 value = 0; //-1 or +1 PlayerColor color = PlayerColor::CANNOT_DETERMINE; virtual void visitTyped(ICPackVisitor & visitor) override; @@ -221,7 +221,7 @@ struct DLL_LINKAGE LobbyChangePlayerOption : public CLobbyPackToServer template void serialize(Handler &h, const int version) { h & what; - h & direction; + h & value; h & color; } }; diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index 0fa101ad0..16e9ae9d3 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -837,6 +837,28 @@ void CVCMIServer::optionNextCastle(PlayerColor player, int dir) s.bonus = PlayerSettings::RANDOM; } +void CVCMIServer::optionSetCastle(PlayerColor player, int id) +{ + PlayerSettings & s = si->playerInfos[player]; + FactionID & cur = s.castle; + auto & allowed = getPlayerInfo(player.getNum()).allowedFactions; + + if(cur == PlayerSettings::NONE) //no change + return; + + if(allowed.find(static_cast(id)) == allowed.end() && id != PlayerSettings::RANDOM) // valid id + return; + + cur = static_cast(id); + + if(s.hero >= 0 && !getPlayerInfo(player.getNum()).hasCustomMainHero()) // remove hero unless it set to fixed one in map editor + { + s.hero = PlayerSettings::RANDOM; + } + if(cur < 0 && s.bonus == PlayerSettings::RESOURCE) + s.bonus = PlayerSettings::RANDOM; +} + void CVCMIServer::setCampaignMap(CampaignScenarioID mapId) { campaignMap = mapId; @@ -884,6 +906,20 @@ void CVCMIServer::optionNextHero(PlayerColor player, int dir) } } +void CVCMIServer::optionSetHero(PlayerColor player, int id) +{ + PlayerSettings & s = si->playerInfos[player]; + if(s.castle < 0 || s.hero == PlayerSettings::NONE) + return; + + if(id == PlayerSettings::RANDOM) + { + s.hero = PlayerSettings::RANDOM; + } + if(canUseThisHero(player, id)) + s.hero = static_cast(id); +} + int CVCMIServer::nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir) { if(dir > 0) @@ -930,6 +966,26 @@ void CVCMIServer::optionNextBonus(PlayerColor player, int dir) } } +void CVCMIServer::optionSetBonus(PlayerColor player, int id) +{ + PlayerSettings & s = si->playerInfos[player]; + + if(s.hero == PlayerSettings::NONE && + !getPlayerInfo(player.getNum()).heroesNames.size() && + id == PlayerSettings::ARTIFACT) //no hero - can't be artifact + return; + + if(id > PlayerSettings::RESOURCE) + return; + if(id < PlayerSettings::RANDOM) + return; + + if(s.castle == PlayerSettings::RANDOM && id == PlayerSettings::RESOURCE) //random castle - can't be resource + return; + + s.bonus = static_cast(static_cast(id)); +} + bool CVCMIServer::canUseThisHero(PlayerColor player, int ID) { return VLC->heroh->size() > ID diff --git a/server/CVCMIServer.h b/server/CVCMIServer.h index 285bcd440..5ecd942d5 100644 --- a/server/CVCMIServer.h +++ b/server/CVCMIServer.h @@ -104,11 +104,14 @@ public: // Work with LobbyInfo void setPlayer(PlayerColor clickedColor); void optionNextHero(PlayerColor player, int dir); //dir == -1 or +1 + void optionSetHero(PlayerColor player, int id); int nextAllowedHero(PlayerColor player, int min, int max, int incl, int dir); bool canUseThisHero(PlayerColor player, int ID); std::vector getUsedHeroes(); void optionNextBonus(PlayerColor player, int dir); //dir == -1 or +1 + void optionSetBonus(PlayerColor player, int id); void optionNextCastle(PlayerColor player, int dir); //dir == -1 or + + void optionSetCastle(PlayerColor player, int id); // Campaigns void setCampaignMap(CampaignScenarioID mapId); diff --git a/server/NetPacksLobbyServer.cpp b/server/NetPacksLobbyServer.cpp index c9ead03b5..eaca04f8c 100644 --- a/server/NetPacksLobbyServer.cpp +++ b/server/NetPacksLobbyServer.cpp @@ -360,14 +360,23 @@ void ApplyOnServerNetPackVisitor::visitLobbyChangePlayerOption(LobbyChangePlayer { switch(pack.what) { + case LobbyChangePlayerOption::TOWN_ID: + srv.optionSetCastle(pack.color, pack.value); + break; case LobbyChangePlayerOption::TOWN: - srv.optionNextCastle(pack.color, pack.direction); + srv.optionNextCastle(pack.color, pack.value); + break; + case LobbyChangePlayerOption::HERO_ID: + srv.optionSetHero(pack.color, pack.value); break; case LobbyChangePlayerOption::HERO: - srv.optionNextHero(pack.color, pack.direction); + srv.optionNextHero(pack.color, pack.value); + break; + case LobbyChangePlayerOption::BONUS_ID: + srv.optionSetBonus(pack.color, pack.value); break; case LobbyChangePlayerOption::BONUS: - srv.optionNextBonus(pack.color, pack.direction); + srv.optionNextBonus(pack.color, pack.value); break; }