mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
* Some changes to game start logic (better handling for disconnected users). Changes to server logging.
This commit is contained in:
parent
5d30cf536b
commit
30869beca0
13 changed files with 132 additions and 107 deletions
|
@ -34,9 +34,9 @@
|
||||||
|
|
||||||
package mage.client.game;
|
package mage.client.game;
|
||||||
|
|
||||||
import java.awt.KeyboardFocusManager;
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import static javax.swing.WindowConstants.DISPOSE_ON_CLOSE;
|
||||||
import mage.client.MagePane;
|
import mage.client.MagePane;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -360,18 +360,18 @@ public class SessionImpl implements Session {
|
||||||
}
|
}
|
||||||
client.showMessage("Unable to connect to server. " + message);
|
client.showMessage("Unable to connect to server. " + message);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
t.printStackTrace();
|
logger.trace("StackTrace", t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param errorCall - was connection lost because of error
|
* @param errorCall - was connection lost because of error - ask user if he want to try to reconnect
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public synchronized void disconnect(boolean errorCall) {
|
public synchronized void disconnect(boolean errorCall) {
|
||||||
if (isConnected()) {
|
if (isConnected()) {
|
||||||
logger.info("DISCONNECT still connected");
|
logger.info("DISCONNECT (still connected)");
|
||||||
sessionState = SessionState.DISCONNECTING;
|
sessionState = SessionState.DISCONNECTING;
|
||||||
}
|
}
|
||||||
if (connection == null || sessionState == SessionState.DISCONNECTED) {
|
if (connection == null || sessionState == SessionState.DISCONNECTED) {
|
||||||
|
@ -1396,6 +1396,7 @@ public class SessionImpl implements Session {
|
||||||
return true;
|
return true;
|
||||||
} catch (MageException ex) {
|
} catch (MageException ex) {
|
||||||
handleMageException(ex);
|
handleMageException(ex);
|
||||||
|
disconnect(true);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
handleThrowable(t);
|
handleThrowable(t);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class ChatManager {
|
||||||
synchronized (chatSession) {
|
synchronized (chatSession) {
|
||||||
if (chatSessions.containsKey(chatId)) {
|
if (chatSessions.containsKey(chatId)) {
|
||||||
chatSessions.remove(chatId);
|
chatSessions.remove(chatId);
|
||||||
logger.debug("Chat removed - chatId: " + chatId);
|
logger.trace("Chat removed - chatId: " + chatId);
|
||||||
} else {
|
} else {
|
||||||
logger.trace("Chat to destroy does not exist - chatId: " + chatId);
|
logger.trace("Chat to destroy does not exist - chatId: " + chatId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ public class ChatSession {
|
||||||
String userName = user.getName();
|
String userName = user.getName();
|
||||||
clients.put(userId, userName);
|
clients.put(userId, userName);
|
||||||
broadcast(null, userName + " has joined", MessageColor.BLUE, true, MessageType.STATUS);
|
broadcast(null, userName + " has joined", MessageColor.BLUE, true, MessageType.STATUS);
|
||||||
logger.debug(userName + " joined chat " + chatId);
|
logger.trace(userName + " joined chat " + chatId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ public class Session {
|
||||||
try {
|
try {
|
||||||
if(lock.tryLock(500, TimeUnit.MILLISECONDS)) {
|
if(lock.tryLock(500, TimeUnit.MILLISECONDS)) {
|
||||||
lockSet = true;
|
lockSet = true;
|
||||||
logger.debug("SESSION LOCK SET sessionId: " + sessionId);
|
logger.trace("SESSION LOCK SET sessionId: " + sessionId);
|
||||||
User user = UserManager.getInstance().getUser(userId);
|
User user = UserManager.getInstance().getUser(userId);
|
||||||
if (user == null || !user.isConnected()) {
|
if (user == null || !user.isConnected()) {
|
||||||
return; //user was already disconnected by other thread
|
return; //user was already disconnected by other thread
|
||||||
|
@ -230,10 +230,10 @@ public class Session {
|
||||||
logger.info("OLD SESSION IGNORED - " + user.getName());
|
logger.info("OLD SESSION IGNORED - " + user.getName());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
logger.info("LOST CONNECTION - " + user.getName() + " id: " + userId);
|
// logger.info("LOST CONNECTION - " + user.getName() + " id: " + userId);
|
||||||
UserManager.getInstance().disconnect(userId, DisconnectReason.LostConnection);
|
UserManager.getInstance().disconnect(userId, DisconnectReason.LostConnection);
|
||||||
} else {
|
} else {
|
||||||
logger.error("SESSION LOCK lost connection - userId: " + userId);
|
logger.error("CAN'T GET LOCK - userId: " + userId);
|
||||||
}
|
}
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
logger.error("SESSION LOCK lost connection - userId: " + userId, ex);
|
logger.error("SESSION LOCK lost connection - userId: " + userId, ex);
|
||||||
|
@ -241,7 +241,7 @@ public class Session {
|
||||||
finally {
|
finally {
|
||||||
if (lockSet) {
|
if (lockSet) {
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
logger.debug("SESSION LOCK UNLOCK sessionId: " + sessionId);
|
logger.trace("SESSION LOCK UNLOCK sessionId: " + sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -502,39 +502,6 @@ public class TableController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// public synchronized void startChallenge(UUID userId, UUID challengeId) {
|
|
||||||
// if (userId.equals(this.userId)) {
|
|
||||||
// try {
|
|
||||||
// match.startMatch();
|
|
||||||
// match.startGame();
|
|
||||||
// table.initGame();
|
|
||||||
// GameOptions gameOptions = new GameOptions();
|
|
||||||
// gameOptions.testMode = true;
|
|
||||||
//// match.getGame().setGameOptions(gameOptions);
|
|
||||||
// GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), null);
|
|
||||||
// ChallengeManager.getInstance().prepareChallenge(getPlayerId(), match);
|
|
||||||
// for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) {
|
|
||||||
// UserManager.getInstance().getUser(entry.getKey()).gameStarted(match.getGame().getId(), entry.getValue());
|
|
||||||
// }
|
|
||||||
// } catch (GameException ex) {
|
|
||||||
// logger.fatal(null, ex);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private UUID getPlayerId() throws GameException {
|
|
||||||
// UUID playerId = null;
|
|
||||||
// for (Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
|
|
||||||
// playerId = entry.getValue();
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// if (playerId == null) {
|
|
||||||
// throw new GameException("Couldn't find a player in challenge mode.");
|
|
||||||
// }
|
|
||||||
// return playerId;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used from non tournament match to start
|
* Used from non tournament match to start
|
||||||
*
|
*
|
||||||
|
@ -572,20 +539,12 @@ public class TableController {
|
||||||
GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId);
|
GameManager.getInstance().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId);
|
||||||
String creator = null;
|
String creator = null;
|
||||||
StringBuilder opponent = new StringBuilder();
|
StringBuilder opponent = new StringBuilder();
|
||||||
int activePlayers = 0;
|
// int activePlayers = 0;
|
||||||
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { // no AI players
|
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) { // no AI players
|
||||||
if (!match.getPlayer(entry.getValue()).hasQuit()) {
|
if (!match.getPlayer(entry.getValue()).hasQuit()) {
|
||||||
User user = UserManager.getInstance().getUser(entry.getKey());
|
User user = UserManager.getInstance().getUser(entry.getKey());
|
||||||
if (user != null) {
|
if (user != null) {
|
||||||
activePlayers++;
|
// activePlayers++;
|
||||||
if (!user.isConnected()) {
|
|
||||||
// if the user is not connected but exits, the user is currently disconnected. So it's neccessary
|
|
||||||
// to join the user to the game here (instead the client does it) , so he can join the game, if he reconnects in time.
|
|
||||||
// remove an existing constructing for the player if it exists
|
|
||||||
user.removeConstructing(match.getPlayer(entry.getValue()).getPlayer().getId());
|
|
||||||
GameManager.getInstance().joinGame(match.getGame().getId(), user.getId());
|
|
||||||
logger.debug("Joined currently not connected user " + user.getName() + " matchId: " + match.getId());
|
|
||||||
}
|
|
||||||
Player player = match.getPlayer(entry.getValue()).getPlayer();
|
Player player = match.getPlayer(entry.getValue()).getPlayer();
|
||||||
player.setRequestToShowHandCardsAllowed(user.getUserData().allowRequestShowHandCards());
|
player.setRequestToShowHandCardsAllowed(user.getUserData().allowRequestShowHandCards());
|
||||||
user.gameStarted(match.getGame().getId(), entry.getValue());
|
user.gameStarted(match.getGame().getId(), entry.getValue());
|
||||||
|
@ -610,16 +569,16 @@ public class TableController {
|
||||||
// Append AI opponents to the log file
|
// Append AI opponents to the log file
|
||||||
for (MatchPlayer mPlayer :match.getPlayers()) {
|
for (MatchPlayer mPlayer :match.getPlayers()) {
|
||||||
if (!mPlayer.getPlayer().isHuman()) {
|
if (!mPlayer.getPlayer().isHuman()) {
|
||||||
activePlayers++;
|
// activePlayers++;
|
||||||
if (opponent.length() > 0) {
|
if (opponent.length() > 0) {
|
||||||
opponent.append(" - ");
|
opponent.append(" - ");
|
||||||
}
|
}
|
||||||
opponent.append(mPlayer.getName());
|
opponent.append(mPlayer.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (activePlayers < 2) {
|
// if (activePlayers < 2) {
|
||||||
throw new MageException("Can't start game - Less than two players active - " +activePlayers);
|
// throw new MageException("Can't start game - Less than two players active - " +activePlayers);
|
||||||
}
|
// }
|
||||||
ServerMessagesUtil.getInstance().incGamesStarted();
|
ServerMessagesUtil.getInstance().incGamesStarted();
|
||||||
|
|
||||||
|
|
||||||
|
@ -737,7 +696,7 @@ public class TableController {
|
||||||
GameManager.getInstance().removeGame(game.getId());
|
GameManager.getInstance().removeGame(game.getId());
|
||||||
try {
|
try {
|
||||||
if (!match.hasEnded()) {
|
if (!match.hasEnded()) {
|
||||||
if (match.getGame().getGameType().isSideboardingAllowed()) {
|
if (match.getGame() != null && match.getGame().getGameType().isSideboardingAllowed()) {
|
||||||
sideboard();
|
sideboard();
|
||||||
}
|
}
|
||||||
if (!match.hasEnded()) {
|
if (!match.hasEnded()) {
|
||||||
|
|
|
@ -94,8 +94,7 @@ public class TableManager {
|
||||||
try {
|
try {
|
||||||
checkTableHealthState();
|
checkTableHealthState();
|
||||||
} catch(Exception ex) {
|
} catch(Exception ex) {
|
||||||
logger.fatal("Check table health state job error:");
|
logger.fatal("Check table health state job error:", ex);
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, EXPIRE_CHECK_PERIOD, EXPIRE_CHECK_PERIOD, TimeUnit.MINUTES);
|
}, EXPIRE_CHECK_PERIOD, EXPIRE_CHECK_PERIOD, TimeUnit.MINUTES);
|
||||||
|
|
|
@ -125,15 +125,15 @@ public class User {
|
||||||
if (sessionId.isEmpty()) {
|
if (sessionId.isEmpty()) {
|
||||||
userState = UserState.Disconnected;
|
userState = UserState.Disconnected;
|
||||||
lostConnection();
|
lostConnection();
|
||||||
logger.debug("USER - lost connection: " + userName + " id: " + userId);
|
logger.trace("USER - lost connection: " + userName + " id: " + userId);
|
||||||
|
|
||||||
} else if (userState == UserState.Created) {
|
} else if (userState == UserState.Created) {
|
||||||
userState = UserState.Connected;
|
userState = UserState.Connected;
|
||||||
logger.debug("USER - created: " + userName + " id: " + userId);
|
logger.trace("USER - created: " + userName + " id: " + userId);
|
||||||
} else {
|
} else {
|
||||||
userState = UserState.Reconnected;
|
userState = UserState.Reconnected;
|
||||||
reconnect();
|
reconnect();
|
||||||
logger.info("USER - reconnected: " + userName + " id: " + userId);
|
logger.trace("USER - reconnected: " + userName + " id: " + userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ public class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDisconnectDuration() {
|
public String getDisconnectDuration() {
|
||||||
long secondsDisconnected = SystemUtil.getDateDiff(lastActivity, new Date(), TimeUnit.SECONDS);
|
long secondsDisconnected = getSecondsDisconnected();
|
||||||
long secondsLeft;
|
long secondsLeft;
|
||||||
String sign = "";
|
String sign = "";
|
||||||
if (secondsDisconnected > (3 * 60)) {
|
if (secondsDisconnected > (3 * 60)) {
|
||||||
|
@ -166,6 +166,10 @@ public class User {
|
||||||
return new StringBuilder(sign).append(Integer.toString(minutes)).append(":").append(seconds > 9 ? seconds: "0" + Integer.toString(seconds)).toString();
|
return new StringBuilder(sign).append(Integer.toString(minutes)).append(":").append(seconds > 9 ? seconds: "0" + Integer.toString(seconds)).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long getSecondsDisconnected() {
|
||||||
|
return SystemUtil.getDateDiff(lastActivity, new Date(), TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
|
||||||
public Date getConnectionTime() {
|
public Date getConnectionTime() {
|
||||||
return connectionTime;
|
return connectionTime;
|
||||||
}
|
}
|
||||||
|
@ -265,7 +269,7 @@ public class User {
|
||||||
|
|
||||||
public boolean isExpired(Date expired) {
|
public boolean isExpired(Date expired) {
|
||||||
if (lastActivity.before(expired)) {
|
if (lastActivity.before(expired)) {
|
||||||
logger.debug(userName + " is expired!");
|
logger.trace(userName + " is expired!");
|
||||||
userState = UserState.Expired;
|
userState = UserState.Expired;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -349,18 +353,18 @@ public class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(DisconnectReason reason) {
|
public void remove(DisconnectReason reason) {
|
||||||
logger.debug("REMOVE " + getName() + " Game sessions: " + gameSessions.size() );
|
logger.trace("REMOVE " + getName() + " Game sessions: " + gameSessions.size() );
|
||||||
for (GameSessionPlayer gameSession: gameSessions.values()) {
|
for (GameSessionPlayer gameSession: gameSessions.values()) {
|
||||||
logger.debug("-- kill game session of gameId: " + gameSession.getGameId() );
|
logger.debug("-- kill game session of gameId: " + gameSession.getGameId() );
|
||||||
gameSession.quitGame();
|
gameSession.quitGame();
|
||||||
}
|
}
|
||||||
gameSessions.clear();
|
gameSessions.clear();
|
||||||
logger.debug("REMOVE " + getName() + " Draft sessions " + draftSessions.size());
|
logger.trace("REMOVE " + getName() + " Draft sessions " + draftSessions.size());
|
||||||
for (DraftSession draftSession: draftSessions.values()) {
|
for (DraftSession draftSession: draftSessions.values()) {
|
||||||
draftSession.setKilled();
|
draftSession.setKilled();
|
||||||
}
|
}
|
||||||
draftSessions.clear();
|
draftSessions.clear();
|
||||||
logger.debug("REMOVE " + getName() + " Tournament sessions " + tournamentSessions.size());
|
logger.trace("REMOVE " + getName() + " Tournament sessions " + tournamentSessions.size());
|
||||||
for (TournamentSession tournamentSession: tournamentSessions.values()) {
|
for (TournamentSession tournamentSession: tournamentSessions.values()) {
|
||||||
TournamentController tournamentController = TournamentManager.getInstance().getTournamentController(tournamentSession.getTournamentId());
|
TournamentController tournamentController = TournamentManager.getInstance().getTournamentController(tournamentSession.getTournamentId());
|
||||||
if (tournamentController != null) {
|
if (tournamentController != null) {
|
||||||
|
@ -369,18 +373,18 @@ public class User {
|
||||||
tournamentSession.setKilled();
|
tournamentSession.setKilled();
|
||||||
}
|
}
|
||||||
tournamentSessions.clear();
|
tournamentSessions.clear();
|
||||||
logger.debug("REMOVE " + getName() + " Tables " + tables.size());
|
logger.trace("REMOVE " + getName() + " Tables " + tables.size());
|
||||||
for (Entry<UUID, Table> entry: tables.entrySet()) {
|
for (Entry<UUID, Table> entry: tables.entrySet()) {
|
||||||
logger.debug("-- leave tableId: " + entry.getValue().getId());
|
logger.debug("-- leave tableId: " + entry.getValue().getId());
|
||||||
TableManager.getInstance().leaveTable(userId, entry.getValue().getId());
|
TableManager.getInstance().leaveTable(userId, entry.getValue().getId());
|
||||||
}
|
}
|
||||||
tables.clear();
|
tables.clear();
|
||||||
logger.debug("REMOVE " + getName() + " watched Games " + watchedGames.size());
|
logger.trace("REMOVE " + getName() + " watched Games " + watchedGames.size());
|
||||||
for (UUID gameId: watchedGames) {
|
for (UUID gameId: watchedGames) {
|
||||||
GameManager.getInstance().stopWatching(gameId, userId);
|
GameManager.getInstance().stopWatching(gameId, userId);
|
||||||
}
|
}
|
||||||
watchedGames.clear();
|
watchedGames.clear();
|
||||||
logger.debug("REMOVE " + getName() + " Chats ");
|
logger.trace("REMOVE " + getName() + " Chats ");
|
||||||
ChatManager.getInstance().removeUser(userId, reason);
|
ChatManager.getInstance().removeUser(userId, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,10 @@ import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.zip.GZIPOutputStream;
|
import java.util.zip.GZIPOutputStream;
|
||||||
import mage.MageException;
|
import mage.MageException;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
@ -95,6 +98,8 @@ public class GameController implements GameCallback {
|
||||||
private static final ExecutorService gameExecutor = ThreadExecutor.getInstance().getGameExecutor();
|
private static final ExecutorService gameExecutor = ThreadExecutor.getInstance().getGameExecutor();
|
||||||
private static final Logger logger = Logger.getLogger(GameController.class);
|
private static final Logger logger = Logger.getLogger(GameController.class);
|
||||||
|
|
||||||
|
protected ScheduledExecutorService joinWaitingExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||||
|
|
||||||
private ConcurrentHashMap<UUID, GameSessionPlayer> gameSessions = new ConcurrentHashMap<>();
|
private ConcurrentHashMap<UUID, GameSessionPlayer> gameSessions = new ConcurrentHashMap<>();
|
||||||
private ConcurrentHashMap<UUID, GameSessionWatcher> watchers = new ConcurrentHashMap<>();
|
private ConcurrentHashMap<UUID, GameSessionWatcher> watchers = new ConcurrentHashMap<>();
|
||||||
private ConcurrentHashMap<UUID, PriorityTimer> timers = new ConcurrentHashMap<>();
|
private ConcurrentHashMap<UUID, PriorityTimer> timers = new ConcurrentHashMap<>();
|
||||||
|
@ -123,6 +128,7 @@ public class GameController implements GameCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
init();
|
init();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanUp() {
|
public void cleanUp() {
|
||||||
|
@ -250,7 +256,16 @@ public class GameController implements GameCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
joinWaitingExecutor.scheduleAtFixedRate(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
sendInfoAboutPlayersNotJoinedYet();
|
||||||
|
} catch(Exception ex) {
|
||||||
|
logger.fatal("Send info about player not joined yet:", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 15, 15, TimeUnit.SECONDS);
|
||||||
checkStart();
|
checkStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +326,7 @@ public class GameController implements GameCallback {
|
||||||
joinType = "rejoined";
|
joinType = "rejoined";
|
||||||
}
|
}
|
||||||
user.addGame(playerId, gameSession);
|
user.addGame(playerId, gameSession);
|
||||||
logger.debug("Player " + playerId + " has " + joinType + " gameId: " + game.getId());
|
logger.debug("Player " + player.getName()+ " " + playerId + " has " + joinType + " gameId: " + game.getId());
|
||||||
ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getName() + " has " + joinType + " the game", MessageColor.ORANGE, true, MessageType.GAME);
|
ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getName() + " has " + joinType + " the game", MessageColor.ORANGE, true, MessageType.GAME);
|
||||||
checkStart();
|
checkStart();
|
||||||
}
|
}
|
||||||
|
@ -319,20 +334,56 @@ public class GameController implements GameCallback {
|
||||||
private synchronized void startGame() {
|
private synchronized void startGame() {
|
||||||
if (gameFuture == null) {
|
if (gameFuture == null) {
|
||||||
for (final Entry<UUID, GameSessionPlayer> entry: gameSessions.entrySet()) {
|
for (final Entry<UUID, GameSessionPlayer> entry: gameSessions.entrySet()) {
|
||||||
if (!entry.getValue().init()) {
|
entry.getValue().init();
|
||||||
logger.fatal("Unable to initialize client");
|
|
||||||
//TODO: generate client error message
|
|
||||||
GameManager.getInstance().removeGame(game.getId());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
GameWorker worker = new GameWorker(game, choosingPlayerId, this);
|
GameWorker worker = new GameWorker(game, choosingPlayerId, this);
|
||||||
gameFuture = gameExecutor.submit(worker);
|
gameFuture = gameExecutor.submit(worker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void sendInfoAboutPlayersNotJoinedYet() {
|
||||||
|
for (Player player: game.getPlayers().values()) {
|
||||||
|
if (!player.hasLeft() && player.isHuman()) {
|
||||||
|
User user = getUserByPlayerId(player.getId());
|
||||||
|
if (user != null) {
|
||||||
|
if (!user.isConnected()) {
|
||||||
|
if (gameSessions.get(player.getId()) == null) {
|
||||||
|
// join the game because player has not joined are was removed because of disconnect
|
||||||
|
user.removeConstructing(player.getId());
|
||||||
|
GameManager.getInstance().joinGame(game.getId(), user.getId());
|
||||||
|
logger.debug("Player " + user.getName() + " (disconnected) has joined gameId: " +game.getId());
|
||||||
|
}
|
||||||
|
ChatManager.getInstance().broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
|
||||||
|
if (user.getSecondsDisconnected() > 240) {
|
||||||
|
// Cancel player join possibility lately after 4 minutes
|
||||||
|
logger.debug("Player " + user.getName() + " - canceled game (after 240 seconds) gameId: " +game.getId());
|
||||||
|
player.leave();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!player.hasLeft()) {
|
||||||
|
logger.debug("Player " + player.getName() + " canceled game (no user) gameId: " + game.getId());
|
||||||
|
player.leave();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
private User getUserByPlayerId(UUID playerId) {
|
||||||
|
for(Map.Entry<UUID,UUID> entry: userPlayerMap.entrySet()) {
|
||||||
|
if (entry.getValue().equals(playerId)) {
|
||||||
|
return UserManager.getInstance().getUser(entry.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void checkStart() {
|
private void checkStart() {
|
||||||
if (allJoined()) {
|
if (allJoined()) {
|
||||||
|
joinWaitingExecutor.shutdownNow();
|
||||||
ThreadExecutor.getInstance().getCallExecutor().execute(
|
ThreadExecutor.getInstance().getCallExecutor().execute(
|
||||||
new Runnable() {
|
new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -345,8 +396,16 @@ public class GameController implements GameCallback {
|
||||||
|
|
||||||
private boolean allJoined() {
|
private boolean allJoined() {
|
||||||
for (Player player: game.getPlayers().values()) {
|
for (Player player: game.getPlayers().values()) {
|
||||||
if (player.isHuman() && gameSessions.get(player.getId()) == null) {
|
if (!player.hasLeft()) {
|
||||||
return false;
|
User user = getUserByPlayerId(player.getId());
|
||||||
|
if (user != null) {
|
||||||
|
if (!user.isConnected()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (player.isHuman() && gameSessions.get(player.getId()) == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -379,30 +438,23 @@ public class GameController implements GameCallback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void removeUser(UUID userId) {
|
|
||||||
// UUID playerId = userPlayerMap.get(userId);
|
|
||||||
// if (playerId != null) {
|
|
||||||
// GameSession gameSession = gameSessions.get(playerId);
|
|
||||||
// if (gameSession != null) {
|
|
||||||
// gameSession.setKilled();
|
|
||||||
// gameSessions.remove(playerId);
|
|
||||||
// quitMatch(userId);
|
|
||||||
// userPlayerMap.remove(userId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// GameWatcher gameWatcher = watchers.get(userId);
|
|
||||||
// if (gameWatcher != null) {
|
|
||||||
// gameWatcher.setKilled();
|
|
||||||
// watchers.remove(userId);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void quitMatch(UUID userId) {
|
public void quitMatch(UUID userId) {
|
||||||
UUID playerId = getPlayerId(userId);
|
UUID playerId = getPlayerId(userId);
|
||||||
if (playerId != null) {
|
if (playerId != null) {
|
||||||
GameSessionPlayer gameSession = gameSessions.get(playerId);
|
if (allJoined()) {
|
||||||
if (gameSession != null) {
|
GameSessionPlayer gameSession = gameSessions.get(playerId);
|
||||||
gameSession.quitGame();
|
if (gameSession != null) {
|
||||||
|
gameSession.quitGame();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// The player did never join the game but the game controller was started because the player was still connected as the
|
||||||
|
// game was started. But the Client never called the join action. So now after the user is expired, the
|
||||||
|
// quit match is called and has to end the game, because the player never joined the game.
|
||||||
|
Player player = game.getPlayer(playerId);
|
||||||
|
if (player != null) {
|
||||||
|
player.leave();
|
||||||
|
checkStart(); // => So the game starts and gets an result or multiplayer game starts with active players
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -320,7 +320,14 @@ public class GameSessionPlayer extends GameSessionWatcher {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
player.quit(game);
|
if (game.getStartTime() == null) {
|
||||||
|
// gameController is still waiting to start the game
|
||||||
|
player.leave();
|
||||||
|
} else {
|
||||||
|
// game was already started
|
||||||
|
player.quit(game);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
if (ex != null) {
|
if (ex != null) {
|
||||||
// It seems this can happen if two threads try to end the game at the exact same time (one wins and one ends here)
|
// It seems this can happen if two threads try to end the game at the exact same time (one wins and one ends here)
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class GameWorker implements Callable {
|
||||||
@Override
|
@Override
|
||||||
public Object call() {
|
public Object call() {
|
||||||
try {
|
try {
|
||||||
logger.debug("GameWorker started gameId "+ game.getId());
|
logger.debug("GAME WORKER started gameId "+ game.getId());
|
||||||
game.start(choosingPlayerId);
|
game.start(choosingPlayerId);
|
||||||
game.fireUpdatePlayersEvent();
|
game.fireUpdatePlayersEvent();
|
||||||
gameController.gameResult(game.getWinner());
|
gameController.gameResult(game.getWinner());
|
||||||
|
|
|
@ -668,7 +668,7 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
}
|
}
|
||||||
if (gameOver(null) && !isSimulation()) {
|
if (gameOver(null) && !isSimulation()) {
|
||||||
winnerId = findWinnersAndLosers();
|
winnerId = findWinnersAndLosers();
|
||||||
StringBuilder sb = new StringBuilder("GAME ended gameId: ").append(this.getId()).append(" ");
|
StringBuilder sb = new StringBuilder("GAME END gameId: ").append(this.getId()).append(" ");
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Player player: this.getState().getPlayers().values()) {
|
for (Player player: this.getState().getPlayers().values()) {
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
|
@ -789,6 +789,10 @@ public abstract class GameImpl implements Game, Serializable {
|
||||||
|
|
||||||
saveState(false);
|
saveState(false);
|
||||||
|
|
||||||
|
if (gameOver(null)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//20091005 - 103.1
|
//20091005 - 103.1
|
||||||
if (!gameOptions.skipInitShuffling) { //don't shuffle in test mode for card injection on top of player's libraries
|
if (!gameOptions.skipInitShuffling) { //don't shuffle in test mode for card injection on top of player's libraries
|
||||||
for (Player player: state.getPlayers().values()) {
|
for (Player player: state.getPlayers().values()) {
|
||||||
|
|
|
@ -185,7 +185,6 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
protected int priorityTimeLeft = Integer.MAX_VALUE;
|
protected int priorityTimeLeft = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// conceded or connection lost game
|
// conceded or connection lost game
|
||||||
protected boolean left;
|
protected boolean left;
|
||||||
// set if the player quits the complete match
|
// set if the player quits the complete match
|
||||||
|
|
Loading…
Reference in a new issue