mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
Merge pull request #1521 from vcmi/android-remove-server-main
Rework netpacks
This commit is contained in:
commit
4f4f2db9c0
@ -212,6 +212,8 @@ set(client_HEADERS
|
||||
CVideoHandler.h
|
||||
Client.h
|
||||
ClientCommandManager.h
|
||||
ClientNetPackVisitors.h
|
||||
LobbyClientNetPackVisitors.h
|
||||
resource.h
|
||||
)
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "../lib/CConfigHandler.h"
|
||||
#include "../lib/CGeneralTextHandler.h"
|
||||
#include "../lib/CThreadHelper.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "../lib/NetPackVisitor.h"
|
||||
#include "../lib/StartInfo.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
#include "../lib/mapping/CCampaignHandler.h"
|
||||
@ -53,6 +53,7 @@
|
||||
#include <boost/uuid/uuid_io.hpp>
|
||||
#include <boost/uuid/uuid_generators.hpp>
|
||||
#include "../lib/serializer/Cast.h"
|
||||
#include "LobbyClientNetPackVisitors.h"
|
||||
|
||||
#include <vcmi/events/EventBus.h>
|
||||
|
||||
@ -86,15 +87,21 @@ public:
|
||||
bool applyOnLobbyHandler(CServerHandler * handler, void * pack) const override
|
||||
{
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
ApplyOnLobbyHandlerNetPackVisitor visitor(*handler);
|
||||
|
||||
logNetwork->trace("\tImmediately apply on lobby: %s", typeList.getTypeInfo(ptr)->name());
|
||||
return ptr->applyOnLobbyHandler(handler);
|
||||
ptr->visit(visitor);
|
||||
|
||||
return visitor.getResult();
|
||||
}
|
||||
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler, void * pack) const override
|
||||
{
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
ApplyOnLobbyScreenNetPackVisitor visitor(*handler, lobby);
|
||||
|
||||
logNetwork->trace("\tApply on lobby from queue: %s", typeList.getTypeInfo(ptr)->name());
|
||||
ptr->applyOnLobbyScreen(lobby, handler);
|
||||
ptr->visit(visitor);
|
||||
}
|
||||
};
|
||||
|
||||
@ -575,7 +582,7 @@ void CServerHandler::sendStartGame(bool allowOnlyAI) const
|
||||
c->disableStackSendingByID();
|
||||
}
|
||||
|
||||
void CServerHandler::startGameplay(CGameState * gameState)
|
||||
void CServerHandler::startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState)
|
||||
{
|
||||
if(CMM)
|
||||
CMM->disable();
|
||||
@ -767,6 +774,30 @@ void CServerHandler::debugStartTest(std::string filename, bool save)
|
||||
}
|
||||
}
|
||||
|
||||
class ServerHandlerCPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
CServerHandler & handler;
|
||||
|
||||
public:
|
||||
ServerHandlerCPackVisitor(CServerHandler & handler)
|
||||
:handler(handler)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool callTyped() override { return false; }
|
||||
|
||||
virtual void visitForLobby(CPackForLobby & lobbyPack) override
|
||||
{
|
||||
handler.visitForLobby(lobbyPack);
|
||||
}
|
||||
|
||||
virtual void visitForClient(CPackForClient & clientPack) override
|
||||
{
|
||||
handler.visitForClient(clientPack);
|
||||
}
|
||||
};
|
||||
|
||||
void CServerHandler::threadHandleConnection()
|
||||
{
|
||||
setThreadName("CServerHandler::threadHandleConnection");
|
||||
@ -787,20 +818,10 @@ void CServerHandler::threadHandleConnection()
|
||||
// Though currently they'll be delivered and might cause crash.
|
||||
vstd::clear_pointer(pack);
|
||||
}
|
||||
else if(auto lobbyPack = dynamic_ptr_cast<CPackForLobby>(pack))
|
||||
else
|
||||
{
|
||||
if(applier->getApplier(typeList.getTypeID(pack))->applyOnLobbyHandler(this, pack))
|
||||
{
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*mx);
|
||||
packsForLobbyScreen.push_back(lobbyPack);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(auto clientPack = dynamic_ptr_cast<CPackForClient>(pack))
|
||||
{
|
||||
client->handlePack(clientPack);
|
||||
ServerHandlerCPackVisitor visitor(*this);
|
||||
pack->visit(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -836,6 +857,23 @@ void CServerHandler::threadHandleConnection()
|
||||
}
|
||||
}
|
||||
|
||||
void CServerHandler::visitForLobby(CPackForLobby & lobbyPack)
|
||||
{
|
||||
if(applier->getApplier(typeList.getTypeID(&lobbyPack))->applyOnLobbyHandler(this, &lobbyPack))
|
||||
{
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*mx);
|
||||
packsForLobbyScreen.push_back(&lobbyPack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CServerHandler::visitForClient(CPackForClient & clientPack)
|
||||
{
|
||||
client->handlePack(&clientPack);
|
||||
}
|
||||
|
||||
void CServerHandler::threadRunServer()
|
||||
{
|
||||
#if !defined(VCMI_ANDROID) && !defined(VCMI_IOS)
|
||||
|
@ -25,13 +25,13 @@ class CGameState;
|
||||
struct ClientPlayer;
|
||||
struct CPack;
|
||||
struct CPackForLobby;
|
||||
struct CPackForClient;
|
||||
|
||||
template<typename T> class CApplier;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class CClient;
|
||||
|
||||
class CBaseForLobbyApply;
|
||||
|
||||
// TODO: Add mutex so we can't set CONNECTION_CANCELLED if client already connected, but thread not setup yet
|
||||
@ -148,7 +148,7 @@ public:
|
||||
void sendRestartGame() const override;
|
||||
void sendStartGame(bool allowOnlyAI = false) const override;
|
||||
|
||||
void startGameplay(CGameState * gameState = nullptr);
|
||||
void startGameplay(VCMI_LIB_WRAP_NAMESPACE(CGameState) * gameState = nullptr);
|
||||
void endGameplay(bool closeConnection = true, bool restart = false);
|
||||
void startCampaignScenario(std::shared_ptr<CCampaignState> cs = {});
|
||||
void showServerError(std::string txt);
|
||||
@ -159,6 +159,9 @@ public:
|
||||
|
||||
void debugStartTest(std::string filename, bool save = false);
|
||||
void restoreLastSession();
|
||||
|
||||
void visitForLobby(CPackForLobby & lobbyPack);
|
||||
void visitForClient(CPackForClient & clientPack);
|
||||
};
|
||||
|
||||
extern CServerHandler * CSH;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "../lib/serializer/Connection.h"
|
||||
#include "../lib/serializer/CLoadIntegrityValidator.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "ClientNetPackVisitors.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
#include "../lib/mapping/CMap.h"
|
||||
@ -80,12 +81,14 @@ public:
|
||||
void applyOnClAfter(CClient * cl, void * pack) const override
|
||||
{
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
ptr->applyCl(cl);
|
||||
ApplyClientNetPackVisitor visitor(*cl, *cl->gameState());
|
||||
ptr->visit(visitor);
|
||||
}
|
||||
void applyOnClBefore(CClient * cl, void * pack) const override
|
||||
{
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
ptr->applyFirstCl(cl);
|
||||
ApplyFirstClientNetPackVisitor visitor(*cl, *cl->gameState());
|
||||
ptr->visit(visitor);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "CServerHandler.h"
|
||||
#include "gui/CGuiHandler.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "ClientNetPackVisitors.h"
|
||||
#include "../lib/CConfigHandler.h"
|
||||
#include "../lib/CGameState.h"
|
||||
#include "../lib/CPlayerState.h"
|
||||
@ -427,7 +428,9 @@ void ClientCommandManager::giveTurn(const PlayerColor &colorIdentifier)
|
||||
YourTurn yt;
|
||||
yt.player = colorIdentifier;
|
||||
yt.daysWithoutCastle = CSH->client->getPlayerState(colorIdentifier)->daysWithoutCastle;
|
||||
yt.applyCl(CSH->client);
|
||||
|
||||
ApplyClientNetPackVisitor visitor(*CSH->client, *CSH->client->gameState());
|
||||
yt.visit(visitor);
|
||||
}
|
||||
|
||||
void ClientCommandManager::printInfoAboutInterfaceObject(const CIntObject *obj, int level)
|
||||
|
132
client/ClientNetPackVisitors.h
Normal file
132
client/ClientNetPackVisitors.h
Normal file
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* ClientNetPackVisitors.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../lib/NetPackVisitor.h"
|
||||
|
||||
class CClient;
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CGameState;
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
class ApplyClientNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
CClient & cl;
|
||||
CGameState & gs;
|
||||
|
||||
public:
|
||||
ApplyClientNetPackVisitor(CClient & cl, CGameState & gs)
|
||||
:cl(cl), gs(gs)
|
||||
{
|
||||
}
|
||||
|
||||
void visitSetResources(SetResources & pack) override;
|
||||
void visitSetPrimSkill(SetPrimSkill & pack) override;
|
||||
void visitSetSecSkill(SetSecSkill & pack) override;
|
||||
void visitHeroVisitCastle(HeroVisitCastle & pack) override;
|
||||
void visitSetMana(SetMana & pack) override;
|
||||
void visitSetMovePoints(SetMovePoints & pack) override;
|
||||
void visitFoWChange(FoWChange & pack) override;
|
||||
void visitChangeStackCount(ChangeStackCount & pack) override;
|
||||
void visitSetStackType(SetStackType & pack) override;
|
||||
void visitEraseStack(EraseStack & pack) override;
|
||||
void visitSwapStacks(SwapStacks & pack) override;
|
||||
void visitInsertNewStack(InsertNewStack & pack) override;
|
||||
void visitRebalanceStacks(RebalanceStacks & pack) override;
|
||||
void visitBulkRebalanceStacks(BulkRebalanceStacks & pack) override;
|
||||
void visitBulkSmartRebalanceStacks(BulkSmartRebalanceStacks & pack) override;
|
||||
void visitPutArtifact(PutArtifact & pack) override;
|
||||
void visitEraseArtifact(EraseArtifact & pack) override;
|
||||
void visitMoveArtifact(MoveArtifact & pack) override;
|
||||
void visitBulkMoveArtifacts(BulkMoveArtifacts & pack) override;
|
||||
void visitAssembledArtifact(AssembledArtifact & pack) override;
|
||||
void visitDisassembledArtifact(DisassembledArtifact & pack) override;
|
||||
void visitHeroVisit(HeroVisit & pack) override;
|
||||
void visitNewTurn(NewTurn & pack) override;
|
||||
void visitGiveBonus(GiveBonus & pack) override;
|
||||
void visitChangeObjPos(ChangeObjPos & pack) override;
|
||||
void visitPlayerEndsGame(PlayerEndsGame & pack) override;
|
||||
void visitPlayerReinitInterface(PlayerReinitInterface & pack) override;
|
||||
void visitRemoveBonus(RemoveBonus & pack) override;
|
||||
void visitRemoveObject(RemoveObject & pack) override;
|
||||
void visitTryMoveHero(TryMoveHero & pack) override;
|
||||
void visitNewStructures(NewStructures & pack) override;
|
||||
void visitRazeStructures(RazeStructures & pack) override;
|
||||
void visitSetAvailableCreatures(SetAvailableCreatures & pack) override;
|
||||
void visitSetHeroesInTown(SetHeroesInTown & pack) override;
|
||||
void visitHeroRecruited(HeroRecruited & pack) override;
|
||||
void visitGiveHero(GiveHero & pack) override;
|
||||
void visitInfoWindow(InfoWindow & pack) override;
|
||||
void visitSetObjectProperty(SetObjectProperty & pack) override;
|
||||
void visitHeroLevelUp(HeroLevelUp & pack) override;
|
||||
void visitCommanderLevelUp(CommanderLevelUp & pack) override;
|
||||
void visitBlockingDialog(BlockingDialog & pack) override;
|
||||
void visitGarrisonDialog(GarrisonDialog & pack) override;
|
||||
void visitExchangeDialog(ExchangeDialog & pack) override;
|
||||
void visitTeleportDialog(TeleportDialog & pack) override;
|
||||
void visitMapObjectSelectDialog(MapObjectSelectDialog & pack) override;
|
||||
void visitBattleStart(BattleStart & pack) override;
|
||||
void visitBattleNextRound(BattleNextRound & pack) override;
|
||||
void visitBattleSetActiveStack(BattleSetActiveStack & pack) override;
|
||||
void visitBattleLogMessage(BattleLogMessage & pack) override;
|
||||
void visitBattleTriggerEffect(BattleTriggerEffect & pack) override;
|
||||
void visitBattleAttack(BattleAttack & pack) override;
|
||||
void visitBattleSpellCast(BattleSpellCast & pack) override;
|
||||
void visitSetStackEffect(SetStackEffect & pack) override;
|
||||
void visitStacksInjured(StacksInjured & pack) override;
|
||||
void visitBattleResultsApplied(BattleResultsApplied & pack) override;
|
||||
void visitBattleUnitsChanged(BattleUnitsChanged & pack) override;
|
||||
void visitBattleObstaclesChanged(BattleObstaclesChanged & pack) override;
|
||||
void visitCatapultAttack(CatapultAttack & pack) override;
|
||||
void visitEndAction(EndAction & pack) override;
|
||||
void visitPackageApplied(PackageApplied & pack) override;
|
||||
void visitSystemMessage(SystemMessage & pack) override;
|
||||
void visitPlayerBlocked(PlayerBlocked & pack) override;
|
||||
void visitYourTurn(YourTurn & pack) override;
|
||||
void visitSaveGameClient(SaveGameClient & pack) override;
|
||||
void visitPlayerMessageClient(PlayerMessageClient & pack) override;
|
||||
void visitShowInInfobox(ShowInInfobox & pack) override;
|
||||
void visitAdvmapSpellCast(AdvmapSpellCast & pack) override;
|
||||
void visitShowWorldViewEx(ShowWorldViewEx & pack) override;
|
||||
void visitOpenWindow(OpenWindow & pack) override;
|
||||
void visitCenterView(CenterView & pack) override;
|
||||
void visitNewObject(NewObject & pack) override;
|
||||
void visitSetAvailableArtifacts(SetAvailableArtifacts & pack) override;
|
||||
void visitEntitiesChanged(EntitiesChanged & pack) override;
|
||||
};
|
||||
|
||||
class ApplyFirstClientNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
CClient & cl;
|
||||
CGameState & gs;
|
||||
|
||||
public:
|
||||
ApplyFirstClientNetPackVisitor(CClient & cl, CGameState & gs)
|
||||
:cl(cl), gs(gs)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void visitChangeObjPos(ChangeObjPos & pack) override;
|
||||
virtual void visitRemoveObject(RemoveObject & pack) override;
|
||||
virtual void visitTryMoveHero(TryMoveHero & pack) override;
|
||||
virtual void visitGiveHero(GiveHero & pack) override;
|
||||
virtual void visitBattleStart(BattleStart & pack) override;
|
||||
virtual void visitBattleNextRound(BattleNextRound & pack) override;
|
||||
virtual void visitBattleUpdateGateState(BattleUpdateGateState & pack) override;
|
||||
virtual void visitBattleResult(BattleResult & pack) override;
|
||||
virtual void visitBattleStackMoved(BattleStackMoved & pack) override;
|
||||
virtual void visitBattleAttack(BattleAttack & pack) override;
|
||||
virtual void visitStartAction(StartAction & pack) override;
|
||||
};
|
56
client/LobbyClientNetPackVisitors.h
Normal file
56
client/LobbyClientNetPackVisitors.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* ClientNetPackVisitors.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../lib/NetPackVisitor.h"
|
||||
|
||||
class CClient;
|
||||
class CGameState;
|
||||
|
||||
class ApplyOnLobbyHandlerNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
CServerHandler & handler;
|
||||
bool result;
|
||||
|
||||
public:
|
||||
ApplyOnLobbyHandlerNetPackVisitor(CServerHandler & handler)
|
||||
:handler(handler), result(true)
|
||||
{
|
||||
}
|
||||
|
||||
bool getResult() const { return result; }
|
||||
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) override;
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyUpdateState(LobbyUpdateState & pack) override;
|
||||
};
|
||||
|
||||
class ApplyOnLobbyScreenNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
CServerHandler & handler;
|
||||
CLobbyScreen * lobby;
|
||||
|
||||
public:
|
||||
ApplyOnLobbyScreenNetPackVisitor(CServerHandler & handler, CLobbyScreen * lobby)
|
||||
:handler(handler), lobby(lobby)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbyChatMessage(LobbyChatMessage & pack) override;
|
||||
virtual void visitLobbyGuiAction(LobbyGuiAction & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyUpdateState(LobbyUpdateState & pack) override;
|
||||
virtual void visitLobbyShowMessage(LobbyShowMessage & pack) override;
|
||||
};
|
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "LobbyClientNetPackVisitors.h"
|
||||
#include "lobby/CSelectionBase.h"
|
||||
#include "lobby/CLobbyScreen.h"
|
||||
|
||||
@ -28,123 +29,120 @@
|
||||
#include "../lib/NetPacksLobby.h"
|
||||
#include "../lib/serializer/Connection.h"
|
||||
|
||||
bool LobbyClientConnected::applyOnLobbyHandler(CServerHandler * handler)
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)
|
||||
{
|
||||
result = false;
|
||||
|
||||
// Check if it's LobbyClientConnected for our client
|
||||
if(uuid == handler->c->uuid)
|
||||
if(pack.uuid == handler.c->uuid)
|
||||
{
|
||||
handler->c->connectionID = clientId;
|
||||
handler.c->connectionID = pack.clientId;
|
||||
if(!settings["session"]["headless"].Bool())
|
||||
GH.pushIntT<CLobbyScreen>(static_cast<ESelectionScreen>(handler->screenType));
|
||||
handler->state = EClientState::LOBBY;
|
||||
return true;
|
||||
GH.pushIntT<CLobbyScreen>(static_cast<ESelectionScreen>(handler.screenType));
|
||||
handler.state = EClientState::LOBBY;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LobbyClientConnected::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
|
||||
{
|
||||
if(pack.clientId != pack.c->connectionID)
|
||||
{
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
handler.stopServerConnection();
|
||||
}
|
||||
|
||||
bool LobbyClientDisconnected::applyOnLobbyHandler(CServerHandler * handler)
|
||||
{
|
||||
if(clientId != c->connectionID)
|
||||
return false;
|
||||
|
||||
handler->stopServerConnection();
|
||||
return true;
|
||||
}
|
||||
|
||||
void LobbyClientDisconnected::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
void ApplyOnLobbyScreenNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
|
||||
{
|
||||
if(GH.listInt.size())
|
||||
GH.popInts(1);
|
||||
}
|
||||
|
||||
void LobbyChatMessage::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
void ApplyOnLobbyScreenNetPackVisitor::visitLobbyChatMessage(LobbyChatMessage & pack)
|
||||
{
|
||||
if(lobby && lobby->card)
|
||||
{
|
||||
lobby->card->chat->addNewMessage(playerName + ": " + message);
|
||||
lobby->card->chat->addNewMessage(pack.playerName + ": " + pack.message);
|
||||
lobby->card->setChat(true);
|
||||
if(lobby->buttonChat)
|
||||
lobby->buttonChat->addTextOverlay(CGI->generaltexth->allTexts[531], FONT_SMALL);
|
||||
}
|
||||
}
|
||||
|
||||
void LobbyGuiAction::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
void ApplyOnLobbyScreenNetPackVisitor::visitLobbyGuiAction(LobbyGuiAction & pack)
|
||||
{
|
||||
if(!lobby || !handler->isGuest())
|
||||
if(!lobby || !handler.isGuest())
|
||||
return;
|
||||
|
||||
switch(action)
|
||||
switch(pack.action)
|
||||
{
|
||||
case NO_TAB:
|
||||
case LobbyGuiAction::NO_TAB:
|
||||
lobby->toggleTab(lobby->curTab);
|
||||
break;
|
||||
case OPEN_OPTIONS:
|
||||
case LobbyGuiAction::OPEN_OPTIONS:
|
||||
lobby->toggleTab(lobby->tabOpt);
|
||||
break;
|
||||
case OPEN_SCENARIO_LIST:
|
||||
case LobbyGuiAction::OPEN_SCENARIO_LIST:
|
||||
lobby->toggleTab(lobby->tabSel);
|
||||
break;
|
||||
case OPEN_RANDOM_MAP_OPTIONS:
|
||||
case LobbyGuiAction::OPEN_RANDOM_MAP_OPTIONS:
|
||||
lobby->toggleTab(lobby->tabRand);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool LobbyEndGame::applyOnLobbyHandler(CServerHandler * handler)
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
{
|
||||
if(handler->state == EClientState::GAMEPLAY)
|
||||
if(handler.state == EClientState::GAMEPLAY)
|
||||
{
|
||||
handler->endGameplay(closeConnection, restart);
|
||||
handler.endGameplay(pack.closeConnection, pack.restart);
|
||||
}
|
||||
|
||||
if(restart)
|
||||
handler->sendStartGame();
|
||||
|
||||
return true;
|
||||
if(pack.restart)
|
||||
handler.sendStartGame();
|
||||
}
|
||||
|
||||
bool LobbyStartGame::applyOnLobbyHandler(CServerHandler * handler)
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
{
|
||||
if(clientId != -1 && clientId != handler->c->connectionID)
|
||||
return false;
|
||||
|
||||
handler->state = EClientState::STARTING;
|
||||
if(handler->si->mode != StartInfo::LOAD_GAME || clientId == handler->c->connectionID)
|
||||
if(pack.clientId != -1 && pack.clientId != handler.c->connectionID)
|
||||
{
|
||||
auto modeBackup = handler->si->mode;
|
||||
handler->si = initializedStartInfo;
|
||||
handler->si->mode = modeBackup;
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
handler.state = EClientState::STARTING;
|
||||
if(handler.si->mode != StartInfo::LOAD_GAME || pack.clientId == handler.c->connectionID)
|
||||
{
|
||||
auto modeBackup = handler.si->mode;
|
||||
handler.si = pack.initializedStartInfo;
|
||||
handler.si->mode = modeBackup;
|
||||
}
|
||||
if(settings["session"]["headless"].Bool())
|
||||
handler->startGameplay(initializedGameState);
|
||||
return true;
|
||||
handler.startGameplay(pack.initializedGameState);
|
||||
}
|
||||
|
||||
void LobbyStartGame::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
void ApplyOnLobbyScreenNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
{
|
||||
if(clientId != -1 && clientId != handler->c->connectionID)
|
||||
if(pack.clientId != -1 && pack.clientId != handler.c->connectionID)
|
||||
return;
|
||||
|
||||
GH.pushIntT<CLoadingScreen>(std::bind(&CServerHandler::startGameplay, handler, initializedGameState));
|
||||
GH.pushIntT<CLoadingScreen>(std::bind(&CServerHandler::startGameplay, &handler, pack.initializedGameState));
|
||||
}
|
||||
|
||||
bool LobbyUpdateState::applyOnLobbyHandler(CServerHandler * handler)
|
||||
void ApplyOnLobbyHandlerNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState & pack)
|
||||
{
|
||||
hostChanged = state.hostClientId != handler->hostClientId;
|
||||
static_cast<LobbyState &>(*handler) = state;
|
||||
return true;
|
||||
pack.hostChanged = pack.state.hostClientId != handler.hostClientId;
|
||||
static_cast<LobbyState &>(handler) = pack.state;
|
||||
}
|
||||
|
||||
void LobbyUpdateState::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
void ApplyOnLobbyScreenNetPackVisitor::visitLobbyUpdateState(LobbyUpdateState & pack)
|
||||
{
|
||||
if(!lobby) //stub: ignore message for game mode
|
||||
return;
|
||||
|
||||
if(!lobby->bonusSel && handler->si->campState && handler->state == EClientState::LOBBY_CAMPAIGN)
|
||||
if(!lobby->bonusSel && handler.si->campState && handler.state == EClientState::LOBBY_CAMPAIGN)
|
||||
{
|
||||
lobby->bonusSel = std::make_shared<CBonusSelection>();
|
||||
GH.pushInt(lobby->bonusSel);
|
||||
@ -155,15 +153,15 @@ void LobbyUpdateState::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler *
|
||||
else
|
||||
lobby->updateAfterStateChange();
|
||||
|
||||
if(hostChanged)
|
||||
lobby->toggleMode(handler->isHost());
|
||||
if(pack.hostChanged)
|
||||
lobby->toggleMode(handler.isHost());
|
||||
}
|
||||
|
||||
void LobbyShowMessage::applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler)
|
||||
void ApplyOnLobbyScreenNetPackVisitor::visitLobbyShowMessage(LobbyShowMessage & pack)
|
||||
{
|
||||
if(!lobby) //stub: ignore message for game mode
|
||||
return;
|
||||
|
||||
lobby->buttonStart->block(false);
|
||||
handler->showServerError(message);
|
||||
handler.showServerError(pack.message);
|
||||
}
|
||||
|
@ -439,6 +439,7 @@ macro(add_main_lib TARGET_NAME LIBRARY_TYPE)
|
||||
${MAIN_LIB_DIR}/NetPacksBase.h
|
||||
${MAIN_LIB_DIR}/NetPacks.h
|
||||
${MAIN_LIB_DIR}/NetPacksLobby.h
|
||||
${MAIN_LIB_DIR}/NetPackVisitor.h
|
||||
${MAIN_LIB_DIR}/ObstacleHandler.h
|
||||
${MAIN_LIB_DIR}/PathfinderUtil.h
|
||||
${MAIN_LIB_DIR}/Point.h
|
||||
|
165
lib/NetPackVisitor.h
Normal file
165
lib/NetPackVisitor.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* CServerHandler.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "NetPacks.h"
|
||||
#include "NetPacksLobby.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class ICPackVisitor
|
||||
{
|
||||
public:
|
||||
virtual bool callTyped() { return true; }
|
||||
|
||||
virtual void visitForLobby(CPackForLobby & pack) {}
|
||||
virtual void visitForServer(CPackForServer & pack) {}
|
||||
virtual void visitForClient(CPackForClient & pack) {}
|
||||
virtual void visitPackageApplied(PackageApplied & pack) {}
|
||||
virtual void visitSystemMessage(SystemMessage & pack) {}
|
||||
virtual void visitPlayerBlocked(PlayerBlocked & pack) {}
|
||||
virtual void visitPlayerCheated(PlayerCheated & pack) {}
|
||||
virtual void visitYourTurn(YourTurn & pack) {}
|
||||
virtual void visitEntitiesChanged(EntitiesChanged & pack) {}
|
||||
virtual void visitSetResources(SetResources & pack) {}
|
||||
virtual void visitSetPrimSkill(SetPrimSkill & pack) {}
|
||||
virtual void visitSetSecSkill(SetSecSkill & pack) {}
|
||||
virtual void visitHeroVisitCastle(HeroVisitCastle & pack) {}
|
||||
virtual void visitChangeSpells(ChangeSpells & pack) {}
|
||||
virtual void visitSetMana(SetMana & pack) {}
|
||||
virtual void visitSetMovePoints(SetMovePoints & pack) {}
|
||||
virtual void visitFoWChange(FoWChange & pack) {}
|
||||
virtual void visitSetAvailableHeroes(SetAvailableHeroes & pack) {}
|
||||
virtual void visitGiveBonus(GiveBonus & pack) {}
|
||||
virtual void visitChangeObjPos(ChangeObjPos & pack) {}
|
||||
virtual void visitPlayerEndsGame(PlayerEndsGame & pack) {}
|
||||
virtual void visitPlayerReinitInterface(PlayerReinitInterface & pack) {}
|
||||
virtual void visitRemoveBonus(RemoveBonus & pack) {}
|
||||
virtual void visitSetCommanderProperty(SetCommanderProperty & pack) {}
|
||||
virtual void visitAddQuest(AddQuest & pack) {}
|
||||
virtual void visitUpdateArtHandlerLists(UpdateArtHandlerLists & pack) {}
|
||||
virtual void visitUpdateMapEvents(UpdateMapEvents & pack) {}
|
||||
virtual void visitUpdateCastleEvents(UpdateCastleEvents & pack) {}
|
||||
virtual void visitChangeFormation(ChangeFormation & pack) {}
|
||||
virtual void visitRemoveObject(RemoveObject & pack) {}
|
||||
virtual void visitTryMoveHero(TryMoveHero & pack) {}
|
||||
virtual void visitNewStructures(NewStructures & pack) {}
|
||||
virtual void visitRazeStructures(RazeStructures & pack) {}
|
||||
virtual void visitSetAvailableCreatures(SetAvailableCreatures & pack) {}
|
||||
virtual void visitSetHeroesInTown(SetHeroesInTown & pack) {}
|
||||
virtual void visitHeroRecruited(HeroRecruited & pack) {}
|
||||
virtual void visitGiveHero(GiveHero & pack) {}
|
||||
virtual void visitCatapultAttack(CatapultAttack & pack) {}
|
||||
virtual void visitOpenWindow(OpenWindow & pack) {}
|
||||
virtual void visitNewObject(NewObject & pack) {}
|
||||
virtual void visitSetAvailableArtifacts(SetAvailableArtifacts & pack) {}
|
||||
virtual void visitNewArtifact(NewArtifact & pack) {}
|
||||
virtual void visitChangeStackCount(ChangeStackCount & pack) {}
|
||||
virtual void visitSetStackType(SetStackType & pack) {}
|
||||
virtual void visitEraseStack(EraseStack & pack) {}
|
||||
virtual void visitSwapStacks(SwapStacks & pack) {}
|
||||
virtual void visitInsertNewStack(InsertNewStack & pack) {}
|
||||
virtual void visitRebalanceStacks(RebalanceStacks & pack) {}
|
||||
virtual void visitBulkRebalanceStacks(BulkRebalanceStacks & pack) {}
|
||||
virtual void visitBulkSmartRebalanceStacks(BulkSmartRebalanceStacks & pack) {}
|
||||
virtual void visitPutArtifact(PutArtifact & pack) {}
|
||||
virtual void visitEraseArtifact(EraseArtifact & pack) {}
|
||||
virtual void visitMoveArtifact(MoveArtifact & pack) {}
|
||||
virtual void visitBulkMoveArtifacts(BulkMoveArtifacts & pack) {}
|
||||
virtual void visitAssembledArtifact(AssembledArtifact & pack) {}
|
||||
virtual void visitDisassembledArtifact(DisassembledArtifact & pack) {}
|
||||
virtual void visitHeroVisit(HeroVisit & pack) {}
|
||||
virtual void visitNewTurn(NewTurn & pack) {}
|
||||
virtual void visitInfoWindow(InfoWindow & pack) {}
|
||||
virtual void visitSetObjectProperty(SetObjectProperty & pack) {}
|
||||
virtual void visitChangeObjectVisitors(ChangeObjectVisitors & pack) {}
|
||||
virtual void visitPrepareHeroLevelUp(PrepareHeroLevelUp & pack) {}
|
||||
virtual void visitHeroLevelUp(HeroLevelUp & pack) {}
|
||||
virtual void visitCommanderLevelUp(CommanderLevelUp & pack) {}
|
||||
virtual void visitBlockingDialog(BlockingDialog & pack) {}
|
||||
virtual void visitGarrisonDialog(GarrisonDialog & pack) {}
|
||||
virtual void visitExchangeDialog(ExchangeDialog & pack) {}
|
||||
virtual void visitTeleportDialog(TeleportDialog & pack) {}
|
||||
virtual void visitMapObjectSelectDialog(MapObjectSelectDialog & pack) {}
|
||||
virtual void visitBattleStart(BattleStart & pack) {}
|
||||
virtual void visitBattleNextRound(BattleNextRound & pack) {}
|
||||
virtual void visitBattleSetActiveStack(BattleSetActiveStack & pack) {}
|
||||
virtual void visitBattleResult(BattleResult & pack) {}
|
||||
virtual void visitBattleLogMessage(BattleLogMessage & pack) {}
|
||||
virtual void visitBattleStackMoved(BattleStackMoved & pack) {}
|
||||
virtual void visitBattleUnitsChanged(BattleUnitsChanged & pack) {}
|
||||
virtual void visitBattleAttack(BattleAttack & pack) {}
|
||||
virtual void visitStartAction(StartAction & pack) {}
|
||||
virtual void visitEndAction(EndAction & pack) {}
|
||||
virtual void visitBattleSpellCast(BattleSpellCast & pack) {}
|
||||
virtual void visitSetStackEffect(SetStackEffect & pack) {}
|
||||
virtual void visitStacksInjured(StacksInjured & pack) {}
|
||||
virtual void visitBattleResultsApplied(BattleResultsApplied & pack) {}
|
||||
virtual void visitBattleObstaclesChanged(BattleObstaclesChanged & pack) {}
|
||||
virtual void visitBattleSetStackProperty(BattleSetStackProperty & pack) {}
|
||||
virtual void visitBattleTriggerEffect(BattleTriggerEffect & pack) {}
|
||||
virtual void visitBattleUpdateGateState(BattleUpdateGateState & pack) {}
|
||||
virtual void visitShowInInfobox(ShowInInfobox & pack) {}
|
||||
virtual void visitAdvmapSpellCast(AdvmapSpellCast & pack) {}
|
||||
virtual void visitShowWorldViewEx(ShowWorldViewEx & pack) {}
|
||||
virtual void visitEndTurn(EndTurn & pack) {}
|
||||
virtual void visitDismissHero(DismissHero & pack) {}
|
||||
virtual void visitMoveHero(MoveHero & pack) {}
|
||||
virtual void visitCastleTeleportHero(CastleTeleportHero & pack) {}
|
||||
virtual void visitArrangeStacks(ArrangeStacks & pack) {}
|
||||
virtual void visitBulkMoveArmy(BulkMoveArmy & pack) {}
|
||||
virtual void visitBulkSplitStack(BulkSplitStack & pack) {}
|
||||
virtual void visitBulkMergeStacks(BulkMergeStacks & pack) {}
|
||||
virtual void visitBulkSmartSplitStack(BulkSmartSplitStack & pack) {}
|
||||
virtual void visitDisbandCreature(DisbandCreature & pack) {}
|
||||
virtual void visitBuildStructure(BuildStructure & pack) {}
|
||||
virtual void visitRazeStructure(RazeStructure & pack) {}
|
||||
virtual void visitRecruitCreatures(RecruitCreatures & pack) {}
|
||||
virtual void visitUpgradeCreature(UpgradeCreature & pack) {}
|
||||
virtual void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) {}
|
||||
virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) {}
|
||||
virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) {}
|
||||
virtual void visitAssembleArtifacts(AssembleArtifacts & pack) {}
|
||||
virtual void visitBuyArtifact(BuyArtifact & pack) {}
|
||||
virtual void visitTradeOnMarketplace(TradeOnMarketplace & pack) {}
|
||||
virtual void visitSetFormation(SetFormation & pack) {}
|
||||
virtual void visitHireHero(HireHero & pack) {}
|
||||
virtual void visitBuildBoat(BuildBoat & pack) {}
|
||||
virtual void visitQueryReply(QueryReply & pack) {}
|
||||
virtual void visitMakeAction(MakeAction & pack) {}
|
||||
virtual void visitMakeCustomAction(MakeCustomAction & pack) {}
|
||||
virtual void visitDigWithHero(DigWithHero & pack) {}
|
||||
virtual void visitCastAdvSpell(CastAdvSpell & pack) {}
|
||||
virtual void visitSaveGame(SaveGame & pack) {}
|
||||
virtual void visitSaveGameClient(SaveGameClient & pack) {}
|
||||
virtual void visitPlayerMessage(PlayerMessage & pack) {}
|
||||
virtual void visitPlayerMessageClient(PlayerMessageClient & pack) {}
|
||||
virtual void visitCenterView(CenterView & pack) {}
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) {}
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) {}
|
||||
virtual void visitLobbyChatMessage(LobbyChatMessage & pack) {}
|
||||
virtual void visitLobbyGuiAction(LobbyGuiAction & pack) {}
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) {}
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) {}
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) {}
|
||||
virtual void visitLobbyUpdateState(LobbyUpdateState & pack) {}
|
||||
virtual void visitLobbySetMap(LobbySetMap & pack) {}
|
||||
virtual void visitLobbySetCampaign(LobbySetCampaign & pack) {}
|
||||
virtual void visitLobbySetCampaignMap(LobbySetCampaignMap & pack) {}
|
||||
virtual void visitLobbySetCampaignBonus(LobbySetCampaignBonus & pack) {}
|
||||
virtual void visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack) {}
|
||||
virtual void visitLobbySetPlayer(LobbySetPlayer & pack) {}
|
||||
virtual void visitLobbySetTurnTime(LobbySetTurnTime & pack) {}
|
||||
virtual void visitLobbySetDifficulty(LobbySetDifficulty & pack) {}
|
||||
virtual void visitLobbyForceSetPlayer(LobbyForceSetPlayer & pack) {}
|
||||
virtual void visitLobbyShowMessage(LobbyShowMessage & pack) {}
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
1168
lib/NetPacks.h
1168
lib/NetPacks.h
File diff suppressed because it is too large
Load Diff
@ -17,6 +17,9 @@
|
||||
|
||||
class CClient;
|
||||
class CGameHandler;
|
||||
class CLobbyScreen;
|
||||
class CServerHandler;
|
||||
class CVCMIServer;
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
@ -30,6 +33,8 @@ class CArtifactSet;
|
||||
class CBonusSystemNode;
|
||||
struct ArtSlotInfo;
|
||||
|
||||
class ICPackVisitor;
|
||||
|
||||
struct DLL_LINKAGE CPack
|
||||
{
|
||||
std::shared_ptr<CConnection> c; // Pointer to connection that pack received from
|
||||
@ -45,27 +50,31 @@ struct DLL_LINKAGE CPack
|
||||
|
||||
void applyGs(CGameState * gs)
|
||||
{}
|
||||
|
||||
void visit(ICPackVisitor & cpackVisitor);
|
||||
|
||||
protected:
|
||||
/// <summary>
|
||||
/// For basic types of netpacks hierarchy like CPackForClient. Called first.
|
||||
/// </summary>
|
||||
virtual void visitBasic(ICPackVisitor & cpackVisitor);
|
||||
|
||||
/// <summary>
|
||||
/// For leaf types of netpacks hierarchy. Called after visitBasic.
|
||||
/// </summary>
|
||||
virtual void visitTyped(ICPackVisitor & cpackVisitor);
|
||||
};
|
||||
|
||||
struct CPackForClient : public CPack
|
||||
struct DLL_LINKAGE CPackForClient : public CPack
|
||||
{
|
||||
CGameState* GS(CClient *cl);
|
||||
void applyFirstCl(CClient *cl)//called before applying to gs
|
||||
{}
|
||||
void applyCl(CClient *cl)//called after applying to gs
|
||||
{}
|
||||
protected:
|
||||
virtual void visitBasic(ICPackVisitor & cpackVisitor) override;
|
||||
};
|
||||
|
||||
struct CPackForServer : public CPack
|
||||
struct DLL_LINKAGE CPackForServer : public CPack
|
||||
{
|
||||
mutable PlayerColor player = PlayerColor::NEUTRAL;
|
||||
mutable si32 requestID;
|
||||
CGameState * GS(CGameHandler * gh);
|
||||
bool applyGh(CGameHandler *gh) //called after applying to gs
|
||||
{
|
||||
logGlobal->error("Should not happen... applying plain CPackForServer");
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -74,14 +83,15 @@ struct CPackForServer : public CPack
|
||||
}
|
||||
|
||||
protected:
|
||||
void throwNotAllowedAction();
|
||||
void throwOnWrongOwner(CGameHandler * gh, ObjectInstanceID id);
|
||||
void throwOnWrongPlayer(CGameHandler * gh, PlayerColor player);
|
||||
void throwAndComplain(CGameHandler * gh, std::string txt);
|
||||
bool isPlayerOwns(CGameHandler * gh, ObjectInstanceID id);
|
||||
virtual void visitBasic(ICPackVisitor & cpackVisitor) override;
|
||||
};
|
||||
|
||||
private:
|
||||
void wrongPlayerMessage(CGameHandler * gh, PlayerColor expectedplayer);
|
||||
struct DLL_LINKAGE CPackForLobby : public CPack
|
||||
{
|
||||
virtual bool isForServer() const;
|
||||
|
||||
protected:
|
||||
virtual void visitBasic(ICPackVisitor & cpackVisitor) override;
|
||||
};
|
||||
|
||||
struct DLL_LINKAGE MetaString
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,6 @@
|
||||
|
||||
#include "StartInfo.h"
|
||||
|
||||
class CLobbyScreen;
|
||||
class CServerHandler;
|
||||
class CVCMIServer;
|
||||
|
||||
@ -25,40 +24,16 @@ struct StartInfo;
|
||||
class CMapGenOptions;
|
||||
struct ClientPlayer;
|
||||
|
||||
struct CPackForLobby : public CPack
|
||||
struct DLL_LINKAGE CLobbyPackToPropagate : public CPackForLobby
|
||||
{
|
||||
bool checkClientPermissions(CVCMIServer * srv) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void applyOnServerAfterAnnounce(CVCMIServer * srv) {}
|
||||
|
||||
bool applyOnLobbyHandler(CServerHandler * handler)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler) {}
|
||||
};
|
||||
|
||||
struct CLobbyPackToPropagate : public CPackForLobby
|
||||
struct DLL_LINKAGE CLobbyPackToServer : public CPackForLobby
|
||||
{
|
||||
|
||||
virtual bool isForServer() const override;
|
||||
};
|
||||
|
||||
struct CLobbyPackToServer : public CPackForLobby
|
||||
{
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
void applyOnServerAfterAnnounce(CVCMIServer * srv);
|
||||
};
|
||||
|
||||
struct LobbyClientConnected : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyClientConnected : public CLobbyPackToPropagate
|
||||
{
|
||||
// Set by client before sending pack to server
|
||||
std::string uuid;
|
||||
@ -68,11 +43,7 @@ struct LobbyClientConnected : public CLobbyPackToPropagate
|
||||
int clientId = -1;
|
||||
int hostClientId = -1;
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
bool applyOnLobbyHandler(CServerHandler * handler);
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler);
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
void applyOnServerAfterAnnounce(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
@ -85,16 +56,13 @@ struct LobbyClientConnected : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyClientDisconnected : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyClientDisconnected : public CLobbyPackToPropagate
|
||||
{
|
||||
int clientId;
|
||||
bool shutdownServer = false;
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
void applyOnServerAfterAnnounce(CVCMIServer * srv);
|
||||
bool applyOnLobbyHandler(CServerHandler * handler);
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler);
|
||||
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -103,12 +71,11 @@ struct LobbyClientDisconnected : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyChatMessage : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyChatMessage : public CLobbyPackToPropagate
|
||||
{
|
||||
std::string playerName, message;
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -117,14 +84,14 @@ struct LobbyChatMessage : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyGuiAction : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyGuiAction : public CLobbyPackToPropagate
|
||||
{
|
||||
enum EAction : ui8 {
|
||||
NONE, NO_TAB, OPEN_OPTIONS, OPEN_SCENARIO_LIST, OPEN_RANDOM_MAP_OPTIONS
|
||||
} action = NONE;
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler);
|
||||
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -132,14 +99,11 @@ struct LobbyGuiAction : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyEndGame : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyEndGame : public CLobbyPackToPropagate
|
||||
{
|
||||
bool closeConnection = false, restart = false;
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
void applyOnServerAfterAnnounce(CVCMIServer * srv);
|
||||
bool applyOnLobbyHandler(CServerHandler * handler);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -148,18 +112,14 @@ struct LobbyEndGame : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyStartGame : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyStartGame : public CLobbyPackToPropagate
|
||||
{
|
||||
// Set by server
|
||||
std::shared_ptr<StartInfo> initializedStartInfo = nullptr;
|
||||
CGameState * initializedGameState = nullptr;
|
||||
int clientId = -1; //-1 means to all clients
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
void applyOnServerAfterAnnounce(CVCMIServer * srv);
|
||||
bool applyOnLobbyHandler(CServerHandler * handler);
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -172,13 +132,11 @@ struct LobbyStartGame : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyChangeHost : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyChangeHost : public CLobbyPackToPropagate
|
||||
{
|
||||
int newHostConnectionId = -1;
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
bool applyOnServerAfterAnnounce(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
@ -186,13 +144,12 @@ struct LobbyChangeHost : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyUpdateState : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyUpdateState : public CLobbyPackToPropagate
|
||||
{
|
||||
LobbyState state;
|
||||
bool hostChanged = false; // Used on client-side only
|
||||
|
||||
bool applyOnLobbyHandler(CServerHandler * handler);
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -200,13 +157,14 @@ struct LobbyUpdateState : public CLobbyPackToPropagate
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbySetMap : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbySetMap : public CLobbyPackToServer
|
||||
{
|
||||
std::shared_ptr<CMapInfo> mapInfo;
|
||||
std::shared_ptr<CMapGenOptions> mapGenOpts;
|
||||
|
||||
LobbySetMap() : mapInfo(nullptr), mapGenOpts(nullptr) {}
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -215,11 +173,11 @@ struct LobbySetMap : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbySetCampaign : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbySetCampaign : public CLobbyPackToServer
|
||||
{
|
||||
std::shared_ptr<CCampaignState> ourCampaign;
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -227,11 +185,11 @@ struct LobbySetCampaign : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbySetCampaignMap : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbySetCampaignMap : public CLobbyPackToServer
|
||||
{
|
||||
int mapId = -1;
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -239,11 +197,11 @@ struct LobbySetCampaignMap : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbySetCampaignBonus : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbySetCampaignBonus : public CLobbyPackToServer
|
||||
{
|
||||
int bonusId = -1;
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -251,15 +209,14 @@ struct LobbySetCampaignBonus : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyChangePlayerOption : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbyChangePlayerOption : public CLobbyPackToServer
|
||||
{
|
||||
enum EWhat : ui8 {UNKNOWN, TOWN, HERO, BONUS};
|
||||
ui8 what = UNKNOWN;
|
||||
si8 direction = 0; //-1 or +1
|
||||
PlayerColor color = PlayerColor::CANNOT_DETERMINE;
|
||||
|
||||
bool checkClientPermissions(CVCMIServer * srv) const;
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -269,11 +226,11 @@ struct LobbyChangePlayerOption : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbySetPlayer : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbySetPlayer : public CLobbyPackToServer
|
||||
{
|
||||
PlayerColor clickedColor = PlayerColor::CANNOT_DETERMINE;
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -281,11 +238,11 @@ struct LobbySetPlayer : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbySetTurnTime : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbySetTurnTime : public CLobbyPackToServer
|
||||
{
|
||||
ui8 turnTime = 0;
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -293,11 +250,11 @@ struct LobbySetTurnTime : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbySetDifficulty : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbySetDifficulty : public CLobbyPackToServer
|
||||
{
|
||||
ui8 difficulty = 0;
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -305,12 +262,12 @@ struct LobbySetDifficulty : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyForceSetPlayer : public CLobbyPackToServer
|
||||
struct DLL_LINKAGE LobbyForceSetPlayer : public CLobbyPackToServer
|
||||
{
|
||||
ui8 targetConnectedPlayer = -1;
|
||||
PlayerColor targetPlayerColor = PlayerColor::CANNOT_DETERMINE;
|
||||
|
||||
bool applyOnServer(CVCMIServer * srv);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
@ -319,11 +276,11 @@ struct LobbyForceSetPlayer : public CLobbyPackToServer
|
||||
}
|
||||
};
|
||||
|
||||
struct LobbyShowMessage : public CLobbyPackToPropagate
|
||||
struct DLL_LINKAGE LobbyShowMessage : public CLobbyPackToPropagate
|
||||
{
|
||||
std::string message;
|
||||
|
||||
void applyOnLobbyScreen(CLobbyScreen * lobby, CServerHandler * handler);
|
||||
virtual void visitTyped(ICPackVisitor & visitor) override;
|
||||
|
||||
template <typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "../lib/CStack.h"
|
||||
#include "../lib/battle/BattleInfo.h"
|
||||
#include "../lib/CondSh.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "ServerNetPackVisitors.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../lib/mapping/CMap.h"
|
||||
#include "../lib/mapping/CMapService.h"
|
||||
@ -196,7 +196,7 @@ template <typename T> class CApplyOnGH;
|
||||
class CBaseForGHApply
|
||||
{
|
||||
public:
|
||||
virtual bool applyOnGH(CGameHandler * gh, void * pack) const =0;
|
||||
virtual bool applyOnGH(CGameHandler * gh, CGameState * gs, void * pack) const =0;
|
||||
virtual ~CBaseForGHApply(){}
|
||||
template<typename U> static CBaseForGHApply *getApplier(const U * t=nullptr)
|
||||
{
|
||||
@ -207,12 +207,16 @@ public:
|
||||
template <typename T> class CApplyOnGH : public CBaseForGHApply
|
||||
{
|
||||
public:
|
||||
bool applyOnGH(CGameHandler * gh, void * pack) const override
|
||||
bool applyOnGH(CGameHandler * gh, CGameState * gs, void * pack) const override
|
||||
{
|
||||
T *ptr = static_cast<T*>(pack);
|
||||
try
|
||||
{
|
||||
return ptr->applyGh(gh);
|
||||
ApplyGhNetPackVisitor applier(*gh, *gs);
|
||||
|
||||
ptr->visit(applier);
|
||||
|
||||
return applier.getResult();
|
||||
}
|
||||
catch(ExceptionNotAllowedAction & e)
|
||||
{
|
||||
@ -230,7 +234,7 @@ template <>
|
||||
class CApplyOnGH<CPack> : public CBaseForGHApply
|
||||
{
|
||||
public:
|
||||
bool applyOnGH(CGameHandler * gh, void * pack) const override
|
||||
bool applyOnGH(CGameHandler * gh, CGameState * gs, void * pack) const override
|
||||
{
|
||||
logGlobal->error("Cannot apply on GH plain CPack!");
|
||||
assert(0);
|
||||
@ -1358,7 +1362,7 @@ void CGameHandler::handleReceivedPack(CPackForServer * pack)
|
||||
}
|
||||
else if(apply)
|
||||
{
|
||||
const bool result = apply->applyOnGH(this, pack);
|
||||
const bool result = apply->applyOnGH(this, this->gs, pack);
|
||||
if(result)
|
||||
logGlobal->trace("Message %s successfully applied!", typeid(*pack).name());
|
||||
else
|
||||
@ -2933,6 +2937,58 @@ void CGameHandler::sendAndApply(NewStructures * pack)
|
||||
checkVictoryLossConditionsForPlayer(getTown(pack->tid)->tempOwner);
|
||||
}
|
||||
|
||||
bool CGameHandler::isPlayerOwns(CPackForServer * pack, ObjectInstanceID id)
|
||||
{
|
||||
return getPlayerAt(pack->c) == getOwner(id);
|
||||
}
|
||||
|
||||
void CGameHandler::throwNotAllowedAction(CPackForServer * pack)
|
||||
{
|
||||
if(pack->c)
|
||||
{
|
||||
SystemMessage temp_message("You are not allowed to perform this action!");
|
||||
pack->c->sendPack(&temp_message);
|
||||
}
|
||||
logNetwork->error("Player is not allowed to perform this action!");
|
||||
throw ExceptionNotAllowedAction();
|
||||
}
|
||||
|
||||
void CGameHandler::wrongPlayerMessage(CPackForServer * pack, PlayerColor expectedplayer)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "You were identified as player " << getPlayerAt(pack->c) << " while expecting " << expectedplayer;
|
||||
logNetwork->error(oss.str());
|
||||
if(pack->c)
|
||||
{
|
||||
SystemMessage temp_message(oss.str());
|
||||
pack->c->sendPack(&temp_message);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::throwOnWrongOwner(CPackForServer * pack, ObjectInstanceID id)
|
||||
{
|
||||
if(!isPlayerOwns(pack, id))
|
||||
{
|
||||
wrongPlayerMessage(pack, getOwner(id));
|
||||
throwNotAllowedAction(pack);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::throwOnWrongPlayer(CPackForServer * pack, PlayerColor player)
|
||||
{
|
||||
if(!hasPlayerAt(player, pack->c) && player != getPlayerAt(pack->c))
|
||||
{
|
||||
wrongPlayerMessage(pack, player);
|
||||
throwNotAllowedAction(pack);
|
||||
}
|
||||
}
|
||||
|
||||
void CGameHandler::throwAndComplain(CPackForServer * pack, std::string txt)
|
||||
{
|
||||
complain(txt);
|
||||
throwNotAllowedAction(pack);
|
||||
}
|
||||
|
||||
void CGameHandler::save(const std::string & filename)
|
||||
{
|
||||
logGlobal->info("Saving to %s", filename);
|
||||
|
@ -303,6 +303,13 @@ public:
|
||||
void sendAndApply(SetResources * pack);
|
||||
void sendAndApply(NewStructures * pack);
|
||||
|
||||
void wrongPlayerMessage(CPackForServer * pack, PlayerColor expectedplayer);
|
||||
void throwNotAllowedAction(CPackForServer * pack);
|
||||
void throwOnWrongOwner(CPackForServer * pack, ObjectInstanceID id);
|
||||
void throwOnWrongPlayer(CPackForServer * pack, PlayerColor player);
|
||||
void throwAndComplain(CPackForServer * pack, std::string txt);
|
||||
bool isPlayerOwns(CPackForServer * pack, ObjectInstanceID id);
|
||||
|
||||
struct FinishingBattleHelper
|
||||
{
|
||||
FinishingBattleHelper();
|
||||
|
@ -14,6 +14,8 @@ set(server_HEADERS
|
||||
CGameHandler.h
|
||||
CQuery.h
|
||||
CVCMIServer.h
|
||||
LobbyNetPackVisitors.h
|
||||
ServerNetPackVisitors.h
|
||||
)
|
||||
|
||||
assign_source_group(${server_SRCS} ${server_HEADERS})
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include "../lib/StartInfo.h"
|
||||
#include "../lib/mapping/CMap.h"
|
||||
#include "../lib/rmg/CMapGenOptions.h"
|
||||
#include "../lib/NetPackVisitor.h"
|
||||
#include "LobbyNetPackVisitors.h"
|
||||
#ifdef VCMI_ANDROID
|
||||
#include <jni.h>
|
||||
#include <android/log.h>
|
||||
@ -81,10 +83,17 @@ public:
|
||||
bool applyOnServerBefore(CVCMIServer * srv, void * pack) const override
|
||||
{
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
if(ptr->checkClientPermissions(srv))
|
||||
ClientPermissionsCheckerNetPackVisitor checker(*srv);
|
||||
ptr->visit(checker);
|
||||
|
||||
if(checker.getResult())
|
||||
{
|
||||
boost::unique_lock<boost::mutex> stateLock(srv->stateMutex);
|
||||
return ptr->applyOnServer(srv);
|
||||
ApplyOnServerNetPackVisitor applier(*srv);
|
||||
|
||||
ptr->visit(applier);
|
||||
|
||||
return applier.getResult();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
@ -93,7 +102,8 @@ public:
|
||||
void applyOnServerAfter(CVCMIServer * srv, void * pack) const override
|
||||
{
|
||||
T * ptr = static_cast<T *>(pack);
|
||||
ptr->applyOnServerAfterAnnounce(srv);
|
||||
ApplyOnServerAfterAnnounceNetPackVisitor applier(*srv);
|
||||
ptr->visit(applier);
|
||||
}
|
||||
};
|
||||
|
||||
@ -363,6 +373,35 @@ void CVCMIServer::connectionAccepted(const boost::system::error_code & ec)
|
||||
startAsyncAccept();
|
||||
}
|
||||
|
||||
class CVCMIServerPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
CVCMIServer & handler;
|
||||
CGameHandler & gh;
|
||||
|
||||
public:
|
||||
CVCMIServerPackVisitor(CVCMIServer & handler, CGameHandler & gh)
|
||||
:handler(handler), gh(gh)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool callTyped() override { return false; }
|
||||
|
||||
virtual void visitForLobby(CPackForLobby & packForLobby) override
|
||||
{
|
||||
handler.handleReceivedPack(std::unique_ptr<CPackForLobby>(&packForLobby));
|
||||
}
|
||||
|
||||
virtual void visitForServer(CPackForServer & serverPack) override
|
||||
{
|
||||
gh.handleReceivedPack(&serverPack);
|
||||
}
|
||||
|
||||
virtual void visitForClient(CPackForClient & clientPack) override
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
|
||||
{
|
||||
setThreadName("CVCMIServer::handleConnection");
|
||||
@ -394,15 +433,9 @@ void CVCMIServer::threadHandleClient(std::shared_ptr<CConnection> c)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(auto lobbyPack = dynamic_ptr_cast<CPackForLobby>(pack))
|
||||
{
|
||||
handleReceivedPack(std::unique_ptr<CPackForLobby>(lobbyPack));
|
||||
}
|
||||
else if(auto serverPack = dynamic_ptr_cast<CPackForServer>(pack))
|
||||
{
|
||||
gh->handleReceivedPack(serverPack);
|
||||
}
|
||||
|
||||
CVCMIServerPackVisitor visitor(*this, *this->gh);
|
||||
pack->visit(visitor);
|
||||
}
|
||||
#ifndef _MSC_VER
|
||||
}
|
||||
@ -1051,8 +1084,16 @@ static void handleCommandOptions(int argc, char * argv[], boost::program_options
|
||||
#ifdef SINGLE_PROCESS_APP
|
||||
#define main server_main
|
||||
#endif
|
||||
#ifdef VCMI_ANDROID
|
||||
void CVCMIServer::create()
|
||||
{
|
||||
const int argc = 1;
|
||||
char * argv[argc] = { "android-server" };
|
||||
#else
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
#endif
|
||||
|
||||
#if !defined(VCMI_ANDROID) && !defined(SINGLE_PROCESS_APP)
|
||||
// Correct working dir executable folder (not bundle folder) so we can use executable relative paths
|
||||
boost::filesystem::current_path(boost::filesystem::system_complete(argv[0]).parent_path());
|
||||
@ -1120,7 +1161,10 @@ int main(int argc, char * argv[])
|
||||
#endif
|
||||
logConfig.deconfigure();
|
||||
vstd::clear_pointer(VLC);
|
||||
|
||||
#ifndef VCMI_ANDROID
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VCMI_ANDROID
|
||||
@ -1129,14 +1173,8 @@ extern "C" JNIEXPORT void JNICALL Java_eu_vcmi_vcmi_NativeMethods_createServer(J
|
||||
{
|
||||
__android_log_write(ANDROID_LOG_INFO, "VCMI", "Got jni call to init server");
|
||||
CAndroidVMHelper::cacheVM(env);
|
||||
CVCMIServer::create();
|
||||
}
|
||||
|
||||
void CVCMIServer::create()
|
||||
{
|
||||
const char * foo = "android-server";
|
||||
std::vector<const void *> argv = {foo};
|
||||
main(argv.size(), reinterpret_cast<char **>(const_cast<void **>(&*argv.begin())));
|
||||
CVCMIServer::create();
|
||||
}
|
||||
|
||||
#elif defined(SINGLE_PROCESS_APP)
|
||||
|
92
server/LobbyNetPackVisitors.h
Normal file
92
server/LobbyNetPackVisitors.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* LobbyNetPackVisitors.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../lib/NetPackVisitor.h"
|
||||
|
||||
class ClientPermissionsCheckerNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
bool result;
|
||||
CVCMIServer & srv;
|
||||
|
||||
public:
|
||||
ClientPermissionsCheckerNetPackVisitor(CVCMIServer & srv)
|
||||
:srv(srv), result(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool getResult() const
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void visitForLobby(CPackForLobby & pack) override;
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) override;
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) override;
|
||||
virtual void visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack) override;
|
||||
virtual void visitLobbyChatMessage(LobbyChatMessage & pack) override;
|
||||
virtual void visitLobbyGuiAction(LobbyGuiAction & pack) override;
|
||||
};
|
||||
|
||||
class ApplyOnServerAfterAnnounceNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
CVCMIServer & srv;
|
||||
|
||||
public:
|
||||
ApplyOnServerAfterAnnounceNetPackVisitor(CVCMIServer & srv)
|
||||
:srv(srv)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void visitForLobby(CPackForLobby & pack) override;
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) override;
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) override;
|
||||
};
|
||||
|
||||
class ApplyOnServerNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
bool result;
|
||||
CVCMIServer & srv;
|
||||
|
||||
public:
|
||||
ApplyOnServerNetPackVisitor(CVCMIServer & srv)
|
||||
:srv(srv), result(true)
|
||||
{
|
||||
}
|
||||
|
||||
bool getResult() const
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void visitLobbyClientConnected(LobbyClientConnected & pack) override;
|
||||
virtual void visitLobbyClientDisconnected(LobbyClientDisconnected & pack) override;
|
||||
virtual void visitLobbySetMap(LobbySetMap & pack) override;
|
||||
virtual void visitLobbySetCampaign(LobbySetCampaign & pack) override;
|
||||
virtual void visitLobbySetCampaignMap(LobbySetCampaignMap & pack) override;
|
||||
virtual void visitLobbySetCampaignBonus(LobbySetCampaignBonus & pack) override;
|
||||
virtual void visitLobbyEndGame(LobbyEndGame & pack) override;
|
||||
virtual void visitLobbyStartGame(LobbyStartGame & pack) override;
|
||||
virtual void visitLobbyChangeHost(LobbyChangeHost & pack) override;
|
||||
virtual void visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack) override;
|
||||
virtual void visitLobbySetPlayer(LobbySetPlayer & pack) override;
|
||||
virtual void visitLobbySetTurnTime(LobbySetTurnTime & pack) override;
|
||||
virtual void visitLobbySetDifficulty(LobbySetDifficulty & pack) override;
|
||||
virtual void visitLobbyForceSetPlayer(LobbyForceSetPlayer & pack) override;
|
||||
};
|
@ -8,6 +8,7 @@
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "LobbyNetPackVisitors.h"
|
||||
|
||||
#include "CVCMIServer.h"
|
||||
#include "CGameHandler.h"
|
||||
@ -21,328 +22,378 @@
|
||||
#include "../lib/mapping/CMapService.h"
|
||||
#include "../lib/mapping/CMapInfo.h"
|
||||
|
||||
bool CLobbyPackToServer::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitForLobby(CPackForLobby & pack)
|
||||
{
|
||||
return srv->isClientHost(c->connectionID);
|
||||
if(pack.isForServer())
|
||||
{
|
||||
result = srv.isClientHost(pack.c->connectionID);
|
||||
}
|
||||
}
|
||||
|
||||
void CLobbyPackToServer::applyOnServerAfterAnnounce(CVCMIServer * srv)
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitForLobby(CPackForLobby & pack)
|
||||
{
|
||||
// Propogate options after every CLobbyPackToServer
|
||||
srv->updateAndPropagateLobbyState();
|
||||
if(pack.isForServer())
|
||||
{
|
||||
srv.updateAndPropagateLobbyState();
|
||||
}
|
||||
}
|
||||
|
||||
bool LobbyClientConnected::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)
|
||||
{
|
||||
if(srv->gh)
|
||||
if(srv.gh)
|
||||
{
|
||||
for(auto & connection : srv->hangingConnections)
|
||||
for(auto & connection : srv.hangingConnections)
|
||||
{
|
||||
if(connection->uuid == uuid)
|
||||
if(connection->uuid == pack.uuid)
|
||||
{
|
||||
return true;
|
||||
{
|
||||
result = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(srv->state == EServerState::LOBBY)
|
||||
return true;
|
||||
if(srv.state == EServerState::LOBBY)
|
||||
{
|
||||
result = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//disconnect immediately and ignore this client
|
||||
srv->connections.erase(c);
|
||||
if(c && c->isOpen())
|
||||
srv.connections.erase(pack.c);
|
||||
if(pack.c && pack.c->isOpen())
|
||||
{
|
||||
c->close();
|
||||
c->connected = false;
|
||||
pack.c->close();
|
||||
pack.c->connected = false;
|
||||
}
|
||||
{
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LobbyClientConnected::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)
|
||||
{
|
||||
if(srv->gh)
|
||||
if(srv.gh)
|
||||
{
|
||||
for(auto & connection : srv->hangingConnections)
|
||||
for(auto & connection : srv.hangingConnections)
|
||||
{
|
||||
if(connection->uuid == uuid)
|
||||
if(connection->uuid == pack.uuid)
|
||||
{
|
||||
logNetwork->info("Reconnection player");
|
||||
c->connectionID = connection->connectionID;
|
||||
for(auto & playerConnection : srv->gh->connections)
|
||||
pack.c->connectionID = connection->connectionID;
|
||||
for(auto & playerConnection : srv.gh->connections)
|
||||
{
|
||||
for(auto & existingConnection : playerConnection.second)
|
||||
{
|
||||
if(existingConnection == connection)
|
||||
{
|
||||
playerConnection.second.erase(existingConnection);
|
||||
playerConnection.second.insert(c);
|
||||
playerConnection.second.insert(pack.c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
srv->hangingConnections.erase(connection);
|
||||
srv.hangingConnections.erase(connection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
srv->clientConnected(c, names, uuid, mode);
|
||||
srv.clientConnected(pack.c, pack.names, pack.uuid, pack.mode);
|
||||
// Server need to pass some data to newly connected client
|
||||
clientId = c->connectionID;
|
||||
mode = srv->si->mode;
|
||||
hostClientId = srv->hostClientId;
|
||||
return true;
|
||||
pack.clientId = pack.c->connectionID;
|
||||
pack.mode = srv.si->mode;
|
||||
pack.hostClientId = srv.hostClientId;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
void LobbyClientConnected::applyOnServerAfterAnnounce(CVCMIServer * srv)
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyClientConnected(LobbyClientConnected & pack)
|
||||
{
|
||||
// FIXME: we need to avoid senting something to client that not yet get answer for LobbyClientConnected
|
||||
// Until UUID set we only pass LobbyClientConnected to this client
|
||||
c->uuid = uuid;
|
||||
srv->updateAndPropagateLobbyState();
|
||||
if(srv->state == EServerState::GAMEPLAY)
|
||||
pack.c->uuid = pack.uuid;
|
||||
srv.updateAndPropagateLobbyState();
|
||||
if(srv.state == EServerState::GAMEPLAY)
|
||||
{
|
||||
//immediately start game
|
||||
std::unique_ptr<LobbyStartGame> startGameForReconnectedPlayer(new LobbyStartGame);
|
||||
startGameForReconnectedPlayer->initializedStartInfo = srv->si;
|
||||
startGameForReconnectedPlayer->initializedGameState = srv->gh->gameState();
|
||||
startGameForReconnectedPlayer->clientId = c->connectionID;
|
||||
srv->addToAnnounceQueue(std::move(startGameForReconnectedPlayer));
|
||||
startGameForReconnectedPlayer->initializedStartInfo = srv.si;
|
||||
startGameForReconnectedPlayer->initializedGameState = srv.gh->gameState();
|
||||
startGameForReconnectedPlayer->clientId = pack.c->connectionID;
|
||||
srv.addToAnnounceQueue(std::move(startGameForReconnectedPlayer));
|
||||
}
|
||||
}
|
||||
|
||||
bool LobbyClientDisconnected::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
|
||||
{
|
||||
if(clientId != c->connectionID)
|
||||
return false;
|
||||
|
||||
if(shutdownServer)
|
||||
if(pack.clientId != pack.c->connectionID)
|
||||
{
|
||||
if(!srv->cmdLineOptions.count("run-by-client"))
|
||||
return false;
|
||||
|
||||
if(c->uuid != srv->cmdLineOptions["uuid"].as<std::string>())
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LobbyClientDisconnected::applyOnServer(CVCMIServer * srv)
|
||||
{
|
||||
srv->clientDisconnected(c);
|
||||
c->close();
|
||||
c->connected = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LobbyClientDisconnected::applyOnServerAfterAnnounce(CVCMIServer * srv)
|
||||
{
|
||||
if(c && c->isOpen())
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*c->mutexWrite);
|
||||
c->close();
|
||||
c->connected = false;
|
||||
}
|
||||
|
||||
if(shutdownServer)
|
||||
{
|
||||
logNetwork->info("Client requested shutdown, server will close itself...");
|
||||
srv->state = EServerState::SHUTDOWN;
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
else if(srv->connections.empty())
|
||||
|
||||
if(pack.shutdownServer)
|
||||
{
|
||||
if(!srv.cmdLineOptions.count("run-by-client"))
|
||||
{
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(pack.c->uuid != srv.cmdLineOptions["uuid"].as<std::string>())
|
||||
{
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
|
||||
{
|
||||
srv.clientDisconnected(pack.c);
|
||||
pack.c->close();
|
||||
pack.c->connected = false;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
|
||||
{
|
||||
if(pack.c && pack.c->isOpen())
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(*pack.c->mutexWrite);
|
||||
pack.c->close();
|
||||
pack.c->connected = false;
|
||||
}
|
||||
|
||||
if(pack.shutdownServer)
|
||||
{
|
||||
logNetwork->info("Client requested shutdown, server will close itself...");
|
||||
srv.state = EServerState::SHUTDOWN;
|
||||
return;
|
||||
}
|
||||
else if(srv.connections.empty())
|
||||
{
|
||||
logNetwork->error("Last connection lost, server will close itself...");
|
||||
srv->state = EServerState::SHUTDOWN;
|
||||
srv.state = EServerState::SHUTDOWN;
|
||||
}
|
||||
else if(c == srv->hostClient)
|
||||
else if(pack.c == srv.hostClient)
|
||||
{
|
||||
auto ph = std::make_unique<LobbyChangeHost>();
|
||||
auto newHost = *RandomGeneratorUtil::nextItem(srv->connections, CRandomGenerator::getDefault());
|
||||
auto newHost = *RandomGeneratorUtil::nextItem(srv.connections, CRandomGenerator::getDefault());
|
||||
ph->newHostConnectionId = newHost->connectionID;
|
||||
srv->addToAnnounceQueue(std::move(ph));
|
||||
srv.addToAnnounceQueue(std::move(ph));
|
||||
}
|
||||
srv->updateAndPropagateLobbyState();
|
||||
srv.updateAndPropagateLobbyState();
|
||||
}
|
||||
|
||||
bool LobbyChatMessage::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyChatMessage(LobbyChatMessage & pack)
|
||||
{
|
||||
return true;
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbySetMap::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbySetMap(LobbySetMap & pack)
|
||||
{
|
||||
if(srv->state != EServerState::LOBBY)
|
||||
return false;
|
||||
|
||||
srv->updateStartInfoOnMapChange(mapInfo, mapGenOpts);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LobbySetCampaign::applyOnServer(CVCMIServer * srv)
|
||||
{
|
||||
srv->si->mapname = ourCampaign->camp->header.filename;
|
||||
srv->si->mode = StartInfo::CAMPAIGN;
|
||||
srv->si->campState = ourCampaign;
|
||||
srv->si->turnTime = 0;
|
||||
bool isCurrentMapConquerable = ourCampaign->currentMap && ourCampaign->camp->conquerable(*ourCampaign->currentMap);
|
||||
for(int i = 0; i < ourCampaign->camp->scenarios.size(); i++)
|
||||
if(srv.state != EServerState::LOBBY)
|
||||
{
|
||||
if(ourCampaign->camp->conquerable(i))
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
srv.updateStartInfoOnMapChange(pack.mapInfo, pack.mapGenOpts);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
void ApplyOnServerNetPackVisitor::visitLobbySetCampaign(LobbySetCampaign & pack)
|
||||
{
|
||||
srv.si->mapname = pack.ourCampaign->camp->header.filename;
|
||||
srv.si->mode = StartInfo::CAMPAIGN;
|
||||
srv.si->campState = pack.ourCampaign;
|
||||
srv.si->turnTime = 0;
|
||||
bool isCurrentMapConquerable = pack.ourCampaign->currentMap && pack.ourCampaign->camp->conquerable(*pack.ourCampaign->currentMap);
|
||||
for(int i = 0; i < pack.ourCampaign->camp->scenarios.size(); i++)
|
||||
{
|
||||
if(pack.ourCampaign->camp->conquerable(i))
|
||||
{
|
||||
if(!isCurrentMapConquerable || (isCurrentMapConquerable && i == *ourCampaign->currentMap))
|
||||
if(!isCurrentMapConquerable || (isCurrentMapConquerable && i == *pack.ourCampaign->currentMap))
|
||||
{
|
||||
srv->setCampaignMap(i);
|
||||
srv.setCampaignMap(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbySetCampaignMap::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbySetCampaignMap(LobbySetCampaignMap & pack)
|
||||
{
|
||||
srv->setCampaignMap(mapId);
|
||||
return true;
|
||||
srv.setCampaignMap(pack.mapId);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbySetCampaignBonus::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbySetCampaignBonus(LobbySetCampaignBonus & pack)
|
||||
{
|
||||
srv->setCampaignBonus(bonusId);
|
||||
return true;
|
||||
srv.setCampaignBonus(pack.bonusId);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbyGuiAction::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyGuiAction(LobbyGuiAction & pack)
|
||||
{
|
||||
return srv->isClientHost(c->connectionID);
|
||||
result = srv.isClientHost(pack.c->connectionID);
|
||||
}
|
||||
|
||||
bool LobbyEndGame::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
{
|
||||
return srv->isClientHost(c->connectionID);
|
||||
result = srv.isClientHost(pack.c->connectionID);
|
||||
}
|
||||
|
||||
bool LobbyEndGame::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
{
|
||||
srv->prepareToRestart();
|
||||
return true;
|
||||
srv.prepareToRestart();
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
void LobbyEndGame::applyOnServerAfterAnnounce(CVCMIServer * srv)
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyEndGame(LobbyEndGame & pack)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> stateLock(srv->stateMutex);
|
||||
for(auto & c : srv->connections)
|
||||
boost::unique_lock<boost::mutex> stateLock(srv.stateMutex);
|
||||
for(auto & c : srv.connections)
|
||||
{
|
||||
c->enterLobbyConnectionMode();
|
||||
c->disableStackSendingByID();
|
||||
}
|
||||
}
|
||||
|
||||
bool LobbyStartGame::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
{
|
||||
return srv->isClientHost(c->connectionID);
|
||||
result = srv.isClientHost(pack.c->connectionID);
|
||||
}
|
||||
|
||||
bool LobbyStartGame::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
{
|
||||
try
|
||||
{
|
||||
srv->verifyStateBeforeStart(true);
|
||||
srv.verifyStateBeforeStart(true);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return false;
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
// Server will prepare gamestate and we announce StartInfo to clients
|
||||
if(!srv->prepareToStartGame())
|
||||
return false;
|
||||
if(!srv.prepareToStartGame())
|
||||
{
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
initializedStartInfo = std::make_shared<StartInfo>(*srv->gh->getStartInfo(true));
|
||||
initializedGameState = srv->gh->gameState();
|
||||
pack.initializedStartInfo = std::make_shared<StartInfo>(*srv.gh->getStartInfo(true));
|
||||
pack.initializedGameState = srv.gh->gameState();
|
||||
|
||||
return true;
|
||||
result = true;
|
||||
}
|
||||
|
||||
void LobbyStartGame::applyOnServerAfterAnnounce(CVCMIServer * srv)
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyStartGame(LobbyStartGame & pack)
|
||||
{
|
||||
if(clientId == -1) //do not restart game for single client only
|
||||
srv->startGameImmidiately();
|
||||
if(pack.clientId == -1) //do not restart game for single client only
|
||||
srv.startGameImmidiately();
|
||||
else
|
||||
{
|
||||
for(auto & c : srv->connections)
|
||||
for(auto & c : srv.connections)
|
||||
{
|
||||
if(c->connectionID == clientId)
|
||||
if(c->connectionID == pack.clientId)
|
||||
{
|
||||
c->enterGameplayConnectionMode(srv->gh->gameState());
|
||||
srv->reconnectPlayer(clientId);
|
||||
c->enterGameplayConnectionMode(srv.gh->gameState());
|
||||
srv.reconnectPlayer(pack.clientId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LobbyChangeHost::checkClientPermissions(CVCMIServer * srv) const
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyChangeHost(LobbyChangeHost & pack)
|
||||
{
|
||||
return srv->isClientHost(c->connectionID);
|
||||
result = srv.isClientHost(pack.c->connectionID);
|
||||
}
|
||||
|
||||
bool LobbyChangeHost::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyChangeHost(LobbyChangeHost & pack)
|
||||
{
|
||||
return true;
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbyChangeHost::applyOnServerAfterAnnounce(CVCMIServer * srv)
|
||||
void ApplyOnServerAfterAnnounceNetPackVisitor::visitLobbyChangeHost(LobbyChangeHost & pack)
|
||||
{
|
||||
return srv->passHost(newHostConnectionId);
|
||||
}
|
||||
|
||||
bool LobbyChangePlayerOption::checkClientPermissions(CVCMIServer * srv) const
|
||||
{
|
||||
if(srv->isClientHost(c->connectionID))
|
||||
return true;
|
||||
|
||||
if(vstd::contains(srv->getAllClientPlayers(c->connectionID), color))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LobbyChangePlayerOption::applyOnServer(CVCMIServer * srv)
|
||||
{
|
||||
switch(what)
|
||||
auto result = srv.passHost(pack.newHostConnectionId);
|
||||
|
||||
if(!result)
|
||||
{
|
||||
case TOWN:
|
||||
srv->optionNextCastle(color, direction);
|
||||
logGlobal->error("passHost returned false. What does it mean?");
|
||||
}
|
||||
}
|
||||
|
||||
void ClientPermissionsCheckerNetPackVisitor::visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack)
|
||||
{
|
||||
if(srv.isClientHost(pack.c->connectionID))
|
||||
{
|
||||
result = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(vstd::contains(srv.getAllClientPlayers(pack.c->connectionID), pack.color))
|
||||
{
|
||||
result = true;
|
||||
return;
|
||||
}
|
||||
|
||||
result = false;
|
||||
}
|
||||
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyChangePlayerOption(LobbyChangePlayerOption & pack)
|
||||
{
|
||||
switch(pack.what)
|
||||
{
|
||||
case LobbyChangePlayerOption::TOWN:
|
||||
srv.optionNextCastle(pack.color, pack.direction);
|
||||
break;
|
||||
case HERO:
|
||||
srv->optionNextHero(color, direction);
|
||||
case LobbyChangePlayerOption::HERO:
|
||||
srv.optionNextHero(pack.color, pack.direction);
|
||||
break;
|
||||
case BONUS:
|
||||
srv->optionNextBonus(color, direction);
|
||||
case LobbyChangePlayerOption::BONUS:
|
||||
srv.optionNextBonus(pack.color, pack.direction);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbySetPlayer::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbySetPlayer(LobbySetPlayer & pack)
|
||||
{
|
||||
srv->setPlayer(clickedColor);
|
||||
return true;
|
||||
srv.setPlayer(pack.clickedColor);
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbySetTurnTime::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbySetTurnTime(LobbySetTurnTime & pack)
|
||||
{
|
||||
srv->si->turnTime = turnTime;
|
||||
return true;
|
||||
srv.si->turnTime = pack.turnTime;
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbySetDifficulty::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbySetDifficulty(LobbySetDifficulty & pack)
|
||||
{
|
||||
srv->si->difficulty = vstd::abetween(difficulty, 0, 4);
|
||||
return true;
|
||||
srv.si->difficulty = vstd::abetween(pack.difficulty, 0, 4);
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool LobbyForceSetPlayer::applyOnServer(CVCMIServer * srv)
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyForceSetPlayer(LobbyForceSetPlayer & pack)
|
||||
{
|
||||
srv->si->playerInfos[targetPlayerColor].connectedPlayerIDs.insert(targetConnectedPlayer);
|
||||
return true;
|
||||
srv.si->playerInfos[pack.targetPlayerColor].connectedPlayerIDs.insert(pack.targetConnectedPlayer);
|
||||
result = true;
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
#include "ServerNetPackVisitors.h"
|
||||
|
||||
#include "CGameHandler.h"
|
||||
#include "../lib/IGameCallback.h"
|
||||
@ -22,384 +22,330 @@
|
||||
#include "../lib/spells/ISpellMechanics.h"
|
||||
#include "../lib/serializer/Cast.h"
|
||||
|
||||
bool CPackForServer::isPlayerOwns(CGameHandler * gh, ObjectInstanceID id)
|
||||
void ApplyGhNetPackVisitor::visitSaveGame(SaveGame & pack)
|
||||
{
|
||||
return gh->getPlayerAt(c) == gh->getOwner(id);
|
||||
gh.save(pack.fname);
|
||||
logGlobal->info("Game has been saved as %s", pack.fname);
|
||||
result = true;
|
||||
}
|
||||
|
||||
void CPackForServer::throwNotAllowedAction()
|
||||
void ApplyGhNetPackVisitor::visitEndTurn(EndTurn & pack)
|
||||
{
|
||||
if(c)
|
||||
PlayerColor currentPlayer = gs.currentPlayer;
|
||||
if(pack.player != currentPlayer)
|
||||
{
|
||||
SystemMessage temp_message("You are not allowed to perform this action!");
|
||||
c->sendPack(&temp_message);
|
||||
}
|
||||
logNetwork->error("Player is not allowed to perform this action!");
|
||||
throw ExceptionNotAllowedAction();
|
||||
}
|
||||
if(gh.getPlayerStatus(pack.player) == EPlayerStatus::INGAME)
|
||||
gh.throwAndComplain(&pack, "pack.player attempted to end turn for another pack.player!");
|
||||
|
||||
void CPackForServer::wrongPlayerMessage(CGameHandler * gh, PlayerColor expectedplayer)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
oss << "You were identified as player " << gh->getPlayerAt(c) << " while expecting " << expectedplayer;
|
||||
logNetwork->error(oss.str());
|
||||
if(c)
|
||||
{
|
||||
SystemMessage temp_message(oss.str());
|
||||
c->sendPack(&temp_message);
|
||||
}
|
||||
}
|
||||
logGlobal->debug("pack.player attempted to end turn after game over. Ignoring this request.");
|
||||
|
||||
void CPackForServer::throwOnWrongOwner(CGameHandler * gh, ObjectInstanceID id)
|
||||
{
|
||||
if(!isPlayerOwns(gh, id))
|
||||
{
|
||||
wrongPlayerMessage(gh, gh->getOwner(id));
|
||||
throwNotAllowedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void CPackForServer::throwOnWrongPlayer(CGameHandler * gh, PlayerColor player)
|
||||
{
|
||||
if(!gh->hasPlayerAt(player, c) && player != gh->getPlayerAt(c))
|
||||
{
|
||||
wrongPlayerMessage(gh, player);
|
||||
throwNotAllowedAction();
|
||||
}
|
||||
}
|
||||
|
||||
void CPackForServer::throwAndComplain(CGameHandler * gh, std::string txt)
|
||||
{
|
||||
gh->complain(txt);
|
||||
throwNotAllowedAction();
|
||||
}
|
||||
|
||||
|
||||
CGameState * CPackForServer::GS(CGameHandler * gh)
|
||||
{
|
||||
return gh->gs;
|
||||
}
|
||||
|
||||
bool SaveGame::applyGh(CGameHandler * gh)
|
||||
{
|
||||
gh->save(fname);
|
||||
logGlobal->info("Game has been saved as %s", fname);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EndTurn::applyGh(CGameHandler * gh)
|
||||
{
|
||||
PlayerColor currentPlayer = GS(gh)->currentPlayer;
|
||||
if(player != currentPlayer)
|
||||
{
|
||||
if(gh->getPlayerStatus(player) == EPlayerStatus::INGAME)
|
||||
throwAndComplain(gh, "Player attempted to end turn for another player!");
|
||||
|
||||
logGlobal->debug("Player attempted to end turn after game over. Ignoring this request.");
|
||||
|
||||
return true;
|
||||
result = true;
|
||||
return;
|
||||
}
|
||||
|
||||
throwOnWrongPlayer(gh, player);
|
||||
if(gh->queries.topQuery(player))
|
||||
throwAndComplain(gh, "Cannot end turn before resolving queries!");
|
||||
gh.throwOnWrongPlayer(&pack, pack.player);
|
||||
if(gh.queries.topQuery(pack.player))
|
||||
gh.throwAndComplain(&pack, "Cannot end turn before resolving queries!");
|
||||
|
||||
gh->states.setFlag(GS(gh)->currentPlayer, &PlayerStatus::makingTurn, false);
|
||||
return true;
|
||||
gh.states.setFlag(gs.currentPlayer, &PlayerStatus::makingTurn, false);
|
||||
result = true;
|
||||
}
|
||||
|
||||
bool DismissHero::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitDismissHero(DismissHero & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, hid);
|
||||
return gh->removeObject(gh->getObj(hid));
|
||||
gh.throwOnWrongOwner(&pack, pack.hid);
|
||||
result = gh.removeObject(gh.getObj(pack.hid));
|
||||
}
|
||||
|
||||
bool MoveHero::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitMoveHero(MoveHero & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, hid);
|
||||
return gh->moveHero(hid, dest, 0, transit, gh->getPlayerAt(c));
|
||||
gh.throwOnWrongOwner(&pack, pack.hid);
|
||||
result = gh.moveHero(pack.hid, pack.dest, 0, pack.transit, gh.getPlayerAt(pack.c));
|
||||
}
|
||||
|
||||
bool CastleTeleportHero::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitCastleTeleportHero(CastleTeleportHero & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, hid);
|
||||
gh.throwOnWrongOwner(&pack, pack.hid);
|
||||
|
||||
return gh->teleportHero(hid, dest, source, gh->getPlayerAt(c));
|
||||
result = gh.teleportHero(pack.hid, pack.dest, pack.source, gh.getPlayerAt(pack.c));
|
||||
}
|
||||
|
||||
bool ArrangeStacks::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitArrangeStacks(ArrangeStacks & pack)
|
||||
{
|
||||
//checks for owning in the gh func
|
||||
return gh->arrangeStacks(id1, id2, what, p1, p2, val, gh->getPlayerAt(c));
|
||||
result = gh.arrangeStacks(pack.id1, pack.id2, pack.what, pack.p1, pack.p2, pack.val, gh.getPlayerAt(pack.c));
|
||||
}
|
||||
|
||||
bool BulkMoveArmy::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitBulkMoveArmy(BulkMoveArmy & pack)
|
||||
{
|
||||
return gh->bulkMoveArmy(srcArmy, destArmy, srcSlot);
|
||||
result = gh.bulkMoveArmy(pack.srcArmy, pack.destArmy, pack.srcSlot);
|
||||
}
|
||||
|
||||
bool BulkSplitStack::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitBulkSplitStack(BulkSplitStack & pack)
|
||||
{
|
||||
return gh->bulkSplitStack(src, srcOwner, amount);
|
||||
result = gh.bulkSplitStack(pack.src, pack.srcOwner, pack.amount);
|
||||
}
|
||||
|
||||
bool BulkMergeStacks::applyGh(CGameHandler* gh)
|
||||
void ApplyGhNetPackVisitor::visitBulkMergeStacks(BulkMergeStacks & pack)
|
||||
{
|
||||
return gh->bulkMergeStacks(src, srcOwner);
|
||||
result = gh.bulkMergeStacks(pack.src, pack.srcOwner);
|
||||
}
|
||||
|
||||
bool BulkSmartSplitStack::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitBulkSmartSplitStack(BulkSmartSplitStack & pack)
|
||||
{
|
||||
return gh->bulkSmartSplitStack(src, srcOwner);
|
||||
result = gh.bulkSmartSplitStack(pack.src, pack.srcOwner);
|
||||
}
|
||||
|
||||
bool DisbandCreature::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitDisbandCreature(DisbandCreature & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, id);
|
||||
return gh->disbandCreature(id, pos);
|
||||
gh.throwOnWrongOwner(&pack, pack.id);
|
||||
result = gh.disbandCreature(pack.id, pack.pos);
|
||||
}
|
||||
|
||||
bool BuildStructure::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitBuildStructure(BuildStructure & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, tid);
|
||||
return gh->buildStructure(tid, bid);
|
||||
gh.throwOnWrongOwner(&pack, pack.tid);
|
||||
result = gh.buildStructure(pack.tid, pack.bid);
|
||||
}
|
||||
|
||||
bool RecruitCreatures::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitRecruitCreatures(RecruitCreatures & pack)
|
||||
{
|
||||
return gh->recruitCreatures(tid, dst, crid, amount, level);
|
||||
result = gh.recruitCreatures(pack.tid, pack.dst, pack.crid, pack.amount, pack.level);
|
||||
}
|
||||
|
||||
bool UpgradeCreature::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitUpgradeCreature(UpgradeCreature & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, id);
|
||||
return gh->upgradeCreature(id, pos, cid);
|
||||
gh.throwOnWrongOwner(&pack, pack.id);
|
||||
result = gh.upgradeCreature(pack.id, pack.pos, pack.cid);
|
||||
}
|
||||
|
||||
bool GarrisonHeroSwap::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitGarrisonHeroSwap(GarrisonHeroSwap & pack)
|
||||
{
|
||||
const CGTownInstance * town = gh->getTown(tid);
|
||||
if(!isPlayerOwns(gh, tid) && !(town->garrisonHero && isPlayerOwns(gh, town->garrisonHero->id)))
|
||||
throwNotAllowedAction(); //neither town nor garrisoned hero (if present) is ours
|
||||
return gh->garrisonSwap(tid);
|
||||
const CGTownInstance * town = gh.getTown(pack.tid);
|
||||
if(!gh.isPlayerOwns(&pack, pack.tid) && !(town->garrisonHero && gh.isPlayerOwns(&pack, town->garrisonHero->id)))
|
||||
gh.throwNotAllowedAction(&pack); //neither town nor garrisoned hero (if present) is ours
|
||||
result = gh.garrisonSwap(pack.tid);
|
||||
}
|
||||
|
||||
bool ExchangeArtifacts::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitExchangeArtifacts(ExchangeArtifacts & pack)
|
||||
{
|
||||
throwOnWrongPlayer(gh, src.owningPlayer()); //second hero can be ally
|
||||
return gh->moveArtifact(src, dst);
|
||||
gh.throwOnWrongPlayer(&pack, pack.src.owningPlayer()); //second hero can be ally
|
||||
result = gh.moveArtifact(pack.src, pack.dst);
|
||||
}
|
||||
|
||||
bool BulkExchangeArtifacts::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack)
|
||||
{
|
||||
const CGHeroInstance * pSrcHero = gh->getHero(srcHero);
|
||||
throwOnWrongPlayer(gh, pSrcHero->getOwner());
|
||||
return gh->bulkMoveArtifacts(srcHero, dstHero, swap);
|
||||
const CGHeroInstance * pSrcHero = gh.getHero(pack.srcHero);
|
||||
gh.throwOnWrongPlayer(&pack, pSrcHero->getOwner());
|
||||
result = gh.bulkMoveArtifacts(pack.srcHero, pack.dstHero, pack.swap);
|
||||
}
|
||||
|
||||
bool AssembleArtifacts::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitAssembleArtifacts(AssembleArtifacts & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, heroID);
|
||||
return gh->assembleArtifacts(heroID, artifactSlot, assemble, assembleTo);
|
||||
gh.throwOnWrongOwner(&pack, pack.heroID);
|
||||
result = gh.assembleArtifacts(pack.heroID, pack.artifactSlot, pack.assemble, pack.assembleTo);
|
||||
}
|
||||
|
||||
bool BuyArtifact::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitBuyArtifact(BuyArtifact & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, hid);
|
||||
return gh->buyArtifact(hid, aid);
|
||||
gh.throwOnWrongOwner(&pack, pack.hid);
|
||||
result = gh.buyArtifact(pack.hid, pack.aid);
|
||||
}
|
||||
|
||||
bool TradeOnMarketplace::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitTradeOnMarketplace(TradeOnMarketplace & pack)
|
||||
{
|
||||
const CGObjectInstance * market = gh->getObj(marketId);
|
||||
const CGObjectInstance * market = gh.getObj(pack.marketId);
|
||||
if(!market)
|
||||
throwAndComplain(gh, "Invalid market object");
|
||||
const CGHeroInstance * hero = gh->getHero(heroId);
|
||||
gh.throwAndComplain(&pack, "Invalid market object");
|
||||
const CGHeroInstance * hero = gh.getHero(pack.heroId);
|
||||
|
||||
//market must be owned or visited
|
||||
const IMarket * m = IMarket::castFrom(market);
|
||||
|
||||
if(!m)
|
||||
throwAndComplain(gh, "market is not-a-market! :/");
|
||||
gh.throwAndComplain(&pack, "market is not-a-market! :/");
|
||||
|
||||
PlayerColor player = market->tempOwner;
|
||||
|
||||
if(player >= PlayerColor::PLAYER_LIMIT)
|
||||
player = gh->getTile(market->visitablePos())->visitableObjects.back()->tempOwner;
|
||||
player = gh.getTile(market->visitablePos())->visitableObjects.back()->tempOwner;
|
||||
|
||||
if(player >= PlayerColor::PLAYER_LIMIT)
|
||||
throwAndComplain(gh, "No player can use this market!");
|
||||
gh.throwAndComplain(&pack, "No player can use this market!");
|
||||
|
||||
bool allyTownSkillTrade = (mode == EMarketMode::RESOURCE_SKILL && gh->getPlayerRelations(player, hero->tempOwner) == PlayerRelations::ALLIES);
|
||||
bool allyTownSkillTrade = (pack.mode == EMarketMode::RESOURCE_SKILL && gh.getPlayerRelations(player, hero->tempOwner) == PlayerRelations::ALLIES);
|
||||
|
||||
if(hero && (!(player == hero->tempOwner || allyTownSkillTrade)
|
||||
|| hero->visitablePos() != market->visitablePos()))
|
||||
throwAndComplain(gh, "This hero can't use this marketplace!");
|
||||
gh.throwAndComplain(&pack, "This hero can't use this marketplace!");
|
||||
|
||||
if(!allyTownSkillTrade)
|
||||
throwOnWrongPlayer(gh, player);
|
||||
gh.throwOnWrongPlayer(&pack, player);
|
||||
|
||||
bool result = true;
|
||||
result = true;
|
||||
|
||||
switch(mode)
|
||||
switch(pack.mode)
|
||||
{
|
||||
case EMarketMode::RESOURCE_RESOURCE:
|
||||
for(int i = 0; i < r1.size(); ++i)
|
||||
result &= gh->tradeResources(m, val[i], player, r1[i], r2[i]);
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.tradeResources(m, pack.val[i], player, pack.r1[i], pack.r2[i]);
|
||||
break;
|
||||
case EMarketMode::RESOURCE_PLAYER:
|
||||
for(int i = 0; i < r1.size(); ++i)
|
||||
result &= gh->sendResources(val[i], player, static_cast<Res::ERes>(r1[i]), PlayerColor(r2[i]));
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.sendResources(pack.val[i], player, static_cast<Res::ERes>(pack.r1[i]), PlayerColor(pack.r2[i]));
|
||||
break;
|
||||
case EMarketMode::CREATURE_RESOURCE:
|
||||
for(int i = 0; i < r1.size(); ++i)
|
||||
result &= gh->sellCreatures(val[i], m, hero, SlotID(r1[i]), static_cast<Res::ERes>(r2[i]));
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.sellCreatures(pack.val[i], m, hero, SlotID(pack.r1[i]), static_cast<Res::ERes>(pack.r2[i]));
|
||||
break;
|
||||
case EMarketMode::RESOURCE_ARTIFACT:
|
||||
for(int i = 0; i < r1.size(); ++i)
|
||||
result &= gh->buyArtifact(m, hero, static_cast<Res::ERes>(r1[i]), ArtifactID(r2[i]));
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.buyArtifact(m, hero, static_cast<Res::ERes>(pack.r1[i]), ArtifactID(pack.r2[i]));
|
||||
break;
|
||||
case EMarketMode::ARTIFACT_RESOURCE:
|
||||
for(int i = 0; i < r1.size(); ++i)
|
||||
result &= gh->sellArtifact(m, hero, ArtifactInstanceID(r1[i]), static_cast<Res::ERes>(r2[i]));
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.sellArtifact(m, hero, ArtifactInstanceID(pack.r1[i]), static_cast<Res::ERes>(pack.r2[i]));
|
||||
break;
|
||||
case EMarketMode::CREATURE_UNDEAD:
|
||||
for(int i = 0; i < r1.size(); ++i)
|
||||
result &= gh->transformInUndead(m, hero, SlotID(r1[i]));
|
||||
for(int i = 0; i < pack.r1.size(); ++i)
|
||||
result &= gh.transformInUndead(m, hero, SlotID(pack.r1[i]));
|
||||
break;
|
||||
case EMarketMode::RESOURCE_SKILL:
|
||||
for(int i = 0; i < r2.size(); ++i)
|
||||
result &= gh->buySecSkill(m, hero, SecondarySkill(r2[i]));
|
||||
for(int i = 0; i < pack.r2.size(); ++i)
|
||||
result &= gh.buySecSkill(m, hero, SecondarySkill(pack.r2[i]));
|
||||
break;
|
||||
case EMarketMode::CREATURE_EXP:
|
||||
{
|
||||
std::vector<SlotID> slotIDs(r1.begin(), r1.end());
|
||||
std::vector<ui32> count(val.begin(), val.end());
|
||||
return gh->sacrificeCreatures(m, hero, slotIDs, count);
|
||||
std::vector<SlotID> slotIDs(pack.r1.begin(), pack.r1.end());
|
||||
std::vector<ui32> count(pack.val.begin(), pack.val.end());
|
||||
result = gh.sacrificeCreatures(m, hero, slotIDs, count);
|
||||
return;
|
||||
}
|
||||
case EMarketMode::ARTIFACT_EXP:
|
||||
{
|
||||
std::vector<ArtifactPosition> positions(r1.begin(), r1.end());
|
||||
return gh->sacrificeArtifact(m, hero, positions);
|
||||
std::vector<ArtifactPosition> positions(pack.r1.begin(), pack.r1.end());
|
||||
result = gh.sacrificeArtifact(m, hero, positions);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
throwAndComplain(gh, "Unknown exchange mode!");
|
||||
gh.throwAndComplain(&pack, "Unknown exchange pack.mode!");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool SetFormation::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitSetFormation(SetFormation & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, hid);
|
||||
return gh->setFormation(hid, formation);
|
||||
gh.throwOnWrongOwner(&pack, pack.hid);
|
||||
result = gh.setFormation(pack.hid, pack.formation);
|
||||
}
|
||||
|
||||
bool HireHero::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitHireHero(HireHero & pack)
|
||||
{
|
||||
const CGObjectInstance * obj = gh->getObj(tid);
|
||||
const CGObjectInstance * obj = gh.getObj(pack.tid);
|
||||
const CGTownInstance * town = dynamic_ptr_cast<CGTownInstance>(obj);
|
||||
if(town && PlayerRelations::ENEMIES == gh->getPlayerRelations(obj->tempOwner, gh->getPlayerAt(c)))
|
||||
throwAndComplain(gh, "Can't buy hero in enemy town!");
|
||||
if(town && PlayerRelations::ENEMIES == gh.getPlayerRelations(obj->tempOwner, gh.getPlayerAt(pack.c)))
|
||||
gh.throwAndComplain(&pack, "Can't buy hero in enemy town!");
|
||||
|
||||
return gh->hireHero(obj, hid, player);
|
||||
result = gh.hireHero(obj, pack.hid, pack.player);
|
||||
}
|
||||
|
||||
bool BuildBoat::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitBuildBoat(BuildBoat & pack)
|
||||
{
|
||||
if(gh->getPlayerRelations(gh->getOwner(objid), gh->getPlayerAt(c)) == PlayerRelations::ENEMIES)
|
||||
throwAndComplain(gh, "Can't build boat at enemy shipyard");
|
||||
if(gh.getPlayerRelations(gh.getOwner(pack.objid), gh.getPlayerAt(pack.c)) == PlayerRelations::ENEMIES)
|
||||
gh.throwAndComplain(&pack, "Can't build boat at enemy shipyard");
|
||||
|
||||
return gh->buildBoat(objid);
|
||||
result = gh.buildBoat(pack.objid);
|
||||
}
|
||||
|
||||
bool QueryReply::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitQueryReply(QueryReply & pack)
|
||||
{
|
||||
auto playerToConnection = gh->connections.find(player);
|
||||
if(playerToConnection == gh->connections.end())
|
||||
throwAndComplain(gh, "No such player!");
|
||||
if(!vstd::contains(playerToConnection->second, c))
|
||||
throwAndComplain(gh, "Message came from wrong connection!");
|
||||
if(qid == QueryID(-1))
|
||||
throwAndComplain(gh, "Cannot answer the query with id -1!");
|
||||
auto playerToConnection = gh.connections.find(pack.player);
|
||||
if(playerToConnection == gh.connections.end())
|
||||
gh.throwAndComplain(&pack, "No such pack.player!");
|
||||
if(!vstd::contains(playerToConnection->second, pack.c))
|
||||
gh.throwAndComplain(&pack, "Message came from wrong connection!");
|
||||
if(pack.qid == QueryID(-1))
|
||||
gh.throwAndComplain(&pack, "Cannot answer the query with pack.id -1!");
|
||||
|
||||
assert(vstd::contains(gh->states.players, player));
|
||||
return gh->queryReply(qid, reply, player);
|
||||
assert(vstd::contains(gh.states.players, pack.player));
|
||||
|
||||
result = gh.queryReply(pack.qid, pack.reply, pack.player);
|
||||
}
|
||||
|
||||
bool MakeAction::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
|
||||
{
|
||||
const BattleInfo * b = GS(gh)->curB;
|
||||
const BattleInfo * b = gs.curB;
|
||||
if(!b)
|
||||
throwNotAllowedAction();
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
|
||||
if(b->tacticDistance)
|
||||
{
|
||||
if(ba.actionType != EActionType::WALK && ba.actionType != EActionType::END_TACTIC_PHASE
|
||||
&& ba.actionType != EActionType::RETREAT && ba.actionType != EActionType::SURRENDER)
|
||||
throwNotAllowedAction();
|
||||
if(!vstd::contains(gh->connections[b->sides[b->tacticsSide].color], c))
|
||||
throwNotAllowedAction();
|
||||
if(pack.ba.actionType != EActionType::WALK && pack.ba.actionType != EActionType::END_TACTIC_PHASE
|
||||
&& pack.ba.actionType != EActionType::RETREAT && pack.ba.actionType != EActionType::SURRENDER)
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
if(!vstd::contains(gh.connections[b->sides[b->tacticsSide].color], pack.c))
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto active = b->battleActiveUnit();
|
||||
if(!active)
|
||||
throwNotAllowedAction();
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
auto unitOwner = b->battleGetOwner(active);
|
||||
if(!vstd::contains(gh->connections[unitOwner], c))
|
||||
throwNotAllowedAction();
|
||||
if(!vstd::contains(gh.connections[unitOwner], pack.c))
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
}
|
||||
return gh->makeBattleAction(ba);
|
||||
|
||||
result = gh.makeBattleAction(pack.ba);
|
||||
}
|
||||
|
||||
bool MakeCustomAction::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitMakeCustomAction(MakeCustomAction & pack)
|
||||
{
|
||||
const BattleInfo * b = GS(gh)->curB;
|
||||
const BattleInfo * b = gs.curB;
|
||||
if(!b)
|
||||
throwNotAllowedAction();
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
if(b->tacticDistance)
|
||||
throwNotAllowedAction();
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
auto active = b->battleActiveUnit();
|
||||
if(!active)
|
||||
throwNotAllowedAction();
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
auto unitOwner = b->battleGetOwner(active);
|
||||
if(!vstd::contains(gh->connections[unitOwner], c))
|
||||
throwNotAllowedAction();
|
||||
if(ba.actionType != EActionType::HERO_SPELL)
|
||||
throwNotAllowedAction();
|
||||
return gh->makeCustomAction(ba);
|
||||
if(!vstd::contains(gh.connections[unitOwner], pack.c))
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
if(pack.ba.actionType != EActionType::HERO_SPELL)
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
|
||||
result = gh.makeCustomAction(pack.ba);
|
||||
}
|
||||
|
||||
bool DigWithHero::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitDigWithHero(DigWithHero & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, id);
|
||||
return gh->dig(gh->getHero(id));
|
||||
gh.throwOnWrongOwner(&pack, pack.id);
|
||||
result = gh.dig(gh.getHero(pack.id));
|
||||
}
|
||||
|
||||
bool CastAdvSpell::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitCastAdvSpell(CastAdvSpell & pack)
|
||||
{
|
||||
throwOnWrongOwner(gh, hid);
|
||||
gh.throwOnWrongOwner(&pack, pack.hid);
|
||||
|
||||
const CSpell * s = sid.toSpell();
|
||||
const CSpell * s = pack.sid.toSpell();
|
||||
if(!s)
|
||||
throwNotAllowedAction();
|
||||
const CGHeroInstance * h = gh->getHero(hid);
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
const CGHeroInstance * h = gh.getHero(pack.hid);
|
||||
if(!h)
|
||||
throwNotAllowedAction();
|
||||
gh.throwNotAllowedAction(&pack);
|
||||
|
||||
AdventureSpellCastParameters p;
|
||||
p.caster = h;
|
||||
p.pos = pos;
|
||||
p.pos = pack.pos;
|
||||
|
||||
return s->adventureCast(gh->spellEnv, p);
|
||||
result = s->adventureCast(gh.spellEnv, p);
|
||||
}
|
||||
|
||||
bool PlayerMessage::applyGh(CGameHandler * gh)
|
||||
void ApplyGhNetPackVisitor::visitPlayerMessage(PlayerMessage & pack)
|
||||
{
|
||||
if(!player.isSpectator()) // TODO: clearly not a great way to verify permissions
|
||||
throwOnWrongPlayer(gh, player);
|
||||
if(!pack.player.isSpectator()) // TODO: clearly not a great way to verify permissions
|
||||
gh.throwOnWrongPlayer(&pack, pack.player);
|
||||
|
||||
gh->playerMessage(player, text, currObj);
|
||||
return true;
|
||||
gh.playerMessage(pack.player, pack.text, pack.currObj);
|
||||
result = true;
|
||||
}
|
||||
|
61
server/ServerNetPackVisitors.h
Normal file
61
server/ServerNetPackVisitors.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* ServerNetPackVisitors.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../lib/NetPackVisitor.h"
|
||||
|
||||
class ApplyGhNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
|
||||
{
|
||||
private:
|
||||
bool result;
|
||||
CGameHandler & gh;
|
||||
CGameState & gs;
|
||||
|
||||
public:
|
||||
ApplyGhNetPackVisitor(CGameHandler & gh, CGameState & gs)
|
||||
:gh(gh), gs(gs), result(false)
|
||||
{
|
||||
}
|
||||
|
||||
bool getResult() const
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual void visitSaveGame(SaveGame & pack) override;
|
||||
virtual void visitEndTurn(EndTurn & pack) override;
|
||||
virtual void visitDismissHero(DismissHero & pack) override;
|
||||
virtual void visitMoveHero(MoveHero & pack) override;
|
||||
virtual void visitCastleTeleportHero(CastleTeleportHero & pack) override;
|
||||
virtual void visitArrangeStacks(ArrangeStacks & pack) override;
|
||||
virtual void visitBulkMoveArmy(BulkMoveArmy & pack) override;
|
||||
virtual void visitBulkSplitStack(BulkSplitStack & pack) override;
|
||||
virtual void visitBulkMergeStacks(BulkMergeStacks & pack) override;
|
||||
virtual void visitBulkSmartSplitStack(BulkSmartSplitStack & pack) override;
|
||||
virtual void visitDisbandCreature(DisbandCreature & pack) override;
|
||||
virtual void visitBuildStructure(BuildStructure & pack) override;
|
||||
virtual void visitRecruitCreatures(RecruitCreatures & pack) override;
|
||||
virtual void visitUpgradeCreature(UpgradeCreature & pack) override;
|
||||
virtual void visitGarrisonHeroSwap(GarrisonHeroSwap & pack) override;
|
||||
virtual void visitExchangeArtifacts(ExchangeArtifacts & pack) override;
|
||||
virtual void visitBulkExchangeArtifacts(BulkExchangeArtifacts & pack) override;
|
||||
virtual void visitAssembleArtifacts(AssembleArtifacts & pack) override;
|
||||
virtual void visitBuyArtifact(BuyArtifact & pack) override;
|
||||
virtual void visitTradeOnMarketplace(TradeOnMarketplace & pack) override;
|
||||
virtual void visitSetFormation(SetFormation & pack) override;
|
||||
virtual void visitHireHero(HireHero & pack) override;
|
||||
virtual void visitBuildBoat(BuildBoat & pack) override;
|
||||
virtual void visitQueryReply(QueryReply & pack) override;
|
||||
virtual void visitMakeAction(MakeAction & pack) override;
|
||||
virtual void visitMakeCustomAction(MakeCustomAction & pack) override;
|
||||
virtual void visitDigWithHero(DigWithHero & pack) override;
|
||||
virtual void visitCastAdvSpell(CastAdvSpell & pack) override;
|
||||
virtual void visitPlayerMessage(PlayerMessage & pack) override;
|
||||
};
|
Loading…
Reference in New Issue
Block a user