diff --git a/Mage.Server/config/config.xml b/Mage.Server/config/config.xml index 6d52fdb1ce..8514f0a0b7 100644 --- a/Mage.Server/config/config.xml +++ b/Mage.Server/config/config.xml @@ -3,13 +3,14 @@ - - + + - + + - + diff --git a/Mage.Server/nbproject/project.properties b/Mage.Server/nbproject/project.properties index c0fae92fc5..5fb1ef044d 100644 --- a/Mage.Server/nbproject/project.properties +++ b/Mage.Server/nbproject/project.properties @@ -26,7 +26,8 @@ jar.compress=false javac.classpath=\ ${reference.Mage.jar}:\ ${reference.Mage_Common.jar}:\ - ${reference.Mage_Sets.jar} + ${reference.Mage_Sets.jar}:\ + ${reference.Mage_Player_AI.jar} # Space-separated list of extra javac options javac.compilerargs= javac.deprecation=false @@ -59,9 +60,11 @@ platform.active=default_platform project.license=bsd project.Mage=../Mage project.Mage_Common=../Mage.Common +project.Mage_Player_AI=../Mage.Player.AI project.Mage_Sets=../Mage.Sets reference.Mage.jar=${project.Mage}/dist/Mage.jar reference.Mage_Common.jar=${project.Mage_Common}/dist/Mage.Common.jar +reference.Mage_Player_AI.jar=${project.Mage_Player_AI}/dist/Mage.Player.AI.jar reference.Mage_Sets.jar=${project.Mage_Sets}/dist/Mage.Sets.jar run-sys-prop.java.endorsed.dirs=${jaxbwiz.endorsed.dirs} run.classpath=\ @@ -74,4 +77,4 @@ run.test.classpath=\ source.encoding=UTF-8 src.dir=src test.src.dir=test -app.version=0.2 +app.version=0.3 diff --git a/Mage.Server/nbproject/project.xml b/Mage.Server/nbproject/project.xml index 820483a2e4..85a76cd19b 100644 --- a/Mage.Server/nbproject/project.xml +++ b/Mage.Server/nbproject/project.xml @@ -33,6 +33,14 @@ clean jar + + Mage_Player_AI + jar + + jar + clean + jar + Mage_Sets jar diff --git a/Mage.Server/plugins/Mage.Game.FreeForAll.jar b/Mage.Server/plugins/Mage.Game.FreeForAll.jar new file mode 100644 index 0000000000..12b0257bce Binary files /dev/null and b/Mage.Server/plugins/Mage.Game.FreeForAll.jar differ diff --git a/Mage.Server/plugins/Mage.Game.TwoPlayerDuel.jar b/Mage.Server/plugins/Mage.Game.TwoPlayerDuel.jar index 9e8f3b8bf8..89990c1d16 100644 Binary files a/Mage.Server/plugins/Mage.Game.TwoPlayerDuel.jar and b/Mage.Server/plugins/Mage.Game.TwoPlayerDuel.jar differ diff --git a/Mage.Server/plugins/Mage.Player.AI.jar b/Mage.Server/plugins/Mage.Player.AI.jar index b39acf58bd..dd2678c0f3 100644 Binary files a/Mage.Server/plugins/Mage.Player.AI.jar and b/Mage.Server/plugins/Mage.Player.AI.jar differ diff --git a/Mage.Server/plugins/Mage.Player.Human.jar b/Mage.Server/plugins/Mage.Player.Human.jar index 7db281cc26..2b4e0027c1 100644 Binary files a/Mage.Server/plugins/Mage.Player.Human.jar and b/Mage.Server/plugins/Mage.Player.Human.jar differ diff --git a/Mage.Server/src/mage/server/Main.java b/Mage.Server/src/mage/server/Main.java index 6de1e956ed..2888193a24 100644 --- a/Mage.Server/src/mage/server/Main.java +++ b/Mage.Server/src/mage/server/Main.java @@ -33,11 +33,13 @@ import java.io.File; import java.io.FilenameFilter; import java.util.logging.Level; import java.util.logging.Logger; +import mage.game.GameType; import mage.server.game.DeckValidatorFactory; import mage.server.game.GameFactory; import mage.server.game.PlayerFactory; import mage.server.util.ConfigSettings; import mage.server.util.config.Plugin; +import mage.server.util.config.GamePlugin; import mage.util.Copier; import mage.util.Logging; @@ -64,8 +66,8 @@ public class Main { logger.info("Logging level: " + Logging.getLevel(logger)); deleteSavedGames(); ConfigSettings config = ConfigSettings.getInstance(); - for (Plugin plugin: config.getGameTypes()) { - GameFactory.getInstance().addGameType(plugin.getName(), loadPlugin(plugin)); + for (GamePlugin plugin: config.getGameTypes()) { + GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin)); } for (Plugin plugin: config.getPlayerTypes()) { PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin)); @@ -98,6 +100,19 @@ public class Main { return null; } + private static GameType loadGameType(GamePlugin plugin) { + try { + classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL()); + logger.info("Loading game type: " + plugin.getClassName()); + return (GameType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance(); + } catch (ClassNotFoundException ex) { + logger.log(Level.SEVERE, "Game 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/"); File[] files = directory.listFiles( diff --git a/Mage.Server/src/mage/server/ServerImpl.java b/Mage.Server/src/mage/server/ServerImpl.java index 39eeb4feca..50d57d6f3b 100644 --- a/Mage.Server/src/mage/server/ServerImpl.java +++ b/Mage.Server/src/mage/server/ServerImpl.java @@ -33,11 +33,12 @@ import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.RemoteServer; import java.rmi.server.UnicastRemoteObject; -import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; +import mage.Constants.MultiplayerAttackOption; +import mage.Constants.RangeOfInfluence; import mage.cards.decks.DeckCardLists; import mage.game.GameException; import mage.interfaces.MageException; @@ -51,6 +52,7 @@ import mage.server.game.PlayerFactory; import mage.server.game.ReplayManager; import mage.server.game.TableManager; import mage.util.Logging; +import mage.view.GameTypeView; import mage.view.TableView; /** @@ -101,9 +103,9 @@ public class ServerImpl extends RemoteServer implements Server { } @Override - public TableView createTable(UUID sessionId, UUID roomId, String gameType, String deckType, List playerTypes) throws MageException { + public TableView createTable(UUID sessionId, UUID roomId, String gameType, String deckType, List playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) throws MageException { try { - TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTable(sessionId, gameType, deckType, playerTypes); + TableView table = GamesRoomManager.getInstance().getRoom(roomId).createTable(sessionId, gameType, deckType, playerTypes, attackOption, range); logger.info("Table " + table.getTableId() + " created"); return table; } @@ -139,7 +141,7 @@ public class ServerImpl extends RemoteServer implements Server { } @Override - public Collection getTables(UUID roomId) throws MageException { + public List getTables(UUID roomId) throws MageException { try { return GamesRoomManager.getInstance().getRoom(roomId).getTables(); } @@ -244,6 +246,16 @@ public class ServerImpl extends RemoteServer implements Server { return false; } + @Override + public void swapSeats(UUID sessionId, UUID roomId, UUID tableId, int seatNum1, int seatNum2) throws RemoteException, MageException { + try { + TableManager.getInstance().swapSeats(tableId, sessionId, seatNum1, seatNum2); + } + catch (Exception ex) { + handleException(ex); + } + } + @Override public void leaveTable(UUID sessionId, UUID roomId, UUID tableId) throws MageException { try { @@ -419,9 +431,9 @@ public class ServerImpl extends RemoteServer implements Server { } @Override - public String[] getGameTypes() throws MageException { + public List getGameTypes() throws MageException { try { - return GameFactory.getInstance().getGameTypes().toArray(new String[0]); + return GameFactory.getInstance().getGameTypes(); } catch (Exception ex) { handleException(ex); diff --git a/Mage.Server/src/mage/server/game/GameFactory.java b/Mage.Server/src/mage/server/game/GameFactory.java index 4326928702..6af3d534bd 100644 --- a/Mage.Server/src/mage/server/game/GameFactory.java +++ b/Mage.Server/src/mage/server/game/GameFactory.java @@ -29,14 +29,19 @@ package mage.server.game; import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import mage.Constants.MultiplayerAttackOption; +import mage.Constants.RangeOfInfluence; import mage.game.Game; -import mage.server.Main; import mage.util.Logging; +import mage.game.GameType; +import mage.view.GameTypeView; /** * @@ -47,7 +52,10 @@ public class GameFactory { private final static GameFactory INSTANCE = new GameFactory(); private final static Logger logger = Logging.getLogger(GameFactory.class.getName()); - private Map gameTypes = new HashMap(); + private Map> games = new HashMap>(); + private Map gameTypes = new HashMap(); + private List gameTypeViews = new ArrayList(); + public static GameFactory getInstance() { return INSTANCE; @@ -55,13 +63,13 @@ public class GameFactory { private GameFactory() {} - public Game createGame(String gameType) { + public Game createGame(String gameType, MultiplayerAttackOption attackOption, RangeOfInfluence range) { Game game; - Constructor con; + Constructor con; try { - con = gameTypes.get(gameType).getConstructor(new Class[]{}); - game = (Game)con.newInstance(new Object[] {}); + con = games.get(gameType).getConstructor(new Class[]{MultiplayerAttackOption.class, RangeOfInfluence.class}); + game = con.newInstance(new Object[] {attackOption, range}); } catch (Exception ex) { logger.log(Level.SEVERE, null, ex); return null; @@ -71,13 +79,16 @@ public class GameFactory { return game; } - public Set getGameTypes() { - return gameTypes.keySet(); + public List getGameTypes() { + return gameTypeViews; } - public void addGameType(String name, Class gameType) { - if (gameType != null) + public void addGameType(String name, GameType gameType, Class game) { + if (game != null) { + this.games.put(name, game); this.gameTypes.put(name, gameType); + this.gameTypeViews.add(new GameTypeView(gameType)); + } } } diff --git a/Mage.Server/src/mage/server/game/GamesRoom.java b/Mage.Server/src/mage/server/game/GamesRoom.java index cdf6887cfa..d7022b0d03 100644 --- a/Mage.Server/src/mage/server/game/GamesRoom.java +++ b/Mage.Server/src/mage/server/game/GamesRoom.java @@ -28,9 +28,10 @@ package mage.server.game; -import java.util.Collection; import java.util.List; import java.util.UUID; +import mage.Constants.MultiplayerAttackOption; +import mage.Constants.RangeOfInfluence; import mage.cards.decks.DeckCardLists; import mage.game.GameException; import mage.view.TableView; @@ -41,9 +42,9 @@ import mage.view.TableView; */ public interface GamesRoom extends Room { - public Collection getTables(); + public List getTables(); public boolean joinTable(UUID sessionId, UUID tableId, int seatNum, String name, DeckCardLists deckList) throws GameException; - public TableView createTable(UUID sessionId, String gameType, String deckType, List playerTypes); + public TableView createTable(UUID sessionId, String gameType, String deckType, List playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range); public void removeTable(UUID sessionId, UUID tableId); public TableView getTable(UUID tableId); public void leaveTable(UUID sessionId, UUID tableId); diff --git a/Mage.Server/src/mage/server/game/GamesRoomImpl.java b/Mage.Server/src/mage/server/game/GamesRoomImpl.java index 2e1660b277..ad87a33b98 100644 --- a/Mage.Server/src/mage/server/game/GamesRoomImpl.java +++ b/Mage.Server/src/mage/server/game/GamesRoomImpl.java @@ -31,11 +31,12 @@ package mage.server.game; import mage.game.Table; import java.io.Serializable; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; +import mage.Constants.MultiplayerAttackOption; +import mage.Constants.RangeOfInfluence; import mage.cards.decks.DeckCardLists; import mage.game.GameException; import mage.util.Logging; @@ -52,7 +53,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { private ConcurrentHashMap tables = new ConcurrentHashMap(); @Override - public Collection getTables() { + public List getTables() { ArrayList tableList = new ArrayList(); for (Table table: tables.values()) { tableList.add(new TableView(table)); @@ -70,8 +71,8 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable { } @Override - public TableView createTable(UUID sessionId, String gameType, String deckType, List playerTypes) { - Table table = TableManager.getInstance().createTable(sessionId, gameType, deckType, playerTypes); + public TableView createTable(UUID sessionId, String gameType, String deckType, List playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) { + Table table = TableManager.getInstance().createTable(sessionId, gameType, deckType, playerTypes, attackOption, range); tables.put(table.getId(), table); return new TableView(table); } diff --git a/Mage.Server/src/mage/server/game/PlayerFactory.java b/Mage.Server/src/mage/server/game/PlayerFactory.java index 8c21882dbb..15dcbef50c 100644 --- a/Mage.Server/src/mage/server/game/PlayerFactory.java +++ b/Mage.Server/src/mage/server/game/PlayerFactory.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; +import mage.Constants.RangeOfInfluence; import mage.cards.decks.Deck; import mage.players.Player; import mage.util.Logging; @@ -55,12 +56,12 @@ public class PlayerFactory { private PlayerFactory() {} - public Player createPlayer(String playerType, String name, Deck deck) { + public Player createPlayer(String playerType, String name, Deck deck, RangeOfInfluence range) { Player player; Constructor con; try { - con = playerTypes.get(playerType).getConstructor(new Class[]{String.class, Deck.class}); - player = (Player)con.newInstance(new Object[] {name, deck}); + con = playerTypes.get(playerType).getConstructor(new Class[]{String.class, Deck.class, RangeOfInfluence.class}); + player = (Player)con.newInstance(new Object[] {name, deck, range}); } catch (Exception ex) { logger.log(Level.SEVERE, null, ex); return null; diff --git a/Mage.Server/src/mage/server/game/TableController.java b/Mage.Server/src/mage/server/game/TableController.java index dafec435a2..efd1ad37b0 100644 --- a/Mage.Server/src/mage/server/game/TableController.java +++ b/Mage.Server/src/mage/server/game/TableController.java @@ -47,6 +47,8 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; +import mage.Constants.MultiplayerAttackOption; +import mage.Constants.RangeOfInfluence; import mage.Constants.TableState; import mage.cards.decks.Deck; import mage.cards.decks.DeckCardLists; @@ -76,10 +78,10 @@ public class TableController { private Game game; private ConcurrentHashMap sessionPlayerMap = new ConcurrentHashMap(); - public TableController(UUID sessionId, String gameType, String deckType, List playerTypes) { + public TableController(UUID sessionId, String gameType, String deckType, List playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) { this.sessionId = sessionId; chatId = ChatManager.getInstance().createChatSession(); - game = GameFactory.getInstance().createGame(gameType); + game = GameFactory.getInstance().createGame(gameType, attackOption, range); gameId = game.getId(); table = new Table(gameType, DeckValidatorFactory.getInstance().createDeckValidator(deckType), playerTypes); } @@ -134,9 +136,8 @@ public class TableController { } private Player createPlayer(String name, Deck deck, String playerType) { - Player player = PlayerFactory.getInstance().createPlayer(playerType, name, deck); + Player player = PlayerFactory.getInstance().createPlayer(playerType, name, deck, game.getRangeOfInfluence()); logger.info("Player created " + player.getId()); -// player.setDeck(deck); return player; } @@ -167,6 +168,19 @@ public class TableController { game = null; } + public void swapSeats(int seatNum1, int seatNum2) { + if (table.getState() == TableState.STARTING) { + if (seatNum1 >= 0 && seatNum2 >= 0 && seatNum1 < table.getSeats().length && seatNum2 < table.getSeats().length) { + Player swapPlayer = table.getSeats()[seatNum1].getPlayer(); + String swapType = table.getSeats()[seatNum1].getPlayerType(); + table.getSeats()[seatNum1].setPlayer(table.getSeats()[seatNum2].getPlayer()); + table.getSeats()[seatNum1].setPlayerType(table.getSeats()[seatNum2].getPlayerType()); + table.getSeats()[seatNum2].setPlayer(swapPlayer); + table.getSeats()[seatNum2].setPlayerType(swapType); + } + } + } + private void saveGame() { try { //use buffering diff --git a/Mage.Server/src/mage/server/game/TableManager.java b/Mage.Server/src/mage/server/game/TableManager.java index a993482cc1..effb5d9ebb 100644 --- a/Mage.Server/src/mage/server/game/TableManager.java +++ b/Mage.Server/src/mage/server/game/TableManager.java @@ -34,6 +34,8 @@ import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; +import mage.Constants.MultiplayerAttackOption; +import mage.Constants.RangeOfInfluence; import mage.cards.decks.DeckCardLists; import mage.game.GameException; import mage.util.Logging; @@ -54,8 +56,8 @@ public class TableManager { return INSTANCE; } - public Table createTable(UUID sessionId, String gameType, String deckType, List playerTypes) { - TableController tableController = new TableController(sessionId, gameType, deckType, playerTypes); + public Table createTable(UUID sessionId, String gameType, String deckType, List playerTypes, MultiplayerAttackOption attackOption, RangeOfInfluence range) { + TableController tableController = new TableController(sessionId, gameType, deckType, playerTypes, attackOption, range); controllers.put(tableController.getTable().getId(), tableController); tables.put(tableController.getTable().getId(), tableController.getTable()); return tableController.getTable(); @@ -117,4 +119,10 @@ public class TableManager { public GameReplay createReplay(UUID tableId) { return controllers.get(tableId).createReplay(); } + + public void swapSeats(UUID tableId, UUID sessionId, int seatNum1, int seatNum2) { + if (isTableOwner(tableId, sessionId)) { + controllers.get(tableId).swapSeats(seatNum1, seatNum2); + } + } } diff --git a/Mage.Server/src/mage/server/util/ConfigSettings.java b/Mage.Server/src/mage/server/util/ConfigSettings.java index c5c1e098de..d0aba9c981 100644 --- a/Mage.Server/src/mage/server/util/ConfigSettings.java +++ b/Mage.Server/src/mage/server/util/ConfigSettings.java @@ -37,6 +37,7 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import mage.server.util.config.Config; import mage.server.util.config.Plugin; +import mage.server.util.config.GamePlugin; import mage.util.Logging; /** * @@ -84,15 +85,15 @@ public class ConfigSettings { } public List getPlayerTypes() { - return config.getPlayerTypes().getPlugin(); + return config.getPlayerTypes().getPlayerType(); } - public List getGameTypes() { - return config.getGameTypes().getPlugin(); + public List getGameTypes() { + return config.getGameTypes().getGameType(); } public List getDeckTypes() { - return config.getDeckTypes().getPlugin(); + return config.getDeckTypes().getDeckType(); } } diff --git a/Mage.Server/src/mage/server/util/resources/config.xml b/Mage.Server/src/mage/server/util/resources/config.xml index 5b6dbf522b..7f2a10247f 100644 --- a/Mage.Server/src/mage/server/util/resources/config.xml +++ b/Mage.Server/src/mage/server/util/resources/config.xml @@ -1,12 +1,15 @@ - + - - + + - + + + + diff --git a/Mage.Server/xml-resources/jaxb/Config/Config.xsd b/Mage.Server/xml-resources/jaxb/Config/Config.xsd index 20c7319dea..142e7f1a74 100644 --- a/Mage.Server/xml-resources/jaxb/Config/Config.xsd +++ b/Mage.Server/xml-resources/jaxb/Config/Config.xsd @@ -23,18 +23,24 @@ - - - - - - - + + + + + + + + + + + + + - + @@ -42,7 +48,7 @@ - + @@ -50,7 +56,7 @@ - +