浏览代码

Moved battle netpack validation to battle processor

Ivan Savenko 2 年之前
父节点
当前提交
5c78060a07
共有 3 个文件被更改,包括 86 次插入42 次删除
  1. 6 36
      server/NetPacksServer.cpp
  2. 75 4
      server/battles/BattleProcessor.cpp
  3. 5 2
      server/battles/BattleProcessor.h

+ 6 - 36
server/NetPacksServer.cpp

@@ -282,48 +282,18 @@ void ApplyGhNetPackVisitor::visitQueryReply(QueryReply & pack)
 
 void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
 {
-	const BattleInfo * b = gs.curB;
-	if(!b)
-		gh.throwAndComplain(&pack, "Can not make action - there is no battle ongoing!");
-
-	if(b->tacticDistance)
-	{
-		if(pack.ba.actionType != EActionType::WALK && pack.ba.actionType != EActionType::END_TACTIC_PHASE
-			&& pack.ba.actionType != EActionType::RETREAT && pack.ba.actionType != EActionType::SURRENDER)
-			gh.throwAndComplain(&pack, "Can not make actions while in tactics mode!");
-		if(!vstd::contains(gh.connections[b->sides[b->tacticsSide].color], pack.c))
-			gh.throwAndComplain(&pack, "Can not make actions in battles you are not part of!");
-	}
-	else
-	{
-		auto active = b->battleActiveUnit();
-		if(!active)
-			gh.throwAndComplain(&pack, "No active unit in battle!");
-		auto unitOwner = b->battleGetOwner(active);
-		if(!vstd::contains(gh.connections[unitOwner], pack.c))
-			gh.throwAndComplain(&pack, "Can not make actions in battles you are not part of!");
-	}
+	if (!gh.hasPlayerAt(pack.player, pack.c))
+		gh.throwAndComplain(&pack, "No such pack.player!");
 
-	result = gh.battles->makeBattleAction(pack.ba);
+	result = gh.battles->makeBattleAction(pack.player, pack.ba);
 }
 
 void ApplyGhNetPackVisitor::visitMakeCustomAction(MakeCustomAction & pack)
 {
-	const BattleInfo * b = gs.curB;
-	if(!b)
-		gh.throwNotAllowedAction(&pack);
-	if(b->tacticDistance)
-		gh.throwNotAllowedAction(&pack);
-	auto active = b->battleActiveUnit();
-	if(!active)
-		gh.throwNotAllowedAction(&pack);
-	auto unitOwner = b->battleGetOwner(active);
-	if(!vstd::contains(gh.connections[unitOwner], pack.c))
-		gh.throwNotAllowedAction(&pack);
-	if(pack.ba.actionType != EActionType::HERO_SPELL)
-		gh.throwNotAllowedAction(&pack);
+	if (!gh.hasPlayerAt(pack.player, pack.c))
+		gh.throwAndComplain(&pack, "No such pack.player!");
 
-	result = gh.battles->makeCustomAction(pack.ba);
+	result = gh.battles->makeCustomAction(pack.player, pack.ba);
 }
 
 void ApplyGhNetPackVisitor::visitDigWithHero(DigWithHero & pack)

+ 75 - 4
server/battles/BattleProcessor.cpp

@@ -349,7 +349,6 @@ void BattleProcessor::startBattlePrimary(const CArmedInstance *army1, const CArm
 	heroes[0] = hero1;
 	heroes[1] = hero2;
 
-
 	setupBattle(tile, armies, heroes, creatureBank, town); //initializes stacks, places creatures on battlefield, blocks and informs player interfaces
 
 	auto lastBattleQuery = std::dynamic_pointer_cast<CBattleQuery>(gameHandler->queries->topQuery(gameHandler->gameState()->curB->sides[0].color));
@@ -819,7 +818,7 @@ bool BattleProcessor::makeAutomaticAction(const CStack *stack, BattleAction &ba)
 	bsa.askPlayerInterface = false;
 	gameHandler->sendAndApply(&bsa);
 
-	bool ret = makeBattleAction(ba);
+	bool ret = makeBattleActionImpl(ba);
 	checkBattleStateChanges();
 	return ret;
 }
@@ -2022,7 +2021,7 @@ void BattleProcessor::checkBattleStateChanges()
 	}
 }
 
-bool BattleProcessor::makeBattleAction(BattleAction &ba)
+bool BattleProcessor::makeBattleActionImpl(BattleAction &ba)
 {
 	bool ok = true;
 
@@ -2445,7 +2444,7 @@ bool BattleProcessor::makeBattleAction(BattleAction &ba)
 	return ok;
 }
 
-bool BattleProcessor::makeCustomAction(BattleAction & ba)
+bool BattleProcessor::makeCustomActionImpl(BattleAction & ba)
 {
 	switch(ba.actionType)
 	{
@@ -2752,3 +2751,75 @@ void BattleProcessor::updateGateState()
 		gameHandler->sendAndApply(&db);
 }
 
+bool BattleProcessor::makeBattleAction(PlayerColor player, BattleAction &ba)
+{
+	boost::unique_lock lock(battleActionMutex);
+
+	const BattleInfo * b = gameHandler->gameState()->curB;
+
+	if(!b && gameHandler->complain("Can not make action - there is no battle ongoing!"))
+		return false;
+
+	if (ba.side != 0 && ba.side != 1 && gameHandler->complain("Can not make action - invalid battle side!"))
+		return false;
+
+	if(b->tacticDistance)
+	{
+		if(ba.actionType != EActionType::WALK && ba.actionType != EActionType::END_TACTIC_PHASE
+			&& ba.actionType != EActionType::RETREAT && ba.actionType != EActionType::SURRENDER)
+		{
+			gameHandler->complain("Can not make actions while in tactics mode!");
+			return false;
+		}
+
+		if(player != b->sides[ba.side].color)
+		{
+			gameHandler->complain("Can not make actions in battles you are not part of!");
+			return false;
+		}
+	}
+	else
+	{
+		auto active = b->battleActiveUnit();
+		if(!active && gameHandler->complain("No active unit in battle!"))
+			return false;
+
+		auto unitOwner = b->battleGetOwner(active);
+
+		if(player != unitOwner && gameHandler->complain("Can not make actions in battles you are not part of!"))
+			return false;
+	}
+
+	return makeBattleActionImpl(ba);
+}
+
+bool BattleProcessor::makeCustomAction(PlayerColor player, BattleAction &ba)
+{
+	const BattleInfo * b = gameHandler->gameState()->curB;
+
+	if(!b && gameHandler->complain("Can not make action - there is no battle ongoing!"))
+		return false;
+
+	if (ba.side != 0 && ba.side != 1 && gameHandler->complain("Can not make action - invalid battle side!"))
+		return false;
+
+	if(b->tacticDistance)
+	{
+		gameHandler->complain("Can not cast spell during tactics mode!");
+		return false;
+	}
+
+	auto active = b->battleActiveUnit();
+	if(!active && gameHandler->complain("No active unit in battle!"))
+		return false;
+
+	auto unitOwner = b->battleGetOwner(active);
+
+	if(player != unitOwner && gameHandler->complain("Can not make actions in battles you are not part of!"))
+		return false;
+
+	if(ba.actionType != EActionType::HERO_SPELL && gameHandler->complain("Invalid custom action type!"))
+		return false;
+
+	return makeCustomActionImpl(ba);
+}

+ 5 - 2
server/battles/BattleProcessor.h

@@ -100,6 +100,9 @@ class BattleProcessor : boost::noncopyable
 	void setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance *heroes[2], bool creatureBank, const CGTownInstance *town);
 	void setBattleResult(BattleResult::EResult resultType, int victoriusSide);
 
+	bool makeBattleActionImpl(BattleAction &ba);
+	bool makeCustomActionImpl(BattleAction &ba);
+
 public:
 	CGameHandler * gameHandler;
 
@@ -114,8 +117,8 @@ public:
 
 	void battleAfterLevelUp(const BattleResult &result);
 
-	bool makeBattleAction(BattleAction &ba);
-	bool makeCustomAction(BattleAction &ba);
+	bool makeBattleAction(PlayerColor player, BattleAction &ba);
+	bool makeCustomAction(PlayerColor player, BattleAction &ba);
 
 	void endBattle(int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2); //ends battle
 	void endBattleConfirm(const BattleInfo * battleInfo);