1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Add LeaveGame netpack and avoid replying on it and CloseServer

This commit is contained in:
Arseniy Shestakov 2017-05-31 09:45:26 +03:00
parent c7e7a4d7be
commit 4b0f702e7e
7 changed files with 68 additions and 12 deletions

View File

@ -83,7 +83,7 @@ struct EvilHlpStruct
void reset()
{
vstd::clear_pointer(serv);
// vstd::clear_pointer(serv);
vstd::clear_pointer(sInfo);
}

View File

@ -701,6 +701,12 @@ void CClient::stopConnection()
sendRequest(&close_server, PlayerColor::NEUTRAL);
logNetwork->infoStream() << "Sent closing signal to the server";
}
else
{
LeaveGame leave_Game;
sendRequest(&leave_Game, PlayerColor::NEUTRAL);
logNetwork->infoStream() << "Sent leaving signal to the server";
}
if(connectionHandler)//end connection handler
{

View File

@ -1774,6 +1774,13 @@ struct CloseServer : public CPackForServer
{}
};
struct LeaveGame : public CPackForServer
{
bool applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{}
};
struct EndTurn : public CPackForServer
{
bool applyGh(CGameHandler *gh);

View File

@ -314,6 +314,7 @@ void registerTypesServerPacks(Serializer &s)
{
s.template registerType<CPack, CPackForServer>();
s.template registerType<CPackForServer, CloseServer>();
s.template registerType<CPackForServer, LeaveGame>();
s.template registerType<CPackForServer, EndTurn>();
s.template registerType<CPackForServer, DismissHero>();
s.template registerType<CPackForServer, MoveHero>();

View File

@ -1031,6 +1031,21 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
{
setThreadName("CGameHandler::handleConnection");
auto handleDisconnection = [&](const std::exception & e)
{
assert(!c.connected); //make sure that connection has been marked as broken
logGlobal->error(e.what());
conns -= &c;
for(auto playerConn : connections)
{
if(playerConn.second == &c)
{
gs->getPlayer(playerConn.first)->enteredLosingCheatCode = 1;
checkVictoryLossConditionsForPlayer(playerConn.first);
}
}
};
try
{
while(1)//server should never shut connection first //was: while(!end2)
@ -1042,6 +1057,8 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
{
boost::unique_lock<boost::mutex> lock(*c.rmx);
if(!c.connected)
throw clientDisconnectedException();
c >> player >> requestID >> pack; //get the package
if (!pack)
@ -1060,6 +1077,11 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
//prepare struct informing that action was applied
auto sendPackageResponse = [&](bool succesfullyApplied)
{
//dont reply to disconnected client
//TODO: this must be implemented as option of CPackForServer
if(dynamic_cast<LeaveGame *>(pack) || dynamic_cast<CloseServer *>(pack))
return;
PackageApplied applied;
applied.player = player;
applied.result = succesfullyApplied;
@ -1095,17 +1117,11 @@ void CGameHandler::handleConnection(std::set<PlayerColor> players, CConnection &
}
catch(boost::system::system_error &e) //for boost errors just log, not crash - probably client shut down connection
{
assert(!c.connected); //make sure that connection has been marked as broken
logGlobal->error(e.what());
conns -= &c;
for(auto playerConn : connections)
{
if(playerConn.second == &c)
{
gs->getPlayer(playerConn.first)->enteredLosingCheatCode = 1;
checkVictoryLossConditionsForPlayer(playerConn.first);
}
handleDisconnection(e);
}
catch(clientDisconnectedException & e)
{
handleDisconnection(e);
}
catch(...)
{
@ -2728,6 +2744,20 @@ void CGameHandler::close()
exit(0);
}
void CGameHandler::playerLeftGame(int cid)
{
for (auto & elem : conns)
{
if(elem->isOpen() && elem->connectionID == cid)
{
boost::unique_lock<boost::mutex> lock(*(elem)->wmx);
elem->close();
elem->connected = false;
break;
}
}
}
bool CGameHandler::arrangeStacks(ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, PlayerColor player)
{
const CArmedInstance * s1 = static_cast<const CArmedInstance *>(getObjInstance(id1)),

View File

@ -223,6 +223,7 @@ public:
bool arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui8 what, SlotID p1, SlotID p2, si32 val, PlayerColor player);
void save(const std::string &fname);
void close();
void playerLeftGame(int cid);
void handleTimeEvents();
void handleTownEvents(CGTownInstance *town, NewTurn &n);
bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
@ -298,4 +299,9 @@ private:
void checkVictoryLossConditionsForAll();
};
class clientDisconnectedException : public std::exception
{
};
void makeStackDoNothing();

View File

@ -65,6 +65,12 @@ bool CloseServer::applyGh( CGameHandler *gh )
return true;
}
bool LeaveGame::applyGh( CGameHandler *gh )
{
gh->playerLeftGame(c->connectionID);
return true;
}
bool EndTurn::applyGh( CGameHandler *gh )
{
PlayerColor player = GS(gh)->currentPlayer;