forked from External/mage
Network upgrade and new reconnection mode: * users can disconnect or close app without game progress loose now; * disconnect dialog will show active tables stats and additional options; * all active tables will be restored on reconnect (tables, tourneys, games, drafts, sideboarding, constructing); * user must use same server and username on next connection; * there are few minutes for reconnect until server kick off a disconnected player from all player's tables (concede/loose); * now you can safety reconnect after IP change (after proxy/vpn/wifi/router restart); Other improvements and fixes: * gui: main menu - improved switch panel button, added stats about current tables/panels; * gui: improved data sync and updates (fixes many use cases with empty battlefield, not started games/drafts/tourneys, not updatable drafts, etc); * gui: improved stability on game updates (fixes some random errors related to wrong threads); * server: fixed miss messages about player's disconnection problems for other players in the chat; * refactor: simplified and improved connection and network related code, deleted outdated code, added docs; * tests: improved load test to support lands only set for more stable performance/network testing (set TEST_AI_RANDOM_DECK_SETS = PELP and run test_TwoAIPlayGame_Multiple);
155 lines
5.5 KiB
Java
155 lines
5.5 KiB
Java
package mage.server;
|
|
|
|
import mage.server.draft.DraftManagerImpl;
|
|
import mage.server.game.GameManagerImpl;
|
|
import mage.server.game.GamesRoomManagerImpl;
|
|
import mage.server.game.ReplayManagerImpl;
|
|
import mage.server.managers.*;
|
|
import mage.server.tournament.TournamentManagerImpl;
|
|
import mage.server.util.ThreadExecutorImpl;
|
|
import org.apache.log4j.Logger;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/**
|
|
* @author Burato, JayDi85
|
|
*/
|
|
public class MainManagerFactory implements ManagerFactory {
|
|
|
|
private final Logger logger = Logger.getLogger(MainManagerFactory.class);
|
|
|
|
// defines how often checking process should be run on server (in minutes)
|
|
// TODO: WARNING, it's can be very buggy but very rare (quit players for no reason, e.g. empty deck bug in sideboard)
|
|
// main reason - health code can run in the moment of game move from one stage to another (e.g. on sideboarding prepare)
|
|
// TODO: add debug menu like "call server health in 10 seconds"
|
|
// TODO: add debug menu like "call server side disconnect in 10 seconds"
|
|
// TODO: add debug menu like "call client side disconnect in 10 seconds"
|
|
private static final int SERVER_HEALTH_CHECK_TIMEOUT_MINS = 10;
|
|
|
|
private final ConfigSettings configSettings;
|
|
private final ThreadExecutor threadExecutor;
|
|
private final ChatManager chatManager;
|
|
private final DraftManager draftManager;
|
|
private final GameManager gameManager;
|
|
private final GamesRoomManager gamesRoomManager;
|
|
private final MailClient mailClient;
|
|
private final MailClient mailgunClient;
|
|
private final ReplayManager replayManager;
|
|
private final SessionManager sessionManager;
|
|
private final TableManager tableManager;
|
|
private final UserManager userManager;
|
|
private final TournamentManager tournamentManager;
|
|
|
|
public MainManagerFactory(ConfigSettings configSettings) {
|
|
this.configSettings = configSettings;
|
|
// ThreadExecutorImpl, MailClientImpl and MailGunClient depend only on the config, so they are initialised first
|
|
this.threadExecutor = new ThreadExecutorImpl(configSettings);
|
|
this.mailClient = new MailClientImpl(configSettings);
|
|
this.mailgunClient = new MailgunClientImpl(configSettings);
|
|
// Chat, Draft, Game, Replay, Session and Tournament managers only require access to the ManagerFactory
|
|
// but do not use them in initialisation
|
|
this.chatManager = new ChatManagerImpl(this);
|
|
this.draftManager = new DraftManagerImpl(this);
|
|
this.gameManager = new GameManagerImpl(this);
|
|
this.replayManager = new ReplayManagerImpl(this);
|
|
this.sessionManager = new SessionManagerImpl(this);
|
|
this.tournamentManager = new TournamentManagerImpl(this);
|
|
// GamesRoom, Table, User managers depend on the ManagerFactory and have an initialisation block which is delayed
|
|
// to the end of the construction
|
|
final GamesRoomManagerImpl gamesRoomManager = new GamesRoomManagerImpl(this);
|
|
final TableManagerImpl tableManager = new TableManagerImpl(this);
|
|
final UserManagerImpl userManager = new UserManagerImpl(this);
|
|
this.gamesRoomManager = gamesRoomManager;
|
|
this.tableManager = tableManager;
|
|
this.userManager = userManager;
|
|
|
|
// execute the initialisation block of the relevant manager (they start the executor services)
|
|
startThreads(gamesRoomManager, tableManager, userManager);
|
|
}
|
|
|
|
private void startThreads(GamesRoomManagerImpl gamesRoomManager, TableManagerImpl tableManager, UserManagerImpl userManager) {
|
|
userManager.init();
|
|
tableManager.init();
|
|
gamesRoomManager.init();
|
|
|
|
threadExecutor().getServerHealthExecutor().scheduleAtFixedRate(() -> {
|
|
try {
|
|
//logger.info("---");
|
|
//logger.info("Server health check started");
|
|
this.tableManager().checkHealth();
|
|
this.chatManager().checkHealth();
|
|
this.userManager().checkHealth();
|
|
this.sessionManager().checkHealth();
|
|
} catch (Exception ex) {
|
|
logger.fatal("Server health check: catch unknown error - " + ex, ex);
|
|
}
|
|
//logger.info("Server health check end");
|
|
//logger.info("---");
|
|
}, SERVER_HEALTH_CHECK_TIMEOUT_MINS, SERVER_HEALTH_CHECK_TIMEOUT_MINS, TimeUnit.MINUTES);
|
|
}
|
|
|
|
@Override
|
|
public ChatManager chatManager() {
|
|
return chatManager;
|
|
}
|
|
|
|
@Override
|
|
public DraftManager draftManager() {
|
|
return draftManager;
|
|
}
|
|
|
|
@Override
|
|
public GameManager gameManager() {
|
|
return gameManager;
|
|
}
|
|
|
|
@Override
|
|
public GamesRoomManager gamesRoomManager() {
|
|
return gamesRoomManager;
|
|
}
|
|
|
|
@Override
|
|
public MailClient mailClient() {
|
|
return mailClient;
|
|
}
|
|
|
|
@Override
|
|
public MailClient mailgunClient() {
|
|
return mailgunClient;
|
|
}
|
|
|
|
@Override
|
|
public ReplayManager replayManager() {
|
|
return replayManager;
|
|
}
|
|
|
|
@Override
|
|
public SessionManager sessionManager() {
|
|
return sessionManager;
|
|
}
|
|
|
|
@Override
|
|
public TableManager tableManager() {
|
|
return tableManager;
|
|
}
|
|
|
|
@Override
|
|
public UserManager userManager() {
|
|
return userManager;
|
|
}
|
|
|
|
@Override
|
|
public ConfigSettings configSettings() {
|
|
return configSettings;
|
|
}
|
|
|
|
@Override
|
|
public ThreadExecutor threadExecutor() {
|
|
return threadExecutor;
|
|
}
|
|
|
|
@Override
|
|
public TournamentManager tournamentManager() {
|
|
return tournamentManager;
|
|
}
|
|
}
|