瀏覽代碼

change servercode to make it more robust

Michael 2 年之前
父節點
當前提交
1d76f456ad
共有 6 個文件被更改,包括 80 次插入10 次删除
  1. 4 2
      client/CServerHandler.cpp
  2. 2 2
      client/CServerHandler.h
  3. 3 3
      lib/NetPacksLobby.h
  4. 56 0
      server/CVCMIServer.cpp
  5. 3 0
      server/CVCMIServer.h
  6. 12 3
      server/NetPacksLobbyServer.cpp

+ 4 - 2
client/CServerHandler.cpp

@@ -86,6 +86,8 @@ template<typename T> class CApplyOnLobby : public CBaseForLobbyApply
 public:
 	bool applyOnLobbyHandler(CServerHandler * handler, void * pack) const override
 	{
+		boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
+
 		T * ptr = static_cast<T *>(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);
 }

+ 2 - 2
client/CServerHandler.h

@@ -62,7 +62,7 @@ public:
 	virtual void setCampaignBonus(int bonusId) const = 0;
 	virtual void setMapInfo(std::shared_ptr<CMapInfo> to, std::shared_ptr<CMapGenOptions> 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<CMapInfo> to, std::shared_ptr<CMapGenOptions> 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;

+ 3 - 3
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 <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & what;
-		h & direction;
+		h & value;
 		h & color;
 	}
 };

+ 56 - 0
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<FactionID>(id)) == allowed.end() && id != PlayerSettings::RANDOM) // valid id
+		return;
+
+	cur = static_cast<FactionID>(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<HeroTypeID>(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<PlayerSettings::Ebonus>(static_cast<int>(id));
+}
+
 bool CVCMIServer::canUseThisHero(PlayerColor player, int ID)
 {
 	return VLC->heroh->size() > ID

+ 3 - 0
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<int> 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);

+ 12 - 3
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;
 	}