diff --git a/Mage.Server/src/mage/server/Main.java b/Mage.Server/src/mage/server/Main.java index ba76b86a7ac..6647332009d 100644 --- a/Mage.Server/src/mage/server/Main.java +++ b/Mage.Server/src/mage/server/Main.java @@ -60,7 +60,7 @@ public class Main { public static void main(String[] args) { logger.info("Starting MAGE server version " + Main.class.getPackage().getImplementationVersion()); - logger.info("Logging level: " + logger.getLevel()); + logger.info("Logging level: " + Logging.getLevel(logger)); ConfigSettings config = ConfigSettings.getInstance(); for (Plugin plugin: config.getGameTypes()) { GameFactory.getInstance().addGameType(plugin.getName(), loadPlugin(plugin)); diff --git a/Mage.Server/src/mage/server/Session.java b/Mage.Server/src/mage/server/Session.java index c0613c95ebc..96707ff6271 100644 --- a/Mage.Server/src/mage/server/Session.java +++ b/Mage.Server/src/mage/server/Session.java @@ -29,11 +29,8 @@ package mage.server; import java.util.logging.Level; -import mage.server.util.ThreadExecutor; import java.util.UUID; -import java.util.concurrent.ExecutorService; import java.util.logging.Logger; -import mage.interfaces.callback.CallbackServer; import mage.interfaces.callback.CallbackServerSession; import mage.interfaces.callback.ClientCallback; import mage.server.game.GameManager; @@ -46,7 +43,6 @@ import mage.util.Logging; */ public class Session { - private static ExecutorService executor = ThreadExecutor.getInstance().getRMIExecutor(); private final static Logger logger = Logging.getLogger(Session.class.getName()); private UUID sessionId; @@ -90,57 +86,14 @@ public class Session { public void gameStarted(final UUID gameId, final UUID playerId) { fireCallback(new ClientCallback("startGame", new UUID[] {gameId, playerId})); -// executor.submit( -// new Runnable() { -// @Override -// public void run() { -// try { -// client.gameStarted(gameId, playerId); -// logger.info("game started for player " + playerId); -// } -// catch (RemoteException ex) { -// logger.log(Level.WARNING, ex.getMessage()); -// kill(); -// } -// } -// } -// ); } public void watchGame(final UUID gameId) { fireCallback(new ClientCallback("watchGame", gameId)); -// executor.submit( -// new Runnable() { -// @Override -// public void run() { -// try { -// client.watchGame(gameId); -// } -// catch (RemoteException ex) { -// logger.log(Level.WARNING, ex.getMessage()); -// kill(); -// } -// } -// } -// ); } - public void replayGame(final UUID gameId) { - fireCallback(new ClientCallback("replayGame", gameId)); -// executor.submit( -// new Runnable() { -// @Override -// public void run() { -// try { -// client.replayGame(gameId); -// } -// catch (RemoteException ex) { -// logger.log(Level.WARNING, ex.getMessage()); -// kill(); -// } -// } -// } -// ); + public void replayGame() { + fireCallback(new ClientCallback("replayGame", null)); } public String getUsername() { diff --git a/Mage.Server/src/mage/server/game/GameController.java b/Mage.Server/src/mage/server/game/GameController.java index 9993872886d..4f8c98850f2 100644 --- a/Mage.Server/src/mage/server/game/GameController.java +++ b/Mage.Server/src/mage/server/game/GameController.java @@ -34,16 +34,13 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; -import java.util.logging.Level; import java.util.logging.Logger; import mage.abilities.Ability; -import mage.abilities.ActivatedAbility; import mage.cards.Card; import mage.cards.Cards; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; import mage.game.Game; -import mage.game.GameReplay; import mage.game.events.TableEvent; import mage.server.ChatManager; import mage.server.util.ThreadExecutor; @@ -147,7 +144,7 @@ public class GameController implements GameCallback { GameSession gameSession = new GameSession(game, sessionId, playerId); gameSessions.put(playerId, gameSession); logger.info("player " + playerId + " has joined game " + game.getId()); - gameSession.init(getGameView(playerId)); +// gameSession.init(getGameView(playerId)); ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getName() + " has joined the game"); if (allJoined()) { startGame(); @@ -156,6 +153,9 @@ public class GameController implements GameCallback { private synchronized void startGame() { if (gameFuture == null) { + for (final Entry entry: gameSessions.entrySet()) { + entry.getValue().init(getGameView(entry.getKey())); + } GameWorker worker = new GameWorker(game, this); gameFuture = gameExecutor.submit(worker); } @@ -176,13 +176,6 @@ public class GameController implements GameCallback { gameWatcher.init(getGameView()); ChatManager.getInstance().broadcast(chatId, "", " has started watching"); } - - public GameReplay createReplay() { - if (game.isGameOver()) { - return new GameReplay(game.getGameStates()); - } - return null; - } public void stopWatching(UUID sessionId) { watchers.remove(sessionId); diff --git a/Mage.Server/src/mage/server/game/GameManager.java b/Mage.Server/src/mage/server/game/GameManager.java index 18bd7cfa173..8f02c9a3c22 100644 --- a/Mage.Server/src/mage/server/game/GameManager.java +++ b/Mage.Server/src/mage/server/game/GameManager.java @@ -32,7 +32,6 @@ import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import mage.cards.decks.DeckCardLists; import mage.game.Game; -import mage.game.GameReplay; /** * @@ -59,10 +58,6 @@ public class GameManager { gameControllers.get(gameId).join(sessionId); } -// public void leaveGame(UUID gameId, UUID clientId) { -// gameControllers.get(gameId).leave(clientId); -// } - public void destroyChatSession(UUID gameId) { gameControllers.remove(gameId); } @@ -109,9 +104,9 @@ public class GameManager { gameControllers.get(gameId).kill(sessionId); } - public GameReplay createReplay(UUID gameId) { - return gameControllers.get(gameId).createReplay(); - } +// public GameReplay createReplay(UUID gameId) { +// return gameControllers.get(gameId).createReplay(); +// } public void cheat(UUID gameId, UUID sessionId, DeckCardLists deckList) { gameControllers.get(gameId).cheat(sessionId, deckList); @@ -121,4 +116,8 @@ public class GameManager { gameControllers.get(gameId).timeout(sessionId); } + void removeGame(UUID gameId) { + gameControllers.remove(gameId); + } + } diff --git a/Mage.Server/src/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/mage/server/game/GamesRoomImpl.java index a86ae813ecd..2e1660b2778 100644 --- a/Mage.Server/src/mage/server/game/GamesRoomImpl.java +++ b/Mage.Server/src/mage/server/game/GamesRoomImpl.java @@ -28,6 +28,7 @@ package mage.server.game; +import mage.game.Table; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; @@ -37,7 +38,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; import mage.cards.decks.DeckCardLists; import mage.game.GameException; -import mage.game.Table; import mage.util.Logging; import mage.view.TableView; diff --git a/Mage.Server/src/mage/server/game/ReplayManager.java b/Mage.Server/src/mage/server/game/ReplayManager.java index 4a30429f5ca..0261520a106 100644 --- a/Mage.Server/src/mage/server/game/ReplayManager.java +++ b/Mage.Server/src/mage/server/game/ReplayManager.java @@ -47,10 +47,10 @@ public class ReplayManager { private ConcurrentHashMap replaySessions = new ConcurrentHashMap(); - public void replayGame(UUID sessionId, UUID gameId) { - ReplaySession replaySession = new ReplaySession(gameId, sessionId); + public void replayGame(UUID sessionId, UUID tableId) { + ReplaySession replaySession = new ReplaySession(tableId, sessionId); replaySessions.put(sessionId, replaySession); - SessionManager.getInstance().getSession(sessionId).replayGame(gameId); + SessionManager.getInstance().getSession(sessionId).replayGame(); } public void startReplay(UUID sessionId) { diff --git a/Mage.Server/src/mage/server/game/ReplaySession.java b/Mage.Server/src/mage/server/game/ReplaySession.java index 697cac92920..d3c0fe1dd38 100644 --- a/Mage.Server/src/mage/server/game/ReplaySession.java +++ b/Mage.Server/src/mage/server/game/ReplaySession.java @@ -30,7 +30,6 @@ package mage.server.game; import java.util.UUID; import java.util.logging.Logger; -import mage.game.GameReplay; import mage.game.GameState; import mage.interfaces.callback.ClientCallback; import mage.server.Session; @@ -44,14 +43,13 @@ import mage.view.GameView; */ public class ReplaySession implements GameCallback { -// protected static ExecutorService rmiExecutor = ThreadExecutor.getInstance().getRMIExecutor(); private final static Logger logger = Logging.getLogger(ReplaySession.class.getName()); private GameReplay game; protected UUID sessionId; - ReplaySession(UUID gameId, UUID sessionId) { - this.game = GameManager.getInstance().createReplay(gameId); + ReplaySession(UUID tableId, UUID sessionId) { + this.game = TableManager.getInstance().createReplay(tableId); this.sessionId = sessionId; } @@ -60,17 +58,6 @@ public class ReplaySession implements GameCallback { Session session = SessionManager.getInstance().getSession(sessionId); if (session != null) session.fireCallback(new ClientCallback("replayInit", new GameView(game.next()))); -// rmiExecutor.submit( -// new Runnable() { -// public void run() { -// try { -// client.init(new GameView(game.next())); -// } catch (RemoteException ex) { -// logger.log(Level.SEVERE, null, ex); -// } -// } -// } -// ); } public void stop() { @@ -90,34 +77,17 @@ public class ReplaySession implements GameCallback { Session session = SessionManager.getInstance().getSession(sessionId); if (session != null) session.fireCallback(new ClientCallback("replayDone", result)); -// rmiExecutor.submit( -// new Runnable() { -// public void run() { -// try { -// client.gameOver(result); -// } catch (RemoteException ex) { -// logger.log(Level.SEVERE, null, ex); -// } -// } -// } -// ); } private void updateGame(final GameState state) { - Session session = SessionManager.getInstance().getSession(sessionId); - if (session != null) - session.fireCallback(new ClientCallback("replayUpdate", new GameView(state))); -// rmiExecutor.submit( -// new Runnable() { -// public void run() { -// try { -// client.update(new GameView(state)); -// } catch (RemoteException ex) { -// logger.log(Level.SEVERE, null, ex); -// } -// } -// } -// ); + if (state == null) { + gameResult("game ended"); + } + else { + Session session = SessionManager.getInstance().getSession(sessionId); + if (session != null) + session.fireCallback(new ClientCallback("replayUpdate", new GameView(state))); + } } } diff --git a/Mage.Server/src/mage/server/game/TableController.java b/Mage.Server/src/mage/server/game/TableController.java index 3152dc3aed1..46f90995590 100644 --- a/Mage.Server/src/mage/server/game/TableController.java +++ b/Mage.Server/src/mage/server/game/TableController.java @@ -28,6 +28,18 @@ package mage.server.game; +import mage.game.Table; +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInput; +import java.io.ObjectInputStream; +import java.io.ObjectOutput; +import java.io.ObjectOutputStream; +import java.io.OutputStream; import java.util.List; import java.util.Map.Entry; import java.util.UUID; @@ -39,8 +51,8 @@ import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; import mage.game.Game; import mage.game.GameException; +import mage.game.GameStates; import mage.game.Seat; -import mage.game.Table; import mage.players.Player; import mage.server.ChatManager; import mage.server.Main; @@ -57,6 +69,7 @@ public class TableController { private UUID sessionId; private UUID chatId; + private UUID gameId; private Table table; private Game game; private ConcurrentHashMap sessionPlayerMap = new ConcurrentHashMap(); @@ -65,7 +78,8 @@ public class TableController { this.sessionId = sessionId; chatId = ChatManager.getInstance().createChatSession(); game = GameFactory.getInstance().createGame(gameType); - table = new Table(game, DeckValidatorFactory.getInstance().createDeckValidator(deckType), playerTypes); + gameId = game.getId(); + table = new Table(gameType, DeckValidatorFactory.getInstance().createDeckValidator(deckType), playerTypes); } public synchronized boolean joinTable(UUID sessionId, int seatNum, String name, DeckCardLists deckList) throws GameException { @@ -90,12 +104,26 @@ public class TableController { } public boolean watchTable(UUID sessionId) { + if (table.getState() != TableState.DUELING) { + return false; + } SessionManager.getInstance().getSession(sessionId).watchGame(game.getId()); return true; } + public GameReplay createReplay() { + if (table.getState() == TableState.FINISHED) { + return new GameReplay(loadGame()); + } + return null; + } + + public boolean replayTable(UUID sessionId) { - ReplayManager.getInstance().replayGame(sessionId, game.getId()); + if (table.getState() != TableState.FINISHED) { + return false; + } + ReplayManager.getInstance().replayGame(sessionId, table.getId()); return true; } @@ -118,7 +146,7 @@ public class TableController { public synchronized void startGame(UUID sessionId) { if (sessionId.equals(this.sessionId) && table.getState() == TableState.STARTING) { try { - table.initGame(); + table.initGame(game); } catch (GameException ex) { logger.log(Level.SEVERE, null, ex); } @@ -132,6 +160,52 @@ public class TableController { public void endGame() { table.endGame(); + saveGame(); + GameManager.getInstance().removeGame(game.getId()); + game = null; + } + + private void saveGame() { + try { + //use buffering + OutputStream file = new FileOutputStream("saved/" + game.getId().toString() + ".game"); + OutputStream buffer = new BufferedOutputStream(file); + ObjectOutput output = new ObjectOutputStream(buffer); + try { + output.writeObject(game.getGameStates()); + } + finally { + output.close(); + logger.log(Level.SEVERE, "Saved game:" + game.getId()); + } + } + catch(IOException ex) { + logger.log(Level.SEVERE, "Cannot save game.", ex); + } + } + + private GameStates loadGame() { + try{ + //use buffering + InputStream file = new FileInputStream("saved/" + gameId.toString() + ".game"); + InputStream buffer = new BufferedInputStream(file); + ObjectInput input = new ObjectInputStream(buffer); + try { + //deserialize the List + GameStates gameStates = (GameStates)input.readObject(); + return gameStates; + } + finally { + input.close(); + } + } + catch(ClassNotFoundException ex) { + logger.log(Level.SEVERE, "Cannot load game. Class not found.", ex); + } + catch(IOException ex) { + logger.log(Level.SEVERE, "Cannot load game:" + game.getId(), ex); + } + return null; } public boolean isOwner(UUID sessionId) { diff --git a/Mage.Server/src/mage/server/game/TableManager.java b/Mage.Server/src/mage/server/game/TableManager.java index 089045d6028..a993482cc1f 100644 --- a/Mage.Server/src/mage/server/game/TableManager.java +++ b/Mage.Server/src/mage/server/game/TableManager.java @@ -28,6 +28,7 @@ package mage.server.game; +import mage.game.Table; import java.util.Collection; import java.util.List; import java.util.UUID; @@ -35,7 +36,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; import mage.cards.decks.DeckCardLists; import mage.game.GameException; -import mage.game.Table; import mage.util.Logging; /** @@ -113,4 +113,8 @@ public class TableManager { public void endGame(UUID tableId) { controllers.get(tableId).endGame(); } + + public GameReplay createReplay(UUID tableId) { + return controllers.get(tableId).createReplay(); + } }