diff --git a/Mage.Common/pom.xml b/Mage.Common/pom.xml
index d1e40dd02f..d922a77a10 100644
--- a/Mage.Common/pom.xml
+++ b/Mage.Common/pom.xml
@@ -56,6 +56,21 @@
gson
2.8.6
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+ org.apache.commons
+ commons-lang3
+ test
+
@@ -82,7 +97,10 @@
UTF-8
-
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
mage-common
diff --git a/Mage.Common/src/main/java/mage/utils/FluentBuilder.java b/Mage.Common/src/main/java/mage/utils/FluentBuilder.java
new file mode 100644
index 0000000000..003cd65167
--- /dev/null
+++ b/Mage.Common/src/main/java/mage/utils/FluentBuilder.java
@@ -0,0 +1,41 @@
+package mage.utils;
+
+import java.util.ArrayList;
+import java.util.function.Consumer;
+import java.util.function.Supplier;
+
+/**
+ * A base class for fluent, immutable, composable builders.
+ *
+ * @see Builder
+ */
+public abstract class FluentBuilder> {
+
+ final ArrayList> buildSequence;
+ private final Supplier newReference;
+
+ protected FluentBuilder(Supplier newReference) {
+ this.buildSequence = new ArrayList<>();
+ this.newReference = newReference;
+ }
+
+ private RealBuilder copy() {
+ final RealBuilder realBuilder = newReference.get();
+ realBuilder.buildSequence.addAll(buildSequence);
+ return realBuilder;
+ }
+
+ protected abstract ToBuild makeValue();
+
+ public RealBuilder with(Consumer consumer) {
+ final RealBuilder nextBuilder = this.copy();
+ nextBuilder.buildSequence.add(consumer);
+ return nextBuilder;
+ }
+
+ public ToBuild build() {
+ final RealBuilder instance = this.copy();
+ instance.buildSequence.forEach(c -> c.accept(instance));
+ return instance.makeValue();
+ }
+}
diff --git a/Mage.Common/src/test/java/mage/remote/ConnectionTest.java b/Mage.Common/src/test/java/mage/remote/ConnectionTest.java
new file mode 100644
index 0000000000..1e49ed9c37
--- /dev/null
+++ b/Mage.Common/src/test/java/mage/remote/ConnectionTest.java
@@ -0,0 +1,123 @@
+package mage.remote;
+
+import mage.utils.FluentBuilder;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.apache.commons.lang3.RandomUtils;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import java.net.URI;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ConnectionTest {
+
+ static class ConnectionBuilder extends FluentBuilder {
+
+ public int port;
+ public String host;
+ public String parameter;
+
+ private ConnectionBuilder() {
+ super(ConnectionBuilder::new);
+ }
+
+ @Override
+ protected Connection makeValue() {
+ final Connection result = new Connection(parameter);
+ result.setHost(host);
+ result.setPort(port);
+ return result;
+ }
+ }
+
+ private ConnectionBuilder baseBuilder() {
+ return new ConnectionBuilder();
+ }
+
+ class TestsTemplate {
+ final ConnectionBuilder testeeBuilder;
+
+ TestsTemplate(ConnectionBuilder testeeBuilder) {
+ this.testeeBuilder = testeeBuilder;
+ }
+
+ @Test
+ @DisplayName("produce the expected scheme")
+ void scheme() throws Exception {
+ final URI testee = make(testeeBuilder);
+ assertThat(testee.getScheme()).isEqualTo("bisocket");
+ }
+
+ URI make(ConnectionBuilder builder) {
+ try {
+ return new URI(builder.build().getURI());
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Test
+ @DisplayName("generate the expected port")
+ void port() {
+ final int expected = RandomUtils.nextInt(1000, 65000);
+ final int port = make(testeeBuilder.with(c -> c.port = expected)).getPort();
+
+ assertThat(port).isEqualTo(expected);
+ }
+
+ @Test
+ @DisplayName("generate the expected serialisation parameter")
+ void serialisation() {
+ final String query = make(testeeBuilder).getQuery();
+
+ assertThat(query).contains("serializationtype=jboss");
+ }
+
+ @Test
+ @DisplayName("generate the expected threadpool parameter")
+ void threadpool() {
+ final String parameter = RandomStringUtils.randomAlphanumeric(12);
+ final String query = make(testeeBuilder.with(c -> c.parameter = parameter)).getQuery();
+
+ assertThat(query).contains("onewayThreadPool=mage.remote.CustomThreadPool" + parameter);
+ }
+
+ }
+
+ @Nested
+ @DisplayName("getUri when host is localhost should")
+ class LocalhostTest extends TestsTemplate {
+
+ LocalhostTest() {
+ super(baseBuilder().with(c -> c.host = "localhost"));
+ }
+
+ @Test
+ @DisplayName("generate an ipv4 as host")
+ void ipv4Gen() {
+ final String host = make(testeeBuilder).getHost();
+
+ assertThat(host).matches("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+");
+ }
+ }
+
+ private final String randomHost = RandomStringUtils.randomAlphabetic(15);
+
+ @Nested
+ @DisplayName("getUri when host is not localhost should")
+ class StandardHostTest extends TestsTemplate {
+ StandardHostTest() {
+ super(baseBuilder().with(c -> c.host = randomHost));
+ }
+
+ @Test
+ @DisplayName("generate the selected host as host")
+ void hostGen() {
+ final String host = make(testeeBuilder).getHost();
+
+ assertThat(host).isEqualTo(randomHost);
+ }
+ }
+}
diff --git a/Mage.Common/src/test/java/mage/utils/FluentBuilderTest.java b/Mage.Common/src/test/java/mage/utils/FluentBuilderTest.java
new file mode 100644
index 0000000000..180f82ef20
--- /dev/null
+++ b/Mage.Common/src/test/java/mage/utils/FluentBuilderTest.java
@@ -0,0 +1,116 @@
+package mage.utils;
+
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
+
+public class FluentBuilderTest {
+
+
+ private ABuilder baseBuilder() {
+ return new ABuilder();
+ }
+
+ @Test
+ @DisplayName("build with default parameters")
+ void testDefault() {
+ final A actual = baseBuilder().build();
+
+ verifyAB(actual, null, 0);
+ }
+
+ private void verifyAB(A actual, String a, int b) {
+ assertThat(actual.getA()).isEqualTo(a);
+ assertThat(actual.getB()).isEqualTo(b);
+ }
+
+ @Test
+ @DisplayName("chain with clause and add new parameters")
+ void testBaseChain() {
+ final A actual = baseBuilder().with(a -> a.a = "hello").build();
+
+ verifyAB(actual, "hello", 0);
+ }
+
+ @Test
+ @DisplayName("chain multiple with clauses and add new parameters")
+ void testMultiChain() {
+ final A actual = baseBuilder().with(a -> a.a = "world").with(a -> a.b = 6).build();
+
+ verifyAB(actual, "world", 6);
+ }
+
+ @Test
+ @DisplayName("chain multiple with clauses and override latest writes")
+ void testMultiChainOverride() {
+ final A actual = baseBuilder().with(a -> a.a = "world").with(a -> a.b = 4).with(a -> a.a = "foobar").build();
+
+ verifyAB(actual, "foobar", 4);
+ }
+
+ @Test
+ @DisplayName("not mutate the state of previous builder in the chain")
+ void testImmutability() {
+ final ABuilder builder1 = baseBuilder().with(a -> a.a = "world");
+ final ABuilder builder2 = builder1.with(a -> {
+ a.a = "hello";
+ a.b = 42;
+ });
+
+ verifyAB(builder1.build(), "world", 0);
+ verifyAB(builder2.build(), "hello", 42);
+ }
+
+ @Test
+ @DisplayName("produce different objects")
+ void differentObjects() {
+ final ABuilder builder = baseBuilder().with(a -> {
+ a.a = "hello";
+ a.b = 42;
+ });
+ final A a1 = builder.build();
+ final A a2 = builder.build();
+
+ assertThat(a1).isNotSameAs(a2);
+ verifyAB(a1, "hello", 42);
+ verifyAB(a2, "hello", 42);
+ }
+
+ static class A {
+ public final String a;
+ private int b;
+
+ public A(String a) {
+ this.a = a;
+ }
+
+ public String getA() {
+ return a;
+ }
+
+ public int getB() {
+ return b;
+ }
+
+ public void setB(int b) {
+ this.b = b;
+ }
+ }
+
+ static class ABuilder extends FluentBuilder {
+ public String a;
+ public int b;
+
+ private ABuilder() {
+ super(ABuilder::new);
+ }
+
+ @Override
+ protected A makeValue() {
+ final A result = new A(a);
+ result.setB(b);
+ return result;
+ }
+ }
+}
diff --git a/Mage.Server/pom.xml b/Mage.Server/pom.xml
index 880c89e6ec..3f3f2c23f8 100644
--- a/Mage.Server/pom.xml
+++ b/Mage.Server/pom.xml
@@ -285,6 +285,18 @@
sqlite-jdbc
3.32.3.2
+
+
+
+ org.junit.jupiter
+ junit-jupiter
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
@@ -358,6 +370,10 @@
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
mage-server
diff --git a/Mage.Server/src/main/java/mage/server/ChatManager.java b/Mage.Server/src/main/java/mage/server/ChatManagerImpl.java
similarity index 89%
rename from Mage.Server/src/main/java/mage/server/ChatManager.java
rename to Mage.Server/src/main/java/mage/server/ChatManagerImpl.java
index 3ff8600963..1bd283e03e 100644
--- a/Mage.Server/src/main/java/mage/server/ChatManager.java
+++ b/Mage.Server/src/main/java/mage/server/ChatManagerImpl.java
@@ -5,8 +5,8 @@ import mage.cards.repository.CardRepository;
import mage.game.Game;
import mage.server.exceptions.UserNotFoundException;
import mage.server.game.GameController;
-import mage.server.game.GameManager;
-import mage.server.game.GamesRoomManager;
+import mage.server.managers.ChatManager;
+import mage.server.managers.ManagerFactory;
import mage.server.util.SystemUtil;
import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType;
@@ -26,21 +26,27 @@ import java.util.stream.Collectors;
/**
* @author BetaSteward_at_googlemail.com
*/
-public enum ChatManager {
+public class ChatManagerImpl implements ChatManager {
- instance;
- private static final Logger logger = Logger.getLogger(ChatManager.class);
+ private static final Logger logger = Logger.getLogger(ChatManagerImpl.class);
private static final HashMap userMessages = new HashMap<>();
+ private final ManagerFactory managerFactory;
private final ConcurrentHashMap chatSessions = new ConcurrentHashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
+ public ChatManagerImpl(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
+ @Override
public UUID createChatSession(String info) {
- ChatSession chatSession = new ChatSession(info);
+ ChatSession chatSession = new ChatSession(managerFactory, info);
chatSessions.put(chatSession.getChatId(), chatSession);
return chatSession.getChatId();
}
+ @Override
public void joinChat(UUID chatId, UUID userId) {
ChatSession chatSession = chatSessions.get(chatId);
if (chatSession != null) {
@@ -51,10 +57,12 @@ public enum ChatManager {
}
+ @Override
public void clearUserMessageStorage() {
userMessages.clear();
}
+ @Override
public void leaveChat(UUID chatId, UUID userId) {
ChatSession chatSession = chatSessions.get(chatId);
if (chatSession != null && chatSession.hasUser(userId)) {
@@ -62,6 +70,7 @@ public enum ChatManager {
}
}
+ @Override
public void destroyChatSession(UUID chatId) {
if (chatId != null) {
ChatSession chatSession = chatSessions.get(chatId);
@@ -84,11 +93,12 @@ public enum ChatManager {
final Pattern cardNamePattern = Pattern.compile("\\[(.*?)\\]");
+ @Override
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime, Game game, MessageType messageType, SoundToPlay soundToPlay) {
ChatSession chatSession = chatSessions.get(chatId);
if (chatSession != null) {
if (message.startsWith("\\") || message.startsWith("/")) {
- Optional user = UserManager.instance.getUserByName(userName);
+ Optional user = managerFactory.userManager().getUserByName(userName);
if (user.isPresent()) {
if (!performUserCommand(user.get(), message, chatId, false)) {
performUserCommand(user.get(), message, chatId, true);
@@ -98,7 +108,7 @@ public enum ChatManager {
}
if (messageType != MessageType.GAME && !userName.isEmpty()) {
- Optional u = UserManager.instance.getUserByName(userName);
+ Optional u = managerFactory.userManager().getUserByName(userName);
if (u.isPresent()) {
User user = u.get();
@@ -184,12 +194,12 @@ public enum ChatManager {
}
if (command.startsWith("H ") || command.startsWith("HISTORY ")) {
- message += "
" + UserManager.instance.getUserHistory(message.substring(command.startsWith("H ") ? 3 : 9));
+ message += "
" + managerFactory.userManager().getUserHistory(message.substring(command.startsWith("H ") ? 3 : 9));
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}
if (command.equals("ME")) {
- message += "
" + UserManager.instance.getUserHistory(user.getName());
+ message += "
" + managerFactory.userManager().getUserHistory(user.getName());
chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true;
}
@@ -200,7 +210,7 @@ public enum ChatManager {
String gameId = session.getInfo();
if (gameId.startsWith("Game ")) {
UUID id = java.util.UUID.fromString(gameId.substring(5));
- for (Entry entry : GameManager.instance.getGameController().entrySet()) {
+ for (Entry entry : managerFactory.gameManager().getGameController().entrySet()) {
if (entry.getKey().equals(id)) {
GameController controller = entry.getValue();
if (controller != null) {
@@ -221,7 +231,7 @@ public enum ChatManager {
String gameId = session.getInfo();
if (gameId.startsWith("Game ")) {
UUID id = java.util.UUID.fromString(gameId.substring(5));
- for (Entry entry : GameManager.instance.getGameController().entrySet()) {
+ for (Entry entry : managerFactory.gameManager().getGameController().entrySet()) {
if (entry.getKey().equals(id)) {
GameController controller = entry.getValue();
if (controller != null) {
@@ -242,7 +252,7 @@ public enum ChatManager {
String gameId = session.getInfo();
if (gameId.startsWith("Game ")) {
UUID id = java.util.UUID.fromString(gameId.substring(5));
- for (Entry entry : GameManager.instance.getGameController().entrySet()) {
+ for (Entry entry : managerFactory.gameManager().getGameController().entrySet()) {
if (entry.getKey().equals(id)) {
GameController controller = entry.getValue();
if (controller != null) {
@@ -281,7 +291,7 @@ public enum ChatManager {
if (first > 1) {
String userToName = rest.substring(0, first);
rest = rest.substring(first + 1).trim();
- Optional userTo = UserManager.instance.getUserByName(userToName);
+ Optional userTo = managerFactory.userManager().getUserByName(userToName);
if (userTo.isPresent()) {
if (!chatSessions.get(chatId).broadcastWhisperToUser(user, userTo.get(), rest)) {
message += new StringBuilder("
User ").append(userToName).append(" not found").toString();
@@ -312,8 +322,9 @@ public enum ChatManager {
* @param color
* @throws mage.server.exceptions.UserNotFoundException
*/
+ @Override
public void broadcast(UUID userId, String message, MessageColor color) throws UserNotFoundException {
- UserManager.instance.getUser(userId).ifPresent(user -> {
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
getChatSessions()
.stream()
.filter(chat -> chat.hasUser(userId))
@@ -322,8 +333,9 @@ public enum ChatManager {
});
}
+ @Override
public void sendReconnectMessage(UUID userId) {
- UserManager.instance.getUser(userId).ifPresent(user
+ managerFactory.userManager().getUser(userId).ifPresent(user
-> getChatSessions()
.stream()
.filter(chat -> chat.hasUser(userId))
@@ -331,8 +343,9 @@ public enum ChatManager {
}
+ @Override
public void sendLostConnectionMessage(UUID userId, DisconnectReason reason) {
- UserManager.instance.getUser(userId).ifPresent(user -> sendMessageToUserChats(userId, user.getName() + " " + reason.getMessage()));
+ managerFactory.userManager().getUser(userId).ifPresent(user -> sendMessageToUserChats(userId, user.getName() + " " + reason.getMessage()));
}
/**
@@ -341,10 +354,11 @@ public enum ChatManager {
* @param userId
* @param message
*/
+ @Override
public void sendMessageToUserChats(UUID userId, String message) {
- UserManager.instance.getUser(userId).ifPresent(user -> {
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
List chatSessions = getChatSessions().stream()
- .filter(chat -> !chat.getChatId().equals(GamesRoomManager.instance.getMainChatId())) // ignore main lobby
+ .filter(chat -> !chat.getChatId().equals(managerFactory.gamesRoomManager().getMainChatId())) // ignore main lobby
.filter(chat -> chat.hasUser(userId))
.collect(Collectors.toList());
@@ -355,6 +369,7 @@ public enum ChatManager {
});
}
+ @Override
public void removeUser(UUID userId, DisconnectReason reason) {
for (ChatSession chatSession : getChatSessions()) {
if (chatSession.hasUser(userId)) {
@@ -363,6 +378,7 @@ public enum ChatManager {
}
}
+ @Override
public List getChatSessions() {
final Lock r = lock.readLock();
r.lock();
diff --git a/Mage.Server/src/main/java/mage/server/ChatSession.java b/Mage.Server/src/main/java/mage/server/ChatSession.java
index fad1424573..73ffa28fe7 100644
--- a/Mage.Server/src/main/java/mage/server/ChatSession.java
+++ b/Mage.Server/src/main/java/mage/server/ChatSession.java
@@ -3,6 +3,7 @@ package mage.server;
import mage.game.Game;
import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
+import mage.server.managers.ManagerFactory;
import mage.view.ChatMessage;
import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType;
@@ -25,6 +26,7 @@ public class ChatSession {
private static final Logger logger = Logger.getLogger(ChatSession.class);
private static final DateFormat timeFormatter = DateFormat.getTimeInstance(DateFormat.SHORT);
+ private final ManagerFactory managerFactory;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final ConcurrentMap clients = new ConcurrentHashMap<>();
@@ -32,14 +34,15 @@ public class ChatSession {
private final Date createTime;
private final String info;
- public ChatSession(String info) {
+ public ChatSession(ManagerFactory managerFactory, String info) {
+ this.managerFactory = managerFactory;
chatId = UUID.randomUUID();
this.createTime = new Date();
this.info = info;
}
public void join(UUID userId) {
- UserManager.instance.getUser(userId).ifPresent(user -> {
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
if (!clients.containsKey(userId)) {
String userName = user.getName();
final Lock w = lock.writeLock();
@@ -121,7 +124,7 @@ public class ChatSession {
r.unlock();
}
for (UUID userId : chatUserIds) {
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = managerFactory.userManager().getUser(userId);
if (user.isPresent()) {
user.get().fireCallback(clientCallback);
} else {
diff --git a/Mage.Server/src/main/java/mage/server/GmailClient.java b/Mage.Server/src/main/java/mage/server/GmailClient.java
deleted file mode 100644
index a091ede4d4..0000000000
--- a/Mage.Server/src/main/java/mage/server/GmailClient.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package mage.server;
-
-import com.google.api.client.auth.oauth2.Credential;
-import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
-import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
-import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
-import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
-import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
-import com.google.api.client.http.HttpTransport;
-import com.google.api.client.json.JsonFactory;
-import com.google.api.client.json.jackson2.JacksonFactory;
-import com.google.api.client.util.Base64;
-import com.google.api.client.util.store.FileDataStoreFactory;
-import com.google.api.services.gmail.Gmail;
-import com.google.api.services.gmail.Gmail.Builder;
-import com.google.api.services.gmail.GmailScopes;
-import com.google.api.services.gmail.model.Message;
-import java.io.ByteArrayOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
-import java.util.Collections;
-import java.util.Properties;
-import javax.mail.MessagingException;
-import javax.mail.Session;
-import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeMessage;
-import mage.server.util.ConfigSettings;
-import org.apache.log4j.Logger;
-
-public final class GmailClient {
-
- private static final Logger logger = Logger.getLogger(Main.class);
- private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
- private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".store/xmage");
- private static FileDataStoreFactory dataStoreFactory;
- private static HttpTransport httpTransport;
- private static Credential credential;
-
- public static boolean initilize() {
- try {
- dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
- httpTransport = GoogleNetHttpTransport.newTrustedTransport();
-
- GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new FileReader("client_secrets.json"));
- if (clientSecrets.getDetails().getClientId().startsWith("Enter")
- || clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
- logger.error("client_secrets.json not found");
- return false;
- }
-
- GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
- httpTransport, JSON_FACTORY, clientSecrets,
- Collections.singleton(GmailScopes.GMAIL_COMPOSE)).setDataStoreFactory(
- dataStoreFactory).build();
-
- credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
- return true;
- } catch (IOException | GeneralSecurityException ex) {
- logger.error("Error initializing GmailClient", ex);
- }
- return false;
- }
-
- public static boolean sendMessage(String email, String subject, String text) {
- if (email.isEmpty()) {
- logger.info("Email is not sent because the address is empty");
- return false;
- }
- try {
- Gmail gmail = new Builder(httpTransport, JSON_FACTORY, credential).setApplicationName("XMage Server").build();
-
- MimeMessage mimeMessage = new MimeMessage(Session.getDefaultInstance(new Properties()));
- mimeMessage.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(email));
- mimeMessage.setSubject(subject);
- mimeMessage.setText(text);
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- mimeMessage.writeTo(baos);
- Message message = new Message();
- message.setRaw(Base64.encodeBase64URLSafeString(baos.toByteArray()));
-
- gmail.users().messages().send(ConfigSettings.instance.getGoogleAccount()
- + (ConfigSettings.instance.getGoogleAccount().endsWith("@gmail.com") ? "" : "@gmail.com"), message).execute();
- return true;
- } catch (MessagingException | IOException ex) {
- logger.error("Error sending message", ex);
- }
- return false;
- }
-}
diff --git a/Mage.Server/src/main/java/mage/server/MageServerImpl.java b/Mage.Server/src/main/java/mage/server/MageServerImpl.java
index e668311ac7..ed545b6467 100644
--- a/Mage.Server/src/main/java/mage/server/MageServerImpl.java
+++ b/Mage.Server/src/main/java/mage/server/MageServerImpl.java
@@ -23,15 +23,14 @@ import mage.players.PlayerType;
import mage.players.net.UserData;
import mage.remote.MageVersionException;
import mage.server.draft.CubeFactory;
-import mage.server.draft.DraftManager;
-import mage.server.game.*;
+import mage.server.game.GameFactory;
+import mage.server.game.GamesRoom;
+import mage.server.game.PlayerFactory;
+import mage.server.managers.ManagerFactory;
import mage.server.services.impl.FeedbackServiceImpl;
import mage.server.tournament.TournamentFactory;
-import mage.server.tournament.TournamentManager;
-import mage.server.util.ConfigSettings;
import mage.server.util.ServerMessagesUtil;
import mage.server.util.SystemUtil;
-import mage.server.util.ThreadExecutor;
import mage.utils.*;
import mage.view.*;
import mage.view.ChatMessage.MessageColor;
@@ -49,9 +48,10 @@ import java.util.concurrent.ExecutorService;
public class MageServerImpl implements MageServer {
private static final Logger logger = Logger.getLogger(MageServerImpl.class);
- private static final ExecutorService callExecutor = ThreadExecutor.instance.getCallExecutor();
+ private final ExecutorService callExecutor;
private static final SecureRandom RANDOM = new SecureRandom();
+ private final ManagerFactory managerFactory;
private final String adminPassword;
private final boolean testMode;
private final LinkedHashMap activeAuthTokens = new LinkedHashMap() {
@@ -62,15 +62,17 @@ public class MageServerImpl implements MageServer {
}
};
- public MageServerImpl(String adminPassword, boolean testMode) {
+ public MageServerImpl(ManagerFactory managerFactory, String adminPassword, boolean testMode) {
+ this.managerFactory = managerFactory;
this.adminPassword = adminPassword;
this.testMode = testMode;
+ this.callExecutor = managerFactory.threadExecutor().getCallExecutor();
ServerMessagesUtil.instance.getMessages();
}
@Override
public boolean registerUser(String sessionId, String userName, String password, String email) throws MageException {
- return SessionManager.instance.registerUser(sessionId, userName, password, email);
+ return managerFactory.sessionManager().registerUser(sessionId, userName, password, email);
}
// generateAuthToken returns a uniformly distributed 6-digits string.
@@ -80,7 +82,7 @@ public class MageServerImpl implements MageServer {
@Override
public boolean emailAuthToken(String sessionId, String email) throws MageException {
- if (!ConfigSettings.instance.isAuthenticationActivated()) {
+ if (!managerFactory.configSettings().isAuthenticationActivated()) {
sendErrorMessageToClient(sessionId, "Registration is disabled by the server config");
return false;
}
@@ -96,10 +98,10 @@ public class MageServerImpl implements MageServer {
String text = "Use this auth token to reset " + authorizedUser.name + "'s password: " + authToken + '\n'
+ "It's valid until the next server restart.";
boolean success;
- if (!ConfigSettings.instance.getMailUser().isEmpty()) {
- success = MailClient.sendMessage(email, subject, text);
+ if (!managerFactory.configSettings().getMailUser().isEmpty()) {
+ success = managerFactory.mailClient().sendMessage(email, subject, text);
} else {
- success = MailgunClient.sendMessage(email, subject, text);
+ success = managerFactory.mailgunClient().sendMessage(email, subject, text);
}
if (!success) {
sendErrorMessageToClient(sessionId, "There was an error inside the server while emailing an auth token");
@@ -110,7 +112,7 @@ public class MageServerImpl implements MageServer {
@Override
public boolean resetPassword(String sessionId, String email, String authToken, String password) throws MageException {
- if (!ConfigSettings.instance.isAuthenticationActivated()) {
+ if (!managerFactory.configSettings().isAuthenticationActivated()) {
sendErrorMessageToClient(sessionId, "Registration is disabled by the server config");
return false;
}
@@ -139,7 +141,7 @@ public class MageServerImpl implements MageServer {
logger.info("MageVersionException: userName=" + userName + ", version=" + version + " sessionId=" + sessionId);
throw new MageVersionException(version, Main.getVersion());
}
- return SessionManager.instance.connectUser(sessionId, userName, password, userIdStr);
+ return managerFactory.sessionManager().connectUser(sessionId, userName, password, userIdStr);
} catch (MageException ex) {
if (ex instanceof MageVersionException) {
throw ex;
@@ -154,7 +156,7 @@ public class MageServerImpl implements MageServer {
return executeWithResult("setUserData", sessionId, new ActionWithBooleanResult() {
@Override
public Boolean execute() throws MageException {
- return SessionManager.instance.setUserData(userName, sessionId, userData, clientVersion, userIdStr);
+ return managerFactory.sessionManager().setUserData(userName, sessionId, userData, clientVersion, userIdStr);
}
});
}
@@ -168,7 +170,7 @@ public class MageServerImpl implements MageServer {
if (!adminPassword.equals(this.adminPassword)) {
throw new MageException("Wrong password");
}
- return SessionManager.instance.connectAdmin(sessionId);
+ return managerFactory.sessionManager().connectAdmin(sessionId);
} catch (Exception ex) {
handleException(ex);
}
@@ -186,13 +188,13 @@ public class MageServerImpl implements MageServer {
@Override
public TableView execute() throws MageException {
try {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session to found : " + sessionId);
return null;
}
UUID userId = session.get().getUserId();
- Optional _user = UserManager.instance.getUser(userId);
+ Optional _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
logger.error("User for session not found. session = " + sessionId);
return null;
@@ -205,7 +207,7 @@ public class MageServerImpl implements MageServer {
throw new MageException("No message");
}
// check AI players max
- String maxAiOpponents = ConfigSettings.instance.getMaxAiOpponents();
+ String maxAiOpponents = managerFactory.configSettings().getMaxAiOpponents();
if (maxAiOpponents != null) {
int aiPlayers = 0;
for (PlayerType playerType : options.getPlayerTypes()) {
@@ -241,7 +243,7 @@ public class MageServerImpl implements MageServer {
user.showUserMessage("Create tournament", message);
throw new MageException("No message");
}
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
if (!room.isPresent()) {
} else {
@@ -260,9 +262,9 @@ public class MageServerImpl implements MageServer {
@Override
public void removeTable(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
execute("removeTable", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- TableManager.instance.removeTable(userId, tableId);
+ managerFactory.tableManager().removeTable(userId, tableId);
});
});
}
@@ -272,7 +274,7 @@ public class MageServerImpl implements MageServer {
return executeWithResult("joinTable", sessionId, new ActionWithBooleanResult() {
@Override
public Boolean execute() throws MageException {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
return false;
}
@@ -282,7 +284,7 @@ public class MageServerImpl implements MageServer {
logger.fatal("Got no userId from sessionId" + sessionId + " tableId" + tableId);
return false;
}
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
if (!room.isPresent()) {
return false;
}
@@ -297,20 +299,20 @@ public class MageServerImpl implements MageServer {
return executeWithResult("joinTournamentTable", sessionId, new ActionWithBooleanResult() {
@Override
public Boolean execute() throws MageException {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
return false;
}
UUID userId = session.get().getUserId();
if (logger.isTraceEnabled()) {
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = managerFactory.userManager().getUser(userId);
user.ifPresent(user1 -> logger.trace("join tourn. tableId: " + tableId + ' ' + name));
}
if (userId == null) {
logger.fatal("Got no userId from sessionId" + sessionId + " tableId" + tableId);
return false;
}
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
if (room.isPresent()) {
return room.get().joinTournamentTable(userId, tableId, name, playerType, skill, deckList, password);
}
@@ -325,12 +327,12 @@ public class MageServerImpl implements MageServer {
return executeWithResult("submitDeck", sessionId, new ActionWithBooleanResult() {
@Override
public Boolean execute() throws MageException {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
return false;
} else {
UUID userId = session.get().getUserId();
- boolean ret = TableManager.instance.submitDeck(userId, tableId, deckList);
+ boolean ret = managerFactory.tableManager().submitDeck(userId, tableId, deckList);
logger.debug("Session " + sessionId + " submitted deck");
return ret;
}
@@ -341,13 +343,13 @@ public class MageServerImpl implements MageServer {
@Override
public void updateDeck(final String sessionId, final UUID tableId, final DeckCardLists deckList) throws MageException {
execute("updateDeck", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- TableManager.instance.updateDeck(userId, tableId, deckList);
+ managerFactory.tableManager().updateDeck(userId, tableId, deckList);
logger.trace("Session " + sessionId + " updated deck");
}
});
@@ -357,7 +359,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public List getTables(UUID roomId) throws MageException {
try {
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
if (room.isPresent()) {
return room.get().getTables();
} else {
@@ -373,7 +375,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public List getFinishedMatches(UUID roomId) throws MageException {
try {
- return GamesRoomManager.instance.getRoom(roomId).map(GamesRoom::getFinished).orElse(new ArrayList<>());
+ return managerFactory.gamesRoomManager().getRoom(roomId).map(GamesRoom::getFinished).orElse(new ArrayList<>());
} catch (Exception ex) {
handleException(ex);
}
@@ -383,7 +385,7 @@ public class MageServerImpl implements MageServer {
@Override
public List getRoomUsers(UUID roomId) throws MageException {
try {
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
if (room.isPresent()) {
return room.get().getRoomUsersInfo();
} else {
@@ -399,7 +401,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public TableView getTable(UUID roomId, UUID tableId) throws MageException {
try {
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
return room.flatMap(r -> r.getTable(tableId)).orElse(null);
} catch (Exception ex) {
@@ -410,22 +412,12 @@ public class MageServerImpl implements MageServer {
@Override
public boolean ping(String sessionId, String pingInfo) {
- return SessionManager.instance.extendUserSession(sessionId, pingInfo);
+ return managerFactory.sessionManager().extendUserSession(sessionId, pingInfo);
}
- // @Override
-// public void deregisterClient(final String sessionId) throws MageException {
-// execute("deregisterClient", sessionId, new Action() {
-// @Override
-// public void execute() {
-// SessionManager.instance.disconnect(sessionId, true);
-// logger.debug("Client deregistered ...");
-// }
-// });
-// }
@Override
public boolean startMatch(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
- Optional controller = TableManager.instance.getController(tableId);
+ Optional controller = managerFactory.tableManager().getController(tableId);
if (!controller.isPresent()) {
logger.error("table not found : " + tableId);
return false;
@@ -434,30 +426,20 @@ public class MageServerImpl implements MageServer {
return false;
}
execute("startMatch", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- TableManager.instance.startMatch(userId, roomId, tableId);
+ managerFactory.tableManager().startMatch(userId, roomId, tableId);
}
});
return true;
}
- // @Override
-// public void startChallenge(final String sessionId, final UUID roomId, final UUID tableId, final UUID challengeId) throws MageException {
-// execute("startChallenge", sessionId, new Action() {
-// @Override
-// public void execute() {
-// UUID userId = SessionManager.instance.getSession(sessionId).getUserId();
-// TableManager.instance.startChallenge(userId, roomId, tableId, challengeId);
-// }
-// });
-// }
@Override
public boolean startTournament(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
- Optional controller = TableManager.instance.getController(tableId);
+ Optional controller = managerFactory.tableManager().getController(tableId);
if (!controller.isPresent()) {
logger.error("table not found : " + tableId);
return false;
@@ -466,12 +448,12 @@ public class MageServerImpl implements MageServer {
return false;
}
execute("startTournament", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- TableManager.instance.startTournament(userId, roomId, tableId);
+ managerFactory.tableManager().startTournament(userId, roomId, tableId);
}
});
return true;
@@ -481,7 +463,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public TournamentView getTournament(UUID tournamentId) throws MageException {
try {
- return TournamentManager.instance.getTournamentView(tournamentId);
+ return managerFactory.tournamentManager().getTournamentView(tournamentId);
} catch (Exception ex) {
handleException(ex);
}
@@ -493,7 +475,7 @@ public class MageServerImpl implements MageServer {
public void sendChatMessage(final UUID chatId, final String userName, final String message) throws MageException {
try {
callExecutor.execute(
- () -> ChatManager.instance.broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE, true, null, ChatMessage.MessageType.TALK, null)
+ () -> managerFactory.chatManager().broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE, true, null, ChatMessage.MessageType.TALK, null)
);
} catch (Exception ex) {
handleException(ex);
@@ -503,10 +485,10 @@ public class MageServerImpl implements MageServer {
@Override
public void joinChat(final UUID chatId, final String sessionId, final String userName) throws MageException {
execute("joinChat", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- ChatManager.instance.joinChat(chatId, userId);
+ managerFactory.chatManager().joinChat(chatId, userId);
});
});
}
@@ -515,9 +497,9 @@ public class MageServerImpl implements MageServer {
public void leaveChat(final UUID chatId, final String sessionId) throws MageException {
execute("leaveChat", sessionId, () -> {
if (chatId != null) {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- ChatManager.instance.leaveChat(chatId, userId);
+ managerFactory.chatManager().leaveChat(chatId, userId);
});
}
});
@@ -527,7 +509,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public UUID getMainRoomId() throws MageException {
try {
- return GamesRoomManager.instance.getMainRoomId();
+ return managerFactory.gamesRoomManager().getMainRoomId();
} catch (Exception ex) {
handleException(ex);
}
@@ -538,7 +520,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public UUID getRoomChatId(UUID roomId) throws MageException {
try {
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
if (!room.isPresent()) {
logger.error("roomId not found : " + roomId);
return null;
@@ -555,12 +537,12 @@ public class MageServerImpl implements MageServer {
return executeWithResult("isTableOwner", sessionId, new ActionWithBooleanResult() {
@Override
public Boolean execute() {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
return false;
} else {
UUID userId = session.get().getUserId();
- return TableManager.instance.isTableOwner(tableId, userId);
+ return managerFactory.tableManager().isTableOwner(tableId, userId);
}
}
});
@@ -569,16 +551,16 @@ public class MageServerImpl implements MageServer {
@Override
public void swapSeats(final String sessionId, final UUID roomId, final UUID tableId, final int seatNum1, final int seatNum2) throws MageException {
execute("swapSeats", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- TableManager.instance.swapSeats(tableId, userId, seatNum1, seatNum2);
+ managerFactory.tableManager().swapSeats(tableId, userId, seatNum1, seatNum2);
});
});
}
@Override
public boolean leaveTable(final String sessionId, final UUID roomId, final UUID tableId) throws MageException {
- Optional tableController = TableManager.instance.getController(tableId);
+ Optional tableController = managerFactory.tableManager().getController(tableId);
if (tableController.isPresent()) {
TableState tableState = tableController.get().getTableState();
if (tableState != TableState.WAITING && tableState != TableState.READY_TO_START) {
@@ -586,9 +568,9 @@ public class MageServerImpl implements MageServer {
return false;
}
execute("leaveTable", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- GamesRoomManager.instance.getRoom(roomId).ifPresent(room ->
+ managerFactory.gamesRoomManager().getRoom(roomId).ifPresent(room ->
room.leaveTable(userId, tableId));
});
@@ -604,7 +586,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public UUID getTableChatId(UUID tableId) throws MageException {
try {
- return TableManager.instance.getChatId(tableId).orElse(null);
+ return managerFactory.tableManager().getChatId(tableId).orElse(null);
} catch (Exception ex) {
handleException(ex);
}
@@ -614,9 +596,9 @@ public class MageServerImpl implements MageServer {
@Override
public void joinGame(final UUID gameId, final String sessionId) throws MageException {
execute("joinGame", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- GameManager.instance.joinGame(gameId, userId);
+ managerFactory.gameManager().joinGame(gameId, userId);
});
});
}
@@ -624,9 +606,9 @@ public class MageServerImpl implements MageServer {
@Override
public void joinDraft(final UUID draftId, final String sessionId) throws MageException {
execute("joinDraft", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- DraftManager.instance.joinDraft(draftId, userId);
+ managerFactory.draftManager().joinDraft(draftId, userId);
});
});
}
@@ -634,12 +616,12 @@ public class MageServerImpl implements MageServer {
@Override
public void joinTournament(final UUID tournamentId, final String sessionId) throws MageException {
execute("joinTournament", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- TournamentManager.instance.joinTournament(tournamentId, userId);
+ managerFactory.tournamentManager().joinTournament(tournamentId, userId);
}
});
}
@@ -648,7 +630,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public UUID getGameChatId(UUID gameId) throws MageException {
try {
- return GameManager.instance.getChatId(gameId).orElse(null);
+ return managerFactory.gameManager().getChatId(gameId).orElse(null);
} catch (Exception ex) {
handleException(ex);
}
@@ -659,7 +641,7 @@ public class MageServerImpl implements MageServer {
//FIXME: why no sessionId here???
public UUID getTournamentChatId(UUID tournamentId) throws MageException {
try {
- return TournamentManager.instance.getChatId(tournamentId).orElse(null);
+ return managerFactory.tournamentManager().getChatId(tournamentId).orElse(null);
} catch (Exception ex) {
handleException(ex);
}
@@ -669,9 +651,8 @@ public class MageServerImpl implements MageServer {
@Override
public void sendPlayerUUID(final UUID gameId, final String sessionId, final UUID data) throws MageException {
execute("sendPlayerUUID", sessionId, () -> {
- Optional user = SessionManager.instance.getUser(sessionId);
+ Optional user = managerFactory.sessionManager().getUser(sessionId);
if (user.isPresent()) {
-// logger.warn("sendPlayerUUID gameId=" + gameId + " sessionId=" + sessionId + " username=" + user.getName());
user.get().sendPlayerUUID(gameId, data);
} else {
logger.warn("Your session expired: gameId=" + gameId + ", sessionId=" + sessionId);
@@ -682,7 +663,7 @@ public class MageServerImpl implements MageServer {
@Override
public void sendPlayerString(final UUID gameId, final String sessionId, final String data) throws MageException {
execute("sendPlayerString", sessionId, () -> {
- Optional user = SessionManager.instance.getUser(sessionId);
+ Optional user = managerFactory.sessionManager().getUser(sessionId);
if (user.isPresent()) {
user.get().sendPlayerString(gameId, data);
} else {
@@ -694,7 +675,7 @@ public class MageServerImpl implements MageServer {
@Override
public void sendPlayerManaType(final UUID gameId, final UUID playerId, final String sessionId, final ManaType data) throws MageException {
execute("sendPlayerManaType", sessionId, () -> {
- Optional user = SessionManager.instance.getUser(sessionId);
+ Optional user = managerFactory.sessionManager().getUser(sessionId);
if (user.isPresent()) {
user.get().sendPlayerManaType(gameId, playerId, data);
} else {
@@ -706,7 +687,7 @@ public class MageServerImpl implements MageServer {
@Override
public void sendPlayerBoolean(final UUID gameId, final String sessionId, final Boolean data) throws MageException {
execute("sendPlayerBoolean", sessionId, () -> {
- Optional user = SessionManager.instance.getUser(sessionId);
+ Optional user = managerFactory.sessionManager().getUser(sessionId);
if (user.isPresent()) {
user.get().sendPlayerBoolean(gameId, data);
} else {
@@ -718,7 +699,7 @@ public class MageServerImpl implements MageServer {
@Override
public void sendPlayerInteger(final UUID gameId, final String sessionId, final Integer data) throws MageException {
execute("sendPlayerInteger", sessionId, () -> {
- Optional user = SessionManager.instance.getUser(sessionId);
+ Optional user = managerFactory.sessionManager().getUser(sessionId);
if (user.isPresent()) {
user.get().sendPlayerInteger(gameId, data);
} else {
@@ -735,9 +716,9 @@ public class MageServerImpl implements MageServer {
@Override
public void sendCardMark(final UUID draftId, final String sessionId, final UUID cardPick) throws MageException {
execute("sendCardMark", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- DraftManager.instance.sendCardMark(draftId, userId, cardPick);
+ managerFactory.draftManager().sendCardMark(draftId, userId, cardPick);
});
});
}
@@ -748,9 +729,9 @@ public class MageServerImpl implements MageServer {
try {
callExecutor.execute(
() -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- GameManager.instance.quitMatch(gameId, userId);
+ managerFactory.gameManager().quitMatch(gameId, userId);
});
}
);
@@ -766,10 +747,10 @@ public class MageServerImpl implements MageServer {
try {
callExecutor.execute(
() -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- TournamentManager.instance.quit(tournamentId, userId);
+ managerFactory.tournamentManager().quit(tournamentId, userId);
});
}
);
@@ -786,14 +767,14 @@ public class MageServerImpl implements MageServer {
try {
callExecutor.execute(
() -> {
- SessionManager.instance.getSession(sessionId).ifPresent(
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(
session -> {
UUID userId = session.getUserId();
- UUID tableId = DraftManager.instance.getControllerByDraftId(draftId).getTableId();
- Table table = TableManager.instance.getTable(tableId);
+ UUID tableId = managerFactory.draftManager().getControllerByDraftId(draftId).getTableId();
+ Table table = managerFactory.tableManager().getTable(tableId);
if (table.isTournament()) {
UUID tournamentId = table.getTournament().getId();
- TournamentManager.instance.quit(tournamentId, userId);
+ managerFactory.tournamentManager().quit(tournamentId, userId);
}
});
}
@@ -808,9 +789,9 @@ public class MageServerImpl implements MageServer {
@Override
public void sendPlayerAction(final PlayerAction playerAction, final UUID gameId, final String sessionId, final Object data) throws MageException {
execute("sendPlayerAction", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- GameManager.instance.sendPlayerAction(playerAction, gameId, userId, data);
+ managerFactory.gameManager().sendPlayerAction(playerAction, gameId, userId, data);
});
});
}
@@ -820,14 +801,14 @@ public class MageServerImpl implements MageServer {
return executeWithResult("setUserData", sessionId, new ActionWithBooleanResult() {
@Override
public Boolean execute() throws MageException {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
return false;
} else {
UUID userId = session.get().getUserId();
- if (GamesRoomManager.instance.getRoom(roomId).isPresent()) {
- return GamesRoomManager.instance.getRoom(roomId).get().watchTable(userId, tableId);
+ if (managerFactory.gamesRoomManager().getRoom(roomId).isPresent()) {
+ return managerFactory.gamesRoomManager().getRoom(roomId).get().watchTable(userId, tableId);
} else {
return false;
}
@@ -846,10 +827,10 @@ public class MageServerImpl implements MageServer {
return executeWithResult("watchGame", sessionId, new ActionWithResult() {
@Override
public Boolean execute() throws MageException {
- return SessionManager.instance.getSession(sessionId)
+ return managerFactory.sessionManager().getSession(sessionId)
.map(session -> {
UUID userId = session.getUserId();
- return GameManager.instance.watchGame(gameId, userId);
+ return managerFactory.gameManager().watchGame(gameId, userId);
}).orElse(false);
}
@@ -863,10 +844,10 @@ public class MageServerImpl implements MageServer {
@Override
public void stopWatching(final UUID gameId, final String sessionId) throws MageException {
execute("stopWatching", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- UserManager.instance.getUser(userId).ifPresent(user -> {
- GameManager.instance.stopWatching(gameId, userId);
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
+ managerFactory.gameManager().stopWatching(gameId, userId);
user.removeGameWatchInfo(gameId);
});
});
@@ -877,9 +858,9 @@ public class MageServerImpl implements MageServer {
@Override
public void replayGame(final UUID gameId, final String sessionId) throws MageException {
execute("replayGame", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- ReplayManager.instance.replayGame(gameId, userId);
+ managerFactory.replayManager().replayGame(gameId, userId);
});
});
}
@@ -887,9 +868,9 @@ public class MageServerImpl implements MageServer {
@Override
public void startReplay(final UUID gameId, final String sessionId) throws MageException {
execute("startReplay", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- ReplayManager.instance.startReplay(gameId, userId);
+ managerFactory.replayManager().startReplay(gameId, userId);
});
});
}
@@ -897,12 +878,12 @@ public class MageServerImpl implements MageServer {
@Override
public void stopReplay(final UUID gameId, final String sessionId) throws MageException {
execute("stopReplay", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- ReplayManager.instance.stopReplay(gameId, userId);
+ managerFactory.replayManager().stopReplay(gameId, userId);
}
});
}
@@ -910,12 +891,12 @@ public class MageServerImpl implements MageServer {
@Override
public void nextPlay(final UUID gameId, final String sessionId) throws MageException {
execute("nextPlay", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- ReplayManager.instance.nextPlay(gameId, userId);
+ managerFactory.replayManager().nextPlay(gameId, userId);
}
});
}
@@ -923,12 +904,12 @@ public class MageServerImpl implements MageServer {
@Override
public void previousPlay(final UUID gameId, final String sessionId) throws MageException {
execute("previousPlay", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- ReplayManager.instance.previousPlay(gameId, userId);
+ managerFactory.replayManager().previousPlay(gameId, userId);
}
});
}
@@ -936,12 +917,12 @@ public class MageServerImpl implements MageServer {
@Override
public void skipForward(final UUID gameId, final String sessionId, final int moves) throws MageException {
execute("skipForward", sessionId, () -> {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- ReplayManager.instance.skipForward(gameId, userId, moves);
+ managerFactory.replayManager().skipForward(gameId, userId, moves);
}
});
}
@@ -971,9 +952,9 @@ public class MageServerImpl implements MageServer {
public void cheat(final UUID gameId, final String sessionId, final UUID playerId, final DeckCardLists deckList) throws MageException {
execute("cheat", sessionId, () -> {
if (testMode) {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- GameManager.instance.cheat(gameId, userId, playerId, deckList);
+ managerFactory.gameManager().cheat(gameId, userId, playerId, deckList);
});
}
});
@@ -985,12 +966,12 @@ public class MageServerImpl implements MageServer {
@Override
public Boolean execute() {
if (testMode) {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
- return GameManager.instance.cheat(gameId, userId, playerId, cardName);
+ return managerFactory.gameManager().cheat(gameId, userId, playerId, cardName);
}
}
return false;
@@ -1024,13 +1005,13 @@ public class MageServerImpl implements MageServer {
@Override
public void disconnectUser(final String sessionId, final String userSessionId) throws MageException {
- execute("disconnectUser", sessionId, () -> SessionManager.instance.disconnectUser(sessionId, userSessionId));
+ execute("disconnectUser", sessionId, () -> managerFactory.sessionManager().disconnectUser(sessionId, userSessionId));
}
@Override
public void muteUser(final String sessionId, final String userName, final long durationMinutes) throws MageException {
execute("muteUser", sessionId, () -> {
- UserManager.instance.getUserByName(userName).ifPresent(user -> {
+ managerFactory.userManager().getUserByName(userName).ifPresent(user -> {
Date muteUntil = new Date(Calendar.getInstance().getTimeInMillis() + (durationMinutes * Timer.ONE_MINUTE));
user.showUserMessage("Admin info", "You were muted for chat messages until " + SystemUtil.dateFormat.format(muteUntil) + '.');
user.setChatLockedUntil(muteUntil);
@@ -1042,12 +1023,12 @@ public class MageServerImpl implements MageServer {
@Override
public void lockUser(final String sessionId, final String userName, final long durationMinutes) throws MageException {
execute("lockUser", sessionId, () -> {
- UserManager.instance.getUserByName(userName).ifPresent(user -> {
+ managerFactory.userManager().getUserByName(userName).ifPresent(user -> {
Date lockUntil = new Date(Calendar.getInstance().getTimeInMillis() + (durationMinutes * Timer.ONE_MINUTE));
user.showUserMessage("Admin info", "Your user profile was locked until " + SystemUtil.dateFormat.format(lockUntil) + '.');
user.setLockedUntil(lockUntil);
if (user.isConnected()) {
- SessionManager.instance.disconnectUser(sessionId, user.getSessionId());
+ managerFactory.sessionManager().disconnectUser(sessionId, user.getSessionId());
}
});
@@ -1058,15 +1039,15 @@ public class MageServerImpl implements MageServer {
public void setActivation(final String sessionId, final String userName, boolean active) throws MageException {
execute("setActivation", sessionId, () -> {
AuthorizedUser authorizedUser = AuthorizedUserRepository.instance.getByName(userName);
- Optional u = UserManager.instance.getUserByName(userName);
+ Optional u = managerFactory.userManager().getUserByName(userName);
if (u.isPresent()) {
User user = u.get();
user.setActive(active);
if (!user.isActive() && user.isConnected()) {
- SessionManager.instance.disconnectUser(sessionId, user.getSessionId());
+ managerFactory.sessionManager().disconnectUser(sessionId, user.getSessionId());
}
} else if (authorizedUser != null) {
- User theUser = new User(userName, "localhost", authorizedUser);
+ User theUser = new User(managerFactory, userName, "localhost", authorizedUser);
theUser.setActive(active);
}
@@ -1076,18 +1057,18 @@ public class MageServerImpl implements MageServer {
@Override
public void toggleActivation(final String sessionId, final String userName) throws MageException {
execute("toggleActivation", sessionId, ()
- -> UserManager.instance.getUserByName(userName).ifPresent(user
+ -> managerFactory.userManager().getUserByName(userName).ifPresent(user
-> {
user.setActive(!user.isActive());
if (!user.isActive() && user.isConnected()) {
- SessionManager.instance.disconnectUser(sessionId, user.getSessionId());
+ managerFactory.sessionManager().disconnectUser(sessionId, user.getSessionId());
}
}));
}
@Override
public void endUserSession(final String sessionId, final String userSessionId) throws MageException {
- execute("endUserSession", sessionId, () -> SessionManager.instance.endUserSession(sessionId, userSessionId));
+ execute("endUserSession", sessionId, () -> managerFactory.sessionManager().endUserSession(sessionId, userSessionId));
}
/**
@@ -1100,9 +1081,9 @@ public class MageServerImpl implements MageServer {
@Override
public void removeTable(final String sessionId, final UUID tableId) throws MageException {
execute("removeTable", sessionId, () -> {
- SessionManager.instance.getSession(sessionId).ifPresent(session -> {
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session -> {
UUID userId = session.getUserId();
- TableManager.instance.removeTable(userId, tableId);
+ managerFactory.tableManager().removeTable(userId, tableId);
});
});
}
@@ -1116,7 +1097,7 @@ public class MageServerImpl implements MageServer {
public void sendFeedbackMessage(final String sessionId, final String username, final String title, final String type, final String message, final String email) throws MageException {
if (title != null && message != null) {
execute("sendFeedbackMessage", sessionId, ()
- -> SessionManager.instance.getSession(sessionId).ifPresent(
+ -> managerFactory.sessionManager().getSession(sessionId).ifPresent(
session -> FeedbackServiceImpl.instance.feedback(username, title, type, message, email, session.getHost())
));
}
@@ -1126,7 +1107,7 @@ public class MageServerImpl implements MageServer {
public void sendBroadcastMessage(final String sessionId, final String message) throws MageException {
if (message != null) {
execute("sendBroadcastMessage", sessionId, () -> {
- for (User user : UserManager.instance.getUsers()) {
+ for (User user : managerFactory.userManager().getUsers()) {
if (message.toLowerCase(Locale.ENGLISH).startsWith("warn")) {
user.fireCallback(new ClientCallback(ClientCallbackMethod.SERVER_MESSAGE, null, new ChatMessage("SERVER", message, null, null, MessageColor.RED)));
} else {
@@ -1138,12 +1119,12 @@ public class MageServerImpl implements MageServer {
}
private void sendErrorMessageToClient(final String sessionId, final String message) throws MageException {
- execute("sendErrorMessageToClient", sessionId, () -> SessionManager.instance.sendErrorMessageToClient(sessionId, message));
+ execute("sendErrorMessageToClient", sessionId, () -> managerFactory.sessionManager().sendErrorMessageToClient(sessionId, message));
}
protected void execute(final String actionName, final String sessionId, final Action action, boolean checkAdminRights) throws MageException {
if (checkAdminRights) {
- if (!SessionManager.instance.isAdmin(sessionId)) {
+ if (!managerFactory.sessionManager().isAdmin(sessionId)) {
return;
}
}
@@ -1151,11 +1132,11 @@ public class MageServerImpl implements MageServer {
}
protected void execute(final String actionName, final String sessionId, final Action action) throws MageException {
- if (SessionManager.instance.isValidSession(sessionId)) {
+ if (managerFactory.sessionManager().isValidSession(sessionId)) {
try {
callExecutor.execute(
() -> {
- if (SessionManager.instance.isValidSession(sessionId)) {
+ if (managerFactory.sessionManager().isValidSession(sessionId)) {
try {
action.execute();
} catch (MageException me) {
@@ -1172,7 +1153,7 @@ public class MageServerImpl implements MageServer {
protected T executeWithResult(String actionName, final String sessionId, final ActionWithResult action, boolean checkAdminRights) throws MageException {
if (checkAdminRights) {
- if (!SessionManager.instance.isAdmin(sessionId)) {
+ if (!managerFactory.sessionManager().isAdmin(sessionId)) {
return action.negativeResult();
}
}
@@ -1181,7 +1162,7 @@ public class MageServerImpl implements MageServer {
//TODO: also run in threads with future task
protected T executeWithResult(String actionName, final String sessionId, final ActionWithResult action) throws MageException {
- if (SessionManager.instance.isValidSession(sessionId)) {
+ if (managerFactory.sessionManager().isValidSession(sessionId)) {
try {
return action.execute();
} catch (Exception ex) {
@@ -1218,15 +1199,15 @@ public class MageServerImpl implements MageServer {
}
}
- private static class ListActionWithNullNegativeResult extends ActionWithNullNegativeResult> {
+ private class ListActionWithNullNegativeResult extends ActionWithNullNegativeResult> {
@Override
public List execute() throws MageException {
- return UserManager.instance.getUserInfoList();
+ return managerFactory.userManager().getUserInfoList();
}
}
- private static class GameViewActionWithNullNegativeResult extends ActionWithNullNegativeResult {
+ private class GameViewActionWithNullNegativeResult extends ActionWithNullNegativeResult {
private final String sessionId;
private final UUID gameId;
@@ -1240,18 +1221,18 @@ public class MageServerImpl implements MageServer {
@Override
public GameView execute() throws MageException {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
return null;
} else {
//UUID userId = session.get().getUserId();
- return GameManager.instance.getGameView(gameId, playerId);
+ return managerFactory.gameManager().getGameView(gameId, playerId);
}
}
}
- private static class MyActionWithBooleanResult extends ActionWithBooleanResult {
+ private class MyActionWithBooleanResult extends ActionWithBooleanResult {
private final String sessionId;
private final UUID tableId;
@@ -1263,17 +1244,17 @@ public class MageServerImpl implements MageServer {
@Override
public Boolean execute() throws MageException {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
return false;
} else {
UUID userId = session.get().getUserId();
- return TableManager.instance.watchTable(userId, tableId);
+ return managerFactory.tableManager().watchTable(userId, tableId);
}
}
}
- private static class DraftPickViewActionWithNullNegativeResult extends ActionWithNullNegativeResult {
+ private class DraftPickViewActionWithNullNegativeResult extends ActionWithNullNegativeResult {
private final String sessionId;
private final UUID draftId;
@@ -1289,9 +1270,9 @@ public class MageServerImpl implements MageServer {
@Override
public DraftPickView execute() {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (session.isPresent()) {
- return DraftManager.instance.sendCardPick(draftId, session.get().getUserId(), cardPick, hiddenCards);
+ return managerFactory.draftManager().sendCardPick(draftId, session.get().getUserId(), cardPick, hiddenCards);
} else {
logger.error("Session not found sessionId: " + sessionId + " draftId:" + draftId);
}
@@ -1299,7 +1280,7 @@ public class MageServerImpl implements MageServer {
}
}
- private static class MyActionWithTableViewResult extends ActionWithTableViewResult {
+ private class MyActionWithTableViewResult extends ActionWithTableViewResult {
private final String sessionId;
private final MatchOptions options;
@@ -1313,12 +1294,12 @@ public class MageServerImpl implements MageServer {
@Override
public TableView execute() throws MageException {
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
return null;
}
UUID userId = session.get().getUserId();
- Optional _user = UserManager.instance.getUser(userId);
+ Optional _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
logger.error("User for session not found. session = " + sessionId);
return null;
@@ -1349,13 +1330,13 @@ public class MageServerImpl implements MageServer {
user.showUserMessage("Create table", message);
throw new MageException("No message");
}
- Optional room = GamesRoomManager.instance.getRoom(roomId);
+ Optional room = managerFactory.gamesRoomManager().getRoom(roomId);
if (room.isPresent()) {
TableView table = room.get().createTable(userId, options);
if (logger.isDebugEnabled()) {
logger.debug("TABLE created - tableId: " + table.getTableId() + ' ' + table.getTableName());
logger.debug("- " + user.getName() + " userId: " + user.getId());
- logger.debug("- chatId: " + TableManager.instance.getChatId(table.getTableId()));
+ logger.debug("- chatId: " + managerFactory.tableManager().getChatId(table.getTableId()));
}
return table;
} else {
diff --git a/Mage.Server/src/main/java/mage/server/MailClient.java b/Mage.Server/src/main/java/mage/server/MailClientImpl.java
similarity index 80%
rename from Mage.Server/src/main/java/mage/server/MailClient.java
rename to Mage.Server/src/main/java/mage/server/MailClientImpl.java
index 69e9518b77..6058fec183 100644
--- a/Mage.Server/src/main/java/mage/server/MailClient.java
+++ b/Mage.Server/src/main/java/mage/server/MailClientImpl.java
@@ -1,25 +1,32 @@
package mage.server;
-import java.util.Properties;
+import mage.server.managers.ConfigSettings;
+import mage.server.managers.MailClient;
+import org.apache.log4j.Logger;
+
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
-import mage.server.util.ConfigSettings;
-import org.apache.log4j.Logger;
+import java.util.Properties;
-public final class MailClient {
+public class MailClientImpl implements MailClient {
private static final Logger logger = Logger.getLogger(Main.class);
- public static boolean sendMessage(String email, String subject, String text) {
+ private final ConfigSettings config;
+
+ public MailClientImpl(ConfigSettings config) {
+ this.config = config;
+ }
+
+ public boolean sendMessage(String email, String subject, String text) {
if (email.isEmpty()) {
logger.info("Email is not sent because the address is empty");
return false;
}
- ConfigSettings config = ConfigSettings.instance;
Properties properties = System.getProperties();
properties.setProperty("mail.smtps.host", config.getMailSmtpHost());
@@ -30,7 +37,7 @@ public final class MailClient {
Session session = Session.getDefaultInstance(properties);
- try{
+ try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(config.getMailFromAddress()));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
@@ -44,7 +51,7 @@ public final class MailClient {
trnsport.close();
return true;
- }catch (MessagingException ex) {
+ } catch (MessagingException ex) {
logger.error("Error sending message to " + email, ex);
}
return false;
diff --git a/Mage.Server/src/main/java/mage/server/MailgunClient.java b/Mage.Server/src/main/java/mage/server/MailgunClientImpl.java
similarity index 65%
rename from Mage.Server/src/main/java/mage/server/MailgunClient.java
rename to Mage.Server/src/main/java/mage/server/MailgunClientImpl.java
index 6cca110a0b..344a77fda2 100644
--- a/Mage.Server/src/main/java/mage/server/MailgunClient.java
+++ b/Mage.Server/src/main/java/mage/server/MailgunClientImpl.java
@@ -5,29 +5,37 @@ import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
import com.sun.jersey.core.util.MultivaluedMapImpl;
-import javax.ws.rs.core.MediaType;
-import mage.server.util.ConfigSettings;
+import mage.server.managers.ConfigSettings;
+import mage.server.managers.MailClient;
import org.apache.log4j.Logger;
-public final class MailgunClient {
+import javax.ws.rs.core.MediaType;
+
+public class MailgunClientImpl implements MailClient {
private static final Logger logger = Logger.getLogger(Main.class);
- public static boolean sendMessage(String email, String subject, String text) {
+ private final ConfigSettings config;
+
+ public MailgunClientImpl(ConfigSettings config) {
+ this.config = config;
+ }
+
+ public boolean sendMessage(String email, String subject, String text) {
if (email.isEmpty()) {
logger.info("Email is not sent because the address is empty");
return false;
}
Client client = Client.create();
- client.addFilter(new HTTPBasicAuthFilter("api", ConfigSettings.instance.getMailgunApiKey()));
- String domain = ConfigSettings.instance.getMailgunDomain();
+ client.addFilter(new HTTPBasicAuthFilter("api", config.getMailgunApiKey()));
+ String domain = config.getMailgunDomain();
WebResource webResource = client.resource("https://api.mailgun.net/v3/" + domain + "/messages");
MultivaluedMapImpl formData = new MultivaluedMapImpl();
formData.add("from", "XMage ');
formData.add("to", email);
formData.add("subject", subject);
formData.add("text", text);
- ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED).post(ClientResponse.class, formData);
+ ClientResponse response = webResource.type(MediaType.APPLICATION_FORM_URLENCODED).post(ClientResponse.class, formData);
boolean succeeded = response.getStatus() == 200;
if (!succeeded) {
logger.error("Error sending message to " + email + ". Status code: " + response.getStatus());
diff --git a/Mage.Server/src/main/java/mage/server/Main.java b/Mage.Server/src/main/java/mage/server/Main.java
index a9b617cd7c..c888866096 100644
--- a/Mage.Server/src/main/java/mage/server/Main.java
+++ b/Mage.Server/src/main/java/mage/server/Main.java
@@ -14,12 +14,11 @@ import mage.remote.Connection;
import mage.server.draft.CubeFactory;
import mage.server.game.GameFactory;
import mage.server.game.PlayerFactory;
+import mage.server.managers.ConfigSettings;
+import mage.server.managers.ManagerFactory;
import mage.server.record.UserStatsRepository;
import mage.server.tournament.TournamentFactory;
-import mage.server.util.ConfigSettings;
-import mage.server.util.PluginClassLoader;
-import mage.server.util.ServerMessagesUtil;
-import mage.server.util.SystemUtil;
+import mage.server.util.*;
import mage.server.util.config.GamePlugin;
import mage.server.util.config.Plugin;
import mage.utils.MageVersion;
@@ -40,6 +39,7 @@ import java.io.IOException;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
+import java.nio.file.Paths;
import java.util.*;
/**
@@ -53,9 +53,16 @@ public final class Main {
private static final String testModeArg = "-testMode=";
private static final String fastDBModeArg = "-fastDbMode=";
private static final String adminPasswordArg = "-adminPassword=";
+ /**
+ * The property that holds the path to the configuration file. Defaults to "config/config.xml".
+ *
+ * To set up a different one, start the application with the java option "-Dxmage.config.path=<path>"
+ */
+ private static final String configPathProp = "xmage.config.path";
private static final File pluginFolder = new File("plugins");
private static final File extensionFolder = new File("extensions");
+ private static final String defaultConfigPath = Paths.get("config", "config.xml").toString();
public static final PluginClassLoader classLoader = new PluginClassLoader();
private static TransporterServer server;
@@ -70,7 +77,6 @@ public final class Main {
logger.info("Starting MAGE server version " + version);
logger.info("Logging level: " + logger.getEffectiveLevel());
logger.info("Default charset: " + Charset.defaultCharset());
-
String adminPassword = "";
for (String arg : args) {
if (arg.startsWith(testModeArg)) {
@@ -83,7 +89,14 @@ public final class Main {
}
}
- if (ConfigSettings.instance.isAuthenticationActivated()) {
+ final String configPath = Optional.ofNullable(System.getProperty(configPathProp))
+ .orElse(defaultConfigPath);
+
+ logger.info(String.format("Reading configuration from path=%s", configPath));
+ final ConfigWrapper config = new ConfigWrapper(ConfigFactory.loadFromFile(configPath));
+
+
+ if (config.isAuthenticationActivated()) {
logger.info("Check authorized user DB version ...");
if (!AuthorizedUserRepository.instance.checkAlterAndMigrateAuthorizedUser()) {
logger.fatal("Failed to start server.");
@@ -148,7 +161,6 @@ public final class Main {
UserStatsRepository.instance.updateUserStats();
logger.info("Done.");
deleteSavedGames();
- ConfigSettings config = ConfigSettings.instance;
for (GamePlugin plugin : config.getGameTypes()) {
GameFactory.instance.addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin));
}
@@ -206,11 +218,12 @@ public final class Main {
Connection connection = new Connection("&maxPoolSize=" + config.getMaxPoolSize());
connection.setHost(config.getServerAddress());
connection.setPort(config.getPort());
+ final ManagerFactory managerFactory = new MainManagerFactory(config);
try {
// Parameter: serializationtype => jboss
InvokerLocator serverLocator = new InvokerLocator(connection.getURI());
- if (!isAlreadyRunning(serverLocator)) {
- server = new MageTransporterServer(serverLocator, new MageServerImpl(adminPassword, testMode), MageServer.class.getName(), new MageServerInvocationHandler());
+ if (!isAlreadyRunning(config, serverLocator)) {
+ server = new MageTransporterServer(managerFactory, serverLocator, new MageServerImpl(managerFactory, adminPassword, testMode), MageServer.class.getName(), new MageServerInvocationHandler(managerFactory));
server.start();
logger.info("Started MAGE server - listening on " + connection.toString());
@@ -230,9 +243,9 @@ public final class Main {
ServerMessagesUtil.instance.setStartDate(System.currentTimeMillis());
}
- static boolean isAlreadyRunning(InvokerLocator serverLocator) {
+ static boolean isAlreadyRunning(ConfigSettings config, InvokerLocator serverLocator) {
Map metadata = new HashMap<>();
- metadata.put(SocketWrapper.WRITE_TIMEOUT, String.valueOf(ConfigSettings.instance.getSocketWriteTimeout()));
+ metadata.put(SocketWrapper.WRITE_TIMEOUT, String.valueOf(config.getSocketWriteTimeout()));
metadata.put("generalizeSocketException", "true");
try {
MageServer testServer = (MageServer) TransporterClient.createTransporterClient(serverLocator.getLocatorURI(), MageServer.class, metadata);
@@ -248,16 +261,22 @@ public final class Main {
static class ClientConnectionListener implements ConnectionListener {
+ private final ManagerFactory managerFactory;
+
+ public ClientConnectionListener(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
@Override
public void handleConnectionException(Throwable throwable, Client client) {
String sessionId = client.getSessionId();
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.trace("Session not found : " + sessionId);
} else {
UUID userId = session.get().getUserId();
StringBuilder sessionInfo = new StringBuilder();
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = managerFactory.userManager().getUser(userId);
if (user.isPresent()) {
sessionInfo.append(user.get().getName()).append(" [").append(user.get().getGameInfo()).append(']');
} else {
@@ -267,12 +286,12 @@ public final class Main {
if (throwable instanceof ClientDisconnectedException) {
// Seems like the random diconnects from public server land here and should not be handled as explicit disconnects
// So it should be possible to reconnect to server and continue games if DisconnectReason is set to LostConnection
- //SessionManager.instance.disconnect(client.getSessionId(), DisconnectReason.Disconnected);
- SessionManager.instance.disconnect(client.getSessionId(), DisconnectReason.LostConnection);
+ //managerFactory.sessionManager().disconnect(client.getSessionId(), DisconnectReason.Disconnected);
+ managerFactory.sessionManager().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
logger.info("CLIENT DISCONNECTED - " + sessionInfo);
logger.debug("Stack Trace", throwable);
} else {
- SessionManager.instance.disconnect(client.getSessionId(), DisconnectReason.LostConnection);
+ managerFactory.sessionManager().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
logger.info("LOST CONNECTION - " + sessionInfo);
if (logger.isDebugEnabled()) {
if (throwable == null) {
@@ -292,11 +311,11 @@ public final class Main {
protected Connector connector;
- public MageTransporterServer(InvokerLocator locator, Object target, String subsystem, MageServerInvocationHandler serverInvocationHandler) throws Exception {
+ public MageTransporterServer(ManagerFactory managerFactory, InvokerLocator locator, Object target, String subsystem, MageServerInvocationHandler serverInvocationHandler) throws Exception {
super(locator, target, subsystem);
connector.addInvocationHandler("callback", serverInvocationHandler);
- connector.setLeasePeriod(ConfigSettings.instance.getLeasePeriod());
- connector.addConnectionListener(new ClientConnectionListener());
+ connector.setLeasePeriod(managerFactory.configSettings().getLeasePeriod());
+ connector.addConnectionListener(new ClientConnectionListener(managerFactory));
}
public Connector getConnector() throws Exception {
@@ -313,6 +332,12 @@ public final class Main {
static class MageServerInvocationHandler implements ServerInvocationHandler {
+ private final ManagerFactory managerFactory;
+
+ public MageServerInvocationHandler(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
@Override
public void setMBeanServer(MBeanServer server) {
/**
@@ -333,9 +358,9 @@ public final class Main {
@Override
public void setInvoker(ServerInvoker invoker) {
- ((BisocketServerInvoker) invoker).setSecondaryBindPort(ConfigSettings.instance.getSecondaryBindPort());
- ((BisocketServerInvoker) invoker).setBacklog(ConfigSettings.instance.getBacklogSize());
- ((BisocketServerInvoker) invoker).setNumAcceptThreads(ConfigSettings.instance.getNumAcceptThreads());
+ ((BisocketServerInvoker) invoker).setSecondaryBindPort(managerFactory.configSettings().getSecondaryBindPort());
+ ((BisocketServerInvoker) invoker).setBacklog(managerFactory.configSettings().getBacklogSize());
+ ((BisocketServerInvoker) invoker).setNumAcceptThreads(managerFactory.configSettings().getNumAcceptThreads());
}
@Override
@@ -344,7 +369,7 @@ public final class Main {
ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
try {
String sessionId = handler.getClientSessionId();
- SessionManager.instance.createSession(sessionId, callbackHandler);
+ managerFactory.sessionManager().createSession(sessionId, callbackHandler);
} catch (Throwable ex) {
logger.fatal("", ex);
}
@@ -362,7 +387,7 @@ public final class Main {
} else {
host = "localhost";
}
- Optional session = SessionManager.instance.getSession(sessionId);
+ Optional session = managerFactory.sessionManager().getSession(sessionId);
if (!session.isPresent()) {
logger.error("Session not found : " + sessionId);
} else {
@@ -375,7 +400,7 @@ public final class Main {
public void removeListener(InvokerCallbackHandler callbackHandler) {
ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
String sessionId = handler.getClientSessionId();
- SessionManager.instance.disconnect(sessionId, DisconnectReason.Disconnected);
+ managerFactory.sessionManager().disconnect(sessionId, DisconnectReason.Disconnected);
}
}
diff --git a/Mage.Server/src/main/java/mage/server/MainManagerFactory.java b/Mage.Server/src/main/java/mage/server/MainManagerFactory.java
new file mode 100644
index 0000000000..753a2810f6
--- /dev/null
+++ b/Mage.Server/src/main/java/mage/server/MainManagerFactory.java
@@ -0,0 +1,124 @@
+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;
+
+public class MainManagerFactory implements ManagerFactory {
+
+ 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();
+ }
+
+ @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;
+ }
+}
diff --git a/Mage.Server/src/main/java/mage/server/RoomImpl.java b/Mage.Server/src/main/java/mage/server/RoomImpl.java
index d92de7b9f0..9221ee0cd3 100644
--- a/Mage.Server/src/main/java/mage/server/RoomImpl.java
+++ b/Mage.Server/src/main/java/mage/server/RoomImpl.java
@@ -1,11 +1,10 @@
-
-
package mage.server;
+import mage.server.managers.ChatManager;
+
import java.util.UUID;
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public abstract class RoomImpl implements Room {
@@ -13,9 +12,9 @@ public abstract class RoomImpl implements Room {
private final UUID chatId;
private final UUID roomId;
- public RoomImpl() {
+ public RoomImpl(ChatManager chatManager) {
roomId = UUID.randomUUID();
- chatId = ChatManager.instance.createChatSession("Room " + roomId);
+ chatId = chatManager.createChatSession("Room " + roomId);
}
/**
@@ -35,5 +34,4 @@ public abstract class RoomImpl implements Room {
}
-
}
diff --git a/Mage.Server/src/main/java/mage/server/Session.java b/Mage.Server/src/main/java/mage/server/Session.java
index 10f0c79876..61d36241d5 100644
--- a/Mage.Server/src/main/java/mage/server/Session.java
+++ b/Mage.Server/src/main/java/mage/server/Session.java
@@ -7,8 +7,8 @@ import mage.interfaces.callback.ClientCallbackMethod;
import mage.players.net.UserData;
import mage.players.net.UserGroup;
import mage.server.game.GamesRoom;
-import mage.server.game.GamesRoomManager;
-import mage.server.util.ConfigSettings;
+import mage.server.managers.ConfigSettings;
+import mage.server.managers.ManagerFactory;
import mage.server.util.SystemUtil;
import mage.util.RandomUtil;
import org.apache.log4j.Logger;
@@ -34,6 +34,7 @@ public class Session {
private static final Pattern alphabetsPattern = Pattern.compile("[a-zA-Z]");
private static final Pattern digitsPattern = Pattern.compile("[0-9]");
+ private final ManagerFactory managerFactory;
private final String sessionId;
private UUID userId;
private String host;
@@ -46,7 +47,8 @@ public class Session {
private final ReentrantLock lock;
private final ReentrantLock callBackLock;
- public Session(String sessionId, InvokerCallbackHandler callbackHandler) {
+ public Session(ManagerFactory managerFactory, String sessionId, InvokerCallbackHandler callbackHandler) {
+ this.managerFactory = managerFactory;
this.sessionId = sessionId;
this.callbackHandler = (AsynchInvokerCallbackHandler) callbackHandler;
this.isAdmin = false;
@@ -56,7 +58,7 @@ public class Session {
}
public String registerUser(String userName, String password, String email) throws MageException {
- if (!ConfigSettings.instance.isAuthenticationActivated()) {
+ if (!managerFactory.configSettings().isAuthenticationActivated()) {
String returnMessage = "Registration is disabled by the server config";
sendErrorMessageToClient(returnMessage);
return returnMessage;
@@ -86,10 +88,10 @@ public class Session {
boolean success;
String subject = "XMage Registration Completed";
- if (!ConfigSettings.instance.getMailUser().isEmpty()) {
- success = MailClient.sendMessage(email, subject, text);
+ if (!managerFactory.configSettings().getMailUser().isEmpty()) {
+ success = managerFactory.mailClient().sendMessage(email, subject, text);
} else {
- success = MailgunClient.sendMessage(email, subject, text);
+ success = managerFactory.mailgunClient().sendMessage(email, subject, text);
}
if (success) {
String ok = "Sent a registration confirmation / initial password email to " + email + " for " + userName;
@@ -109,18 +111,18 @@ public class Session {
}
}
- private static String validateUserName(String userName) {
+ private String validateUserName(String userName) {
if (userName.equals("Admin")) {
return "User name Admin already in use";
}
- ConfigSettings config = ConfigSettings.instance;
+ ConfigSettings config = managerFactory.configSettings();
if (userName.length() < config.getMinUserNameLength()) {
return "User name may not be shorter than " + config.getMinUserNameLength() + " characters";
}
if (userName.length() > config.getMaxUserNameLength()) {
return "User name may not be longer than " + config.getMaxUserNameLength() + " characters";
}
- Pattern invalidUserNamePattern = Pattern.compile(ConfigSettings.instance.getInvalidUserNamePattern(), Pattern.CASE_INSENSITIVE);
+ Pattern invalidUserNamePattern = Pattern.compile(managerFactory.configSettings().getInvalidUserNamePattern(), Pattern.CASE_INSENSITIVE);
Matcher m = invalidUserNamePattern.matcher(userName);
if (m.find()) {
return "User name '" + userName + "' includes not allowed characters: use a-z, A-Z and 0-9";
@@ -132,8 +134,8 @@ public class Session {
return null;
}
- private static String validatePassword(String password, String userName) {
- ConfigSettings config = ConfigSettings.instance;
+ private String validatePassword(String password, String userName) {
+ ConfigSettings config = managerFactory.configSettings();
if (password.length() < config.getMinPasswordLength()) {
return "Password may not be shorter than " + config.getMinPasswordLength() + " characters";
}
@@ -178,7 +180,7 @@ public class Session {
public String connectUserHandling(String userName, String password) throws MageException {
this.isAdmin = false;
AuthorizedUser authorizedUser = null;
- if (ConfigSettings.instance.isAuthenticationActivated()) {
+ if (managerFactory.configSettings().isAuthenticationActivated()) {
authorizedUser = AuthorizedUserRepository.instance.getByName(userName);
String errorMsg = "Wrong username or password. In case you haven't, please register your account first.";
if (authorizedUser == null) {
@@ -196,7 +198,7 @@ public class Session {
if (authorizedUser.lockedUntil.compareTo(Calendar.getInstance().getTime()) > 0) {
return "Your profile is deactivated until " + SystemUtil.dateFormat.format(authorizedUser.lockedUntil);
} else {
- UserManager.instance.createUser(userName, host, authorizedUser).ifPresent(user
+ managerFactory.userManager().createUser(userName, host, authorizedUser).ifPresent(user
-> user.setLockedUntil(null)
);
@@ -204,15 +206,15 @@ public class Session {
}
}
- Optional selectUser = UserManager.instance.createUser(userName, host, authorizedUser);
+ Optional selectUser = managerFactory.userManager().createUser(userName, host, authorizedUser);
boolean reconnect = false;
if (!selectUser.isPresent()) {
// user already connected
- selectUser = UserManager.instance.getUserByName(userName);
+ selectUser = managerFactory.userManager().getUserByName(userName);
if (selectUser.isPresent()) {
User user = selectUser.get();
// If authentication is not activated, check the identity using IP address.
- if (ConfigSettings.instance.isAuthenticationActivated() || user.getHost().equals(host)) {
+ if (managerFactory.configSettings().isAuthenticationActivated() || user.getHost().equals(host)) {
user.updateLastActivity(null); // minimizes possible expiration
this.userId = user.getId();
if (user.getSessionId().isEmpty()) {
@@ -221,7 +223,7 @@ public class Session {
} else {
//disconnect previous session
logger.info("Disconnecting another user instance: " + userName);
- SessionManager.instance.disconnect(user.getSessionId(), DisconnectReason.ConnectingOtherInstance);
+ managerFactory.sessionManager().disconnect(user.getSessionId(), DisconnectReason.ConnectingOtherInstance);
}
} else {
return "User name " + userName + " already in use (or your IP address changed)";
@@ -232,18 +234,18 @@ public class Session {
}
}
User user = selectUser.get();
- if (!UserManager.instance.connectToSession(sessionId, user.getId())) {
+ if (!managerFactory.userManager().connectToSession(sessionId, user.getId())) {
return "Error connecting " + userName;
}
this.userId = user.getId();
if (reconnect) { // must be connected to receive the message
- Optional room = GamesRoomManager.instance.getRoom(GamesRoomManager.instance.getMainRoomId());
+ Optional room = managerFactory.gamesRoomManager().getRoom(managerFactory.gamesRoomManager().getMainRoomId());
if (!room.isPresent()) {
logger.warn("main room not found"); // after server restart users try to use old rooms on reconnect
return null;
}
- ChatManager.instance.joinChat(room.get().getChatId(), userId);
- ChatManager.instance.sendReconnectMessage(userId);
+ managerFactory.chatManager().joinChat(room.get().getChatId(), userId);
+ managerFactory.chatManager().sendReconnectMessage(userId);
}
return null;
@@ -251,12 +253,12 @@ public class Session {
public void connectAdmin() {
this.isAdmin = true;
- User user = UserManager.instance.createUser("Admin", host, null).orElse(
- UserManager.instance.getUserByName("Admin").get());
+ User user = managerFactory.userManager().createUser("Admin", host, null).orElse(
+ managerFactory.userManager().getUserByName("Admin").get());
UserData adminUserData = UserData.getDefaultUserDataView();
adminUserData.setGroupId(UserGroup.ADMIN.getGroupId());
user.setUserData(adminUserData);
- if (!UserManager.instance.connectToSession(sessionId, user.getId())) {
+ if (!managerFactory.userManager().connectToSession(sessionId, user.getId())) {
logger.info("Error connecting Admin!");
} else {
user.setUserState(User.UserState.Connected);
@@ -265,7 +267,7 @@ public class Session {
}
public boolean setUserData(String userName, UserData userData, String clientVersion, String userIdStr) {
- Optional _user = UserManager.instance.getUserByName(userName);
+ Optional _user = managerFactory.userManager().getUserByName(userName);
_user.ifPresent(user -> {
if (clientVersion != null) {
user.setClientVersion(clientVersion);
@@ -313,7 +315,7 @@ public class Session {
// because different threads can activate this
public void userLostConnection() {
- Optional _user = UserManager.instance.getUser(userId);
+ Optional _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
return; //user was already disconnected by other thread
}
@@ -338,7 +340,7 @@ public class Session {
} else {
logger.error("SESSION LOCK - kill: userId " + userId);
}
- UserManager.instance.removeUserFromAllTablesAndChat(userId, reason);
+ managerFactory.userManager().removeUserFromAllTablesAndChat(userId, reason);
} catch (InterruptedException ex) {
logger.error("SESSION LOCK - kill: userId " + userId, ex);
} finally {
@@ -372,11 +374,11 @@ public class Session {
logger.warn("SESSION LOCK - fireCallback - userId: " + userId + " messageId: " + call.getMessageId(), ex);
} catch (HandleCallbackException ex) {
this.valid = false;
- UserManager.instance.getUser(userId).ifPresent(user -> {
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
user.setUserState(User.UserState.Disconnected);
logger.warn("SESSION CALLBACK EXCEPTION - " + user.getName() + " userId " + userId + " messageId: " + call.getMessageId() + " - cause: " + getBasicCause(ex).toString());
logger.trace("Stack trace:", ex);
- SessionManager.instance.disconnect(sessionId, LostConnection);
+ managerFactory.sessionManager().disconnect(sessionId, LostConnection);
});
} catch (Exception ex) {
logger.warn("Unspecific exception:", ex);
diff --git a/Mage.Server/src/main/java/mage/server/SessionManager.java b/Mage.Server/src/main/java/mage/server/SessionManagerImpl.java
similarity index 84%
rename from Mage.Server/src/main/java/mage/server/SessionManager.java
rename to Mage.Server/src/main/java/mage/server/SessionManagerImpl.java
index b87dc49c9c..896195a52d 100644
--- a/Mage.Server/src/main/java/mage/server/SessionManager.java
+++ b/Mage.Server/src/main/java/mage/server/SessionManagerImpl.java
@@ -1,8 +1,9 @@
-
package mage.server;
import mage.MageException;
import mage.players.net.UserData;
+import mage.server.managers.SessionManager;
+import mage.server.managers.ManagerFactory;
import org.apache.log4j.Logger;
import org.jboss.remoting.callback.InvokerCallbackHandler;
@@ -13,21 +14,25 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* @author BetaSteward_at_googlemail.com
*/
-public enum SessionManager {
+public class SessionManagerImpl implements SessionManager {
- instance;
-
- private static final Logger logger = Logger.getLogger(SessionManager.class);
+ private static final Logger logger = Logger.getLogger(SessionManagerImpl.class);
+ private final ManagerFactory managerFactory;
private final ConcurrentHashMap sessions = new ConcurrentHashMap<>();
+ public SessionManagerImpl(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
+ @Override
public Optional getSession(@Nonnull String sessionId) {
Session session = sessions.get(sessionId);
if (session == null) {
logger.trace("Session with sessionId " + sessionId + " is not found");
return Optional.empty();
}
- if (session.getUserId() != null && !UserManager.instance.getUser(session.getUserId()).isPresent()) {
+ if (session.getUserId() != null && !managerFactory.userManager().getUser(session.getUserId()).isPresent()) {
logger.error("User for session " + sessionId + " with userId " + session.getUserId() + " is missing. Session removed.");
// can happen if user from same host signs in multiple time with multiple clients, after they disconnect with one client
disconnect(sessionId, DisconnectReason.ConnectingOtherInstance, session); // direct disconnect
@@ -36,11 +41,13 @@ public enum SessionManager {
return Optional.of(session);
}
+ @Override
public void createSession(String sessionId, InvokerCallbackHandler callbackHandler) {
- Session session = new Session(sessionId, callbackHandler);
+ Session session = new Session(managerFactory, sessionId, callbackHandler);
sessions.put(sessionId, session);
}
+ @Override
public boolean registerUser(String sessionId, String userName, String password, String email) throws MageException {
Session session = sessions.get(sessionId);
if (session == null) {
@@ -59,6 +66,7 @@ public enum SessionManager {
return true;
}
+ @Override
public boolean connectUser(String sessionId, String userName, String password, String userIdStr) throws MageException {
Session session = sessions.get(sessionId);
if (session != null) {
@@ -78,6 +86,7 @@ public enum SessionManager {
return false;
}
+ @Override
public boolean connectAdmin(String sessionId) {
Session session = sessions.get(sessionId);
if (session != null) {
@@ -88,17 +97,20 @@ public enum SessionManager {
return false;
}
+ @Override
public boolean setUserData(String userName, String sessionId, UserData userData, String clientVersion, String userIdStr) throws MageException {
- return getSession(sessionId)
- .map(session -> session.setUserData(userName,userData, clientVersion, userIdStr))
- .orElse(false);
+ return getSession(sessionId)
+ .map(session -> session.setUserData(userName, userData, clientVersion, userIdStr))
+ .orElse(false);
}
+ @Override
public void disconnect(String sessionId, DisconnectReason reason) {
disconnect(sessionId, reason, null);
}
+ @Override
public void disconnect(String sessionId, DisconnectReason reason, Session directSession) {
if (directSession == null) {
// find real session to disconnects
@@ -115,13 +127,13 @@ public enum SessionManager {
break;
case ConnectingOtherInstance:
case Disconnected: // regular session end or wrong client version
- UserManager.instance.disconnect(session.getUserId(), reason);
+ managerFactory.userManager().disconnect(session.getUserId(), reason);
break;
case SessionExpired: // session ends after no reconnect happens in the defined time span
break;
case LostConnection: // user lost connection - session expires countdown starts
session.userLostConnection();
- UserManager.instance.disconnect(session.getUserId(), reason);
+ managerFactory.userManager().disconnect(session.getUserId(), reason);
break;
default:
logger.trace("endSession: unexpected reason " + reason.toString() + " - sessionId: " + sessionId);
@@ -141,6 +153,7 @@ public enum SessionManager {
* @param sessionId
* @param userSessionId
*/
+ @Override
public void disconnectUser(String sessionId, String userSessionId) {
if (isAdmin(sessionId)) {
getUserFromSession(sessionId).ifPresent(admin -> {
@@ -159,40 +172,46 @@ public enum SessionManager {
private Optional getUserFromSession(String sessionId) {
return getSession(sessionId)
- .flatMap(s -> UserManager.instance.getUser(s.getUserId()));
+ .flatMap(s -> managerFactory.userManager().getUser(s.getUserId()));
}
+ @Override
public void endUserSession(String sessionId, String userSessionId) {
if (isAdmin(sessionId)) {
disconnect(userSessionId, DisconnectReason.AdminDisconnect);
}
}
+ @Override
public boolean isAdmin(String sessionId) {
return getSession(sessionId).map(Session::isAdmin).orElse(false);
}
+ @Override
public boolean isValidSession(@Nonnull String sessionId) {
return sessions.containsKey(sessionId);
}
+ @Override
public Optional getUser(@Nonnull String sessionId) {
Session session = sessions.get(sessionId);
if (session != null) {
- return UserManager.instance.getUser(sessions.get(sessionId).getUserId());
+ return managerFactory.userManager().getUser(sessions.get(sessionId).getUserId());
}
logger.error(String.format("Session %s could not be found", sessionId));
return Optional.empty();
}
+ @Override
public boolean extendUserSession(String sessionId, String pingInfo) {
return getSession(sessionId)
- .map(session -> UserManager.instance.extendUserSession(session.getUserId(), pingInfo))
+ .map(session -> managerFactory.userManager().extendUserSession(session.getUserId(), pingInfo))
.orElse(false);
}
+ @Override
public void sendErrorMessageToClient(String sessionId, String message) {
Session session = sessions.get(sessionId);
if (session == null) {
diff --git a/Mage.Server/src/main/java/mage/server/TableController.java b/Mage.Server/src/main/java/mage/server/TableController.java
index 868fd5f4ee..ca2ce8fe04 100644
--- a/Mage.Server/src/main/java/mage/server/TableController.java
+++ b/Mage.Server/src/main/java/mage/server/TableController.java
@@ -20,16 +20,12 @@ import mage.game.tournament.TournamentOptions;
import mage.game.tournament.TournamentPlayer;
import mage.players.Player;
import mage.players.PlayerType;
-import mage.server.draft.DraftManager;
import mage.server.game.GameFactory;
-import mage.server.game.GameManager;
import mage.server.game.PlayerFactory;
+import mage.server.managers.ManagerFactory;
import mage.server.record.TableRecorderImpl;
import mage.server.tournament.TournamentFactory;
-import mage.server.tournament.TournamentManager;
-import mage.server.util.ConfigSettings;
import mage.server.util.ServerMessagesUtil;
-import mage.server.util.ThreadExecutor;
import mage.view.ChatMessage;
import org.apache.log4j.Logger;
@@ -47,6 +43,7 @@ public class TableController {
private static final Logger logger = Logger.getLogger(TableController.class);
+ private final ManagerFactory managerFactory;
private final UUID userId;
private final UUID chatId;
private final String controllerName;
@@ -58,32 +55,36 @@ public class TableController {
private Tournament tournament;
private ScheduledFuture> futureTimeout;
- protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.instance.getTimeoutExecutor();
+ protected final ScheduledExecutorService timeoutExecutor;
- public TableController(UUID roomId, UUID userId, MatchOptions options) {
+ public TableController(ManagerFactory managerFactory, UUID roomId, UUID userId, MatchOptions options) {
+ this.managerFactory = managerFactory;
+ timeoutExecutor = managerFactory.threadExecutor().getTimeoutExecutor();
this.userId = userId;
this.options = options;
match = GameFactory.instance.createMatch(options.getGameType(), options);
if (userId != null) {
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = managerFactory.userManager().getUser(userId);
// TODO: Handle if user == null
controllerName = user.map(User::getName).orElse("undefined");
} else {
controllerName = "System";
}
table = new Table(roomId, options.getGameType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getDeckType()),
- options.getPlayerTypes(), TableRecorderImpl.instance, match, options.getBannedUsers(), options.isPlaneChase());
- chatId = ChatManager.instance.createChatSession("Match Table " + table.getId());
+ options.getPlayerTypes(), new TableRecorderImpl(managerFactory.userManager()), match, options.getBannedUsers(), options.isPlaneChase());
+ chatId = managerFactory.chatManager().createChatSession("Match Table " + table.getId());
init();
}
- public TableController(UUID roomId, UUID userId, TournamentOptions options) {
+ public TableController(ManagerFactory managerFactory, UUID roomId, UUID userId, TournamentOptions options) {
+ this.managerFactory = managerFactory;
+ this.timeoutExecutor = managerFactory.threadExecutor().getTimeoutExecutor();
this.userId = userId;
tournament = TournamentFactory.instance.createTournament(options.getTournamentType(), options);
if (userId != null) {
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = managerFactory.userManager().getUser(userId);
if (!user.isPresent()) {
- logger.fatal(new StringBuilder("User for userId ").append(userId).append(" could not be retrieved from UserManager").toString());
+ logger.fatal(new StringBuilder("User for userId ").append(userId).append(" could not be retrieved from UserManagerImpl").toString());
controllerName = "[unknown]";
} else {
controllerName = user.get().getName();
@@ -92,8 +93,8 @@ public class TableController {
controllerName = "System";
}
table = new Table(roomId, options.getTournamentType(), options.getName(), controllerName, DeckValidatorFactory.instance.createDeckValidator(options.getMatchOptions().getDeckType()),
- options.getPlayerTypes(), TableRecorderImpl.instance, tournament, options.getMatchOptions().getBannedUsers(), options.isPlaneChase());
- chatId = ChatManager.instance.createChatSession("Tourn. table " + table.getId());
+ options.getPlayerTypes(), new TableRecorderImpl(managerFactory.userManager()), tournament, options.getMatchOptions().getBannedUsers(), options.isPlaneChase());
+ chatId = managerFactory.chatManager().createChatSession("Tourn. table " + table.getId());
}
private void init() {
@@ -121,7 +122,7 @@ public class TableController {
if (seat == null) {
throw new GameException("No available seats.");
}
- Optional _user = UserManager.instance.getUser(userId);
+ Optional _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
logger.fatal("couldn't get user " + name + " for join tournament userId = " + userId);
return false;
@@ -156,7 +157,7 @@ public class TableController {
user.showUserMessage("Join Table", sb.toString());
if (isOwner(userId)) {
logger.debug("New table removed because owner submitted invalid deck tableId " + table.getId());
- TableManager.instance.removeTable(table.getId());
+ managerFactory.tableManager().removeTable(table.getId());
}
return false;
}
@@ -231,12 +232,12 @@ public class TableController {
newTournamentPlayer.setState(oldTournamentPlayer.getState());
newTournamentPlayer.setReplacedTournamentPlayer(oldTournamentPlayer);
- DraftManager.instance.getController(table.getId()).ifPresent(controller -> controller.replacePlayer(oldPlayer, newPlayer));
+ managerFactory.draftManager().getController(table.getId()).ifPresent(controller -> controller.replacePlayer(oldPlayer, newPlayer));
return true;
}
public synchronized boolean joinTable(UUID userId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException {
- Optional _user = UserManager.instance.getUser(userId);
+ Optional _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
logger.error("Join Table: can't find user to join " + name + " Id = " + userId);
return false;
@@ -274,7 +275,7 @@ public class TableController {
user.showUserMessage("Join Table", sb.toString());
if (isOwner(userId)) {
logger.debug("New table removed because owner submitted invalid deck tableId " + table.getId());
- TableManager.instance.removeTable(table.getId());
+ managerFactory.tableManager().removeTable(table.getId());
}
return false;
}
@@ -420,7 +421,7 @@ public class TableController {
}
}
if (!Main.isTestMode() && !table.getValidator().validate(deck)) {
- Optional _user = UserManager.instance.getUser(userId);
+ Optional _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
return false;
}
@@ -453,10 +454,10 @@ public class TableController {
private void submitDeck(UUID userId, UUID playerId, Deck deck) {
if (table.getState() == TableState.SIDEBOARDING) {
match.submitDeck(playerId, deck);
- UserManager.instance.getUser(userId).ifPresent(user -> user.removeSideboarding(table.getId()));
+ managerFactory.userManager().getUser(userId).ifPresent(user -> user.removeSideboarding(table.getId()));
} else {
- TournamentManager.instance.submitDeck(tournament.getId(), playerId, deck);
- UserManager.instance.getUser(userId).ifPresent(user -> user.removeConstructing(playerId));
+ managerFactory.tournamentManager().submitDeck(tournament.getId(), playerId, deck);
+ managerFactory.userManager().getUser(userId).ifPresent(user -> user.removeConstructing(playerId));
}
}
@@ -464,7 +465,7 @@ public class TableController {
boolean validDeck = true;
if (table.isTournament()) {
if (tournament != null) {
- validDeck = TournamentManager.instance.updateDeck(tournament.getId(), playerId, deck);
+ validDeck = managerFactory.tournamentManager().updateDeck(tournament.getId(), playerId, deck);
} else {
logger.fatal("Tournament == null table: " + table.getId() + " userId: " + userId);
}
@@ -478,7 +479,7 @@ public class TableController {
public boolean watchTable(UUID userId) {
if (table.isTournament()) {
- UserManager.instance.getUser(userId).ifPresent(user -> user.ccShowTournament(table.getTournament().getId()));
+ managerFactory.userManager().getUser(userId).ifPresent(user -> user.ccShowTournament(table.getTournament().getId()));
return true;
} else {
if (table.isTournamentSubTable() && !table.getTournament().getOptions().isWatchingAllowed()) {
@@ -491,7 +492,7 @@ public class TableController {
if (userPlayerMap.get(userId) != null) {
return false;
}
- Optional _user = UserManager.instance.getUser(userId);
+ Optional _user = managerFactory.userManager().getUser(userId);
if (!_user.isPresent()) {
return false;
}
@@ -533,7 +534,7 @@ public class TableController {
&& (table.getState() == TableState.WAITING
|| table.getState() == TableState.READY_TO_START)) {
// table not started yet and user is the owner, removeUserFromAllTablesAndChat the table
- TableManager.instance.removeTable(table.getId());
+ managerFactory.tableManager().removeTable(table.getId());
} else {
UUID playerId = userPlayerMap.get(userId);
if (playerId != null) {
@@ -544,9 +545,9 @@ public class TableController {
} else {
match.quitMatch(playerId);
}
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = managerFactory.userManager().getUser(userId);
if (user.isPresent()) {
- ChatManager.instance.broadcast(chatId, user.get().getName(), "has left the table", ChatMessage.MessageColor.BLUE, true, null, ChatMessage.MessageType.STATUS, ChatMessage.SoundToPlay.PlayerLeft);
+ managerFactory.chatManager().broadcast(chatId, user.get().getName(), "has left the table", ChatMessage.MessageColor.BLUE, true, null, ChatMessage.MessageType.STATUS, ChatMessage.SoundToPlay.PlayerLeft);
if (!table.isTournamentSubTable()) {
user.get().removeTable(playerId);
}
@@ -557,9 +558,9 @@ public class TableController {
} else if (table.getState() != TableState.FINISHED) {
if (table.isTournament()) {
logger.debug("Quit tournament sub tables for userId: " + userId);
- TableManager.instance.userQuitTournamentSubTables(tournament.getId(), userId);
+ managerFactory.tableManager().userQuitTournamentSubTables(tournament.getId(), userId);
logger.debug("Quit tournament Id: " + table.getTournament().getId() + '(' + table.getTournament().getTournamentState() + ')');
- TournamentManager.instance.quit(tournament.getId(), userId);
+ managerFactory.tournamentManager().quit(tournament.getId(), userId);
} else {
MatchPlayer matchPlayer = match.getPlayer(playerId);
if (matchPlayer != null && !match.hasEnded() && !matchPlayer.hasQuit()) {
@@ -567,7 +568,7 @@ public class TableController {
if (game != null && !game.hasEnded()) {
Player player = match.getPlayer(playerId).getPlayer();
if (player != null && player.isInGame()) {
- GameManager.instance.quitMatch(game.getId(), userId);
+ managerFactory.gameManager().quitMatch(game.getId(), userId);
}
match.quitMatch(playerId);
} else {
@@ -605,7 +606,7 @@ public class TableController {
if (table.isTournamentSubTable()) {
logger.info("Tourn. match started id:" + match.getId() + " tournId: " + table.getTournament().getId());
} else {
- UserManager.instance.getUser(userId).ifPresent(user -> {
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
logger.info("MATCH started [" + match.getName() + "] " + match.getId() + '(' + user.getName() + ')');
logger.debug("- " + match.getOptions().getGameType() + " - " + match.getOptions().getDeckType());
});
@@ -628,12 +629,12 @@ public class TableController {
gameOptions.bannedUsers = match.getOptions().getBannedUsers();
gameOptions.planeChase = match.getOptions().isPlaneChase();
match.getGame().setGameOptions(gameOptions);
- GameManager.instance.createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId, gameOptions);
+ managerFactory.gameManager().createGameSession(match.getGame(), userPlayerMap, table.getId(), choosingPlayerId, gameOptions);
String creator = null;
StringBuilder opponent = new StringBuilder();
for (Entry entry : userPlayerMap.entrySet()) { // do only for no AI players
if (match.getPlayer(entry.getValue()) != null && !match.getPlayer(entry.getValue()).hasQuit()) {
- Optional _user = UserManager.instance.getUser(entry.getKey());
+ Optional _user = managerFactory.userManager().getUser(entry.getKey());
if (_user.isPresent()) {
User user = _user.get();
user.ccGameStarted(match.getGame().getId(), entry.getValue());
@@ -670,17 +671,17 @@ public class TableController {
logger.info("GAME started " + (match.getGame() != null ? match.getGame().getId() : "no Game") + " [" + match.getName() + "] " + creator + " - " + opponent.toString());
logger.debug("- matchId: " + match.getId() + " [" + match.getName() + ']');
if (match.getGame() != null) {
- logger.debug("- chatId: " + GameManager.instance.getChatId(match.getGame().getId()));
+ logger.debug("- chatId: " + managerFactory.gameManager().getChatId(match.getGame().getId()));
}
} catch (Exception ex) {
logger.fatal("Error starting game table: " + table.getId(), ex);
if (table != null) {
- TableManager.instance.removeTable(table.getId());
+ managerFactory.tableManager().removeTable(table.getId());
}
if (match != null) {
Game game = match.getGame();
if (game != null) {
- GameManager.instance.removeGame(game.getId());
+ managerFactory.gameManager().removeGame(game.getId());
// game ended by error, so don't add it to ended stats
}
}
@@ -691,9 +692,9 @@ public class TableController {
try {
if (userId.equals(this.userId) && table.getState() == TableState.STARTING) {
tournament.setStartTime();
- TournamentManager.instance.createTournamentSession(tournament, userPlayerMap, table.getId());
+ managerFactory.tournamentManager().createTournamentSession(tournament, userPlayerMap, table.getId());
for (Entry entry : userPlayerMap.entrySet()) {
- UserManager.instance.getUser(entry.getKey()).ifPresent(user -> {
+ managerFactory.userManager().getUser(entry.getKey()).ifPresent(user -> {
logger.info(new StringBuilder("User ").append(user.getName()).append(" tournament started: ").append(tournament.getId()).append(" userId: ").append(user.getId()));
user.ccTournamentStarted(tournament.getId(), entry.getValue());
});
@@ -702,16 +703,16 @@ public class TableController {
}
} catch (Exception ex) {
logger.fatal("Error starting tournament", ex);
- TableManager.instance.removeTable(table.getId());
- TournamentManager.instance.quit(tournament.getId(), userId);
+ managerFactory.tableManager().removeTable(table.getId());
+ managerFactory.tournamentManager().quit(tournament.getId(), userId);
}
}
public void startDraft(Draft draft) {
table.initDraft();
- DraftManager.instance.createDraftSession(draft, userPlayerMap, table.getId());
+ managerFactory.draftManager().createDraftSession(draft, userPlayerMap, table.getId());
for (Entry entry : userPlayerMap.entrySet()) {
- Optional user = UserManager.instance.getUser(entry.getKey());
+ Optional user = managerFactory.userManager().getUser(entry.getKey());
if (user.isPresent()) {
logger.info(new StringBuilder("User ").append(user.get().getName()).append(" draft started: ").append(draft.getId()).append(" userId: ").append(user.get().getId()));
user.get().ccDraftStarted(draft.getId(), entry.getValue());
@@ -725,7 +726,7 @@ public class TableController {
for (Entry entry : userPlayerMap.entrySet()) {
if (entry.getValue().equals(playerId)) {
- Optional user = UserManager.instance.getUser(entry.getKey());
+ Optional user = managerFactory.userManager().getUser(entry.getKey());
int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS);
user.ifPresent(user1 -> user1.ccSideboard(deck, table.getId(), remaining, options.isLimited()));
break;
@@ -767,12 +768,12 @@ public class TableController {
}
UUID choosingPlayerId = match.getChooser();
match.endGame();
- if (ConfigSettings.instance.isSaveGameActivated() && !game.isSimulation()) {
- if (GameManager.instance.saveGame(game.getId())) {
+ if (managerFactory.configSettings().isSaveGameActivated() && !game.isSimulation()) {
+ if (managerFactory.gameManager().saveGame(game.getId())) {
match.setReplayAvailable(true);
}
}
- GameManager.instance.removeGame(game.getId());
+ managerFactory.gameManager().removeGame(game.getId());
ServerMessagesUtil.instance.incGamesEnded();
try {
@@ -835,7 +836,7 @@ public class TableController {
// opponent(s) left during sideboarding
if (matchPlayer != null) {
if (!matchPlayer.hasQuit()) {
- UserManager.instance.getUser(entry.getKey()).ifPresent(user -> {
+ managerFactory.userManager().getUser(entry.getKey()).ifPresent(user -> {
if (table.getState() == TableState.SIDEBOARDING) {
StringBuilder sb = new StringBuilder();
if (table.isTournamentSubTable()) {
@@ -860,7 +861,7 @@ public class TableController {
}
}
// free resources no longer needed
- match.cleanUpOnMatchEnd(ConfigSettings.instance.isSaveGameActivated(), table.isTournament());
+ match.cleanUpOnMatchEnd(managerFactory.configSettings().isSaveGameActivated(), table.isTournament());
}
}
}
@@ -932,13 +933,13 @@ public class TableController {
public boolean isTournamentStillValid() {
if (table.getTournament() != null) {
if (table.getState() != TableState.WAITING && table.getState() != TableState.READY_TO_START && table.getState() != TableState.STARTING) {
- return TournamentManager.instance.getTournamentController(table.getTournament().getId())
+ return managerFactory.tournamentManager().getTournamentController(table.getTournament().getId())
.map(tc -> tc.isTournamentStillValid(table.getState()))
.orElse(false);
} else {
// check if table creator is still a valid user, if not removeUserFromAllTablesAndChat table
- return UserManager.instance.getUser(userId).isPresent();
+ return managerFactory.userManager().getUser(userId).isPresent();
}
}
return false;
@@ -1004,7 +1005,7 @@ public class TableController {
|| table.getState() == TableState.READY_TO_START)
|| !match.isDoneSideboarding()
|| (!matchPlayer.hasQuit() && match.getGame() != null && matchPlayer.getPlayer().isInGame())) {
- Optional user = UserManager.instance.getUser(userPlayerEntry.getKey());
+ Optional user = managerFactory.userManager().getUser(userPlayerEntry.getKey());
if (!user.isPresent() || !user.get().isActive()) {
logger.warn("- Active user of match is missing: " + matchPlayer.getName());
logger.warn("-- matchId:" + match.getId());
@@ -1028,12 +1029,12 @@ public class TableController {
void cleanUp() {
if (!table.isTournamentSubTable()) {
for (Map.Entry entry : userPlayerMap.entrySet()) {
- UserManager.instance.getUser(entry.getKey()).ifPresent(user
+ managerFactory.userManager().getUser(entry.getKey()).ifPresent(user
-> user.removeTable(entry.getValue()));
}
}
- ChatManager.instance.destroyChatSession(chatId);
+ managerFactory.chatManager().destroyChatSession(chatId);
}
public synchronized TableState getTableState() {
diff --git a/Mage.Server/src/main/java/mage/server/TableManager.java b/Mage.Server/src/main/java/mage/server/TableManagerImpl.java
similarity index 85%
rename from Mage.Server/src/main/java/mage/server/TableManager.java
rename to Mage.Server/src/main/java/mage/server/TableManagerImpl.java
index b898241ab2..268c4f20fe 100644
--- a/Mage.Server/src/main/java/mage/server/TableManager.java
+++ b/Mage.Server/src/main/java/mage/server/TableManagerImpl.java
@@ -14,9 +14,8 @@ import mage.game.tournament.TournamentOptions;
import mage.game.tournament.TournamentPlayer;
import mage.players.PlayerType;
import mage.server.game.GameController;
-import mage.server.game.GameManager;
-import mage.server.game.GamesRoomManager;
-import mage.server.util.ThreadExecutor;
+import mage.server.managers.TableManager;
+import mage.server.managers.ManagerFactory;
import org.apache.log4j.Logger;
import java.text.DateFormat;
@@ -34,12 +33,12 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @author BetaSteward_at_googlemail.com
*/
-public enum TableManager {
- instance;
+public class TableManagerImpl implements TableManager {
protected final ScheduledExecutorService expireExecutor = Executors.newSingleThreadScheduledExecutor();
- // protected static ScheduledExecutorService expireExecutor = ThreadExecutor.getInstance().getExpireExecutor();
- private final Logger logger = Logger.getLogger(TableManager.class);
+ // protected static ScheduledExecutorService expireExecutor = ThreadExecutorImpl.getInstance().getExpireExecutor();
+ private final ManagerFactory managerFactory;
+ private final Logger logger = Logger.getLogger(TableManagerImpl.class);
private final DateFormat formatter = new SimpleDateFormat("HH:mm:ss");
private final ConcurrentHashMap controllers = new ConcurrentHashMap<>();
@@ -55,10 +54,14 @@ public enum TableManager {
*/
private static final int EXPIRE_CHECK_PERIOD = 10;
- TableManager() {
+ public TableManagerImpl(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
+ public void init() {
expireExecutor.scheduleAtFixedRate(() -> {
try {
- ChatManager.instance.clearUserMessageStorage();
+ managerFactory.chatManager().clearUserMessageStorage();
checkTableHealthState();
} catch (Exception ex) {
logger.fatal("Check table health state job error:", ex);
@@ -66,22 +69,25 @@ public enum TableManager {
}, EXPIRE_CHECK_PERIOD, EXPIRE_CHECK_PERIOD, TimeUnit.MINUTES);
}
+ @Override
public Table createTable(UUID roomId, UUID userId, MatchOptions options) {
- TableController tableController = new TableController(roomId, userId, options);
+ TableController tableController = new TableController(managerFactory, roomId, userId, options);
putControllers(tableController.getTable().getId(), tableController);
putTables(tableController.getTable().getId(), tableController.getTable());
return tableController.getTable();
}
+ @Override
public Table createTable(UUID roomId, MatchOptions options) {
- TableController tableController = new TableController(roomId, null, options);
+ TableController tableController = new TableController(managerFactory, roomId, null, options);
putControllers(tableController.getTable().getId(), tableController);
putTables(tableController.getTable().getId(), tableController.getTable());
return tableController.getTable();
}
+ @Override
public Table createTournamentTable(UUID roomId, UUID userId, TournamentOptions options) {
- TableController tableController = new TableController(roomId, userId, options);
+ TableController tableController = new TableController(managerFactory, roomId, userId, options);
putControllers(tableController.getTable().getId(), tableController);
putTables(tableController.getTable().getId(), tableController.getTable());
return tableController.getTable();
@@ -107,10 +113,12 @@ public enum TableManager {
}
}
+ @Override
public Table getTable(UUID tableId) {
return tables.get(tableId);
}
+ @Override
public Optional getMatch(UUID tableId) {
if (controllers.containsKey(tableId)) {
return Optional.of(controllers.get(tableId).getMatch());
@@ -118,6 +126,7 @@ public enum TableManager {
return Optional.empty();
}
+ @Override
public Collection getTables() {
Collection newTables = new ArrayList<>();
final Lock r = tablesLock.readLock();
@@ -130,6 +139,7 @@ public enum TableManager {
return newTables;
}
+ @Override
public Collection getControllers() {
Collection newControllers = new ArrayList<>();
final Lock r = controllersLock.readLock();
@@ -142,6 +152,7 @@ public enum TableManager {
return newControllers;
}
+ @Override
public Optional getController(UUID tableId) {
if (controllers.containsKey(tableId)) {
return Optional.of(controllers.get(tableId));
@@ -149,6 +160,7 @@ public enum TableManager {
return Optional.empty();
}
+ @Override
public boolean joinTable(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws MageException {
if (controllers.containsKey(tableId)) {
return controllers.get(tableId).joinTable(userId, name, playerType, skill, deckList, password);
@@ -156,6 +168,7 @@ public enum TableManager {
return false;
}
+ @Override
public boolean joinTournament(UUID userId, UUID tableId, String name, PlayerType playerType, int skill, DeckCardLists deckList, String password) throws GameException {
if (controllers.containsKey(tableId)) {
return controllers.get(tableId).joinTournament(userId, name, playerType, skill, deckList, password);
@@ -163,11 +176,12 @@ public enum TableManager {
return false;
}
+ @Override
public boolean submitDeck(UUID userId, UUID tableId, DeckCardLists deckList) throws MageException {
if (controllers.containsKey(tableId)) {
return controllers.get(tableId).submitDeck(userId, deckList);
}
- UserManager.instance.getUser(userId).ifPresent(user -> {
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
user.removeSideboarding(tableId);
user.showUserMessage("Submit deck", "Table no longer active");
@@ -176,6 +190,7 @@ public enum TableManager {
return true;
}
+ @Override
public void updateDeck(UUID userId, UUID tableId, DeckCardLists deckList) throws MageException {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).updateDeck(userId, deckList);
@@ -183,6 +198,7 @@ public enum TableManager {
}
// removeUserFromAllTablesAndChat user from all tournament sub tables
+ @Override
public void userQuitTournamentSubTables(UUID userId) {
for (TableController controller : getControllers()) {
if (controller.getTable() != null) {
@@ -190,12 +206,13 @@ public enum TableManager {
controller.leaveTable(userId);
}
} else {
- logger.error("TableManager.userQuitTournamentSubTables table == null - userId " + userId);
+ logger.error("TableManagerImpl.userQuitTournamentSubTables table == null - userId " + userId);
}
}
}
// removeUserFromAllTablesAndChat user from all sub tables of a tournament
+ @Override
public void userQuitTournamentSubTables(UUID tournamentId, UUID userId) {
for (TableController controller : getControllers()) {
if (controller.getTable().isTournamentSubTable() && controller.getTable().getTournament().getId().equals(tournamentId)) {
@@ -206,6 +223,7 @@ public enum TableManager {
}
}
+ @Override
public boolean isTableOwner(UUID tableId, UUID userId) {
if (controllers.containsKey(tableId)) {
return controllers.get(tableId).isOwner(userId);
@@ -213,13 +231,14 @@ public enum TableManager {
return false;
}
+ @Override
public boolean removeTable(UUID userId, UUID tableId) {
- if (isTableOwner(tableId, userId) || UserManager.instance.isAdmin(userId)) {
+ if (isTableOwner(tableId, userId) || managerFactory.userManager().isAdmin(userId)) {
logger.debug("Table remove request - userId: " + userId + " tableId: " + tableId);
TableController tableController = controllers.get(tableId);
if (tableController != null) {
tableController.leaveTableAll();
- ChatManager.instance.destroyChatSession(tableController.getChatId());
+ managerFactory.chatManager().destroyChatSession(tableController.getChatId());
removeTable(tableId);
}
return true;
@@ -227,6 +246,7 @@ public enum TableManager {
return false;
}
+ @Override
public void leaveTable(UUID userId, UUID tableId) {
TableController tableController = controllers.get(tableId);
if (tableController != null) {
@@ -234,6 +254,7 @@ public enum TableManager {
}
}
+ @Override
public Optional getChatId(UUID tableId) {
if (controllers.containsKey(tableId)) {
return Optional.of(controllers.get(tableId).getChatId());
@@ -248,11 +269,12 @@ public enum TableManager {
* @param roomId
* @param tableId
*/
+ @Override
public void startMatch(UUID userId, UUID roomId, UUID tableId) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).startMatch(userId);
// chat of start dialog can be killed
- ChatManager.instance.destroyChatSession(controllers.get(tableId).getChatId());
+ managerFactory.chatManager().destroyChatSession(controllers.get(tableId).getChatId());
}
}
@@ -262,25 +284,29 @@ public enum TableManager {
* @param roomId
* @param tableId
*/
+ @Override
public void startTournamentSubMatch(UUID roomId, UUID tableId) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).startMatch();
}
}
+ @Override
public void startTournament(UUID userId, UUID roomId, UUID tableId) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).startTournament(userId);
- ChatManager.instance.destroyChatSession(controllers.get(tableId).getChatId());
+ managerFactory.chatManager().destroyChatSession(controllers.get(tableId).getChatId());
}
}
+ @Override
public void startDraft(UUID tableId, Draft draft) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).startDraft(draft);
}
}
+ @Override
public boolean watchTable(UUID userId, UUID tableId) {
if (controllers.containsKey(tableId)) {
return controllers.get(tableId).watchTable(userId);
@@ -288,6 +314,7 @@ public enum TableManager {
return false;
}
+ @Override
public void endGame(UUID tableId) {
if (controllers.containsKey(tableId)) {
if (controllers.get(tableId).endGameAndStartNextGame()) {
@@ -296,42 +323,49 @@ public enum TableManager {
}
}
+ @Override
public void endDraft(UUID tableId, Draft draft) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).endDraft(draft);
}
}
+ @Override
public void endTournament(UUID tableId, Tournament tournament) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).endTournament(tournament);
}
}
+ @Override
public void swapSeats(UUID tableId, UUID userId, int seatNum1, int seatNum2) {
if (controllers.containsKey(tableId) && isTableOwner(tableId, userId)) {
controllers.get(tableId).swapSeats(seatNum1, seatNum2);
}
}
+ @Override
public void construct(UUID tableId) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).construct();
}
}
+ @Override
public void initTournament(UUID tableId) {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).initTournament();
}
}
+ @Override
public void addPlayer(UUID userId, UUID tableId, TournamentPlayer player) throws GameException {
if (controllers.containsKey(tableId)) {
controllers.get(tableId).addPlayer(userId, player.getPlayer(), player.getPlayerType(), player.getDeck());
}
}
+ @Override
public void removeTable(UUID tableId) {
TableController tableController = controllers.get(tableId);
if (tableController != null) {
@@ -365,21 +399,22 @@ public enum TableManager {
// If table is not finished, the table has to be removed completly because it's not a normal state (if finished it will be removed in GamesRoomImpl.Update())
if (table.getState() != TableState.FINISHED) {
if (game != null) {
- GameManager.instance.removeGame(game.getId());
+ managerFactory.gameManager().removeGame(game.getId());
// something goes wrong, so don't add it to ended stats
}
- GamesRoomManager.instance.removeTable(tableId);
+ managerFactory.gamesRoomManager().removeTable(tableId);
}
}
}
+ @Override
public void debugServerState() {
logger.debug("--- Server state ----------------------------------------------");
- Collection users = UserManager.instance.getUsers();
+ Collection users = managerFactory.userManager().getUsers();
logger.debug("--------User: " + users.size() + " [userId | since | lock | name -----------------------");
for (User user : users) {
- Optional session = SessionManager.instance.getSession(user.getSessionId());
+ Optional session = managerFactory.sessionManager().getSession(user.getSessionId());
String sessionState = "N";
if (session.isPresent()) {
if (session.get().isLocked()) {
@@ -393,14 +428,14 @@ public enum TableManager {
+ " | " + sessionState
+ " | " + user.getName() + " (" + user.getUserState().toString() + " - " + user.getPingInfo() + ')');
}
- List chatSessions = ChatManager.instance.getChatSessions();
+ List chatSessions = managerFactory.chatManager().getChatSessions();
logger.debug("------- ChatSessions: " + chatSessions.size() + " ----------------------------------");
for (ChatSession chatSession : chatSessions) {
logger.debug(chatSession.getChatId() + " " + formatter.format(chatSession.getCreateTime()) + ' ' + chatSession.getInfo() + ' ' + chatSession.getClients().values().toString());
}
- logger.debug("------- Games: " + GameManager.instance.getNumberActiveGames() + " --------------------------------------------");
- logger.debug(" Active Game Worker: " + ThreadExecutor.instance.getActiveThreads(ThreadExecutor.instance.getGameExecutor()));
- for (Entry entry : GameManager.instance.getGameController().entrySet()) {
+ logger.debug("------- Games: " + managerFactory.gameManager().getNumberActiveGames() + " --------------------------------------------");
+ logger.debug(" Active Game Worker: " + managerFactory.threadExecutor().getActiveThreads(managerFactory.threadExecutor().getGameExecutor()));
+ for (Entry entry : managerFactory.gameManager().getGameController().entrySet()) {
logger.debug(entry.getKey() + entry.getValue().getPlayerNameList());
}
logger.debug("--- Server state END ------------------------------------------");
diff --git a/Mage.Server/src/main/java/mage/server/User.java b/Mage.Server/src/main/java/mage/server/User.java
index 7cde19283f..cb0dba3047 100644
--- a/Mage.Server/src/main/java/mage/server/User.java
+++ b/Mage.Server/src/main/java/mage/server/User.java
@@ -10,14 +10,13 @@ import mage.interfaces.callback.ClientCallback;
import mage.interfaces.callback.ClientCallbackMethod;
import mage.players.net.UserData;
import mage.server.draft.DraftSession;
-import mage.server.game.GameManager;
import mage.server.game.GameSessionPlayer;
+import mage.server.managers.ManagerFactory;
import mage.server.rating.GlickoRating;
import mage.server.rating.GlickoRatingSystem;
import mage.server.record.UserStats;
import mage.server.record.UserStatsRepository;
import mage.server.tournament.TournamentController;
-import mage.server.tournament.TournamentManager;
import mage.server.tournament.TournamentSession;
import mage.server.util.ServerMessagesUtil;
import mage.server.util.SystemUtil;
@@ -43,6 +42,7 @@ public class User {
Offline // set if the user was disconnected and expired or regularly left XMage. Removed is the user later after some time
}
+ private final ManagerFactory managerFactory;
private final UUID userId;
private final String userName;
private final String host;
@@ -68,7 +68,8 @@ public class User {
private String clientVersion;
private String userIdStr;
- public User(String userName, String host, AuthorizedUser authorizedUser) {
+ public User(ManagerFactory managerFactory, String userName, String host, AuthorizedUser authorizedUser) {
+ this.managerFactory = managerFactory;
this.userId = UUID.randomUUID();
this.userName = userName;
this.host = host;
@@ -181,7 +182,7 @@ public class User {
// Because watched games don't get restored after reconnection call stop watching
for (Iterator iterator = watchedGames.iterator(); iterator.hasNext(); ) {
UUID gameId = iterator.next();
- GameManager.instance.stopWatching(gameId, userId);
+ managerFactory.gameManager().stopWatching(gameId, userId);
iterator.remove();
}
ServerMessagesUtil.instance.incLostConnection();
@@ -227,7 +228,7 @@ public class User {
public void fireCallback(final ClientCallback call) {
if (isConnected()) {
- SessionManager.instance.getSession(sessionId).ifPresent(session
+ managerFactory.sessionManager().getSession(sessionId).ifPresent(session
-> session.fireCallback(call)
);
}
@@ -288,27 +289,27 @@ public class User {
public void sendPlayerUUID(final UUID gameId, final UUID data) {
lastActivity = new Date();
- GameManager.instance.sendPlayerUUID(gameId, userId, data);
+ managerFactory.gameManager().sendPlayerUUID(gameId, userId, data);
}
public void sendPlayerString(final UUID gameId, final String data) {
lastActivity = new Date();
- GameManager.instance.sendPlayerString(gameId, userId, data);
+ managerFactory.gameManager().sendPlayerString(gameId, userId, data);
}
public void sendPlayerManaType(final UUID gameId, final UUID playerId, final ManaType data) {
lastActivity = new Date();
- GameManager.instance.sendPlayerManaType(gameId, playerId, userId, data);
+ managerFactory.gameManager().sendPlayerManaType(gameId, playerId, userId, data);
}
public void sendPlayerBoolean(final UUID gameId, final Boolean data) {
lastActivity = new Date();
- GameManager.instance.sendPlayerBoolean(gameId, userId, data);
+ managerFactory.gameManager().sendPlayerBoolean(gameId, userId, data);
}
public void sendPlayerInteger(final UUID gameId, final Integer data) {
lastActivity = new Date();
- GameManager.instance.sendPlayerInteger(gameId, userId, data);
+ managerFactory.gameManager().sendPlayerInteger(gameId, userId, data);
}
public void updateLastActivity(String pingInfo) {
@@ -338,7 +339,7 @@ public class User {
}
for (Iterator> iterator = userTournaments.entrySet().iterator(); iterator.hasNext(); ) {
Entry next = iterator.next();
- Optional tournamentController = TournamentManager.instance.getTournamentController(next.getValue());
+ Optional tournamentController = managerFactory.tournamentManager().getTournamentController(next.getValue());
if (tournamentController.isPresent()) {
ccTournamentStarted(next.getValue(), next.getKey());
tournamentController.get().rejoin(next.getKey());
@@ -349,7 +350,7 @@ public class User {
for (Entry entry : gameSessions.entrySet()) {
ccGameStarted(entry.getValue().getGameId(), entry.getKey());
entry.getValue().init();
- GameManager.instance.sendPlayerString(entry.getValue().getGameId(), userId, "");
+ managerFactory.gameManager().sendPlayerString(entry.getValue().getGameId(), userId, "");
}
for (Entry entry : draftSessions.entrySet()) {
@@ -362,7 +363,7 @@ public class User {
entry.getValue().construct(0); // TODO: Check if this is correct
}
for (Entry entry : sideboarding.entrySet()) {
- Optional controller = TableManager.instance.getController(entry.getKey());
+ Optional controller = managerFactory.tableManager().getController(entry.getKey());
if (controller.isPresent()) {
ccSideboard(entry.getValue(), entry.getKey(), controller.get().getRemainingTime(), controller.get().getOptions().isLimited());
} else {
@@ -427,32 +428,32 @@ public class User {
draftSessions.clear();
logger.trace("REMOVE " + userName + " Tournament sessions " + userTournaments.size());
for (UUID tournamentId : userTournaments.values()) {
- TournamentManager.instance.quit(tournamentId, userId);
+ managerFactory.tournamentManager().quit(tournamentId, userId);
}
userTournaments.clear();
constructing.clear();
logger.trace("REMOVE " + userName + " Tables " + tables.size());
for (Entry entry : tables.entrySet()) {
logger.debug("-- leave tableId: " + entry.getValue().getId());
- TableManager.instance.leaveTable(userId, entry.getValue().getId());
+ managerFactory.tableManager().leaveTable(userId, entry.getValue().getId());
}
tables.clear();
sideboarding.clear();
logger.trace("REMOVE " + userName + " Game sessions: " + gameSessions.size());
for (GameSessionPlayer gameSessionPlayer : gameSessions.values()) {
logger.debug("-- kill game session of gameId: " + gameSessionPlayer.getGameId());
- GameManager.instance.quitMatch(gameSessionPlayer.getGameId(), userId);
+ managerFactory.gameManager().quitMatch(gameSessionPlayer.getGameId(), userId);
gameSessionPlayer.quitGame();
}
gameSessions.clear();
logger.trace("REMOVE " + userName + " watched Games " + watchedGames.size());
for (Iterator it = watchedGames.iterator(); it.hasNext(); ) { // Iterator to prevent ConcurrentModificationException
UUID gameId = it.next();
- GameManager.instance.stopWatching(gameId, userId);
+ managerFactory.gameManager().stopWatching(gameId, userId);
}
watchedGames.clear();
logger.trace("REMOVE " + userName + " Chats ");
- ChatManager.instance.removeUser(userId, reason);
+ managerFactory.chatManager().removeUser(userId, reason);
}
public void setUserData(UserData userData) {
@@ -788,7 +789,7 @@ public class User {
if (table.getState() == TableState.FINISHED) {
number++;
} else {
- Optional tableController = TableManager.instance.getController(table.getId());
+ Optional tableController = managerFactory.tableManager().getController(table.getId());
if (!tableController.isPresent()) {
logger.error("table not found : " + table.getId());
} else if (tableController.get().isUserStillActive(userId)) {
diff --git a/Mage.Server/src/main/java/mage/server/UserManager.java b/Mage.Server/src/main/java/mage/server/UserManagerImpl.java
similarity index 91%
rename from Mage.Server/src/main/java/mage/server/UserManager.java
rename to Mage.Server/src/main/java/mage/server/UserManagerImpl.java
index 50c41e7fc0..8b1fa6ff34 100644
--- a/Mage.Server/src/main/java/mage/server/UserManager.java
+++ b/Mage.Server/src/main/java/mage/server/UserManagerImpl.java
@@ -1,9 +1,10 @@
package mage.server;
import mage.server.User.UserState;
+import mage.server.managers.UserManager;
+import mage.server.managers.ManagerFactory;
import mage.server.record.UserStats;
import mage.server.record.UserStatsRepository;
-import mage.server.util.ThreadExecutor;
import mage.view.UserView;
import org.apache.log4j.Logger;
@@ -19,37 +20,43 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
*
* @author BetaSteward_at_googlemail.com
*/
-public enum UserManager {
- instance;
+public class UserManagerImpl implements UserManager {
private static final int SERVER_TIMEOUTS_USER_INFORM_OPPONENTS_ABOUT_DISCONNECT_AFTER_SECS = 30; // send to chat info about disconnection troubles, must be more than ping timeout
private static final int SERVER_TIMEOUTS_USER_DISCONNECT_FROM_SERVER_AFTER_SECS = 3 * 60; // removes from all games and chats too (can be seen in users list with disconnected status)
private static final int SERVER_TIMEOUTS_USER_REMOVE_FROM_SERVER_AFTER_SECS = 8 * 60; // removes from users list
- private static final Logger logger = Logger.getLogger(UserManager.class);
+ private static final Logger logger = Logger.getLogger(UserManagerImpl.class);
protected final ScheduledExecutorService expireExecutor = Executors.newSingleThreadScheduledExecutor();
protected final ScheduledExecutorService userListExecutor = Executors.newSingleThreadScheduledExecutor();
private List userInfoList = new ArrayList<>();
+ private final ManagerFactory managerFactory;
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private final ConcurrentHashMap users = new ConcurrentHashMap<>();
- private static final ExecutorService USER_EXECUTOR = ThreadExecutor.instance.getCallExecutor();
+ private ExecutorService USER_EXECUTOR;
- UserManager() {
+ public UserManagerImpl(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
+ public void init() {
+ USER_EXECUTOR = managerFactory.threadExecutor().getCallExecutor();
expireExecutor.scheduleAtFixedRate(this::checkExpired, 60, 60, TimeUnit.SECONDS);
userListExecutor.scheduleAtFixedRate(this::updateUserInfoList, 4, 4, TimeUnit.SECONDS);
}
+ @Override
public Optional createUser(String userName, String host, AuthorizedUser authorizedUser) {
if (getUserByName(userName).isPresent()) {
return Optional.empty(); //user already exists
}
- User user = new User(userName, host, authorizedUser);
+ User user = new User(managerFactory, userName, host, authorizedUser);
final Lock w = lock.writeLock();
w.lock();
try {
@@ -60,6 +67,7 @@ public enum UserManager {
return Optional.of(user);
}
+ @Override
public Optional getUser(UUID userId) {
if (!users.containsKey(userId)) {
//logger.warn(String.format("User with id %s could not be found", userId), new Throwable()); // TODO: remove after session freezes fixed
@@ -69,6 +77,7 @@ public enum UserManager {
}
}
+ @Override
public Optional getUserByName(String userName) {
final Lock r = lock.readLock();
r.lock();
@@ -81,6 +90,7 @@ public enum UserManager {
}
+ @Override
public Collection getUsers() {
List userList = new ArrayList<>();
final Lock r = lock.readLock();
@@ -93,6 +103,7 @@ public enum UserManager {
return userList;
}
+ @Override
public boolean connectToSession(String sessionId, UUID userId) {
if (userId != null) {
User user = users.get(userId);
@@ -104,19 +115,19 @@ public enum UserManager {
return false;
}
+ @Override
public void disconnect(UUID userId, DisconnectReason reason) {
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = getUser(userId);
if (user.isPresent()) {
user.get().setSessionId("");
if (reason == DisconnectReason.Disconnected) {
removeUserFromAllTablesAndChat(userId, reason);
user.get().setUserState(UserState.Offline);
- } else {
-// ChatManager.instance.sendLostConnectionMessage(userId, reason);
}
}
}
+ @Override
public boolean isAdmin(UUID userId) {
if (userId != null) {
User user = users.get(userId);
@@ -127,6 +138,7 @@ public enum UserManager {
return false;
}
+ @Override
public void removeUserFromAllTablesAndChat(final UUID userId, final DisconnectReason reason) {
if (userId != null) {
getUser(userId).ifPresent(user
@@ -135,7 +147,7 @@ public enum UserManager {
try {
logger.info("USER REMOVE - " + user.getName() + " (" + reason.toString() + ") userId: " + userId + " [" + user.getGameInfo() + ']');
user.removeUserFromAllTables(reason);
- ChatManager.instance.removeUser(user.getId(), reason);
+ managerFactory.chatManager().removeUser(user.getId(), reason);
logger.debug("USER REMOVE END - " + user.getName());
} catch (Exception ex) {
handleException(ex);
@@ -146,13 +158,14 @@ public enum UserManager {
}
}
+ @Override
public void informUserOpponents(final UUID userId, final String message) {
if (userId != null) {
getUser(userId).ifPresent(user
-> USER_EXECUTOR.execute(
() -> {
try {
- ChatManager.instance.sendMessageToUserChats(user.getId(), message);
+ managerFactory.chatManager().sendMessageToUserChats(user.getId(), message);
} catch (Exception ex) {
handleException(ex);
}
@@ -161,6 +174,7 @@ public enum UserManager {
}
}
+ @Override
public boolean extendUserSession(UUID userId, String pingInfo) {
if (userId != null) {
User user = users.get(userId);
@@ -245,7 +259,7 @@ public enum UserManager {
private void updateUserInfoList() {
try {
List newUserInfoList = new ArrayList<>();
- for (User user : UserManager.instance.getUsers()) {
+ for (User user : getUsers()) {
newUserInfoList.add(new UserView(
user.getName(),
user.getHost(),
@@ -266,10 +280,12 @@ public enum UserManager {
}
}
+ @Override
public List getUserInfoList() {
return userInfoList;
}
+ @Override
public void handleException(Exception ex) {
if (ex != null) {
logger.fatal("User manager exception ", ex);
@@ -281,6 +297,7 @@ public enum UserManager {
}
}
+ @Override
public String getUserHistory(String userName) {
Optional user = getUserByName(userName);
if (user.isPresent()) {
@@ -295,6 +312,7 @@ public enum UserManager {
return "User " + userName + " not found";
}
+ @Override
public void updateUserHistory() {
USER_EXECUTOR.execute(() -> {
for (String updatedUser : UserStatsRepository.instance.updateUserStats()) {
diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftController.java b/Mage.Server/src/main/java/mage/server/draft/DraftController.java
index 24ef713bf6..2bead233f7 100644
--- a/Mage.Server/src/main/java/mage/server/draft/DraftController.java
+++ b/Mage.Server/src/main/java/mage/server/draft/DraftController.java
@@ -1,5 +1,3 @@
-
-
package mage.server.draft;
import mage.MageException;
@@ -9,10 +7,8 @@ import mage.game.events.Listener;
import mage.game.events.PlayerQueryEvent;
import mage.game.events.TableEvent;
import mage.players.Player;
-import mage.server.TableManager;
-import mage.server.UserManager;
import mage.server.game.GameController;
-import mage.server.util.ThreadExecutor;
+import mage.server.managers.ManagerFactory;
import mage.view.DraftPickView;
import org.apache.log4j.Logger;
@@ -25,7 +21,6 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
- *
* @author BetaSteward_at_googlemail.com
*/
public class DraftController {
@@ -33,6 +28,7 @@ public class DraftController {
private static final Logger logger = Logger.getLogger(GameController.class);
public static final String INIT_FILE_PATH = "config" + File.separator + "init.txt";
+ private final ManagerFactory managerFactory;
private final ConcurrentMap draftSessions = new ConcurrentHashMap<>();
private final ConcurrentMap userPlayerMap;
private final UUID draftSessionId;
@@ -40,7 +36,8 @@ public class DraftController {
private final UUID tableId;
private final UUID markedCard;
- public DraftController(Draft draft, ConcurrentHashMap userPlayerMap, UUID tableId) {
+ public DraftController(ManagerFactory managerFactory, Draft draft, ConcurrentHashMap userPlayerMap, UUID tableId) {
+ this.managerFactory = managerFactory;
draftSessionId = UUID.randomUUID();
this.userPlayerMap = userPlayerMap;
this.draft = draft;
@@ -61,8 +58,7 @@ public class DraftController {
endDraft();
break;
}
- }
- catch (MageException ex) {
+ } catch (MageException ex) {
logger.fatal("Table event listener error", ex);
}
}
@@ -75,13 +71,12 @@ public class DraftController {
pickCard(event.getPlayerId(), event.getMax());
break;
}
- }
- catch (MageException ex) {
+ } catch (MageException ex) {
logger.fatal("Table event listener error", ex);
}
}
);
- for (DraftPlayer player: draft.getPlayers()) {
+ for (DraftPlayer player : draft.getPlayers()) {
if (!player.getPlayer().isHuman()) {
player.setJoined();
logger.debug("player " + player.getPlayer().getId() + " has joined draft " + draft.getId());
@@ -96,13 +91,13 @@ public class DraftController {
public void join(UUID userId) {
UUID playerId = userPlayerMap.get(userId);
- DraftSession draftSession = new DraftSession(draft, userId, playerId);
+ DraftSession draftSession = new DraftSession(managerFactory, draft, userId, playerId);
draftSessions.put(playerId, draftSession);
- UserManager.instance.getUser(userId).ifPresent(user-> {
- user.addDraft(playerId, draftSession);
- logger.debug("User " + user.getName() + " has joined draft " + draft.getId());
- draft.getPlayer(playerId).setJoined();
- });
+ managerFactory.userManager().getUser(userId).ifPresent(user -> {
+ user.addDraft(playerId, draftSession);
+ logger.debug("User " + user.getName() + " has joined draft " + draft.getId());
+ draft.getPlayer(playerId).setJoined();
+ });
checkStart();
}
@@ -114,7 +109,7 @@ public class DraftController {
}
public boolean replacePlayer(Player oldPlayer, Player newPlayer) {
- if (draft.replacePlayer(oldPlayer, newPlayer)) {
+ if (draft.replacePlayer(oldPlayer, newPlayer)) {
DraftSession draftSession = draftSessions.get(oldPlayer.getId());
if (draftSession != null) {
draftSession.draftOver(); // closes the draft panel of the replaced player
@@ -128,12 +123,12 @@ public class DraftController {
private synchronized void checkStart() {
if (!draft.isStarted() && allJoined()) {
draft.setStarted();
- ThreadExecutor.instance.getCallExecutor().execute(this::startDraft);
+ managerFactory.threadExecutor().getCallExecutor().execute(this::startDraft);
}
}
private void startDraft() {
- for (final Entry entry: draftSessions.entrySet()) {
+ for (final Entry entry : draftSessions.entrySet()) {
if (!entry.getValue().init()) {
logger.fatal("Unable to initialize client for playerId " + entry.getKey());
//TODO: generate client error message
@@ -147,7 +142,7 @@ public class DraftController {
if (!draft.allJoined()) {
return false;
}
- for (DraftPlayer player: draft.getPlayers()) {
+ for (DraftPlayer player : draft.getPlayers()) {
if (player.getPlayer().isHuman() && !draftSessions.containsKey(player.getPlayer().getId())) {
return false;
}
@@ -160,12 +155,12 @@ public class DraftController {
}
private void endDraft() throws MageException {
- for (final DraftSession draftSession: draftSessions.values()) {
+ for (final DraftSession draftSession : draftSessions.values()) {
draftSession.draftOver();
draftSession.removeDraft();
}
- TableManager.instance.endDraft(tableId, draft);
- DraftManager.instance.removeDraft(draft.getId());
+ managerFactory.tableManager().endDraft(tableId, draft);
+ managerFactory.draftManager().removeDraft(draft.getId());
}
public void kill(UUID userId) {
@@ -210,7 +205,7 @@ public class DraftController {
}
private synchronized void updateDraft() throws MageException {
- for (final Entry entry: draftSessions.entrySet()) {
+ for (final Entry entry : draftSessions.entrySet()) {
entry.getValue().update();
}
}
@@ -229,7 +224,7 @@ public class DraftController {
draft.setAbort(true);
try {
endDraft();
- } catch(MageException ex) {
+ } catch (MageException ex) {
}
}
diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftManager.java b/Mage.Server/src/main/java/mage/server/draft/DraftManagerImpl.java
similarity index 75%
rename from Mage.Server/src/main/java/mage/server/draft/DraftManager.java
rename to Mage.Server/src/main/java/mage/server/draft/DraftManagerImpl.java
index 3d49b6762d..69127d4479 100644
--- a/Mage.Server/src/main/java/mage/server/draft/DraftManager.java
+++ b/Mage.Server/src/main/java/mage/server/draft/DraftManagerImpl.java
@@ -1,69 +1,83 @@
-
-
package mage.server.draft;
+import mage.game.draft.Draft;
+import mage.server.managers.DraftManager;
+import mage.server.managers.ManagerFactory;
+import mage.view.DraftPickView;
+
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import mage.game.draft.Draft;
-import mage.view.DraftPickView;
-
/**
- *
* @author BetaSteward_at_googlemail.com
*/
-public enum DraftManager {
- instance;
+public class DraftManagerImpl implements DraftManager {
+ private final ManagerFactory managerFactory;
private final ConcurrentMap draftControllers = new ConcurrentHashMap<>();
+ public DraftManagerImpl(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
+ @Override
public UUID createDraftSession(Draft draft, ConcurrentHashMap userPlayerMap, UUID tableId) {
- DraftController draftController = new DraftController(draft, userPlayerMap, tableId);
+ DraftController draftController = new DraftController(managerFactory, draft, userPlayerMap, tableId);
draftControllers.put(draft.getId(), draftController);
return draftController.getSessionId();
}
+ @Override
public void joinDraft(UUID draftId, UUID userId) {
draftControllers.get(draftId).join(userId);
}
+ @Override
public void destroyChatSession(UUID gameId) {
draftControllers.remove(gameId);
}
+ @Override
public DraftPickView sendCardPick(UUID draftId, UUID userId, UUID cardId, Set hiddenCards) {
return draftControllers.get(draftId).sendCardPick(userId, cardId, hiddenCards);
}
+ @Override
public void sendCardMark(UUID draftId, UUID userId, UUID cardId) {
draftControllers.get(draftId).sendCardMark(userId, cardId);
}
+ @Override
public void removeSession(UUID userId) {
- for (DraftController controller: draftControllers.values()) {
+ for (DraftController controller : draftControllers.values()) {
controller.kill(userId);
}
}
+ @Override
public void kill(UUID draftId, UUID userId) {
draftControllers.get(draftId).kill(userId);
}
+ @Override
public void timeout(UUID gameId, UUID userId) {
draftControllers.get(gameId).timeout(userId);
}
+ @Override
public void removeDraft(UUID draftId) {
draftControllers.remove(draftId);
}
+ @Override
public DraftController getControllerByDraftId(UUID draftId) {
return draftControllers.get(draftId);
}
+ @Override
public Optional getController(UUID tableId) {
return draftControllers.values().stream().filter(controller -> controller.getTableId().equals(tableId)).findFirst();
}
diff --git a/Mage.Server/src/main/java/mage/server/draft/DraftSession.java b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java
index d34848fdb1..bea9c5b612 100644
--- a/Mage.Server/src/main/java/mage/server/draft/DraftSession.java
+++ b/Mage.Server/src/main/java/mage/server/draft/DraftSession.java
@@ -1,6 +1,15 @@
-
package mage.server.draft;
+import mage.game.draft.Draft;
+import mage.interfaces.callback.ClientCallback;
+import mage.interfaces.callback.ClientCallbackMethod;
+import mage.server.User;
+import mage.server.managers.ManagerFactory;
+import mage.view.DraftClientMessage;
+import mage.view.DraftPickView;
+import mage.view.DraftView;
+import org.apache.log4j.Logger;
+
import java.rmi.RemoteException;
import java.util.Optional;
import java.util.Set;
@@ -8,16 +17,6 @@ import java.util.UUID;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
-import mage.game.draft.Draft;
-import mage.interfaces.callback.ClientCallback;
-import mage.interfaces.callback.ClientCallbackMethod;
-import mage.server.User;
-import mage.server.UserManager;
-import mage.server.util.ThreadExecutor;
-import mage.view.DraftClientMessage;
-import mage.view.DraftPickView;
-import mage.view.DraftView;
-import org.apache.log4j.Logger;
/**
* @author BetaSteward_at_googlemail.com
@@ -26,6 +25,7 @@ public class DraftSession {
protected static final Logger logger = Logger.getLogger(DraftSession.class);
+ private final ManagerFactory managerFactory;
protected final UUID userId;
protected final UUID playerId;
protected final Draft draft;
@@ -33,9 +33,11 @@ public class DraftSession {
protected UUID markedCard;
private ScheduledFuture> futureTimeout;
- protected static final ScheduledExecutorService timeoutExecutor = ThreadExecutor.instance.getTimeoutExecutor();
+ protected final ScheduledExecutorService timeoutExecutor;
- public DraftSession(Draft draft, UUID userId, UUID playerId) {
+ public DraftSession(ManagerFactory managerFactory, Draft draft, UUID userId, UUID playerId) {
+ this.managerFactory = managerFactory;
+ this.timeoutExecutor = managerFactory.threadExecutor().getTimeoutExecutor();
this.userId = userId;
this.draft = draft;
this.playerId = playerId;
@@ -44,12 +46,12 @@ public class DraftSession {
public boolean init() {
if (!killed) {
- Optional user = UserManager.instance.getUser(userId);
+ Optional user = managerFactory.userManager().getUser(userId);
if (user.isPresent()) {
if (futureTimeout != null && !futureTimeout.isDone()) {
int remaining = (int) futureTimeout.getDelay(TimeUnit.SECONDS);
user.get().fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_INIT, draft.getId(),
- new DraftClientMessage(getDraftView(), getDraftPickView(remaining))));
+ new DraftClientMessage(getDraftView(), getDraftPickView(remaining))));
}
return true;
}
@@ -59,16 +61,16 @@ public class DraftSession {
public void update() {
if (!killed) {
- UserManager.instance
+ managerFactory.userManager()
.getUser(userId).
ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_UPDATE, draft.getId(),
- new DraftClientMessage(getDraftView(), null))));
+ new DraftClientMessage(getDraftView(), null))));
}
}
public void draftOver() {
if (!killed) {
- UserManager.instance
+ managerFactory.userManager()
.getUser(userId)
.ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_OVER, draft.getId())));
}
@@ -77,10 +79,10 @@ public class DraftSession {
public void pickCard(int timeout) {
if (!killed) {
setupTimeout(timeout);
- UserManager.instance
+ managerFactory.userManager()
.getUser(userId)
.ifPresent(user -> user.fireCallback(new ClientCallback(ClientCallbackMethod.DRAFT_PICK, draft.getId(),
- new DraftClientMessage(getDraftView(), getDraftPickView(timeout)))));
+ new DraftClientMessage(getDraftView(), getDraftPickView(timeout)))));
}
}
@@ -89,7 +91,7 @@ public class DraftSession {
cancelTimeout();
if (seconds > 0) {
futureTimeout = timeoutExecutor.schedule(
- () -> DraftManager.instance.timeout(draft.getId(), userId),
+ () -> managerFactory.draftManager().timeout(draft.getId(), userId),
seconds, TimeUnit.SECONDS
);
}
@@ -103,7 +105,7 @@ public class DraftSession {
protected void handleRemoteException(RemoteException ex) {
logger.fatal("DraftSession error ", ex);
- DraftManager.instance.kill(draft.getId(), userId);
+ managerFactory.draftManager().kill(draft.getId(), userId);
}
public void setKilled() {
@@ -119,7 +121,7 @@ public class DraftSession {
}
public void removeDraft() {
- UserManager.instance.getUser(userId).ifPresent(user -> user.removeDraft(playerId));
+ managerFactory.userManager().getUser(userId).ifPresent(user -> user.removeDraft(playerId));
}
diff --git a/Mage.Server/src/main/java/mage/server/game/GameController.java b/Mage.Server/src/main/java/mage/server/game/GameController.java
index 3de2c5f5cd..f6ea6a032a 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameController.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameController.java
@@ -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 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 userPlayerMap, UUID tableId, UUID choosingPlayerId, GameOptions gameOptions) {
+ public GameController(ManagerFactory managerFactory, Game game, ConcurrentMap 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 = UserManager.instance.getUser(userId);
+ Optional 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 getUserByPlayerId(UUID playerId) {
for (Map.Entry 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 u = UserManager.instance.getUser(origId);
+ Optional 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 = UserManager.instance.getUser(userId);
+ Optional 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 usersInfo = new ArrayList<>();
for (Map.Entry entry : userPlayerMap.entrySet()) {
- Optional user = UserManager.instance.getUser(entry.getKey());
+ Optional 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 watchersinfo = new ArrayList<>();
for (Map.Entry entry : watchers.entrySet()) {
- Optional user = UserManager.instance.getUser(entry.getValue().userId);
+ Optional user = managerFactory.userManager().getUser(entry.getValue().userId);
user.ifPresent(u -> watchersinfo.add("* " + u.getName() + ": " + u.getPingInfo()));
}
Collections.sort(watchersinfo);
diff --git a/Mage.Server/src/main/java/mage/server/game/GameManager.java b/Mage.Server/src/main/java/mage/server/game/GameManagerImpl.java
similarity index 89%
rename from Mage.Server/src/main/java/mage/server/game/GameManager.java
rename to Mage.Server/src/main/java/mage/server/game/GameManagerImpl.java
index f265090149..3121bfdbdb 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameManager.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameManagerImpl.java
@@ -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 gameControllers = new ConcurrentHashMap<>();
private final ReadWriteLock gameControllersLock = new ReentrantReadWriteLock();
+ public GameManagerImpl(ManagerFactory managerFactory) {
+ this.managerFactory = managerFactory;
+ }
+
+ @Override
public UUID createGameSession(Game game, ConcurrentHashMap 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 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 getGameController() {
Map newControllers = new HashMap<>();
final Lock r = gameControllersLock.readLock();
diff --git a/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java b/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java
index 38e0ea9647..b7f3c9aae9 100644
--- a/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java
+++ b/Mage.Server/src/main/java/mage/server/game/GameSessionPlayer.java
@@ -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 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 targets, final boolean required, final Map 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 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