mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Fixes for player disconnection handling
- Fixed lack of notification if player disconnects via connection loss, e.g. app crash / network going down - Replaced notification via chat message with notification via info window
This commit is contained in:
parent
b79897f598
commit
371eac070f
@ -143,6 +143,7 @@
|
||||
"vcmi.client.errors.invalidMap" : "{Invalid map or campaign}\n\nFailed to start game! Selected map or campaign might be invalid or corrupted. Reason:\n%s",
|
||||
"vcmi.client.errors.missingCampaigns" : "{Missing data files}\n\nCampaigns data files were not found! You may be using incomplete or corrupted Heroes 3 data files. Please reinstall game data.",
|
||||
"vcmi.server.errors.disconnected" : "{Network Error}\n\nConnection to game server has been lost!",
|
||||
"vcmi.server.errors.playerLeft" : "{Player Left}\n\n%s player have disconnected from the game!", //%s -> player color
|
||||
"vcmi.server.errors.existingProcess" : "Another VCMI server process is running. Please terminate it before starting a new game.",
|
||||
"vcmi.server.errors.modsToEnable" : "{Following mods are required}",
|
||||
"vcmi.server.errors.modsToDisable" : "{Following mods must be disabled}",
|
||||
|
@ -431,10 +431,28 @@ void CGameHandler::handleClientDisconnection(std::shared_ptr<CConnection> c)
|
||||
continue;
|
||||
|
||||
auto playerConnection = vstd::find(playerConnections.second, c);
|
||||
if(playerConnection != playerConnections.second.end())
|
||||
if(playerConnection == playerConnections.second.end())
|
||||
continue;
|
||||
|
||||
logGlobal->trace("Player %s disconnected. Notifying remaining players", playerId.toString());
|
||||
|
||||
// this player have left the game - broadcast infowindow to all in-game players
|
||||
for (auto i = gs->players.cbegin(); i!=gs->players.cend(); i++)
|
||||
{
|
||||
std::string messageText = boost::str(boost::format("%s (cid %d) was disconnected") % playerSettings->name % c->connectionID);
|
||||
playerMessages->broadcastMessage(playerId, messageText);
|
||||
if (i->first == playerId)
|
||||
continue;
|
||||
|
||||
if (getPlayerState(i->first)->status != EPlayerStatus::INGAME)
|
||||
continue;
|
||||
|
||||
logGlobal->trace("Notifying player %s", i->first);
|
||||
|
||||
InfoWindow out;
|
||||
out.player = i->first;
|
||||
out.text.appendTextID("vcmi.server.errors.playerLeft");
|
||||
out.text.replaceName(playerId);
|
||||
out.components.emplace_back(ComponentType::FLAG, playerId);
|
||||
sendAndApply(&out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -297,25 +297,19 @@ void CVCMIServer::onDisconnected(const std::shared_ptr<INetworkConnection> & con
|
||||
logNetwork->error("Network error receiving a pack. Connection has been closed");
|
||||
|
||||
std::shared_ptr<CConnection> c = findConnection(connection);
|
||||
if (!c)
|
||||
return; // player have already disconnected via clientDisconnected call
|
||||
|
||||
vstd::erase(activeConnections, c);
|
||||
|
||||
if(activeConnections.empty() || hostClientId == c->connectionID)
|
||||
// player may have already disconnected via clientDisconnected call
|
||||
if (c)
|
||||
{
|
||||
setState(EServerState::SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
//clientDisconnected(c);
|
||||
|
||||
if(gh && getState() == EServerState::GAMEPLAY)
|
||||
{
|
||||
gh->handleClientDisconnection(c);
|
||||
|
||||
auto lcd = std::make_unique<LobbyClientDisconnected>();
|
||||
lcd->c = c;
|
||||
lcd->clientId = c->connectionID;
|
||||
handleReceivedPack(std::move(lcd));
|
||||
if(gh && getState() == EServerState::GAMEPLAY)
|
||||
{
|
||||
auto lcd = std::make_unique<LobbyClientDisconnected>();
|
||||
lcd->c = c;
|
||||
lcd->clientId = c->connectionID;
|
||||
handleReceivedPack(std::move(lcd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,9 +428,21 @@ void CVCMIServer::clientConnected(std::shared_ptr<CConnection> c, std::vector<st
|
||||
|
||||
void CVCMIServer::clientDisconnected(std::shared_ptr<CConnection> connection)
|
||||
{
|
||||
connection->getConnection()->close();
|
||||
assert(vstd::contains(activeConnections, connection));
|
||||
logGlobal->trace("Received disconnection request");
|
||||
vstd::erase(activeConnections, connection);
|
||||
|
||||
if(activeConnections.empty() || hostClientId == connection->connectionID)
|
||||
{
|
||||
setState(EServerState::SHUTDOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
if(gh && getState() == EServerState::GAMEPLAY)
|
||||
{
|
||||
gh->handleClientDisconnection(connection);
|
||||
}
|
||||
|
||||
// PlayerReinitInterface startAiPack;
|
||||
// startAiPack.playerConnectionId = PlayerSettings::PLAYER_AI;
|
||||
//
|
||||
|
@ -108,6 +108,7 @@ void ClientPermissionsCheckerNetPackVisitor::visitLobbyClientDisconnected(LobbyC
|
||||
|
||||
void ApplyOnServerNetPackVisitor::visitLobbyClientDisconnected(LobbyClientDisconnected & pack)
|
||||
{
|
||||
pack.c->getConnection()->close();
|
||||
srv.clientDisconnected(pack.c);
|
||||
result = true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user