mirror of
https://github.com/correl/mage.git
synced 2024-12-24 11:50:45 +00:00
Improved reconnect and tournament handling. Reconnect time is now shown for disconneted players on player list and tournament panel. You can now reconnect (during 3 minutes) to a tournament also if meanwhile new game (after sideboarding ended) or round was started. Conceding the complete match in a tournament can no longer result in a draw, if you won games before. Quitting a tournament does now always end all active games of that quitting player.
This commit is contained in:
parent
c76529bf91
commit
9ff5bcbd92
29 changed files with 282 additions and 109 deletions
|
@ -657,7 +657,7 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
||||||
for (JInternalFrame window : desktopPane.getAllFramesInLayer(JLayeredPane.DEFAULT_LAYER)) {
|
for (JInternalFrame window : desktopPane.getAllFramesInLayer(JLayeredPane.DEFAULT_LAYER)) {
|
||||||
if (window instanceof DraftPane) {
|
if (window instanceof DraftPane) {
|
||||||
DraftPane draftPane = (DraftPane) window;
|
DraftPane draftPane = (DraftPane) window;
|
||||||
draftPane.hideDraft();
|
draftPane.removeDraft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -997,12 +997,21 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
|
||||||
}
|
}
|
||||||
if (window instanceof DraftPane) {
|
if (window instanceof DraftPane) {
|
||||||
DraftPane draftPane = (DraftPane) window;
|
DraftPane draftPane = (DraftPane) window;
|
||||||
draftPane.hideDraft();
|
draftPane.removeDraft();
|
||||||
}
|
}
|
||||||
if (window instanceof TournamentPane) {
|
if (window instanceof TournamentPane) {
|
||||||
TournamentPane tournamentPane = (TournamentPane) window;
|
TournamentPane tournamentPane = (TournamentPane) window;
|
||||||
tournamentPane.hideTournament();
|
tournamentPane.removeTournament();
|
||||||
}
|
}
|
||||||
|
// close & remove sideboarding or construction pane if open
|
||||||
|
if (window instanceof DeckEditorPane) {
|
||||||
|
DeckEditorPane deckEditorPane = (DeckEditorPane) window;
|
||||||
|
if (deckEditorPane.getDeckEditorMode().equals(DeckEditorMode.Limited)
|
||||||
|
|| deckEditorPane.getDeckEditorMode().equals(DeckEditorMode.Sideboard)){
|
||||||
|
deckEditorPane.removeFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,9 @@ public class DeckEditorPane extends MagePane {
|
||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DeckEditorMode getDeckEditorMode() {
|
||||||
|
return this.deckEditorPanel1.getDeckEditorMode();
|
||||||
|
}
|
||||||
|
|
||||||
/** This method is called from within the constructor to
|
/** This method is called from within the constructor to
|
||||||
* initialize the form.
|
* initialize the form.
|
||||||
|
|
|
@ -329,6 +329,10 @@ public class DeckEditorPanel extends javax.swing.JPanel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DeckEditorMode getDeckEditorMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
private BigCard getBigCard() {
|
private BigCard getBigCard() {
|
||||||
return this.bigCard;
|
return this.bigCard;
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ public class DraftPane extends MagePane {
|
||||||
this.draftPanel1.showDraft(draftId);
|
this.draftPanel1.showDraft(draftId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideDraft() {
|
public void removeDraft() {
|
||||||
draftPanel1.cleanUp();
|
draftPanel1.cleanUp();
|
||||||
this.removeFrame();
|
this.removeFrame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,7 +175,7 @@ public class DraftPanel extends javax.swing.JPanel {
|
||||||
c = c.getParent();
|
c = c.getParent();
|
||||||
}
|
}
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
((DraftPane)c).hideDraft();
|
((DraftPane)c).removeDraft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public class TournamentPane extends MagePane {
|
||||||
this.repaint();
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideTournament() {
|
public void removeTournament() {
|
||||||
tournamentPanel.cleanUp();
|
tournamentPanel.cleanUp();
|
||||||
removeFrame();
|
removeFrame();
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ public class TournamentPanel extends javax.swing.JPanel {
|
||||||
c = c.getParent();
|
c = c.getParent();
|
||||||
}
|
}
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
((TournamentPane)c).hideTournament();
|
((TournamentPane)c).removeTournament();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,6 +209,9 @@ public class TournamentPanel extends javax.swing.JPanel {
|
||||||
firstInitDone = true;
|
firstInitDone = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (txtEndTime == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (txtEndTime.getText().equals("running...") && tournament.getEndTime() != null) {
|
if (txtEndTime.getText().equals("running...") && tournament.getEndTime() != null) {
|
||||||
txtEndTime.setText(df.format(tournament.getEndTime()));
|
txtEndTime.setText(df.format(tournament.getEndTime()));
|
||||||
}
|
}
|
||||||
|
@ -608,14 +611,16 @@ class UpdateTournamentTask extends SwingWorker<Void, TournamentView> {
|
||||||
protected Void doInBackground() throws Exception {
|
protected Void doInBackground() throws Exception {
|
||||||
while (!isCancelled()) {
|
while (!isCancelled()) {
|
||||||
this.publish(session.getTournament(tournamentId));
|
this.publish(session.getTournament(tournamentId));
|
||||||
Thread.sleep(1000);
|
Thread.sleep(2000);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void process(List<TournamentView> view) {
|
protected void process(List<TournamentView> view) {
|
||||||
panel.update(view.get(0));
|
if (view != null) { // if user disconnects, view can be null for a short time
|
||||||
|
panel.update(view.get(0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -50,7 +50,8 @@ public interface MageServer {
|
||||||
// connection methods
|
// connection methods
|
||||||
boolean registerClient(String userName, String sessionId, MageVersion version) throws MageException;
|
boolean registerClient(String userName, String sessionId, MageVersion version) throws MageException;
|
||||||
boolean registerAdmin(String password, String sessionId, MageVersion version) throws MageException;
|
boolean registerAdmin(String password, String sessionId, MageVersion version) throws MageException;
|
||||||
void deregisterClient(String sessionId) throws MageException;
|
// Not used
|
||||||
|
// void deregisterClient(String sessionId) throws MageException;
|
||||||
|
|
||||||
// update methods
|
// update methods
|
||||||
List<ExpansionInfo> getMissingExpansionData(List<String> codes);
|
List<ExpansionInfo> getMissingExpansionData(List<String> codes);
|
||||||
|
|
|
@ -48,9 +48,11 @@ public class TournamentPlayerView implements Serializable, Comparable{
|
||||||
TournamentPlayerView(TournamentPlayer player) {
|
TournamentPlayerView(TournamentPlayer player) {
|
||||||
this.name = player.getPlayer().getName();
|
this.name = player.getPlayer().getName();
|
||||||
StringBuilder sb = new StringBuilder(player.getState().toString());
|
StringBuilder sb = new StringBuilder(player.getState().toString());
|
||||||
if (!player.getStateInfo().isEmpty()) {
|
String stateInfo = player.getStateInfo();
|
||||||
sb.append(" (").append(player.getStateInfo()).append(")");
|
if (!stateInfo.isEmpty()) {
|
||||||
|
sb.append(" (").append(stateInfo).append(")");
|
||||||
}
|
}
|
||||||
|
sb.append(player.getDisconnectInfo());
|
||||||
this.state = sb.toString();
|
this.state = sb.toString();
|
||||||
this.points = player.getPoints();
|
this.points = player.getPoints();
|
||||||
this.results = player.getResults();
|
this.results = player.getResults();
|
||||||
|
|
|
@ -109,6 +109,7 @@ public class MageServerImpl implements MageServer {
|
||||||
LogServiceImpl.instance.log(LogKeys.KEY_WRONG_VERSION, userName, version.toString(), Main.getVersion().toString(), sessionId);
|
LogServiceImpl.instance.log(LogKeys.KEY_WRONG_VERSION, userName, version.toString(), Main.getVersion().toString(), sessionId);
|
||||||
throw new MageVersionException(version, Main.getVersion());
|
throw new MageVersionException(version, Main.getVersion());
|
||||||
}
|
}
|
||||||
|
logger.info(new StringBuilder("RegisterClient - userName: ").append(userName).append(" sessionId = ").append(sessionId));
|
||||||
return SessionManager.getInstance().registerUser(sessionId, userName);
|
return SessionManager.getInstance().registerUser(sessionId, userName);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
if (ex instanceof MageVersionException) {
|
if (ex instanceof MageVersionException) {
|
||||||
|
@ -333,16 +334,16 @@ public class MageServerImpl implements MageServer {
|
||||||
return SessionManager.getInstance().extendUserSession(sessionId);
|
return SessionManager.getInstance().extendUserSession(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void deregisterClient(final String sessionId) throws MageException {
|
// public void deregisterClient(final String sessionId) throws MageException {
|
||||||
execute("deregisterClient", sessionId, new Action() {
|
// execute("deregisterClient", sessionId, new Action() {
|
||||||
@Override
|
// @Override
|
||||||
public void execute() {
|
// public void execute() {
|
||||||
SessionManager.getInstance().disconnect(sessionId, true);
|
// SessionManager.getInstance().disconnect(sessionId, true);
|
||||||
logger.debug("Client deregistered ...");
|
// logger.debug("Client deregistered ...");
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startMatch(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
|
public void startMatch(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
|
||||||
|
|
|
@ -37,6 +37,7 @@ import mage.interfaces.callback.ClientCallback;
|
||||||
import mage.players.net.UserData;
|
import mage.players.net.UserData;
|
||||||
import mage.players.net.UserGroup;
|
import mage.players.net.UserGroup;
|
||||||
import mage.server.util.ConfigSettings;
|
import mage.server.util.ConfigSettings;
|
||||||
|
import mage.view.ChatMessage;
|
||||||
import mage.view.UserDataView;
|
import mage.view.UserDataView;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.jboss.remoting.callback.AsynchInvokerCallbackHandler;
|
import org.jboss.remoting.callback.AsynchInvokerCallbackHandler;
|
||||||
|
@ -88,6 +89,8 @@ public class Session {
|
||||||
user = UserManager.getInstance().findUser(userName);
|
user = UserManager.getInstance().findUser(userName);
|
||||||
if (user.getHost().equals(host)) {
|
if (user.getHost().equals(host)) {
|
||||||
if (user.getSessionId().isEmpty()) {
|
if (user.getSessionId().isEmpty()) {
|
||||||
|
// TODO Send Chat message to tables (user is not registered yet)
|
||||||
|
// ChatManager.getInstance().broadcast([CHAT ID TABLES], "has reconnected", ChatMessage.MessageColor.GREEN);
|
||||||
logger.info("Reconnecting session for " + userName);
|
logger.info("Reconnecting session for " + userName);
|
||||||
} else {
|
} else {
|
||||||
//throw new MageException("This machine is already connected");
|
//throw new MageException("This machine is already connected");
|
||||||
|
@ -124,7 +127,10 @@ public class Session {
|
||||||
userData = new UserData(UserGroup.PLAYER, userDataView.getAvatarId(), userDataView.isShowAbilityPickerForced());
|
userData = new UserData(UserGroup.PLAYER, userDataView.getAvatarId(), userDataView.isShowAbilityPickerForced());
|
||||||
user.setUserData(userData);
|
user.setUserData(userData);
|
||||||
} else {
|
} else {
|
||||||
userData.setAvatarId(userDataView.getAvatarId());
|
if (userDataView.getAvatarId() == 51) { // Update special avatar if first avatar is selected
|
||||||
|
updateAvatar(userName, userData);
|
||||||
|
}
|
||||||
|
userData.setAvatarId(userDataView.getAvatarId());
|
||||||
userData.setShowAbilityPickerForced(userDataView.isShowAbilityPickerForced());
|
userData.setShowAbilityPickerForced(userDataView.isShowAbilityPickerForced());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -111,7 +111,7 @@ public class SessionManager {
|
||||||
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId);
|
LogServiceImpl.instance.log(LogKeys.KEY_SESSION_DISCONNECTED, sessionId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.info("could not find session with id " + sessionId);
|
logger.info("disconnect: could not find session with id " + sessionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,6 @@ import mage.cards.decks.InvalidDeckException;
|
||||||
import mage.constants.RangeOfInfluence;
|
import mage.constants.RangeOfInfluence;
|
||||||
import mage.constants.TableState;
|
import mage.constants.TableState;
|
||||||
import mage.game.GameException;
|
import mage.game.GameException;
|
||||||
import mage.game.GameOptions;
|
|
||||||
import mage.game.Seat;
|
import mage.game.Seat;
|
||||||
import mage.game.Table;
|
import mage.game.Table;
|
||||||
import mage.game.draft.Draft;
|
import mage.game.draft.Draft;
|
||||||
|
@ -56,7 +55,6 @@ import mage.game.tournament.Tournament;
|
||||||
import mage.game.tournament.TournamentOptions;
|
import mage.game.tournament.TournamentOptions;
|
||||||
import mage.game.tournament.TournamentPlayer;
|
import mage.game.tournament.TournamentPlayer;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.server.challenge.ChallengeManager;
|
|
||||||
import mage.server.draft.DraftManager;
|
import mage.server.draft.DraftManager;
|
||||||
import mage.server.game.DeckValidatorFactory;
|
import mage.server.game.DeckValidatorFactory;
|
||||||
import mage.server.game.GameFactory;
|
import mage.server.game.GameFactory;
|
||||||
|
@ -306,7 +304,7 @@ public class TableController {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TournamentManager.getInstance().submitDeck(tournament.getId(), playerId, deck);
|
TournamentManager.getInstance().submitDeck(tournament.getId(), playerId, deck);
|
||||||
UserManager.getInstance().getUser(userId).removeConstructing(table.getId());
|
UserManager.getInstance().getUser(userId).removeConstructing(playerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,6 +472,14 @@ public class TableController {
|
||||||
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) {
|
||||||
|
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, so he can join the game, if he reconnects in time.
|
||||||
|
// remove a 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.info(new StringBuilder("User ").append(user.getName()).append(" game started - matchId ").append(match.getId()).append(" userId: ").append(user.getId()));
|
logger.info(new StringBuilder("User ").append(user.getName()).append(" game started - matchId ").append(match.getId()).append(" userId: ").append(user.getId()));
|
||||||
user.gameStarted(match.getGame().getId(), entry.getValue());
|
user.gameStarted(match.getGame().getId(), entry.getValue());
|
||||||
if (creator == null) {
|
if (creator == null) {
|
||||||
|
@ -486,10 +492,8 @@ public class TableController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TableManager.getInstance().removeTable(table.getId());
|
|
||||||
GameManager.getInstance().removeGame(match.getGame().getId());
|
|
||||||
logger.warn("Unable to find player " + entry.getKey());
|
logger.warn("Unable to find player " + entry.getKey());
|
||||||
break;
|
match.getPlayer(entry.getValue()).setQuit(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,7 +662,9 @@ public class TableController {
|
||||||
user.showUserMessage("Match info", sb.toString());
|
user.showUserMessage("Match info", sb.toString());
|
||||||
}
|
}
|
||||||
// remove table from user - table manager holds table for display of finished matches
|
// remove table from user - table manager holds table for display of finished matches
|
||||||
user.removeTable(entry.getValue());
|
if (!table.isTournamentSubTable()) {
|
||||||
|
user.removeTable(entry.getValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -735,4 +741,29 @@ public class TableController {
|
||||||
return match;
|
return match;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isMatchTableStillValid() {
|
||||||
|
// check only normal match table
|
||||||
|
if (!table.isTournament() && !table.isTournamentSubTable()) {
|
||||||
|
int humanPlayers = 0;
|
||||||
|
int validHumanPlayers = 0;
|
||||||
|
if (match == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for(Map.Entry<UUID, UUID> userPlayerEntry: userPlayerMap.entrySet()) {
|
||||||
|
MatchPlayer matchPlayer = match.getPlayer(userPlayerEntry.getValue());
|
||||||
|
if (matchPlayer.getPlayer().isHuman()) {
|
||||||
|
humanPlayers++;
|
||||||
|
if (!matchPlayer.hasQuit()) {
|
||||||
|
User user = UserManager.getInstance().getUser(userPlayerEntry.getKey());
|
||||||
|
if (user != null) {
|
||||||
|
validHumanPlayers++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if at least 2 human players are valid (multiplayer) or all human players are valid the table is valid
|
||||||
|
return validHumanPlayers >= 2 || validHumanPlayers == humanPlayers;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ import mage.game.match.MatchPlayer;
|
||||||
import mage.game.tournament.Tournament;
|
import mage.game.tournament.Tournament;
|
||||||
import mage.game.tournament.TournamentOptions;
|
import mage.game.tournament.TournamentOptions;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
import mage.server.game.GameManager;
|
||||||
import mage.server.game.GamesRoomManager;
|
import mage.server.game.GamesRoomManager;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@ -175,6 +176,20 @@ public class TableManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove user from all sub tables of a tournament
|
||||||
|
public void userQuitTournamentSubTables(UUID tournamentId, UUID userId) {
|
||||||
|
for (TableController controller: controllers.values()) {
|
||||||
|
if (controller.getTable().isTournamentSubTable() && controller.getTable().getTournament().getId().equals(tournamentId)) {
|
||||||
|
Match match = controller.getTable().getMatch();
|
||||||
|
if (match != null) {
|
||||||
|
if (match.getGame() != null) {
|
||||||
|
GameManager.getInstance().quitMatch(match.getGame().getId(), userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isTableOwner(UUID tableId, UUID userId) {
|
public boolean isTableOwner(UUID tableId, UUID userId) {
|
||||||
if (controllers.containsKey(tableId)) {
|
if (controllers.containsKey(tableId)) {
|
||||||
return controllers.get(tableId).isOwner(userId);
|
return controllers.get(tableId).isOwner(userId);
|
||||||
|
@ -341,20 +356,10 @@ public class TableManager {
|
||||||
logger.warn("Table expired: id = " + table.getId() + ", created_by=" + table.getControllerName() + ". Removing...");
|
logger.warn("Table expired: id = " + table.getId() + ", created_by=" + table.getControllerName() + ". Removing...");
|
||||||
toRemove.add(table.getId());
|
toRemove.add(table.getId());
|
||||||
}
|
}
|
||||||
// remove immediately non tournament tables with no human players
|
// remove tables not valid anymore
|
||||||
else if (!table.isTournament()) {
|
else if (!table.isTournament()) {
|
||||||
boolean canBeRemoved = true;
|
TableController tableController = getController(table.getId());
|
||||||
for (MatchPlayer matchPlayer :table.getMatch().getPlayers()) {
|
if (!tableController.isMatchTableStillValid()) {
|
||||||
Player player = matchPlayer.getPlayer();
|
|
||||||
if (player != null && player.isHuman() && !player.hasLeft()) {
|
|
||||||
canBeRemoved = false;
|
|
||||||
}
|
|
||||||
// tournament sub tables may not be removed as long the tournament is not finished
|
|
||||||
if(table.isTournamentSubTable() && table.getTournament().getEndTime() == null) {
|
|
||||||
canBeRemoved = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (canBeRemoved) {
|
|
||||||
logger.warn("Table with no active human player: id = " + table.getId() + ", created_by=" + table.getControllerName() + ". Removing...");
|
logger.warn("Table with no active human player: id = " + table.getId() + ", created_by=" + table.getControllerName() + ". Removing...");
|
||||||
toRemove.add(table.getId());
|
toRemove.add(table.getId());
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.game.Table;
|
import mage.game.Table;
|
||||||
import mage.interfaces.callback.ClientCallback;
|
import mage.interfaces.callback.ClientCallback;
|
||||||
|
@ -42,6 +43,7 @@ import mage.server.draft.DraftSession;
|
||||||
import mage.server.game.GameManager;
|
import mage.server.game.GameManager;
|
||||||
import mage.server.game.GameSession;
|
import mage.server.game.GameSession;
|
||||||
import mage.server.tournament.TournamentSession;
|
import mage.server.tournament.TournamentSession;
|
||||||
|
import mage.server.util.SystemUtil;
|
||||||
import mage.view.TableClientMessage;
|
import mage.view.TableClientMessage;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
@ -133,6 +135,13 @@ public class User {
|
||||||
return userState == UserState.Connected || userState == UserState.Reconnected;
|
return userState == UserState.Connected || userState == UserState.Reconnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisconnectDuration() {
|
||||||
|
long secondsDisconnected = SystemUtil.getDateDiff(lastActivity, new Date(), TimeUnit.SECONDS);
|
||||||
|
int minutes = (int) secondsDisconnected / 60;
|
||||||
|
int seconds = (int) secondsDisconnected % 60;
|
||||||
|
return new StringBuilder(Integer.toString(minutes)).append(":").append(seconds > 9 ? seconds: "0" + Integer.toString(seconds)).toString();
|
||||||
|
}
|
||||||
|
|
||||||
public Date getConnectionTime() {
|
public Date getConnectionTime() {
|
||||||
return connectionTime;
|
return connectionTime;
|
||||||
}
|
}
|
||||||
|
@ -246,7 +255,7 @@ public class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Entry<UUID, TournamentSession> entry: constructing.entrySet()) {
|
for (Entry<UUID, TournamentSession> entry: constructing.entrySet()) {
|
||||||
entry.getValue().construct(0);
|
entry.getValue().construct(0); // TODO: Check if this is correct
|
||||||
}
|
}
|
||||||
for (Entry<UUID, Deck> entry: sideboarding.entrySet()) {
|
for (Entry<UUID, Deck> entry: sideboarding.entrySet()) {
|
||||||
TableController controller = TableManager.getInstance().getController(entry.getKey());
|
TableController controller = TableManager.getInstance().getController(entry.getKey());
|
||||||
|
@ -323,10 +332,15 @@ public class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGameInfo() {
|
public String getGameInfo() {
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
String disconnectInfo = "";
|
||||||
|
if (!isConnected()) {
|
||||||
|
disconnectInfo = new StringBuilder(" (discon. ").append(getDisconnectDuration()).append(")").toString();
|
||||||
|
}
|
||||||
int draft = 0, match = 0, sideboard = 0, tournament = 0, construct = 0;
|
int draft = 0, match = 0, sideboard = 0, tournament = 0, construct = 0;
|
||||||
for (Table table : tables.values()) {
|
for (Map.Entry<UUID, Table> tableEntry : tables.entrySet()) {
|
||||||
|
Table table = tableEntry.getValue();
|
||||||
if (table.isTournament()) {
|
if (table.isTournament()) {
|
||||||
switch (table.getState()) {
|
switch (table.getState()) {
|
||||||
case CONSTRUCTING:
|
case CONSTRUCTING:
|
||||||
|
@ -339,6 +353,11 @@ public class User {
|
||||||
tournament++;
|
tournament++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!isConnected()) {
|
||||||
|
table.getTournament().getPlayer(tableEntry.getKey()).setDisconnectInfo(disconnectInfo);
|
||||||
|
} else {
|
||||||
|
table.getTournament().getPlayer(tableEntry.getKey()).setDisconnectInfo("");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (table.getState()) {
|
switch (table.getState()) {
|
||||||
case SIDEBOARDING:
|
case SIDEBOARDING:
|
||||||
|
@ -365,6 +384,7 @@ public class User {
|
||||||
if (tournament > 0) {
|
if (tournament > 0) {
|
||||||
sb.append("TP: ").append(tournament).append(" ");
|
sb.append("TP: ").append(tournament).append(" ");
|
||||||
}
|
}
|
||||||
|
sb.append(disconnectInfo);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,13 +102,13 @@ public class UserManager {
|
||||||
|
|
||||||
public void disconnect(UUID userId, User.DisconnectReason reason) {
|
public void disconnect(UUID userId, User.DisconnectReason reason) {
|
||||||
if (userId != null) {
|
if (userId != null) {
|
||||||
ChatManager.getInstance().removeUser(userId, reason);
|
|
||||||
if (users.containsKey(userId)) {
|
if (users.containsKey(userId)) {
|
||||||
User user = users.get(userId);
|
User user = users.get(userId);
|
||||||
logger.debug(new StringBuilder("User ").append(user.getName()).append(" has lost connection userId:").append(userId));
|
user.setSessionId(""); // Session will be set again with new id if user reconnects
|
||||||
users.get(userId).setSessionId("");
|
|
||||||
ChatManager.getInstance().broadcast(userId, "has lost connection", MessageColor.BLACK);
|
ChatManager.getInstance().broadcast(userId, "has lost connection", MessageColor.BLACK);
|
||||||
|
logger.info(new StringBuilder("User ").append(user.getName()).append(" has lost connection userId:").append(userId));
|
||||||
}
|
}
|
||||||
|
ChatManager.getInstance().removeUser(userId, reason);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +143,9 @@ public class UserManager {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Is the connection lost for more than 3 minutes, the user will be removed (within 3 minutes he can reconnect)
|
||||||
|
*/
|
||||||
private void checkExpired() {
|
private void checkExpired() {
|
||||||
Calendar expired = Calendar.getInstance();
|
Calendar expired = Calendar.getInstance();
|
||||||
expired.add(Calendar.MINUTE, -3) ;
|
expired.add(Calendar.MINUTE, -3) ;
|
||||||
|
|
|
@ -112,9 +112,6 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
|
||||||
List<UsersView> users = new ArrayList<>();
|
List<UsersView> users = new ArrayList<>();
|
||||||
for (User user : UserManager.getInstance().getUsers()) {
|
for (User user : UserManager.getInstance().getUsers()) {
|
||||||
StringBuilder sb = new StringBuilder(user.getGameInfo());
|
StringBuilder sb = new StringBuilder(user.getGameInfo());
|
||||||
if (!user.isConnected()) {
|
|
||||||
sb.append(" (discon.)");
|
|
||||||
}
|
|
||||||
users.add(new UsersView(user.getName(), user.getInfo(), sb.toString()));
|
users.add(new UsersView(user.getName(), user.getInfo(), sb.toString()));
|
||||||
}
|
}
|
||||||
Collections.sort(users, new UserNameSorter());
|
Collections.sort(users, new UserNameSorter());
|
||||||
|
|
|
@ -53,6 +53,7 @@ import mage.server.UserManager;
|
||||||
import mage.server.draft.DraftController;
|
import mage.server.draft.DraftController;
|
||||||
import mage.server.draft.DraftManager;
|
import mage.server.draft.DraftManager;
|
||||||
import mage.server.draft.DraftSession;
|
import mage.server.draft.DraftSession;
|
||||||
|
import mage.server.game.GameManager;
|
||||||
import mage.server.game.GamesRoomManager;
|
import mage.server.game.GamesRoomManager;
|
||||||
import mage.server.util.ThreadExecutor;
|
import mage.server.util.ThreadExecutor;
|
||||||
import mage.view.ChatMessage.MessageColor;
|
import mage.view.ChatMessage.MessageColor;
|
||||||
|
@ -91,6 +92,9 @@ public class TournamentController {
|
||||||
@Override
|
@Override
|
||||||
public void event(TableEvent event) {
|
public void event(TableEvent event) {
|
||||||
switch (event.getEventType()) {
|
switch (event.getEventType()) {
|
||||||
|
case CHECK_STATE_PLAYERS:
|
||||||
|
checkPlayersState();
|
||||||
|
break;
|
||||||
case INFO:
|
case INFO:
|
||||||
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS);
|
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS);
|
||||||
logger.debug(tournament.getId() + " " + event.getMessage());
|
logger.debug(tournament.getId() + " " + event.getMessage());
|
||||||
|
@ -214,8 +218,8 @@ public class TournamentController {
|
||||||
table.setTournament(tournament);
|
table.setTournament(tournament);
|
||||||
TournamentPlayer player1 = pair.getPlayer1();
|
TournamentPlayer player1 = pair.getPlayer1();
|
||||||
TournamentPlayer player2 = pair.getPlayer2();
|
TournamentPlayer player2 = pair.getPlayer2();
|
||||||
tableManager.addPlayer(getPlayerSessionId(player1.getPlayer().getId()), table.getId(), player1.getPlayer(), player1.getPlayerType(), player1.getDeck());
|
tableManager.addPlayer(getPlayerUserId(player1.getPlayer().getId()), table.getId(), player1.getPlayer(), player1.getPlayerType(), player1.getDeck());
|
||||||
tableManager.addPlayer(getPlayerSessionId(player2.getPlayer().getId()), table.getId(), player2.getPlayer(), player2.getPlayerType(), player2.getDeck());
|
tableManager.addPlayer(getPlayerUserId(player2.getPlayer().getId()), table.getId(), player2.getPlayer(), player2.getPlayerType(), player2.getDeck());
|
||||||
tableManager.startTournamentSubMatch(null, table.getId());
|
tableManager.startTournamentSubMatch(null, table.getId());
|
||||||
pair.setMatch(tableManager.getMatch(table.getId()));
|
pair.setMatch(tableManager.getMatch(table.getId()));
|
||||||
pair.setTableId(table.getId());
|
pair.setTableId(table.getId());
|
||||||
|
@ -242,7 +246,7 @@ public class TournamentController {
|
||||||
if (tournamentSessions.containsKey(playerId)) {
|
if (tournamentSessions.containsKey(playerId)) {
|
||||||
TournamentSession tournamentSession = tournamentSessions.get(playerId);
|
TournamentSession tournamentSession = tournamentSessions.get(playerId);
|
||||||
tournamentSession.construct(timeout);
|
tournamentSession.construct(timeout);
|
||||||
UserManager.getInstance().getUser(getPlayerSessionId(playerId)).addConstructing(playerId, tournamentSession);
|
UserManager.getInstance().getUser(getPlayerUserId(playerId)).addConstructing(playerId, tournamentSession);
|
||||||
TournamentPlayer player = tournament.getPlayer(playerId);
|
TournamentPlayer player = tournament.getPlayer(playerId);
|
||||||
player.setState(TournamentPlayerState.CONSTRUCTING);
|
player.setState(TournamentPlayerState.CONSTRUCTING);
|
||||||
}
|
}
|
||||||
|
@ -285,6 +289,8 @@ public class TournamentController {
|
||||||
String info;
|
String info;
|
||||||
if (tournament.isDoneConstructing()) {
|
if (tournament.isDoneConstructing()) {
|
||||||
info = new StringBuilder("during round ").append(tournament.getRounds().size()).toString();
|
info = new StringBuilder("during round ").append(tournament.getRounds().size()).toString();
|
||||||
|
// quit active matches of that tournament
|
||||||
|
TableManager.getInstance().userQuitTournamentSubTables(tournament.getId(), userId);
|
||||||
} else {
|
} else {
|
||||||
if (tPlayer.getState().equals(TournamentPlayerState.DRAFTING)) {
|
if (tPlayer.getState().equals(TournamentPlayerState.DRAFTING)) {
|
||||||
info = "during Draft phase";
|
info = "during Draft phase";
|
||||||
|
@ -344,7 +350,7 @@ public class TournamentController {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID getPlayerSessionId(UUID playerId) {
|
private UUID getPlayerUserId(UUID playerId) {
|
||||||
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) {
|
for (Entry<UUID, UUID> entry: userPlayerMap.entrySet()) {
|
||||||
if (entry.getValue().equals(playerId)) {
|
if (entry.getValue().equals(playerId)) {
|
||||||
return entry.getKey();
|
return entry.getKey();
|
||||||
|
@ -365,4 +371,28 @@ public class TournamentController {
|
||||||
public boolean isAbort() {
|
public boolean isAbort() {
|
||||||
return tournament.isAbort();
|
return tournament.isAbort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPlayerAlive(UUID playerId) {
|
||||||
|
if (tournamentSessions.containsKey(playerId)) {
|
||||||
|
return tournamentSessions.get(playerId).isKilled();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPlayersState() {
|
||||||
|
for (TournamentPlayer tournamentPlayer: tournament.getPlayers()) {
|
||||||
|
if (!tournamentPlayer.getEliminated()) {
|
||||||
|
if (tournamentSessions.containsKey(tournamentPlayer.getPlayer().getId())) {
|
||||||
|
if (tournamentSessions.get(tournamentPlayer.getPlayer().getId()).isKilled()) {
|
||||||
|
tournamentPlayer.setEliminated();
|
||||||
|
tournamentPlayer.setStateInfo("disconnected");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tournamentPlayer.setEliminated();
|
||||||
|
tournamentPlayer.setStateInfo("no tournament session");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ import mage.interfaces.callback.ClientCallback;
|
||||||
import mage.server.User;
|
import mage.server.User;
|
||||||
import mage.server.UserManager;
|
import mage.server.UserManager;
|
||||||
import mage.server.util.ThreadExecutor;
|
import mage.server.util.ThreadExecutor;
|
||||||
import mage.view.*;
|
import mage.view.TournamentView;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,6 +123,10 @@ public class TournamentSession {
|
||||||
killed = true;
|
killed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isKilled() {
|
||||||
|
return killed;
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized void setupTimeout(int seconds) {
|
private synchronized void setupTimeout(int seconds) {
|
||||||
if (futureTimeout != null && !futureTimeout.isDone()) {
|
if (futureTimeout != null && !futureTimeout.isDone()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -8,11 +8,13 @@ import mage.game.Game;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -164,4 +166,17 @@ public class SystemUtil {
|
||||||
System.out.println(sanitize("anPlsdf123 ") + "|");
|
System.out.println(sanitize("anPlsdf123 ") + "|");
|
||||||
System.out.println(sanitize("anPlsdf123\r\n") + "|");
|
System.out.println(sanitize("anPlsdf123\r\n") + "|");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a diff between two dates
|
||||||
|
*
|
||||||
|
* @param date1 the oldest date
|
||||||
|
* @param date2 the newest date
|
||||||
|
* @param timeUnit the unit in which you want the diff
|
||||||
|
* @return the diff value, in the provided unit
|
||||||
|
*/
|
||||||
|
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
|
||||||
|
long diffInMillies = date2.getTime() - date1.getTime();
|
||||||
|
return timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ import mage.target.common.TargetControlledCreaturePermanent;
|
||||||
public class NaturalOrder extends CardImpl<NaturalOrder> {
|
public class NaturalOrder extends CardImpl<NaturalOrder> {
|
||||||
|
|
||||||
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a green creature");
|
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("a green creature");
|
||||||
private static final FilterCard filterCard = new FilterCard("a green creature card");
|
private static final FilterCard filterCard = new FilterCard("green creature card");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
filter.add(new ColorPredicate(ObjectColor.GREEN));
|
||||||
|
|
|
@ -34,44 +34,62 @@ public class LoadCallbackClient implements CallbackClient {
|
||||||
controlCount = 0;
|
controlCount = 0;
|
||||||
log.info(callback.getMethod());
|
log.info(callback.getMethod());
|
||||||
callback.setData(CompressUtil.decompress(callback.getData()));
|
callback.setData(CompressUtil.decompress(callback.getData()));
|
||||||
if (callback.getMethod().equals("startGame")) {
|
switch (callback.getMethod()) {
|
||||||
TableClientMessage message = (TableClientMessage) callback.getData();
|
case "startGame":
|
||||||
gameId = message.getGameId();
|
{
|
||||||
playerId = message.getPlayerId();
|
TableClientMessage message = (TableClientMessage) callback.getData();
|
||||||
session.joinGame(message.getGameId());
|
gameId = message.getGameId();
|
||||||
startControlThread();
|
playerId = message.getPlayerId();
|
||||||
} else if (callback.getMethod().equals("gameInform")) {
|
session.joinGame(message.getGameId());
|
||||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
startControlThread();
|
||||||
log.info("Inform: " + message.getMessage());
|
break;
|
||||||
gameView = message.getGameView();
|
}
|
||||||
} else if (callback.getMethod().equals("gameInit")) {
|
case "gameInform":
|
||||||
|
{
|
||||||
} else if (callback.getMethod().equals("gameTarget")) {
|
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
log.info("Inform: " + message.getMessage());
|
||||||
log.info("Target: " + message.getMessage());
|
gameView = message.getGameView();
|
||||||
if (message.getMessage().equals("Select a starting player")) {
|
break;
|
||||||
session.sendPlayerUUID(gameId, playerId);
|
}
|
||||||
} else if (message.getMessage().equals("Select a card to discard")) {
|
case "gameInit":
|
||||||
log.info("hand size: " + gameView.getHand().size());
|
break;
|
||||||
SimpleCardView card = gameView.getHand().values().iterator().next();
|
case "gameTarget":
|
||||||
session.sendPlayerUUID(gameId, card.getId());
|
{
|
||||||
}
|
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||||
} else if (callback.getMethod().equals("gameAsk")) {
|
log.info("Target: " + message.getMessage());
|
||||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
switch (message.getMessage()) {
|
||||||
log.info("Ask: " + message.getMessage());
|
case "Select a starting player":
|
||||||
if (message.getMessage().equals("Do you want to take a mulligan?")) {
|
session.sendPlayerUUID(gameId, playerId);
|
||||||
session.sendPlayerBoolean(gameId, false);
|
break;
|
||||||
}
|
case "Select a card to discard":
|
||||||
} else if (callback.getMethod().equals("gameSelect")) {
|
log.info("hand size: " + gameView.getHand().size());
|
||||||
GameClientMessage message = (GameClientMessage) callback.getData();
|
SimpleCardView card = gameView.getHand().values().iterator().next();
|
||||||
log.info("Select: " + message.getMessage());
|
session.sendPlayerUUID(gameId, card.getId());
|
||||||
if (LoadPhaseManager.getInstance().isSkip(message.getGameView(), message.getMessage(), playerId)) {
|
break;
|
||||||
log.info("Skipped: " + message.getMessage());
|
}
|
||||||
session.sendPlayerBoolean(gameId, false);
|
break;
|
||||||
}
|
}
|
||||||
} else if (callback.getMethod().equals("gameOver")) {
|
case "gameAsk":
|
||||||
log.info("Game over");
|
{
|
||||||
gameOver = true;
|
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||||
|
log.info("Ask: " + message.getMessage());
|
||||||
|
if (message.getMessage().equals("Do you want to take a mulligan?")) {
|
||||||
|
session.sendPlayerBoolean(gameId, false);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
case "gameSelect":
|
||||||
|
{
|
||||||
|
GameClientMessage message = (GameClientMessage) callback.getData();
|
||||||
|
log.info("Select: " + message.getMessage());
|
||||||
|
if (LoadPhaseManager.getInstance().isSkip(message.getGameView(), message.getMessage(), playerId)) {
|
||||||
|
log.info("Skipped: " + message.getMessage());
|
||||||
|
session.sendPlayerBoolean(gameId, false);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
case "gameOver":
|
||||||
|
log.info("Game over");
|
||||||
|
gameOver = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class TableEvent extends EventObject implements ExternalEvent, Serializab
|
||||||
|
|
||||||
public enum EventType {
|
public enum EventType {
|
||||||
UPDATE, INFO, STATUS, START_DRAFT, START_MATCH, SIDEBOARD, CONSTRUCT, SUBMIT_DECK, END, END_GAME_INFO, ERROR,
|
UPDATE, INFO, STATUS, START_DRAFT, START_MATCH, SIDEBOARD, CONSTRUCT, SUBMIT_DECK, END, END_GAME_INFO, ERROR,
|
||||||
INIT_TIMER, RESUME_TIMER, PAUSE_TIMER
|
INIT_TIMER, RESUME_TIMER, PAUSE_TIMER, CHECK_STATE_PLAYERS
|
||||||
}
|
}
|
||||||
|
|
||||||
private Game game;
|
private Game game;
|
||||||
|
|
|
@ -72,7 +72,7 @@ public class Round {
|
||||||
public boolean isRoundOver() {
|
public boolean isRoundOver() {
|
||||||
boolean roundIsOver = true;
|
boolean roundIsOver = true;
|
||||||
for (TournamentPairing pair: pairs) {
|
for (TournamentPairing pair: pairs) {
|
||||||
if (!pair.getMatch().isMatchOver()) {
|
if (pair.getMatch() != null && !pair.getMatch().isMatchOver()) {
|
||||||
roundIsOver = false;
|
roundIsOver = false;
|
||||||
} else {
|
} else {
|
||||||
if (!pair.isAlreadyPublished()) {
|
if (!pair.isAlreadyPublished()) {
|
||||||
|
|
|
@ -199,6 +199,7 @@ public abstract class TournamentImpl implements Tournament {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void playRound(Round round) {
|
protected void playRound(Round round) {
|
||||||
|
|
||||||
for (TournamentPairing pair: round.getPairs()) {
|
for (TournamentPairing pair: round.getPairs()) {
|
||||||
playMatch(pair);
|
playMatch(pair);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +241,7 @@ public abstract class TournamentImpl implements Tournament {
|
||||||
UUID player1Id = pair.getPlayer1().getPlayer().getId();
|
UUID player1Id = pair.getPlayer1().getPlayer().getId();
|
||||||
UUID player2Id = pair.getPlayer2().getPlayer().getId();
|
UUID player2Id = pair.getPlayer2().getPlayer().getId();
|
||||||
Match match = pair.getMatch();
|
Match match = pair.getMatch();
|
||||||
if (match.isMatchOver()) {
|
if (match != null && match.isMatchOver()) {
|
||||||
if (round.getRoundNumber() == rounds.size()) {
|
if (round.getRoundNumber() == rounds.size()) {
|
||||||
if (players.get(player1Id).getState().equals(TournamentPlayerState.DUELING)) {
|
if (players.get(player1Id).getState().equals(TournamentPlayerState.DUELING)) {
|
||||||
players.get(player1Id).setState(TournamentPlayerState.WAITING);
|
players.get(player1Id).setState(TournamentPlayerState.WAITING);
|
||||||
|
@ -259,10 +260,10 @@ public abstract class TournamentImpl implements Tournament {
|
||||||
sb2.append("-").append(match.getPlayer(player1Id).getWins()).append(") ");
|
sb2.append("-").append(match.getPlayer(player1Id).getWins()).append(") ");
|
||||||
players.get(player1Id).setResults(sb1.toString());
|
players.get(player1Id).setResults(sb1.toString());
|
||||||
players.get(player2Id).setResults(sb2.toString());
|
players.get(player2Id).setResults(sb2.toString());
|
||||||
if (match.getPlayer(player1Id).getWins() > match.getPlayer(player2Id).getWins()) {
|
if (match.getPlayer(player2Id).hasQuit() || match.getPlayer(player1Id).getWins() > match.getPlayer(player2Id).getWins()) {
|
||||||
int points = players.get(player1Id).getPoints();
|
int points = players.get(player1Id).getPoints();
|
||||||
players.get(player1Id).setPoints(points + 3);
|
players.get(player1Id).setPoints(points + 3);
|
||||||
} else if (match.getPlayer(player1Id).getWins() < match.getPlayer(player2Id).getWins()) {
|
} else if (match.getPlayer(player1Id).hasQuit() || match.getPlayer(player1Id).getWins() < match.getPlayer(player2Id).getWins()) {
|
||||||
int points = players.get(player2Id).getPoints();
|
int points = players.get(player2Id).getPoints();
|
||||||
players.get(player2Id).setPoints(points + 3);
|
players.get(player2Id).setPoints(points + 3);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -42,10 +42,11 @@ public class TournamentPlayer {
|
||||||
protected int points;
|
protected int points;
|
||||||
protected String playerType;
|
protected String playerType;
|
||||||
protected TournamentPlayerState state;
|
protected TournamentPlayerState state;
|
||||||
protected String stateInfo = "";
|
protected String stateInfo;
|
||||||
|
protected String disconnectInfo;
|
||||||
protected Player player;
|
protected Player player;
|
||||||
protected Deck deck;
|
protected Deck deck;
|
||||||
protected String results = "";
|
protected String results;
|
||||||
protected boolean eliminated = false;
|
protected boolean eliminated = false;
|
||||||
protected boolean quit = false;
|
protected boolean quit = false;
|
||||||
protected boolean doneConstructing;
|
protected boolean doneConstructing;
|
||||||
|
@ -55,6 +56,10 @@ public class TournamentPlayer {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.playerType = playerType;
|
this.playerType = playerType;
|
||||||
this.state = TournamentPlayerState.JOINED;
|
this.state = TournamentPlayerState.JOINED;
|
||||||
|
this.stateInfo = "";
|
||||||
|
this.disconnectInfo = "";
|
||||||
|
this.results = "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
|
@ -151,6 +156,14 @@ public class TournamentPlayer {
|
||||||
this.stateInfo = stateInfo;
|
this.stateInfo = stateInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDisconnectInfo() {
|
||||||
|
return disconnectInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDisconnectInfo(String disconnectInfo) {
|
||||||
|
this.disconnectInfo = disconnectInfo;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasQuit() {
|
public boolean hasQuit() {
|
||||||
return quit;
|
return quit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ package mage.game.tournament;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import mage.game.events.TableEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -43,15 +44,15 @@ public abstract class TournamentSingleElimination extends TournamentImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void runTournament() {
|
protected void runTournament() {
|
||||||
|
|
||||||
for (Map.Entry<UUID, TournamentPlayer> entry: players.entrySet()) {
|
for (Map.Entry<UUID, TournamentPlayer> entry: players.entrySet()) {
|
||||||
if (entry.getValue().getPlayer().autoLoseGame()) {
|
if (entry.getValue().getPlayer().autoLoseGame()) {
|
||||||
entry.getValue().setEliminated();
|
entry.getValue().setEliminated();
|
||||||
entry.getValue().setResults("Auto Eliminated");
|
entry.getValue().setResults("Auto Eliminated");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (this.getActivePlayers().size() > 1) {
|
while (this.getActivePlayers().size() > 1) {
|
||||||
|
// check if some player got killed / disconnected meanwhile and update their state
|
||||||
|
tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
|
||||||
Round round = createRoundRandom();
|
Round round = createRoundRandom();
|
||||||
playRound(round);
|
playRound(round);
|
||||||
eliminatePlayers(round);
|
eliminatePlayers(round);
|
||||||
|
|
|
@ -33,6 +33,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import mage.constants.TournamentPlayerState;
|
import mage.constants.TournamentPlayerState;
|
||||||
|
import mage.game.events.TableEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -45,7 +46,7 @@ public abstract class TournamentSwiss extends TournamentImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void runTournament() {
|
protected void runTournament() {
|
||||||
for (Map.Entry<UUID, TournamentPlayer> entry: players.entrySet()) {
|
for (Map.Entry<UUID, TournamentPlayer> entry: players.entrySet()) {
|
||||||
if (entry.getValue().getPlayer().autoLoseGame()) {
|
if (entry.getValue().getPlayer().autoLoseGame()) {
|
||||||
entry.getValue().setEliminated();
|
entry.getValue().setEliminated();
|
||||||
|
@ -54,6 +55,8 @@ public abstract class TournamentSwiss extends TournamentImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (this.getActivePlayers().size() > 1 && this.getNumberRounds() > this.getRounds().size()) {
|
while (this.getActivePlayers().size() > 1 && this.getNumberRounds() > this.getRounds().size()) {
|
||||||
|
// check if some player got killed / disconnected meanwhile and update their state
|
||||||
|
tableEventSource.fireTableEvent(TableEvent.EventType.CHECK_STATE_PLAYERS);
|
||||||
// Swiss pairing
|
// Swiss pairing
|
||||||
Round round = createRoundSwiss();
|
Round round = createRoundSwiss();
|
||||||
playRound(round);
|
playRound(round);
|
||||||
|
|
|
@ -337,7 +337,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
||||||
this.wins = false;
|
this.wins = false;
|
||||||
this.loses = false;
|
this.loses = false;
|
||||||
this.left = false;
|
this.left = false;
|
||||||
// quittet won't be reset because the player stays quit
|
this.quit = false;
|
||||||
this.passed = false;
|
this.passed = false;
|
||||||
this.passedTurn = false;
|
this.passedTurn = false;
|
||||||
this.passedAllTurns = false;
|
this.passedAllTurns = false;
|
||||||
|
@ -1469,6 +1469,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void quit(Game game) {
|
public void quit(Game game) {
|
||||||
|
quit = true;
|
||||||
this.concede(game);
|
this.concede(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue