added tournaments - drafts are now a variant of tournament

This commit is contained in:
BetaSteward 2011-02-06 11:09:25 -05:00
parent 78e60ce457
commit ffc7b5bfd8
88 changed files with 3768 additions and 311 deletions

View file

@ -34,7 +34,6 @@ import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.interfaces.callback.ClientCallback;
import mage.util.Logging;

View file

@ -36,10 +36,11 @@ import java.net.InetAddress;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.game.match.MatchType;
import mage.game.tournament.TournamentType;
import mage.server.game.DeckValidatorFactory;
import mage.server.game.DraftFactory;
import mage.server.game.GameFactory;
import mage.server.game.PlayerFactory;
import mage.server.tournament.TournamentFactory;
import mage.server.util.ConfigSettings;
import mage.server.util.config.Plugin;
import mage.server.util.config.GamePlugin;
@ -73,8 +74,8 @@ public class Main {
for (GamePlugin plugin: config.getGameTypes()) {
GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin));
}
for (Plugin plugin: config.getDraftTypes()) {
DraftFactory.getInstance().addDraftType(plugin.getName(), loadPlugin(plugin));
for (GamePlugin plugin: config.getTournamentTypes()) {
TournamentFactory.getInstance().addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin));
}
for (Plugin plugin: config.getPlayerTypes()) {
PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin));
@ -136,6 +137,19 @@ public class Main {
return null;
}
private static TournamentType loadTournamentType(GamePlugin plugin) {
try {
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
logger.info("Loading tournament type: " + plugin.getClassName());
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
} catch (ClassNotFoundException ex) {
logger.log(Level.SEVERE, "Tournament type not found:" + plugin.getJar() + " - check plugin folder");
} catch (Exception ex) {
logger.log(Level.SEVERE, "Error loading game type " + plugin.getJar(), ex);
}
return null;
}
private static void deleteSavedGames() {
File directory = new File("saved/");
if (!directory.exists())

View file

@ -26,7 +26,7 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server;
import java.rmi.Remote;
import java.util.UUID;

View file

@ -26,7 +26,7 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server;
import java.util.UUID;
import mage.server.ChatManager;

View file

@ -41,25 +41,27 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import mage.cards.decks.DeckCardLists;
import mage.game.GameException;
import mage.game.draft.DraftOptions;
import mage.interfaces.MageException;
import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions;
import mage.interfaces.Server;
import mage.interfaces.ServerState;
import mage.interfaces.callback.ClientCallback;
import mage.server.game.DeckValidatorFactory;
import mage.server.game.DraftManager;
import mage.server.draft.DraftManager;
import mage.server.game.GameFactory;
import mage.server.game.GameManager;
import mage.server.game.GamesRoomManager;
import mage.server.game.PlayerFactory;
import mage.server.game.ReplayManager;
import mage.server.game.TableManager;
import mage.server.tournament.TournamentFactory;
import mage.server.tournament.TournamentManager;
import mage.server.util.ThreadExecutor;
import mage.util.Logging;
import mage.view.ChatMessage.MessageColor;
import mage.view.GameView;
import mage.view.TableView;
import mage.view.TournamentView;
/**
*
@ -130,10 +132,10 @@ public class ServerImpl extends RemoteServer implements Server {
}
@Override
public TableView createDraftTable(UUID sessionId, UUID roomId, DraftOptions options) throws MageException {
public TableView createTournamentTable(UUID sessionId, UUID roomId, TournamentOptions options) throws MageException {
try {
TableView table = GamesRoomManager.getInstance().getRoom(roomId).createDraftTable(sessionId, options);
logger.info("Draft table " + table.getTableId() + " created");
TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTournamentTable(sessionId, options);
logger.log(Level.INFO, "Tournament table {0} created", table.getTableId());
return table;
}
catch (Exception ex) {
@ -175,9 +177,9 @@ public class ServerImpl extends RemoteServer implements Server {
}
@Override
public boolean joinDraftTable(UUID sessionId, UUID roomId, UUID tableId, String name) throws MageException, GameException {
public boolean joinTournamentTable(UUID sessionId, UUID roomId, UUID tableId, String name) throws MageException, GameException {
try {
boolean ret = GamesRoomManager.getInstance().getRoom(roomId).joinDraftTable(sessionId, tableId, name);
boolean ret = GamesRoomManager.getInstance().getRoom(roomId).joinTournamentTable(sessionId, tableId, name);
logger.info("Session " + sessionId + " joined table " + tableId);
return ret;
}
@ -262,13 +264,13 @@ public class ServerImpl extends RemoteServer implements Server {
}
@Override
public void startDraft(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException {
public void startTournament(final UUID sessionId, final UUID roomId, final UUID tableId) throws MageException {
try {
rmiExecutor.execute(
new Runnable() {
@Override
public void run() {
TableManager.getInstance().startDraft(sessionId, roomId, tableId);
TableManager.getInstance().startTournament(sessionId, roomId, tableId);
}
}
);
@ -278,6 +280,17 @@ public class ServerImpl extends RemoteServer implements Server {
}
}
@Override
public TournamentView getTournament(UUID tournamentId) throws RemoteException, MageException {
try {
return TournamentManager.getInstance().getTournamentView(tournamentId);
}
catch (Exception ex) {
handleException(ex);
}
return null;
}
@Override
public void sendChatMessage(final UUID chatId, final String userName, final String message) throws MageException {
try {
@ -441,6 +454,23 @@ public class ServerImpl extends RemoteServer implements Server {
}
}
@Override
public void joinTournament(final UUID tournamentId, final UUID sessionId) throws MageException {
try {
rmiExecutor.execute(
new Runnable() {
@Override
public void run() {
TournamentManager.getInstance().joinTournament(tournamentId, sessionId);
}
}
);
}
catch (Exception ex) {
handleException(ex);
}
}
@Override
public UUID getGameChatId(UUID gameId) throws MageException {
try {
@ -452,6 +482,17 @@ public class ServerImpl extends RemoteServer implements Server {
return null;
}
@Override
public UUID getTournamentChatId(UUID tournamentId) throws MageException {
try {
return TournamentManager.getInstance().getChatId(tournamentId);
}
catch (Exception ex) {
handleException(ex);
}
return null;
}
@Override
public void sendPlayerUUID(final UUID gameId, final UUID sessionId, final UUID data) throws MageException {
try {
@ -683,6 +724,7 @@ public class ServerImpl extends RemoteServer implements Server {
try {
return new ServerState(
GameFactory.getInstance().getGameTypes(),
TournamentFactory.getInstance().getTournamentTypes(),
PlayerFactory.getInstance().getPlayerTypes().toArray(new String[0]),
DeckValidatorFactory.getInstance().getDeckTypes().toArray(new String[0]),
testMode);
@ -722,7 +764,7 @@ public class ServerImpl extends RemoteServer implements Server {
public void handleException(Exception ex) throws MageException {
logger.log(Level.SEVERE, "", ex);
throw new MageException("Server error");
throw new MageException("Server error: " + ex.getMessage());
}
public GameView getGameView(final UUID gameId, final UUID sessionId, final UUID playerId) {

View file

@ -35,7 +35,6 @@ import mage.cards.decks.Deck;
import mage.interfaces.callback.CallbackServerSession;
import mage.interfaces.callback.ClientCallback;
import mage.server.game.GameManager;
import mage.server.game.TableManager;
import mage.util.Logging;
import mage.view.TableClientMessage;
@ -99,6 +98,10 @@ public class Session {
fireCallback(new ClientCallback("startDraft", new TableClientMessage(draftId, playerId)));
}
public void tournamentStarted(final UUID tournamentId, final UUID playerId) {
fireCallback(new ClientCallback("startTournament", new TableClientMessage(tournamentId, playerId)));
}
public void sideboard(final Deck deck, final UUID tableId) {
fireCallback(new ClientCallback("sideboard", new TableClientMessage(deck, tableId)));
}

View file

@ -30,6 +30,7 @@ package mage.server;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import mage.interfaces.MageException;
/**
*
@ -49,15 +50,25 @@ public class SessionManager {
return sessions.get(sessionId);
}
public UUID createSession(String userName, UUID clientId) {
Session session = new Session(userName, clientId);
sessions.put(session.getId(), session);
return session.getId();
public UUID createSession(String userName, UUID clientId) throws MageException {
if (!isNameUsed(userName)) {
Session session = new Session(userName, clientId);
sessions.put(session.getId(), session);
return session.getId();
}
throw new MageException("User name already in use");
}
public void removeSession(UUID sessionId) {
sessions.remove(sessionId);
}
private boolean isNameUsed(String name) {
for (Session session: sessions.values()) {
if (session.getUsername().equals(name))
return true;
}
return false;
}
}

View file

@ -26,8 +26,11 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server;
import mage.server.draft.DraftManager;
import mage.server.tournament.TournamentFactory;
import mage.server.tournament.TournamentManager;
import mage.game.Table;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
@ -56,16 +59,24 @@ import mage.game.GameStates;
import mage.game.match.Match;
import mage.game.Seat;
import mage.game.draft.Draft;
import mage.game.draft.DraftOptions;
import mage.game.draft.DraftPlayer;
import mage.game.events.Listener;
import mage.game.events.TableEvent;
import mage.game.match.MatchOptions;
import mage.game.match.MatchPlayer;
import mage.game.tournament.Tournament;
import mage.game.tournament.TournamentOptions;
import mage.game.tournament.TournamentPlayer;
import mage.players.Player;
import mage.server.ChatManager;
import mage.server.Main;
import mage.server.SessionManager;
import mage.server.game.DeckValidatorFactory;
import mage.server.game.GameFactory;
import mage.server.game.GameManager;
import mage.server.game.GameReplay;
import mage.server.game.PlayerFactory;
import mage.server.game.ReplayManager;
import mage.util.CopierObjectInputStream;
import mage.util.Logging;
@ -82,8 +93,8 @@ public class TableController {
private Table table;
private Match match;
private MatchOptions options;
private Draft draft;
private DraftOptions draftOptions;
private Tournament tournament;
private TournamentOptions tournamentOptions;
private ConcurrentHashMap<UUID, UUID> sessionPlayerMap = new ConcurrentHashMap<UUID, UUID>();
public TableController(UUID sessionId, MatchOptions options) {
@ -95,12 +106,12 @@ public class TableController {
init();
}
public TableController(UUID sessionId, DraftOptions options) {
public TableController(UUID sessionId, TournamentOptions options) {
this.sessionId = sessionId;
chatId = ChatManager.getInstance().createChatSession();
this.draftOptions = options;
draft = DraftFactory.getInstance().createDraft(options.getDraftType(), options);
table = new Table(options.getDraftType(), options.getName(), DeckValidatorFactory.getInstance().createDeckValidator("Limited"), options.getPlayerTypes());
this.tournamentOptions = options;
tournament = TournamentFactory.getInstance().createTournament(options.getTournamentType(), options);
table = new Table(options.getTournamentType(), options.getName(), DeckValidatorFactory.getInstance().createDeckValidator(options.getMatchOptions().getDeckType()), options.getPlayerTypes());
init();
}
@ -125,7 +136,7 @@ public class TableController {
);
}
public synchronized boolean joinDraft(UUID sessionId, String name) throws GameException {
public synchronized boolean joinTournament(UUID sessionId, String name) throws GameException {
if (table.getState() != TableState.WAITING) {
return false;
}
@ -134,7 +145,7 @@ public class TableController {
throw new GameException("No available seats.");
}
Player player = createPlayer(name, seat.getPlayerType());
draft.addPlayer(player);
tournament.addPlayer(player, seat.getPlayerType());
table.joinTable(player, seat);
logger.info("player joined " + player.getId());
//only add human players to sessionPlayerMap
@ -170,6 +181,21 @@ public class TableController {
return true;
}
public void addPlayer(UUID sessionId, Player player, Deck deck) throws GameException {
if (table.getState() != TableState.WAITING) {
return;
}
Seat seat = table.getNextAvailableSeat();
if (seat == null) {
throw new GameException("No available seats.");
}
match.addPlayer(player, deck);
table.joinTable(player, seat);
if (player.isHuman()) {
sessionPlayerMap.put(sessionId, player.getId());
}
}
public synchronized boolean submitDeck(UUID sessionId, DeckCardLists deckList) throws GameException {
if (table.getState() != TableState.SIDEBOARDING && table.getState() != TableState.CONSTRUCTING) {
return false;
@ -180,7 +206,7 @@ public class TableController {
playerName = player.getPlayer().getName();
}
else {
DraftPlayer player = draft.getPlayer(sessionPlayerMap.get(sessionId));
TournamentPlayer player = tournament.getPlayer(sessionPlayerMap.get(sessionId));
playerName = player.getPlayer().getName();
}
Deck deck = Deck.load(deckList);
@ -196,9 +222,8 @@ public class TableController {
MatchPlayer player = match.getPlayer(playerId);
player.submitDeck(deck);
}
else if (table.getState() == TableState.CONSTRUCTING) {
DraftPlayer player = draft.getPlayer(playerId);
player.submitDeck(deck);
else {
tournament.submitDeck(playerId, deck);
}
}
@ -267,17 +292,25 @@ public class TableController {
}
}
public synchronized void startDraft(UUID sessionId) {
public synchronized void startTournament(UUID sessionId) {
if (sessionId.equals(this.sessionId) && table.getState() == TableState.STARTING) {
table.initDraft();
DraftManager.getInstance().createDraftSession(draft, sessionPlayerMap, table.getId());
TournamentManager.getInstance().createTournamentSession(tournament, sessionPlayerMap, table.getId());
SessionManager sessionManager = SessionManager.getInstance();
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
sessionManager.getSession(entry.getKey()).draftStarted(draft.getId(), entry.getValue());
sessionManager.getSession(entry.getKey()).tournamentStarted(tournament.getId(), entry.getValue());
}
}
}
public void startDraft(Draft draft) {
table.initDraft();
DraftManager.getInstance().createDraftSession(draft, sessionPlayerMap, table.getId());
SessionManager sessionManager = SessionManager.getInstance();
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
sessionManager.getSession(entry.getKey()).draftStarted(draft.getId(), entry.getValue());
}
}
private void sideboard() {
table.sideboard();
for (MatchPlayer player: match.getPlayers()) {
@ -297,13 +330,12 @@ public class TableController {
}
}
private void construct() {
public void construct() {
table.construct();
for (DraftPlayer player: draft.getPlayers()) {
for (TournamentPlayer player: tournament.getPlayers()) {
player.setConstructing();
player.getPlayer().construct(table, player.getDeck());
}
while (!draft.isDoneConstructing()){}
}
private void construct(UUID playerId, Deck deck) {
@ -332,9 +364,11 @@ public class TableController {
}
}
public void endDraft() {
construct();
public void endDraft(Draft draft) {
for (DraftPlayer player: draft.getPlayers()) {
tournament.getPlayer(player.getPlayer().getId()).setDeck(player.getDeck());
}
tournament.nextStep();
}
public void swapSeats(int seatNum1, int seatNum2) {
@ -405,4 +439,7 @@ public class TableController {
return chatId;
}
public Match getMatch() {
return match;
}
}

View file

@ -26,17 +26,22 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server;
import mage.game.Table;
import java.util.Collection;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Logger;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardLists;
import mage.game.GameException;
import mage.game.draft.DraftOptions;
import mage.game.draft.Draft;
import mage.game.match.Match;
import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions;
import mage.players.Player;
import mage.server.game.GameReplay;
import mage.util.Logging;
/**
@ -62,7 +67,7 @@ public class TableManager {
return tableController.getTable();
}
public Table createDraftTable(UUID sessionId, DraftOptions options) {
public Table createTournamentTable(UUID sessionId, TournamentOptions options) {
TableController tableController = new TableController(sessionId, options);
controllers.put(tableController.getTable().getId(), tableController);
tables.put(tableController.getTable().getId(), tableController.getTable());
@ -73,6 +78,10 @@ public class TableManager {
return tables.get(tableId);
}
public Match getMatch(UUID tableId) {
return controllers.get(tableId).getMatch();
}
public Collection<Table> getTables() {
return tables.values();
}
@ -81,8 +90,8 @@ public class TableManager {
return controllers.get(tableId).joinTable(sessionId, name, deckList);
}
public boolean joinDraft(UUID sessionId, UUID tableId, String name) throws GameException {
return controllers.get(tableId).joinDraft(sessionId, name);
public boolean joinTournament(UUID sessionId, UUID tableId, String name) throws GameException {
return controllers.get(tableId).joinTournament(sessionId, name);
}
public boolean submitDeck(UUID sessionId, UUID tableId, DeckCardLists deckList) throws GameException {
@ -118,8 +127,12 @@ public class TableManager {
controllers.get(tableId).startMatch(sessionId);
}
public void startDraft(UUID sessionId, UUID roomId, UUID tableId) {
controllers.get(tableId).startDraft(sessionId);
public void startTournament(UUID sessionId, UUID roomId, UUID tableId) {
controllers.get(tableId).startTournament(sessionId);
}
public void startDraft(UUID tableId, Draft draft) {
controllers.get(tableId).startDraft(draft);
}
public boolean watchTable(UUID sessionId, UUID tableId) {
@ -129,13 +142,13 @@ public class TableManager {
public boolean replayTable(UUID sessionId, UUID tableId) {
return controllers.get(tableId).replayTable(sessionId);
}
public void endGame(UUID tableId) {
controllers.get(tableId).endGame();
}
public void endDraft(UUID tableId) {
controllers.get(tableId).endDraft();
public void endDraft(UUID tableId, Draft draft) {
controllers.get(tableId).endDraft(draft);
}
public GameReplay createReplay(UUID tableId) {
@ -147,4 +160,12 @@ public class TableManager {
controllers.get(tableId).swapSeats(seatNum1, seatNum2);
}
}
public void construct(UUID tableId) {
controllers.get(tableId).construct();
}
public void addPlayer(UUID sessionId, UUID tableId, Player player, Deck deck) throws GameException {
controllers.get(tableId).addPlayer(sessionId, player, deck);
}
}

View file

@ -26,13 +26,12 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server.draft;
import java.io.File;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.logging.Logger;
import mage.game.draft.Draft;
@ -40,11 +39,11 @@ import mage.game.draft.DraftPlayer;
import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
import mage.game.events.TableEvent;
import mage.server.ChatManager;
import mage.server.game.GameController;
import mage.server.TableManager;
import mage.server.util.ThreadExecutor;
import mage.util.Logging;
import mage.view.DraftPickView;
import mage.view.ChatMessage.MessageColor;
import mage.view.DraftView;
/**
@ -60,13 +59,11 @@ public class DraftController {
private ConcurrentHashMap<UUID, UUID> sessionPlayerMap;
private UUID draftSessionId;
private Draft draft;
private UUID chatId;
private UUID tableId;
public DraftController(Draft draft, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId) {
draftSessionId = UUID.randomUUID();
this.sessionPlayerMap = sessionPlayerMap;
chatId = ChatManager.getInstance().createChatSession();
this.draft = draft;
this.tableId = tableId;
init();
@ -100,6 +97,13 @@ public class DraftController {
}
}
);
for (DraftPlayer player: draft.getPlayers()) {
if (!player.getPlayer().isHuman()) {
player.setJoined();
logger.info("player " + player.getPlayer().getId() + " has joined draft " + draft.getId());
}
}
checkStart();
}
private UUID getPlayerId(UUID sessionId) {
@ -111,16 +115,8 @@ public class DraftController {
DraftSession draftSession = new DraftSession(draft, sessionId, playerId);
draftSessions.put(playerId, draftSession);
logger.info("player " + playerId + " has joined draft " + draft.getId());
ChatManager.getInstance().broadcast(chatId, "", draft.getPlayer(playerId).getPlayer().getName() + " has joined the draft", MessageColor.BLACK);
if (allJoined()) {
ThreadExecutor.getInstance().getRMIExecutor().execute(
new Runnable() {
@Override
public void run() {
startDraft();
}
});
}
draft.getPlayer(playerId).setJoined();
checkStart();
}
private synchronized void startDraft() {
@ -134,7 +130,21 @@ public class DraftController {
draft.start();
}
private void checkStart() {
if (allJoined()) {
ThreadExecutor.getInstance().getRMIExecutor().execute(
new Runnable() {
@Override
public void run() {
startDraft();
}
});
}
}
private boolean allJoined() {
if (!draft.allJoined())
return false;
for (DraftPlayer player: draft.getPlayers()) {
if (player.getPlayer().isHuman() && draftSessions.get(player.getPlayer().getId()) == null) {
return false;
@ -148,7 +158,10 @@ public class DraftController {
}
private void endDraft() {
TableManager.getInstance().endDraft(tableId);
for (final DraftSession draftSession: draftSessions.values()) {
draftSession.draftOver();
}
TableManager.getInstance().endDraft(tableId, draft);
}
public void kill(UUID sessionId) {
@ -162,26 +175,15 @@ public class DraftController {
public void timeout(UUID sessionId) {
if (sessionPlayerMap.containsKey(sessionId)) {
ChatManager.getInstance().broadcast(chatId, "", draft.getPlayer(sessionPlayerMap.get(sessionId)).getPlayer().getName() + " has timed out. Auto picking.", MessageColor.BLACK);
// ChatManager.getInstance().broadcast(chatId, "", draft.getPlayer(sessionPlayerMap.get(sessionId)).getPlayer().getName() + " has timed out. Auto picking.", MessageColor.BLACK);
draft.autoPick(sessionPlayerMap.get(sessionId));
}
}
public void endDraft(final String message) {
for (final DraftSession draftSession: draftSessions.values()) {
draftSession.gameOver(message);
}
TableManager.getInstance().endDraft(tableId);
}
public UUID getSessionId() {
return this.draftSessionId;
}
public UUID getChatId() {
return chatId;
}
public void sendCardPick(UUID sessionId, UUID cardId) {
draftSessions.get(sessionPlayerMap.get(sessionId)).sendCardPick(cardId);
}

View file

@ -26,7 +26,7 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server.draft;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@ -61,10 +61,6 @@ public class DraftManager {
draftControllers.remove(gameId);
}
public UUID getChatId(UUID draftId) {
return draftControllers.get(draftId).getChatId();
}
public void sendCardPick(UUID draftId, UUID sessionId, UUID cardId) {
draftControllers.get(draftId).sendCardPick(sessionId, cardId);
}

View file

@ -26,7 +26,7 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server.draft;
import java.rmi.RemoteException;
import java.util.UUID;
@ -44,7 +44,6 @@ import mage.util.Logging;
import mage.view.DraftClientMessage;
import mage.view.DraftPickView;
import mage.view.DraftView;
import mage.view.GameClientMessage;
/**
*
@ -52,7 +51,7 @@ import mage.view.GameClientMessage;
*/
public class DraftSession {
protected final static Logger logger = Logging.getLogger(GameWatcher.class.getName());
protected final static Logger logger = Logging.getLogger(DraftSession.class.getName());
protected UUID sessionId;
protected UUID playerId;
@ -105,11 +104,11 @@ public class DraftSession {
}
}
public void gameOver(final String message) {
public void draftOver() {
if (!killed) {
Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null)
session.fireCallback(new ClientCallback("gameOver", message));
session.fireCallback(new ClientCallback("draftOver"));
}
}

View file

@ -28,6 +28,7 @@
package mage.server.game;
import mage.server.TableManager;
import java.io.File;
import java.io.Serializable;
import java.util.*;
@ -43,7 +44,6 @@ import java.util.regex.Pattern;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.decks.Deck;
import mage.cards.decks.DeckCardLists;
@ -153,6 +153,12 @@ public class GameController implements GameCallback {
}
}
);
for (Player player: game.getPlayers().values()) {
if (!player.isHuman()) {
ChatManager.getInstance().broadcast(chatId, "", player.getName() + " has joined the game", MessageColor.BLACK);
}
}
checkStart();
}
private UUID getPlayerId(UUID sessionId) {
@ -165,15 +171,7 @@ public class GameController implements GameCallback {
gameSessions.put(playerId, gameSession);
logger.info("player " + playerId + " has joined game " + game.getId());
ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getName() + " has joined the game", MessageColor.BLACK);
if (allJoined()) {
ThreadExecutor.getInstance().getRMIExecutor().execute(
new Runnable() {
@Override
public void run() {
startGame();
}
});
}
checkStart();
}
private synchronized void startGame() {
@ -190,6 +188,18 @@ public class GameController implements GameCallback {
}
}
private void checkStart() {
if (allJoined()) {
ThreadExecutor.getInstance().getRMIExecutor().execute(
new Runnable() {
@Override
public void run() {
startGame();
}
});
}
}
private boolean allJoined() {
for (Player player: game.getPlayers().values()) {
if (player.isHuman() && gameSessions.get(player.getId()) == null) {

View file

@ -117,11 +117,11 @@ public class GameManager {
return gameControllers.get(gameId).cheat(sessionId, playerId, cardName);
}
void timeout(UUID gameId, UUID sessionId) {
public void timeout(UUID gameId, UUID sessionId) {
gameControllers.get(gameId).timeout(sessionId);
}
void removeGame(UUID gameId) {
public void removeGame(UUID gameId) {
gameControllers.remove(gameId);
}

View file

@ -28,12 +28,13 @@
package mage.server.game;
import mage.server.Room;
import java.util.List;
import java.util.UUID;
import mage.cards.decks.DeckCardLists;
import mage.game.GameException;
import mage.game.draft.DraftOptions;
import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions;
import mage.view.TableView;
/**
@ -44,9 +45,9 @@ public interface GamesRoom extends Room {
public List<TableView> getTables();
public boolean joinTable(UUID sessionId, UUID tableId, String name, DeckCardLists deckList) throws GameException;
public boolean joinDraftTable(UUID sessionId, UUID tableId, String name) throws GameException;
public boolean joinTournamentTable(UUID sessionId, UUID tableId, String name) throws GameException;
public TableView createTable(UUID sessionId, MatchOptions options);
public TableView createDraftTable(UUID sessionId, DraftOptions options);
public TableView createTournamentTable(UUID sessionId, TournamentOptions options);
public void removeTable(UUID sessionId, UUID tableId);
public TableView getTable(UUID tableId);
public void leaveTable(UUID sessionId, UUID tableId);

View file

@ -28,6 +28,8 @@
package mage.server.game;
import mage.server.TableManager;
import mage.server.RoomImpl;
import mage.game.Table;
import java.io.Serializable;
import java.util.ArrayList;
@ -39,6 +41,7 @@ import mage.cards.decks.DeckCardLists;
import mage.game.GameException;
import mage.game.draft.DraftOptions;
import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions;
import mage.util.Logging;
import mage.view.TableView;
@ -78,17 +81,17 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
}
@Override
public boolean joinDraftTable(UUID sessionId, UUID tableId, String name) throws GameException {
public boolean joinTournamentTable(UUID sessionId, UUID tableId, String name) throws GameException {
if (tables.containsKey(tableId)) {
return TableManager.getInstance().joinDraft(sessionId, tableId, name);
return TableManager.getInstance().joinTournament(sessionId, tableId, name);
} else {
return false;
}
}
@Override
public TableView createDraftTable(UUID sessionId, DraftOptions options) {
Table table = TableManager.getInstance().createDraftTable(sessionId, options);
public TableView createTournamentTable(UUID sessionId, TournamentOptions options) {
Table table = TableManager.getInstance().createTournamentTable(sessionId, options);
tables.put(table.getId(), table);
return new TableView(table);
}

View file

@ -28,6 +28,7 @@
package mage.server.game;
import mage.server.TableManager;
import java.util.UUID;
import java.util.logging.Logger;
import mage.game.Game;

View file

@ -0,0 +1,214 @@
/*
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.tournament;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.game.GameException;
import mage.game.Table;
import mage.game.draft.Draft;
import mage.game.events.Listener;
import mage.game.events.TableEvent;
import mage.game.match.MatchOptions;
import mage.game.tournament.Tournament;
import mage.game.tournament.TournamentPairing;
import mage.game.tournament.TournamentPlayer;
import mage.server.ChatManager;
import mage.server.TableManager;
import mage.server.util.ThreadExecutor;
import mage.util.Logging;
import mage.view.ChatMessage.MessageColor;
import mage.view.TournamentView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class TournamentController {
private final static Logger logger = Logging.getLogger(TournamentController.class.getName());
private UUID sessionId;
private UUID chatId;
private UUID tableId;
private Tournament tournament;
private ConcurrentHashMap<UUID, UUID> sessionPlayerMap = new ConcurrentHashMap<UUID, UUID>();
private ConcurrentHashMap<UUID, TournamentSession> tournamentSessions = new ConcurrentHashMap<UUID, TournamentSession>();
public TournamentController(Tournament tournament, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId) {
sessionId = UUID.randomUUID();
this.sessionPlayerMap = sessionPlayerMap;
chatId = ChatManager.getInstance().createChatSession();
this.tournament = tournament;
this.tableId = tableId;
init();
}
private void init() {
tournament.addTableEventListener(
new Listener<TableEvent> () {
@Override
public void event(TableEvent event) {
switch (event.getEventType()) {
case INFO:
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK);
logger.finest(tournament.getId() + " " + event.getMessage());
break;
case CONSTRUCT:
construct();
break;
case START_DRAFT:
startDraft(event.getDraft());
break;
case START_MATCH:
startMatch(event.getPair(), event.getMatchOptions());
break;
}
}
}
);
for (TournamentPlayer player: tournament.getPlayers()) {
if (!player.getPlayer().isHuman()) {
player.setJoined();
logger.info("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId());
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK);
}
}
checkStart();
}
public void join(UUID sessionId) {
UUID playerId = sessionPlayerMap.get(sessionId);
TournamentSession tournamentSession = new TournamentSession(tournament, sessionId, playerId);
tournamentSessions.put(playerId, tournamentSession);
TournamentPlayer player = tournament.getPlayer(playerId);
player.setJoined();
logger.info("player " + playerId + " has joined tournament " + tournament.getId());
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getName() + " has joined the tournament", MessageColor.BLACK);
checkStart();
}
private void checkStart() {
if (allJoined()) {
ThreadExecutor.getInstance().getRMIExecutor().execute(
new Runnable() {
@Override
public void run() {
startTournament();
}
});
}
}
private boolean allJoined() {
if (!tournament.allJoined())
return false;
for (TournamentPlayer player: tournament.getPlayers()) {
if (player.getPlayer().isHuman() && tournamentSessions.get(player.getPlayer().getId()) == null) {
return false;
}
}
return true;
}
private synchronized void startTournament() {
for (final Entry<UUID, TournamentSession> entry: tournamentSessions.entrySet()) {
if (!entry.getValue().init(getTournamentView())) {
logger.severe("Unable to initialize client");
//TODO: generate client error message
return;
}
}
tournament.nextStep();
}
private void startMatch(TournamentPairing pair, MatchOptions matchOptions) {
try {
TableManager tableManager = TableManager.getInstance();
Table table = tableManager.createTable(sessionId, matchOptions);
TournamentPlayer player1 = pair.getPlayer1();
TournamentPlayer player2 = pair.getPlayer2();
tableManager.addPlayer(getPlayerSessionId(player1.getPlayer().getId()), table.getId(), player1.getPlayer(), player1.getDeck());
tableManager.addPlayer(getPlayerSessionId(player2.getPlayer().getId()), table.getId(), player2.getPlayer(), player2.getDeck());
tableManager.startMatch(sessionId, null, table.getId());
pair.setMatch(tableManager.getMatch(table.getId()));
} catch (GameException ex) {
Logger.getLogger(TournamentController.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void startDraft(Draft draft) {
TableManager.getInstance().startDraft(tableId, draft);
}
private void construct() {
TableManager.getInstance().construct(tableId);
}
public UUID getSessionId() {
return this.sessionId;
}
public UUID getChatId() {
return chatId;
}
public void kill(UUID sessionId) {
if (sessionPlayerMap.containsKey(sessionId)) {
tournamentSessions.get(sessionPlayerMap.get(sessionId)).setKilled();
tournamentSessions.remove(sessionPlayerMap.get(sessionId));
leave(sessionId);
sessionPlayerMap.remove(sessionId);
}
}
private void leave(UUID sessionId) {
tournament.leave(getPlayerId(sessionId));
}
private UUID getPlayerId(UUID sessionId) {
return sessionPlayerMap.get(sessionId);
}
private UUID getPlayerSessionId(UUID playerId) {
for (Entry<UUID, UUID> entry: sessionPlayerMap.entrySet()) {
if (entry.getValue().equals(playerId))
return entry.getKey();
}
return null;
}
public TournamentView getTournamentView() {
return new TournamentView(tournament);
}
}

View file

@ -0,0 +1,91 @@
/*
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.tournament;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.game.tournament.Tournament;
import mage.game.tournament.TournamentOptions;
import mage.game.tournament.TournamentType;
import mage.util.Logging;
import mage.view.TournamentTypeView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class TournamentFactory {
private final static TournamentFactory INSTANCE = new TournamentFactory();
private final static Logger logger = Logging.getLogger(TournamentFactory.class.getName());
private Map<String, Class<Tournament>> tournaments = new HashMap<String, Class<Tournament>>();
private Map<String, TournamentType> tournamentTypes = new HashMap<String, TournamentType>();
private List<TournamentTypeView> tournamentTypeViews = new ArrayList<TournamentTypeView>();
public static TournamentFactory getInstance() {
return INSTANCE;
}
private TournamentFactory() {}
public Tournament createTournament(String tournamentType, TournamentOptions options) {
Tournament tournament;
Constructor<Tournament> con;
try {
con = tournaments.get(tournamentType).getConstructor(new Class[]{TournamentOptions.class});
tournament = con.newInstance(new Object[] {options});
} catch (Exception ex) {
logger.log(Level.SEVERE, null, ex);
return null;
}
logger.info("Tournament created: " + tournamentType); // + game.getId().toString());
return tournament;
}
public List<TournamentTypeView> getTournamentTypes() {
return tournamentTypeViews;
}
public void addTournamentType(String name, TournamentType tournamentType, Class tournament) {
if (tournament != null) {
this.tournaments.put(name, tournament);
this.tournamentTypes.put(name, tournamentType);
this.tournamentTypeViews.add(new TournamentTypeView(tournamentType));
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
@ -26,54 +26,47 @@
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.game;
package mage.server.tournament;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.game.draft.Draft;
import mage.game.draft.DraftOptions;
import mage.util.Logging;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import mage.game.tournament.Tournament;
import mage.view.TournamentView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class DraftFactory {
public class TournamentManager {
private final static DraftFactory INSTANCE = new DraftFactory();
private final static Logger logger = Logging.getLogger(DraftFactory.class.getName());
private final static TournamentManager INSTANCE = new TournamentManager();
private Map<String, Class<Draft>> drafts = new HashMap<String, Class<Draft>>();
private ConcurrentHashMap<UUID, TournamentController> controllers = new ConcurrentHashMap<UUID, TournamentController>();
public static DraftFactory getInstance() {
public static TournamentManager getInstance() {
return INSTANCE;
}
private DraftFactory() {}
public Draft createDraft(String draftType, DraftOptions options) {
Draft draft;
Constructor<Draft> con;
try {
con = drafts.get(draftType).getConstructor(new Class[]{DraftOptions.class});
draft = con.newInstance(new Object[] {options});
} catch (Exception ex) {
logger.log(Level.SEVERE, null, ex);
return null;
}
logger.info("Draft created: " + draftType); // + game.getId().toString());
return draft;
public UUID createTournamentSession(Tournament tournament, ConcurrentHashMap<UUID, UUID> sessionPlayerMap, UUID tableId) {
TournamentController tournamentController = new TournamentController(tournament, sessionPlayerMap, tableId);
controllers.put(tournament.getId(), tournamentController);
return tournamentController.getSessionId();
}
public void addDraftType(String name, Class draft) {
if (draft != null) {
this.drafts.put(name, draft);
}
public void joinTournament(UUID tournamentId, UUID sessionId) {
controllers.get(tournamentId).join(sessionId);
}
public void kill(UUID tournamentId, UUID sessionId) {
controllers.get(tournamentId).kill(sessionId);
}
public TournamentView getTournamentView(UUID tournamentId) {
return controllers.get(tournamentId).getTournamentView();
}
public UUID getChatId(UUID tournamentId) {
return controllers.get(tournamentId).getChatId();
}
}

View file

@ -0,0 +1,106 @@
/*
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.tournament;
import java.rmi.RemoteException;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import mage.game.tournament.Tournament;
import mage.interfaces.callback.ClientCallback;
import mage.server.Session;
import mage.server.SessionManager;
import mage.util.Logging;
import mage.view.TournamentView;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class TournamentSession {
protected final static Logger logger = Logging.getLogger(TournamentSession.class.getName());
protected UUID sessionId;
protected UUID playerId;
protected Tournament tournament;
protected boolean killed = false;
public TournamentSession(Tournament tournament, UUID sessionId, UUID playerId) {
this.sessionId = sessionId;
this.tournament = tournament;
this.playerId = playerId;
}
public boolean init(final TournamentView tournamentView) {
if (!killed) {
Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null) {
session.clearAck();
session.fireCallback(new ClientCallback("tournamentInit", tournamentView));
if (waitForAck("tournamentInit"))
return true;
}
}
return false;
}
public boolean waitForAck(String message) {
Session session = SessionManager.getInstance().getSession(sessionId);
do {
//TODO: add timeout
} while (!session.getAckMessage().equals(message) && !killed);
return true;
}
public void update(final TournamentView tournamentView) {
if (!killed) {
Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null)
session.fireCallback(new ClientCallback("tournamentUpdate", tournamentView));
}
}
public void gameOver(final String message) {
if (!killed) {
Session session = SessionManager.getInstance().getSession(sessionId);
if (session != null)
session.fireCallback(new ClientCallback("tournamentOver", message));
}
}
protected void handleRemoteException(RemoteException ex) {
logger.log(Level.SEVERE, null, ex);
TournamentManager.getInstance().kill(tournament.getId(), sessionId);
}
public void setKilled() {
killed = true;
}
}

View file

@ -92,8 +92,8 @@ public class ConfigSettings {
return config.getGameTypes().getGameType();
}
public List<Plugin> getDraftTypes() {
return config.getDraftTypes().getDraftType();
public List<GamePlugin> getTournamentTypes() {
return config.getTournamentTypes().getTournamentType();
}
public List<Plugin> getDeckTypes() {