Merge pull request #7158 from fburato/app-wiring-refactor

Application wiring refactor and externalise configuration path for server
This commit is contained in:
Oleg Agafonov 2020-12-26 07:42:46 +01:00 committed by GitHub
commit 81e0cc6403
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
59 changed files with 2367 additions and 779 deletions

View file

@ -23,11 +23,11 @@ import mage.game.permanent.Permanent;
import mage.game.turn.Phase;
import mage.interfaces.Action;
import mage.players.Player;
import mage.server.*;
import mage.server.util.ConfigSettings;
import mage.server.Main;
import mage.server.User;
import mage.server.managers.ManagerFactory;
import mage.server.util.Splitter;
import mage.server.util.SystemUtil;
import mage.server.util.ThreadExecutor;
import mage.utils.StreamUtils;
import mage.utils.timer.PriorityTimer;
import mage.view.*;
@ -53,13 +53,14 @@ public class GameController implements GameCallback {
private static final int GAME_TIMEOUTS_CHECK_JOINING_STATUS_EVERY_SECS = 10; // checks and inform players about joining status
private static final int GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS = 2 * 60; // leave player from game if it don't join and inactive on server
private static final ExecutorService gameExecutor = ThreadExecutor.instance.getGameExecutor();
private final ExecutorService gameExecutor;
private static final Logger logger = Logger.getLogger(GameController.class);
protected final ScheduledExecutorService joinWaitingExecutor = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> futureTimeout;
protected static final ScheduledExecutorService timeoutIdleExecutor = ThreadExecutor.instance.getTimeoutIdleExecutor();
private final ManagerFactory managerFactory;
protected final ScheduledExecutorService timeoutIdleExecutor;
private final ConcurrentMap<UUID, GameSessionPlayer> gameSessions = new ConcurrentHashMap<>();
private final ReadWriteLock gameSessionsLock = new ReentrantReadWriteLock();
@ -83,13 +84,16 @@ public class GameController implements GameCallback {
private int turnsToRollback;
private int requestsOpen;
public GameController(Game game, ConcurrentMap<UUID, UUID> userPlayerMap, UUID tableId, UUID choosingPlayerId, GameOptions gameOptions) {
public GameController(ManagerFactory managerFactory, Game game, ConcurrentMap<UUID, UUID> userPlayerMap, UUID tableId, UUID choosingPlayerId, GameOptions gameOptions) {
this.managerFactory = managerFactory;
gameExecutor = managerFactory.threadExecutor().getGameExecutor();
timeoutIdleExecutor = managerFactory.threadExecutor().getTimeoutIdleExecutor();
gameSessionId = UUID.randomUUID();
this.userPlayerMap = userPlayerMap;
chatId = ChatManager.instance.createChatSession("Game " + game.getId());
chatId = managerFactory.chatManager().createChatSession("Game " + game.getId());
this.userReqestingRollback = null;
this.game = game;
this.game.setSaveGame(ConfigSettings.instance.isSaveGameActivated());
this.game.setSaveGame(managerFactory.configSettings().isSaveGameActivated());
this.tableId = tableId;
this.choosingPlayerId = choosingPlayerId;
this.gameOptions = gameOptions;
@ -103,7 +107,7 @@ public class GameController implements GameCallback {
for (GameSessionPlayer gameSessionPlayer : getGameSessions()) {
gameSessionPlayer.cleanUp();
}
ChatManager.instance.destroyChatSession(chatId);
managerFactory.chatManager().destroyChatSession(chatId);
for (PriorityTimer priorityTimer : timers.values()) {
priorityTimer.cancel();
}
@ -120,11 +124,11 @@ public class GameController implements GameCallback {
updateGame();
break;
case INFO:
ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, event.getGame(), MessageType.GAME, null);
managerFactory.chatManager().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, event.getGame(), MessageType.GAME, null);
logger.trace(game.getId() + " " + event.getMessage());
break;
case STATUS:
ChatManager.instance.broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), event.getWithTurnInfo() ? event.getGame() : null, MessageType.GAME, null);
managerFactory.chatManager().broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), event.getWithTurnInfo() ? event.getGame() : null, MessageType.GAME, null);
logger.trace(game.getId() + " " + event.getMessage());
break;
case ERROR:
@ -273,7 +277,7 @@ public class GameController implements GameCallback {
logger.fatal("- userId: " + userId);
return;
}
Optional<User> user = UserManager.instance.getUser(userId);
Optional<User> user = managerFactory.userManager().getUser(userId);
if (!user.isPresent()) {
logger.fatal("User not found : " + userId);
return;
@ -286,7 +290,7 @@ public class GameController implements GameCallback {
GameSessionPlayer gameSession = gameSessions.get(playerId);
String joinType;
if (gameSession == null) {
gameSession = new GameSessionPlayer(game, userId, playerId);
gameSession = new GameSessionPlayer(managerFactory, game, userId, playerId);
final Lock w = gameSessionsLock.writeLock();
w.lock();
try {
@ -300,7 +304,7 @@ public class GameController implements GameCallback {
}
user.get().addGame(playerId, gameSession);
logger.debug("Player " + player.getName() + ' ' + playerId + " has " + joinType + " gameId: " + game.getId());
ChatManager.instance.broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, game, MessageType.GAME, null);
managerFactory.chatManager().broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, game, MessageType.GAME, null);
checkStart();
}
@ -335,7 +339,7 @@ public class GameController implements GameCallback {
// join the game because player has not joined or was removed because of disconnect
String problemPlayerFixes;
user.removeConstructing(player.getId());
GameManager.instance.joinGame(game.getId(), user.getId());
managerFactory.gameManager().joinGame(game.getId(), user.getId());
logger.warn("Forced join of player " + player.getName() + " (" + user.getUserState() + ") to gameId: " + game.getId());
if (user.isConnected()) {
// init game session, see reconnect()
@ -345,7 +349,7 @@ public class GameController implements GameCallback {
logger.warn("Send forced game start event for player " + player.getName() + " in gameId: " + game.getId());
user.ccGameStarted(session.getGameId(), player.getId());
session.init();
GameManager.instance.sendPlayerString(session.getGameId(), user.getId(), "");
managerFactory.gameManager().sendPlayerString(session.getGameId(), user.getId(), "");
} else {
problemPlayerFixes = "leave on broken game session";
logger.error("Can't find game session for forced join, leave it: player " + player.getName() + " in gameId: " + game.getId());
@ -357,7 +361,7 @@ public class GameController implements GameCallback {
player.leave();
}
ChatManager.instance.broadcast(chatId, player.getName(), user.getPingInfo()
managerFactory.chatManager().broadcast(chatId, player.getName(), user.getPingInfo()
+ " is forced to join the game (waiting ends after "
+ GAME_TIMEOUTS_CANCEL_PLAYER_GAME_JOINING_AFTER_INACTIVE_SECS
+ " secs, applied fixes: " + problemPlayerFixes + ")",
@ -382,7 +386,7 @@ public class GameController implements GameCallback {
private Optional<User> getUserByPlayerId(UUID playerId) {
for (Map.Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
if (entry.getValue().equals(playerId)) {
return UserManager.instance.getUser(entry.getKey());
return managerFactory.userManager().getUser(entry.getKey());
}
}
return Optional.empty();
@ -391,7 +395,7 @@ public class GameController implements GameCallback {
private void checkStart() {
if (allJoined()) {
joinWaitingExecutor.shutdownNow();
ThreadExecutor.instance.getCallExecutor().execute(this::startGame);
managerFactory.threadExecutor().getCallExecutor().execute(this::startGame);
}
}
@ -423,14 +427,14 @@ public class GameController implements GameCallback {
}
if (!isAllowedToWatch(userId)) {
// Dont want people on our ignore list to stalk us
UserManager.instance.getUser(userId).ifPresent(user -> {
managerFactory.userManager().getUser(userId).ifPresent(user -> {
user.showUserMessage("Not allowed", "You are banned from watching this game");
ChatManager.instance.broadcast(chatId, user.getName(), " tried to join, but is banned", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
managerFactory.chatManager().broadcast(chatId, user.getName(), " tried to join, but is banned", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
});
return false;
}
UserManager.instance.getUser(userId).ifPresent(user -> {
GameSessionWatcher gameWatcher = new GameSessionWatcher(userId, game, false);
managerFactory.userManager().getUser(userId).ifPresent(user -> {
GameSessionWatcher gameWatcher = new GameSessionWatcher(managerFactory.userManager(), userId, game, false);
final Lock w = gameWatchersLock.writeLock();
w.lock();
try {
@ -440,7 +444,7 @@ public class GameController implements GameCallback {
}
gameWatcher.init();
user.addGameWatchInfo(game.getId());
ChatManager.instance.broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
managerFactory.chatManager().broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
});
return true;
}
@ -453,8 +457,8 @@ public class GameController implements GameCallback {
} finally {
w.unlock();
}
UserManager.instance.getUser(userId).ifPresent(user -> {
ChatManager.instance.broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
managerFactory.userManager().getUser(userId).ifPresent(user -> {
managerFactory.chatManager().broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, game, ChatMessage.MessageType.STATUS, null);
});
}
@ -628,7 +632,7 @@ public class GameController implements GameCallback {
gameSession.requestPermissionToSeeHandCards(userIdRequester);
} else {
// player does not allow the request
UserManager.instance.getUser(userIdRequester).ifPresent(requester -> {
managerFactory.userManager().getUser(userIdRequester).ifPresent(requester -> {
requester.showUserMessage("Request to show hand cards", "Player " + grantingPlayer.getName() + " does not allow to request to show hand cards!");
});
}
@ -640,7 +644,7 @@ public class GameController implements GameCallback {
}
} else {
// user can already see the cards
UserManager.instance.getUser(userIdRequester).ifPresent(requester -> {
managerFactory.userManager().getUser(userIdRequester).ifPresent(requester -> {
requester.showUserMessage("Request to show hand cards", "You can see already the hand cards of player " + grantingPlayer.getName() + '!');
});
@ -653,9 +657,9 @@ public class GameController implements GameCallback {
Player viewLimitedDeckPlayer = game.getPlayer(userIdRequester);
if (viewLimitedDeckPlayer != null) {
if (viewLimitedDeckPlayer.isHuman()) {
for (MatchPlayer p : TableManager.instance.getTable(tableId).getMatch().getPlayers()) {
for (MatchPlayer p : managerFactory.tableManager().getTable(tableId).getMatch().getPlayers()) {
if (p.getPlayer().getId().equals(userIdRequester)) {
Optional<User> u = UserManager.instance.getUser(origId);
Optional<User> u = managerFactory.userManager().getUser(origId);
if (u.isPresent() && p.getDeck() != null) {
u.get().ccViewLimitedDeck(p.getDeck(), tableId, requestsOpen, true);
}
@ -698,8 +702,8 @@ public class GameController implements GameCallback {
if (player != null) {
String sb = player.getLogName()
+ " has timed out (player had priority and was not active for "
+ ConfigSettings.instance.getMaxSecondsIdle() + " seconds ) - Auto concede.";
ChatManager.instance.broadcast(chatId, "", sb, MessageColor.BLACK, true, game, MessageType.STATUS, null);
+ managerFactory.configSettings().getMaxSecondsIdle() + " seconds ) - Auto concede.";
managerFactory.chatManager().broadcast(chatId, "", sb, MessageColor.BLACK, true, game, MessageType.STATUS, null);
game.idleTimeout(playerId);
}
}
@ -712,7 +716,7 @@ public class GameController implements GameCallback {
for (final GameSessionWatcher gameWatcher : getGameSessionWatchers()) {
gameWatcher.gameOver(message);
}
TableManager.instance.endGame(tableId);
managerFactory.tableManager().endGame(tableId);
}
public UUID getSessionId() {
@ -763,7 +767,7 @@ public class GameController implements GameCallback {
}
private synchronized void endGameInfo() {
Table table = TableManager.instance.getTable(tableId);
Table table = managerFactory.tableManager().getTable(tableId);
if (table != null) {
if (table.getMatch() != null) {
for (final GameSessionPlayer gameSession : getGameSessions()) {
@ -1012,7 +1016,7 @@ public class GameController implements GameCallback {
cancelTimeout();
futureTimeout = timeoutIdleExecutor.schedule(
() -> idleTimeout(playerId),
Main.isTestMode() ? 3600 : ConfigSettings.instance.getMaxSecondsIdle(),
Main.isTestMode() ? 3600 : managerFactory.configSettings().getMaxSecondsIdle(),
TimeUnit.SECONDS
);
}
@ -1094,7 +1098,7 @@ public class GameController implements GameCallback {
}
public boolean isAllowedToWatch(UUID userId) {
Optional<User> user = UserManager.instance.getUser(userId);
Optional<User> user = managerFactory.userManager().getUser(userId);
if (user.isPresent()) {
return !gameOptions.bannedUsers.contains(user.get().getName());
}
@ -1208,7 +1212,7 @@ public class GameController implements GameCallback {
public String getPingsInfo() {
List<String> usersInfo = new ArrayList<>();
for (Map.Entry<UUID, UUID> entry : userPlayerMap.entrySet()) {
Optional<User> user = UserManager.instance.getUser(entry.getKey());
Optional<User> user = managerFactory.userManager().getUser(entry.getKey());
user.ifPresent(u -> usersInfo.add("* " + u.getName() + ": " + u.getPingInfo()));
}
Collections.sort(usersInfo);
@ -1216,7 +1220,7 @@ public class GameController implements GameCallback {
List<String> watchersinfo = new ArrayList<>();
for (Map.Entry<UUID, GameSessionWatcher> entry : watchers.entrySet()) {
Optional<User> user = UserManager.instance.getUser(entry.getValue().userId);
Optional<User> user = managerFactory.userManager().getUser(entry.getValue().userId);
user.ifPresent(u -> watchersinfo.add("* " + u.getName() + ": " + u.getPingInfo()));
}
Collections.sort(watchersinfo);

View file

@ -5,6 +5,8 @@ import mage.constants.ManaType;
import mage.constants.PlayerAction;
import mage.game.Game;
import mage.game.GameOptions;
import mage.server.managers.GameManager;
import mage.server.managers.ManagerFactory;
import mage.view.GameView;
import java.util.HashMap;
@ -20,14 +22,19 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @author BetaSteward_at_googlemail.com
*/
public enum GameManager {
instance;
public class GameManagerImpl implements GameManager {
private final ManagerFactory managerFactory;
private final ConcurrentMap<UUID, GameController> gameControllers = new ConcurrentHashMap<>();
private final ReadWriteLock gameControllersLock = new ReentrantReadWriteLock();
public GameManagerImpl(ManagerFactory managerFactory) {
this.managerFactory = managerFactory;
}
@Override
public UUID createGameSession(Game game, ConcurrentHashMap<UUID, UUID> userPlayerMap, UUID tableId, UUID choosingPlayerId, GameOptions gameOptions) {
GameController gameController = new GameController(game, userPlayerMap, tableId, choosingPlayerId, gameOptions);
GameController gameController = new GameController(managerFactory, game, userPlayerMap, tableId, choosingPlayerId, gameOptions);
final Lock w = gameControllersLock.writeLock();
w.lock();
try {
@ -48,6 +55,7 @@ public enum GameManager {
}
}
@Override
public void joinGame(UUID gameId, UUID userId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -55,6 +63,7 @@ public enum GameManager {
}
}
@Override
public Optional<UUID> getChatId(UUID gameId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -63,6 +72,7 @@ public enum GameManager {
return Optional.empty();
}
@Override
public void sendPlayerUUID(UUID gameId, UUID userId, UUID data) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -70,6 +80,7 @@ public enum GameManager {
}
}
@Override
public void sendPlayerString(UUID gameId, UUID userId, String data) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -77,6 +88,7 @@ public enum GameManager {
}
}
@Override
public void sendPlayerManaType(UUID gameId, UUID playerId, UUID userId, ManaType data) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -84,6 +96,7 @@ public enum GameManager {
}
}
@Override
public void sendPlayerBoolean(UUID gameId, UUID userId, Boolean data) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -91,6 +104,7 @@ public enum GameManager {
}
}
@Override
public void sendPlayerInteger(UUID gameId, UUID userId, Integer data) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -98,6 +112,7 @@ public enum GameManager {
}
}
@Override
public void quitMatch(UUID gameId, UUID userId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -105,6 +120,7 @@ public enum GameManager {
}
}
@Override
public void sendPlayerAction(PlayerAction playerAction, UUID gameId, UUID userId, Object data) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -112,6 +128,7 @@ public enum GameManager {
}
}
@Override
public boolean watchGame(UUID gameId, UUID userId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -120,6 +137,7 @@ public enum GameManager {
return false;
}
@Override
public void stopWatching(UUID gameId, UUID userId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -127,6 +145,7 @@ public enum GameManager {
}
}
@Override
public void cheat(UUID gameId, UUID userId, UUID playerId, DeckCardLists deckList) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -134,6 +153,7 @@ public enum GameManager {
}
}
@Override
public boolean cheat(UUID gameId, UUID userId, UUID playerId, String cardName) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -142,6 +162,7 @@ public enum GameManager {
return false;
}
@Override
public void removeGame(UUID gameId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -156,6 +177,7 @@ public enum GameManager {
}
}
@Override
public boolean saveGame(UUID gameId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -164,6 +186,7 @@ public enum GameManager {
return false;
}
@Override
public GameView getGameView(UUID gameId, UUID playerId) {
GameController gameController = getGameControllerSafe(gameId);
if (gameController != null) {
@ -172,10 +195,12 @@ public enum GameManager {
return null;
}
@Override
public int getNumberActiveGames() {
return getGameController().size();
}
@Override
public Map<UUID, GameController> getGameController() {
Map<UUID, GameController> newControllers = new HashMap<>();
final Lock r = gameControllersLock.readLock();

View file

@ -11,8 +11,8 @@ import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
import mage.players.Player;
import mage.server.User;
import mage.server.UserManager;
import mage.server.util.ThreadExecutor;
import mage.server.managers.UserManager;
import mage.server.managers.ManagerFactory;
import mage.view.*;
import org.apache.log4j.Logger;
@ -28,12 +28,15 @@ public class GameSessionPlayer extends GameSessionWatcher {
private static final Logger logger = Logger.getLogger(GameSessionPlayer.class);
private final UserManager userManager;
private final UUID playerId;
private static final ExecutorService callExecutor = ThreadExecutor.instance.getCallExecutor();
private final ExecutorService callExecutor;
public GameSessionPlayer(Game game, UUID userId, UUID playerId) {
super(userId, game, true);
public GameSessionPlayer(ManagerFactory managerFactory, Game game, UUID userId, UUID playerId) {
super(managerFactory.userManager(), userId, game, true);
this.userManager = managerFactory.userManager();
callExecutor = managerFactory.threadExecutor().getCallExecutor();
this.playerId = playerId;
}
@ -44,14 +47,14 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void ask(final String question, final Map<String, Serializable> options) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_ASK, game.getId(), new GameClientMessage(getGameView(), question, options)))
userManager.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_ASK, game.getId(), new GameClientMessage(getGameView(), question, options)))
);
}
}
public void target(final String question, final CardsView cardView, final Set<UUID> targets, final boolean required, final Map<String, Serializable> options) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> {
userManager.getUser(userId).ifPresent(user -> {
user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_TARGET, game.getId(), new GameClientMessage(getGameView(), question, cardView, targets, required, options)));
});
@ -60,13 +63,13 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void select(final String message, final Map<String, Serializable> options) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_SELECT, game.getId(), new GameClientMessage(getGameView(), message, options))));
userManager.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_SELECT, game.getId(), new GameClientMessage(getGameView(), message, options))));
}
}
public void chooseAbility(final AbilityPickerView abilities) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user
userManager.getUser(userId).ifPresent(user
-> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_CHOOSE_ABILITY, game.getId(), abilities)));
}
@ -74,7 +77,7 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void choosePile(final String message, final CardsView pile1, final CardsView pile2) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user
userManager.getUser(userId).ifPresent(user
-> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_CHOOSE_PILE, game.getId(), new GameClientMessage(message, pile1, pile2))));
}
@ -82,7 +85,7 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void chooseChoice(final Choice choice) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user
userManager.getUser(userId).ifPresent(user
-> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_CHOOSE_CHOICE, game.getId(), new GameClientMessage(choice))));
}
@ -90,14 +93,14 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void playMana(final String message, final Map<String, Serializable> options) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user
userManager.getUser(userId).ifPresent(user
-> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_PLAY_MANA, game.getId(), new GameClientMessage(getGameView(), message, options))));
}
}
public void playXMana(final String message) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user
userManager.getUser(userId).ifPresent(user
-> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_PLAY_XMANA, game.getId(), new GameClientMessage(getGameView(), message))));
}
@ -105,7 +108,7 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void getAmount(final String message, final int min, final int max) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> {
userManager.getUser(userId).ifPresent(user -> {
user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_GET_AMOUNT, game.getId(), new GameClientMessage(message, min, max)));
});
}
@ -113,15 +116,15 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void endGameInfo(Table table) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.END_GAME_INFO, game.getId(), getGameEndView(playerId, table))));
userManager.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.END_GAME_INFO, game.getId(), getGameEndView(playerId, table))));
}
}
public void requestPermissionToRollbackTurn(UUID requestingUserId, int numberTurns) {
if (!killed) {
Optional<User> requestingUser = UserManager.instance.getUser(requestingUserId);
Optional<User> requestedUser = UserManager.instance.getUser(userId);
Optional<User> requestingUser = userManager.getUser(requestingUserId);
Optional<User> requestedUser = userManager.getUser(userId);
if (requestedUser.isPresent() && requestingUser.isPresent()) {
String message;
switch (numberTurns) {
@ -147,8 +150,8 @@ public class GameSessionPlayer extends GameSessionWatcher {
public void requestPermissionToSeeHandCards(UUID watcherId) {
if (!killed) {
Optional<User> watcher = UserManager.instance.getUser(watcherId);
Optional<User> user = UserManager.instance.getUser(userId);
Optional<User> watcher = userManager.getUser(watcherId);
Optional<User> user = userManager.getUser(userId);
if (user.isPresent() && watcher.isPresent()) {
UserRequestMessage userRequestMessage = new UserRequestMessage(
"User request",
@ -217,7 +220,7 @@ public class GameSessionPlayer extends GameSessionWatcher {
}
public void removeGame() {
UserManager.instance.getUser(userId).ifPresent(user -> user.removeGame(playerId));
userManager.getUser(userId).ifPresent(user -> user.removeGame(playerId));
}

View file

@ -6,7 +6,7 @@ import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
import mage.players.Player;
import mage.server.User;
import mage.server.UserManager;
import mage.server.managers.UserManager;
import mage.view.GameClientMessage;
import mage.view.GameEndView;
import mage.view.GameView;
@ -25,12 +25,14 @@ public class GameSessionWatcher {
protected static final Logger logger = Logger.getLogger(GameSessionWatcher.class);
private final UserManager userManager;
protected final UUID userId;
protected final Game game;
protected boolean killed = false;
protected final boolean isPlayer;
public GameSessionWatcher(UUID userId, Game game, boolean isPlayer) {
public GameSessionWatcher(UserManager userManager, UUID userId, Game game, boolean isPlayer) {
this.userManager = userManager;
this.userId = userId;
this.game = game;
this.isPlayer = isPlayer;
@ -38,7 +40,7 @@ public class GameSessionWatcher {
public boolean init() {
if (!killed) {
Optional<User> user = UserManager.instance.getUser(userId);
Optional<User> user = userManager.getUser(userId);
if (user.isPresent()) {
user.get().fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INIT, game.getId(), getGameView()));
return true;
@ -49,28 +51,28 @@ public class GameSessionWatcher {
public void update() {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_UPDATE, game.getId(), getGameView())));
userManager.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_UPDATE, game.getId(), getGameView())));
}
}
public void inform(final String message) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INFORM, game.getId(), new GameClientMessage(getGameView(), message))));
userManager.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INFORM, game.getId(), new GameClientMessage(getGameView(), message))));
}
}
public void informPersonal(final String message) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INFORM_PERSONAL, game.getId(), new GameClientMessage(getGameView(), message))));
userManager.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_INFORM_PERSONAL, game.getId(), new GameClientMessage(getGameView(), message))));
}
}
public void gameOver(final String message) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> {
userManager.getUser(userId).ifPresent(user -> {
user.removeGameWatchInfo(game.getId());
user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_OVER, game.getId(), message));
});
@ -86,7 +88,7 @@ public class GameSessionWatcher {
public void gameError(final String message) {
if (!killed) {
UserManager.instance.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_ERROR, game.getId(), message)));
userManager.getUser(userId).ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.GAME_ERROR, game.getId(), message)));
}
}

View file

@ -1,12 +1,5 @@
package mage.server.game;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import mage.MageException;
import mage.cards.decks.DeckCardLists;
import mage.constants.TableState;
@ -16,18 +9,21 @@ import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions;
import mage.players.PlayerType;
import mage.server.RoomImpl;
import mage.server.TableManager;
import mage.server.User;
import mage.server.UserManager;
import mage.server.tournament.TournamentManager;
import mage.server.util.ConfigSettings;
import mage.server.util.ThreadExecutor;
import mage.server.managers.ManagerFactory;
import mage.view.MatchView;
import mage.view.RoomUsersView;
import mage.view.TableView;
import mage.view.UsersView;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author BetaSteward_at_googlemail.com
*/
@ -40,9 +36,12 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
private static List<MatchView> matchView = new ArrayList<>();
private static List<RoomUsersView> roomUsersView = new ArrayList<>();
private final ManagerFactory managerFactory;
private final ConcurrentHashMap<UUID, Table> tables = new ConcurrentHashMap<>();
public GamesRoomImpl() {
public GamesRoomImpl(ManagerFactory managerFactory) {
super(managerFactory.chatManager());
this.managerFactory = managerFactory;
UPDATE_EXECUTOR.scheduleAtFixedRate(() -> {
try {
update();
@ -71,7 +70,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
} else {
// more since 50 matches finished since this match so removeUserFromAllTablesAndChat it
if (table.isTournament()) {
TournamentManager.instance.removeTournament(table.getTournament().getId());
managerFactory.tournamentManager().removeTournament(table.getTournament().getId());
}
this.removeTable(table.getId());
}
@ -79,7 +78,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
tableView = tableList;
matchView = matchList;
List<UsersView> users = new ArrayList<>();
for (User user : UserManager.instance.getUsers()) {
for (User user : managerFactory.userManager().getUsers()) {
if (user.getUserState() != User.UserState.Offline && !user.getName().equals("Admin")) {
try {
users.add(new UsersView(user.getUserData().getFlagName(), user.getName(),
@ -108,9 +107,9 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
users.sort((one, two) -> one.getUserName().compareToIgnoreCase(two.getUserName()));
List<RoomUsersView> roomUserInfo = new ArrayList<>();
roomUserInfo.add(new RoomUsersView(users,
GameManager.instance.getNumberActiveGames(),
ThreadExecutor.instance.getActiveThreads(ThreadExecutor.instance.getGameExecutor()),
ConfigSettings.instance.getMaxGameThreads()
managerFactory.gameManager().getNumberActiveGames(),
managerFactory.threadExecutor().getActiveThreads(managerFactory.threadExecutor().getGameExecutor()),
managerFactory.configSettings().getMaxGameThreads()
));
roomUsersView = roomUserInfo;
}
@ -123,7 +122,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
@Override
public boolean joinTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException {
if (tables.containsKey(tableId)) {
return TableManager.instance.joinTable(userId, tableId, name, playerType, skill, deckList, password);
return managerFactory.tableManager().joinTable(userId, tableId, name, playerType, skill, deckList, password);
} else {
return false;
}
@ -131,7 +130,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
@Override
public TableView createTable(UUID userId, MatchOptions options) {
Table table = TableManager.instance.createTable(this.getRoomId(), userId, options);
Table table = managerFactory.tableManager().createTable(this.getRoomId(), userId, options);
tables.put(table.getId(), table);
return new TableView(table);
}
@ -139,7 +138,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
@Override
public boolean joinTournamentTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws GameException {
if (tables.containsKey(tableId)) {
return TableManager.instance.joinTournament(userId, tableId, name, playerType, skill, deckList, password);
return managerFactory.tableManager().joinTournament(userId, tableId, name, playerType, skill, deckList, password);
} else {
return false;
}
@ -147,7 +146,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
@Override
public TableView createTournamentTable(UUID userId, TournamentOptions options) {
Table table = TableManager.instance.createTournamentTable(this.getRoomId(), userId, options);
Table table = managerFactory.tableManager().createTournamentTable(this.getRoomId(), userId, options);
tables.put(table.getId(), table);
return new TableView(table);
}
@ -179,12 +178,12 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
@Override
public void leaveTable(UUID userId, UUID tableId) {
TableManager.instance.leaveTable(userId, tableId);
managerFactory.tableManager().leaveTable(userId, tableId);
}
@Override
public boolean watchTable(UUID userId, UUID tableId) throws MageException {
return TableManager.instance.watchTable(userId, tableId);
return managerFactory.tableManager().watchTable(userId, tableId);
}
@Override

View file

@ -1,5 +1,7 @@
package mage.server.game;
import mage.server.managers.GamesRoomManager;
import mage.server.managers.ManagerFactory;
import org.apache.log4j.Logger;
import java.util.Optional;
@ -9,36 +11,44 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* @author BetaSteward_at_googlemail.com
*/
public enum GamesRoomManager {
instance;
public class GamesRoomManagerImpl implements GamesRoomManager {
private final ManagerFactory managerFactory;
private final ConcurrentHashMap<UUID, GamesRoom> rooms = new ConcurrentHashMap<>();
private final UUID mainRoomId;
private final UUID mainChatId;
private static final Logger logger = Logger.getLogger(GamesRoomManager.class);
private UUID mainRoomId;
private UUID mainChatId;
private static final Logger logger = Logger.getLogger(GamesRoomManagerImpl.class);
GamesRoomManager() {
GamesRoom mainRoom = new GamesRoomImpl();
public GamesRoomManagerImpl(ManagerFactory managerFactory) {
this.managerFactory = managerFactory;
}
public void init() {
GamesRoom mainRoom = new GamesRoomImpl(managerFactory);
mainRoomId = mainRoom.getRoomId();
mainChatId = mainRoom.getChatId();
rooms.put(mainRoomId, mainRoom);
}
@Override
public UUID createRoom() {
GamesRoom room = new GamesRoomImpl();
GamesRoom room = new GamesRoomImpl(managerFactory);
rooms.put(room.getRoomId(), room);
return room.getRoomId();
}
@Override
public UUID getMainRoomId() {
return mainRoomId;
}
@Override
public UUID getMainChatId() {
return mainChatId;
}
@Override
public Optional<GamesRoom> getRoom(UUID roomId) {
if (rooms.containsKey(roomId)) {
return Optional.of(rooms.get(roomId));
@ -48,6 +58,7 @@ public enum GamesRoomManager {
}
@Override
public void removeTable(UUID tableId) {
for (GamesRoom room : rooms.values()) {
room.removeTable(tableId);

View file

@ -1,46 +1,56 @@
package mage.server.game;
import mage.server.managers.ReplayManager;
import mage.server.managers.ManagerFactory;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import mage.server.UserManager;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public enum ReplayManager {
instance;
public class ReplayManagerImpl implements ReplayManager {
private final ConcurrentHashMap<String, ReplaySession> replaySessions = new ConcurrentHashMap<>();
private final ManagerFactory managerFactory;
public void replayGame(UUID gameId, UUID userId) {
ReplaySession replaySession = new ReplaySession(gameId, userId);
replaySessions.put(gameId.toString() + userId.toString(), replaySession);
UserManager.instance.getUser(userId).ifPresent(user->user.ccReplayGame(gameId));
public ReplayManagerImpl(ManagerFactory managerFactory) {
this.managerFactory = managerFactory;
}
@Override
public void replayGame(UUID gameId, UUID userId) {
ReplaySession replaySession = new ReplaySession(managerFactory, gameId, userId);
replaySessions.put(gameId.toString() + userId.toString(), replaySession);
managerFactory.userManager().getUser(userId).ifPresent(user -> user.ccReplayGame(gameId));
}
@Override
public void startReplay(UUID gameId, UUID userId) {
replaySessions.get(gameId.toString() + userId.toString()).replay();
}
@Override
public void stopReplay(UUID gameId, UUID userId) {
replaySessions.get(gameId.toString() + userId.toString()).stop();
}
@Override
public void nextPlay(UUID gameId, UUID userId) {
replaySessions.get(gameId.toString() + userId.toString()).next();
}
@Override
public void previousPlay(UUID gameId, UUID userId) {
replaySessions.get(gameId.toString() + userId.toString()).previous();
}
@Override
public void skipForward(UUID gameId, UUID userId, int moves) {
replaySessions.get(gameId.toString() + userId.toString()).next(moves);
}
@Override
public void endReplay(UUID gameId, UUID userId) {
replaySessions.remove(gameId.toString() + userId.toString());
}

View file

@ -1,32 +1,32 @@
package mage.server.game;
import java.util.UUID;
import mage.game.Game;
import mage.game.GameState;
import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
import mage.server.UserManager;
import mage.server.managers.ManagerFactory;
import mage.view.GameView;
import java.util.UUID;
/**
* @author BetaSteward_at_googlemail.com
*/
public class ReplaySession implements GameCallback {
private final ManagerFactory managerFactory;
private final GameReplay replay;
protected final UUID userId;
ReplaySession(UUID gameId, UUID userId) {
ReplaySession(ManagerFactory managerFactory, UUID gameId, UUID userId) {
this.managerFactory = managerFactory;
this.replay = new GameReplay(gameId);
this.userId = userId;
}
public void replay() {
replay.start();
UserManager.instance.getUser(userId).ifPresent(user ->
managerFactory.userManager().getUser(userId).ifPresent(user ->
user.fireCallback(new ClientCallback(ClientCallbackMethod.REPLAY_INIT, replay.getGame().getId(), new GameView(replay.next(), replay.getGame(), null, null))));
}
@ -52,17 +52,17 @@ public class ReplaySession implements GameCallback {
@Override
public void gameResult(final String result) {
UserManager.instance.getUser(userId).ifPresent(user ->
managerFactory.userManager().getUser(userId).ifPresent(user ->
user.fireCallback(new ClientCallback(ClientCallbackMethod.REPLAY_DONE, replay.getGame().getId(), result)));
ReplayManager.instance.endReplay(replay.getGame().getId(), userId);
managerFactory.replayManager().endReplay(replay.getGame().getId(), userId);
}
private void updateGame(final GameState state, Game game) {
if (state == null) {
gameResult("game ended");
} else {
UserManager.instance.getUser(userId).ifPresent(user ->
managerFactory.userManager().getUser(userId).ifPresent(user ->
user.fireCallback(new ClientCallback(ClientCallbackMethod.REPLAY_UPDATE, replay.getGame().getId(), new GameView(state, game, null, null))));
}