* Game: fixed that server can close non started tables with one player by random (#8209);

This commit is contained in:
Oleg Agafonov 2021-09-04 17:19:55 +04:00
parent 84ea133ec5
commit 5ded8468f7

View file

@ -668,7 +668,7 @@ public class TableController {
ServerMessagesUtil.instance.incGamesStarted(); ServerMessagesUtil.instance.incGamesStarted();
// log about game started // log about game started
logger.info("GAME started " + (match.getGame() != null ? match.getGame().getId() : "no Game") + " [" + match.getName() + "] " + creator + " - " + opponent.toString()); logger.info("GAME started " + (match.getGame() != null ? match.getGame().getId() : "no Game") + " [" + match.getName() + "] " + creator + " - " + opponent);
logger.debug("- matchId: " + match.getId() + " [" + match.getName() + ']'); logger.debug("- matchId: " + match.getId() + " [" + match.getName() + ']');
if (match.getGame() != null) { if (match.getGame() != null) {
logger.debug("- chatId: " + managerFactory.gameManager().getChatId(match.getGame().getId())); logger.debug("- chatId: " + managerFactory.gameManager().getChatId(match.getGame().getId()));
@ -971,52 +971,62 @@ public class TableController {
} }
public boolean isMatchTableStillValid() { public boolean isMatchTableStillValid() {
// check only normal match table with state != Finished // removes active match only, not tourney
if (!table.isTournament()) { if (table.isTournament()) {
if (!(table.getState() == TableState.WAITING || table.getState() == TableState.STARTING || table.getState() == TableState.READY_TO_START)) { return true;
if (match == null) {
logger.warn("- Match table with no match:");
logger.warn("-- match: null , table : " + table.getId());
// return false;
} else if (match.isDoneSideboarding() && match.getGame() == null) {
// no sideboarding and not active game -> match seems to hang (maybe the Draw bug)
logger.warn("- Match with no active game and not in sideboard state:");
logger.warn("-- matchId:" + match.getId() + " [" + match.getName() + ']');
// return false;
}
} }
// check for active players // only started games need to check
if (Arrays.asList(
TableState.WAITING,
TableState.READY_TO_START,
TableState.STARTING
).contains(table.getState())) {
// waiting in start dialog
return true;
}
if (match != null && !match.isDoneSideboarding()) {
// waiting sideboard complete
return true;
}
// no games in started match (error in match init code?)
if (match.getGame() == null) {
logger.error("- Match without started games:");
logger.error("-- matchId:" + match.getId());
return false; // critical error
}
// find player stats
int validHumanPlayers = 0; int validHumanPlayers = 0;
int validAIPlayers = 0; int validAIPlayers = 0;
int aiPlayers = 0;
int humanPlayers = 0;
// check humans // check humans
for (Map.Entry<UUID, UUID> userPlayerEntry : userPlayerMap.entrySet()) { for (Map.Entry<UUID, UUID> userPlayerEntry : userPlayerMap.entrySet()) {
MatchPlayer matchPlayer = match.getPlayer(userPlayerEntry.getValue()); MatchPlayer matchPlayer = match.getPlayer(userPlayerEntry.getValue());
// de-synced users and players listst?
if (matchPlayer == null) { if (matchPlayer == null) {
logger.warn("- Match player not found:"); logger.error("- Match player not found in started game:");
logger.warn("-- matchId:" + match.getId()); logger.error("-- matchId:" + match.getId());
logger.warn("-- userId:" + userPlayerEntry.getKey()); logger.error("-- userId:" + userPlayerEntry.getKey());
logger.warn("-- playerId:" + userPlayerEntry.getValue()); logger.error("-- playerId:" + userPlayerEntry.getValue());
continue; continue;
} }
if (matchPlayer.getPlayer().isHuman()) { if (matchPlayer.getPlayer().isHuman()) {
humanPlayers++; if (matchPlayer.getPlayer().isInGame()) {
if ((table.getState() == TableState.WAITING
|| table.getState() == TableState.STARTING
|| table.getState() == TableState.READY_TO_START)
|| !match.isDoneSideboarding()
|| (!matchPlayer.hasQuit() && match.getGame() != null && matchPlayer.getPlayer().isInGame())) {
Optional<User> user = managerFactory.userManager().getUser(userPlayerEntry.getKey()); Optional<User> user = managerFactory.userManager().getUser(userPlayerEntry.getKey());
// user was logout or disconnected from server, but still in the game somehow
if (!user.isPresent() || !user.get().isActive()) { if (!user.isPresent() || !user.get().isActive()) {
logger.warn("- Active user of match is missing: " + matchPlayer.getName()); logger.error("- Active user of match is missing: " + matchPlayer.getName());
logger.warn("-- matchId:" + match.getId()); logger.error("-- matchId:" + match.getId());
logger.warn("-- userId:" + userPlayerEntry.getKey()); logger.error("-- userId:" + userPlayerEntry.getKey());
logger.warn("-- playerId:" + userPlayerEntry.getValue()); logger.error("-- playerId:" + userPlayerEntry.getValue());
return false; return false; // critical error
} }
// user exits on the server and match player has not quit -> player is valid // user exits on the server and match player has not quit -> player is valid
validHumanPlayers++; validHumanPlayers++;
} }
@ -1026,17 +1036,14 @@ public class TableController {
// check AI // check AI
for (MatchPlayer matchPlayer : match.getPlayers()) { for (MatchPlayer matchPlayer : match.getPlayers()) {
if (!matchPlayer.getPlayer().isHuman()) { if (!matchPlayer.getPlayer().isHuman()) {
aiPlayers++;
if (matchPlayer.getPlayer().isInGame()) { if (matchPlayer.getPlayer().isInGame()) {
validAIPlayers++; validAIPlayers++;
} }
} }
} }
// table must contain minimum two active players // if someone can play 1 vs 1 (e.g. 2+ players) then keep table
return (validAIPlayers + validHumanPlayers) >= 2; return validAIPlayers + validHumanPlayers >= 2;
}
return true;
} }
void cleanUp() { void cleanUp() {