|
@@ -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)),
|