Change all line endings to LF

This commit is contained in:
Fenhl 2016-04-13 16:34:45 +00:00
parent 13d9a56b7a
commit 430ae503c7
17069 changed files with 1263498 additions and 1263497 deletions

View file

@ -1,10 +1,10 @@
package mage.server;
/**
*
* @author LevelX2
*/
public enum DisconnectReason {
LostConnection, Disconnected, CleaningUp, ConnectingOtherInstance, AdminDisconnect, SessionExpired, Undefined;
}
package mage.server;
/**
*
* @author LevelX2
*/
public enum DisconnectReason {
LostConnection, Disconnected, CleaningUp, ConnectingOtherInstance, AdminDisconnect, SessionExpired, Undefined;
}

File diff suppressed because it is too large Load diff

View file

@ -1,381 +1,381 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server;
import java.io.File;
import java.io.FilenameFilter;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServer;
import mage.cards.repository.CardScanner;
import mage.game.match.MatchType;
import mage.game.tournament.TournamentType;
import mage.interfaces.MageServer;
import mage.remote.Connection;
import mage.server.draft.CubeFactory;
import mage.server.game.DeckValidatorFactory;
import mage.server.game.GameFactory;
import mage.server.game.PlayerFactory;
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.config.GamePlugin;
import mage.server.util.config.Plugin;
import mage.utils.MageVersion;
import org.apache.log4j.Logger;
import org.jboss.remoting.Client;
import org.jboss.remoting.ClientDisconnectedException;
import org.jboss.remoting.ConnectionListener;
import org.jboss.remoting.InvocationRequest;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.Remoting;
import org.jboss.remoting.ServerInvocationHandler;
import org.jboss.remoting.ServerInvoker;
import org.jboss.remoting.callback.InvokerCallbackHandler;
import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
import org.jboss.remoting.transport.Connector;
import org.jboss.remoting.transport.bisocket.BisocketServerInvoker;
import org.jboss.remoting.transport.socket.SocketWrapper;
import org.jboss.remoting.transporter.TransporterClient;
import org.jboss.remoting.transporter.TransporterServer;
import org.w3c.dom.Element;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class Main {
private static final Logger logger = Logger.getLogger(Main.class);
private static final MageVersion version = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO);
private static final String testModeArg = "-testMode=";
private static final String fastDBModeArg = "-fastDbMode=";
private static final String adminPasswordArg = "-adminPassword=";
private static final String pluginFolder = "plugins";
public static PluginClassLoader classLoader = new PluginClassLoader();
public static TransporterServer server;
protected static boolean testMode;
protected static boolean fastDbMode;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
logger.info("Starting MAGE server version " + version);
logger.info("Logging level: " + logger.getEffectiveLevel());
String adminPassword = "";
for (String arg : args) {
if (arg.startsWith(testModeArg)) {
testMode = Boolean.valueOf(arg.replace(testModeArg, ""));
} else if (arg.startsWith(adminPasswordArg)) {
adminPassword = arg.replace(adminPasswordArg, "");
adminPassword = SystemUtil.sanitize(adminPassword);
} else if (arg.startsWith(fastDBModeArg)) {
fastDbMode = Boolean.valueOf(arg.replace(fastDBModeArg, ""));
}
}
logger.info("Loading cards...");
if (fastDbMode) {
CardScanner.scanned = true;
} else {
CardScanner.scan();
}
logger.info("Done.");
logger.info("Updating user stats DB...");
UserStatsRepository.instance.updateUserStats();
logger.info("Done.");
deleteSavedGames();
ConfigSettings config = ConfigSettings.getInstance();
for (GamePlugin plugin : config.getGameTypes()) {
GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin));
}
for (GamePlugin plugin : config.getTournamentTypes()) {
TournamentFactory.getInstance().addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin));
}
for (Plugin plugin : config.getPlayerTypes()) {
PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin));
}
for (Plugin plugin : config.getDraftCubes()) {
CubeFactory.getInstance().addDraftCube(plugin.getName(), loadPlugin(plugin));
}
for (Plugin plugin : config.getDeckTypes()) {
DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
}
logger.info("Config - max seconds idle: " + config.getMaxSecondsIdle());
logger.info("Config - max game threads: " + config.getMaxGameThreads());
logger.info("Config - max AI opponents: " + config.getMaxAiOpponents());
logger.info("Config - min usr name le.: " + config.getMinUserNameLength());
logger.info("Config - max usr name le.: " + config.getMaxUserNameLength());
logger.info("Config - min pswrd length: " + config.getMinPasswordLength());
logger.info("Config - max pswrd length: " + config.getMaxPasswordLength());
logger.info("Config - inv.usr name pat: " + config.getInvalidUserNamePattern());
logger.info("Config - save game active: " + (config.isSaveGameActivated() ? "true" : "false"));
logger.info("Config - backlog size : " + config.getBacklogSize());
logger.info("Config - lease period : " + config.getLeasePeriod());
logger.info("Config - max pool size : " + config.getMaxPoolSize());
logger.info("Config - num accp.threads: " + config.getNumAcceptThreads());
logger.info("Config - second.bind port: " + config.getSecondaryBindPort());
logger.info("Config - auth. activated : " + (config.isAuthenticationActivated() ? "true" : "false"));
logger.info("Config - mailgun api key : " + config.getMailgunApiKey());
logger.info("Config - mailgun domain : " + config.getMailgunDomain());
logger.info("Config - mail smtp Host : " + config.getMailSmtpHost());
logger.info("Config - mail smtpPort : " + config.getMailSmtpPort());
logger.info("Config - mail user : " + config.getMailUser());
logger.info("Config - mail passw. len.: " + config.getMailPassword().length());
logger.info("Config - mail from addre.: " + config.getMailFromAddress());
logger.info("Config - google account : " + config.getGoogleAccount());
Connection connection = new Connection("&maxPoolSize=" + config.getMaxPoolSize());
connection.setHost(config.getServerAddress());
connection.setPort(config.getPort());
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());
server.start();
logger.info("Started MAGE server - listening on " + connection.toString());
if (testMode) {
logger.info("MAGE server running in test mode");
}
initStatistics();
} else {
logger.fatal("Unable to start MAGE server - another server is already started");
}
} catch (Exception ex) {
logger.fatal("Failed to start server - " + connection.toString(), ex);
}
}
static void initStatistics() {
ServerMessagesUtil.getInstance().setStartDate(System.currentTimeMillis());
}
static boolean isAlreadyRunning(InvokerLocator serverLocator) {
Map<String, String> metadata = new HashMap<>();
metadata.put(SocketWrapper.WRITE_TIMEOUT, "2000");
metadata.put("generalizeSocketException", "true");
try {
MageServer testServer = (MageServer) TransporterClient.createTransporterClient(serverLocator.getLocatorURI(), MageServer.class, metadata);
if (testServer != null) {
testServer.getServerState();
return true;
}
} catch (Throwable t) {
// assume server is not running
}
return false;
}
static class ClientConnectionListener implements ConnectionListener {
@Override
public void handleConnectionException(Throwable throwable, Client client) {
Session session = SessionManager.getInstance().getSession(client.getSessionId());
if (session != null) {
StringBuilder sessionInfo = new StringBuilder();
User user = UserManager.getInstance().getUser(session.getUserId());
if (user != null) {
sessionInfo.append(user.getName());
} else {
sessionInfo.append("[user missing] ");
}
sessionInfo.append(" at ").append(session.getHost()).append(" sessionId: ").append(session.getId());
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.getInstance().disconnect(client.getSessionId(), DisconnectReason.Disconnected);
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
logger.info("CLIENT DISCONNECTED - " + sessionInfo);
logger.debug("Stack Trace", throwable);
} else {
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
logger.info("LOST CONNECTION - " + sessionInfo);
if (logger.isDebugEnabled()) {
if (throwable == null) {
logger.debug("- cause: Lease expired");
} else {
logger.debug(" - cause: " + Session.getBasicCause(throwable).toString());
}
}
}
}
}
}
static class MageTransporterServer extends TransporterServer {
protected Connector connector;
public MageTransporterServer(InvokerLocator locator, Object target, String subsystem, MageServerInvocationHandler callback) throws Exception {
super(locator, target, subsystem);
connector.addInvocationHandler("callback", callback);
connector.setLeasePeriod(ConfigSettings.getInstance().getLeasePeriod());
connector.addConnectionListener(new ClientConnectionListener());
}
public Connector getConnector() throws Exception {
return connector;
}
@Override
protected Connector getConnector(InvokerLocator locator, Map config, Element xmlConfig) throws Exception {
Connector c = super.getConnector(locator, config, xmlConfig);
this.connector = c;
return c;
}
}
static class MageServerInvocationHandler implements ServerInvocationHandler {
@Override
public void setMBeanServer(MBeanServer server) {
}
@Override
public void setInvoker(ServerInvoker invoker) {
((BisocketServerInvoker) invoker).setSecondaryBindPort(ConfigSettings.getInstance().getSecondaryBindPort());
((BisocketServerInvoker) invoker).setBacklog(ConfigSettings.getInstance().getBacklogSize());
((BisocketServerInvoker) invoker).setNumAcceptThreads(ConfigSettings.getInstance().getNumAcceptThreads());
}
@Override
public Object invoke(final InvocationRequest invocation) throws Throwable {
String sessionId = invocation.getSessionId();
Map map = invocation.getRequestPayload();
String host;
if (map != null) {
InetAddress clientAddress = (InetAddress) invocation.getRequestPayload().get(Remoting.CLIENT_ADDRESS);
host = clientAddress.getHostAddress();
} else {
host = "localhost";
}
SessionManager.getInstance().getSession(sessionId).setHost(host);
return null;
}
@Override
public void addListener(InvokerCallbackHandler callbackHandler) {
ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
try {
String sessionId = handler.getClientSessionId();
SessionManager.getInstance().createSession(sessionId, callbackHandler);
} catch (Throwable ex) {
logger.fatal("", ex);
}
}
@Override
public void removeListener(InvokerCallbackHandler callbackHandler) {
ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
String sessionId = handler.getClientSessionId();
SessionManager.getInstance().disconnect(sessionId, DisconnectReason.Disconnected);
}
}
private static Class<?> loadPlugin(Plugin plugin) {
try {
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
logger.debug("Loading plugin: " + plugin.getClassName());
return Class.forName(plugin.getClassName(), true, classLoader);
} catch (ClassNotFoundException ex) {
logger.warn(new StringBuilder("Plugin not Found: ").append(plugin.getClassName()).append(" - ").append(plugin.getJar()).append(" - check plugin folder"), ex);
} catch (MalformedURLException ex) {
logger.fatal("Error loading plugin " + plugin.getJar(), ex);
}
return null;
}
private static MatchType loadGameType(GamePlugin plugin) {
try {
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
logger.debug("Loading game type: " + plugin.getClassName());
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
} catch (ClassNotFoundException ex) {
logger.warn("Game type not found:" + plugin.getJar() + " - check plugin folder", ex);
} catch (Exception ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
}
return null;
}
private static TournamentType loadTournamentType(GamePlugin plugin) {
try {
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
logger.debug("Loading tournament type: " + plugin.getClassName());
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
} catch (ClassNotFoundException ex) {
logger.warn("Tournament type not found:" + plugin.getName() + " / " + plugin.getJar() + " - check plugin folder", ex);
} catch (Exception ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
}
return null;
}
private static void deleteSavedGames() {
File directory = new File("saved/");
if (!directory.exists()) {
directory.mkdirs();
}
File[] files = directory.listFiles(
new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".game");
}
}
);
for (File file : files) {
file.delete();
}
}
public static MageVersion getVersion() {
return version;
}
public static boolean isTestMode() {
return testMode;
}
}
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server;
import java.io.File;
import java.io.FilenameFilter;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import javax.management.MBeanServer;
import mage.cards.repository.CardScanner;
import mage.game.match.MatchType;
import mage.game.tournament.TournamentType;
import mage.interfaces.MageServer;
import mage.remote.Connection;
import mage.server.draft.CubeFactory;
import mage.server.game.DeckValidatorFactory;
import mage.server.game.GameFactory;
import mage.server.game.PlayerFactory;
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.config.GamePlugin;
import mage.server.util.config.Plugin;
import mage.utils.MageVersion;
import org.apache.log4j.Logger;
import org.jboss.remoting.Client;
import org.jboss.remoting.ClientDisconnectedException;
import org.jboss.remoting.ConnectionListener;
import org.jboss.remoting.InvocationRequest;
import org.jboss.remoting.InvokerLocator;
import org.jboss.remoting.Remoting;
import org.jboss.remoting.ServerInvocationHandler;
import org.jboss.remoting.ServerInvoker;
import org.jboss.remoting.callback.InvokerCallbackHandler;
import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
import org.jboss.remoting.transport.Connector;
import org.jboss.remoting.transport.bisocket.BisocketServerInvoker;
import org.jboss.remoting.transport.socket.SocketWrapper;
import org.jboss.remoting.transporter.TransporterClient;
import org.jboss.remoting.transporter.TransporterServer;
import org.w3c.dom.Element;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class Main {
private static final Logger logger = Logger.getLogger(Main.class);
private static final MageVersion version = new MageVersion(MageVersion.MAGE_VERSION_MAJOR, MageVersion.MAGE_VERSION_MINOR, MageVersion.MAGE_VERSION_PATCH, MageVersion.MAGE_VERSION_MINOR_PATCH, MageVersion.MAGE_VERSION_INFO);
private static final String testModeArg = "-testMode=";
private static final String fastDBModeArg = "-fastDbMode=";
private static final String adminPasswordArg = "-adminPassword=";
private static final String pluginFolder = "plugins";
public static PluginClassLoader classLoader = new PluginClassLoader();
public static TransporterServer server;
protected static boolean testMode;
protected static boolean fastDbMode;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
System.setProperty("java.util.Arrays.useLegacyMergeSort", "true");
logger.info("Starting MAGE server version " + version);
logger.info("Logging level: " + logger.getEffectiveLevel());
String adminPassword = "";
for (String arg : args) {
if (arg.startsWith(testModeArg)) {
testMode = Boolean.valueOf(arg.replace(testModeArg, ""));
} else if (arg.startsWith(adminPasswordArg)) {
adminPassword = arg.replace(adminPasswordArg, "");
adminPassword = SystemUtil.sanitize(adminPassword);
} else if (arg.startsWith(fastDBModeArg)) {
fastDbMode = Boolean.valueOf(arg.replace(fastDBModeArg, ""));
}
}
logger.info("Loading cards...");
if (fastDbMode) {
CardScanner.scanned = true;
} else {
CardScanner.scan();
}
logger.info("Done.");
logger.info("Updating user stats DB...");
UserStatsRepository.instance.updateUserStats();
logger.info("Done.");
deleteSavedGames();
ConfigSettings config = ConfigSettings.getInstance();
for (GamePlugin plugin : config.getGameTypes()) {
GameFactory.getInstance().addGameType(plugin.getName(), loadGameType(plugin), loadPlugin(plugin));
}
for (GamePlugin plugin : config.getTournamentTypes()) {
TournamentFactory.getInstance().addTournamentType(plugin.getName(), loadTournamentType(plugin), loadPlugin(plugin));
}
for (Plugin plugin : config.getPlayerTypes()) {
PlayerFactory.getInstance().addPlayerType(plugin.getName(), loadPlugin(plugin));
}
for (Plugin plugin : config.getDraftCubes()) {
CubeFactory.getInstance().addDraftCube(plugin.getName(), loadPlugin(plugin));
}
for (Plugin plugin : config.getDeckTypes()) {
DeckValidatorFactory.getInstance().addDeckType(plugin.getName(), loadPlugin(plugin));
}
logger.info("Config - max seconds idle: " + config.getMaxSecondsIdle());
logger.info("Config - max game threads: " + config.getMaxGameThreads());
logger.info("Config - max AI opponents: " + config.getMaxAiOpponents());
logger.info("Config - min usr name le.: " + config.getMinUserNameLength());
logger.info("Config - max usr name le.: " + config.getMaxUserNameLength());
logger.info("Config - min pswrd length: " + config.getMinPasswordLength());
logger.info("Config - max pswrd length: " + config.getMaxPasswordLength());
logger.info("Config - inv.usr name pat: " + config.getInvalidUserNamePattern());
logger.info("Config - save game active: " + (config.isSaveGameActivated() ? "true" : "false"));
logger.info("Config - backlog size : " + config.getBacklogSize());
logger.info("Config - lease period : " + config.getLeasePeriod());
logger.info("Config - max pool size : " + config.getMaxPoolSize());
logger.info("Config - num accp.threads: " + config.getNumAcceptThreads());
logger.info("Config - second.bind port: " + config.getSecondaryBindPort());
logger.info("Config - auth. activated : " + (config.isAuthenticationActivated() ? "true" : "false"));
logger.info("Config - mailgun api key : " + config.getMailgunApiKey());
logger.info("Config - mailgun domain : " + config.getMailgunDomain());
logger.info("Config - mail smtp Host : " + config.getMailSmtpHost());
logger.info("Config - mail smtpPort : " + config.getMailSmtpPort());
logger.info("Config - mail user : " + config.getMailUser());
logger.info("Config - mail passw. len.: " + config.getMailPassword().length());
logger.info("Config - mail from addre.: " + config.getMailFromAddress());
logger.info("Config - google account : " + config.getGoogleAccount());
Connection connection = new Connection("&maxPoolSize=" + config.getMaxPoolSize());
connection.setHost(config.getServerAddress());
connection.setPort(config.getPort());
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());
server.start();
logger.info("Started MAGE server - listening on " + connection.toString());
if (testMode) {
logger.info("MAGE server running in test mode");
}
initStatistics();
} else {
logger.fatal("Unable to start MAGE server - another server is already started");
}
} catch (Exception ex) {
logger.fatal("Failed to start server - " + connection.toString(), ex);
}
}
static void initStatistics() {
ServerMessagesUtil.getInstance().setStartDate(System.currentTimeMillis());
}
static boolean isAlreadyRunning(InvokerLocator serverLocator) {
Map<String, String> metadata = new HashMap<>();
metadata.put(SocketWrapper.WRITE_TIMEOUT, "2000");
metadata.put("generalizeSocketException", "true");
try {
MageServer testServer = (MageServer) TransporterClient.createTransporterClient(serverLocator.getLocatorURI(), MageServer.class, metadata);
if (testServer != null) {
testServer.getServerState();
return true;
}
} catch (Throwable t) {
// assume server is not running
}
return false;
}
static class ClientConnectionListener implements ConnectionListener {
@Override
public void handleConnectionException(Throwable throwable, Client client) {
Session session = SessionManager.getInstance().getSession(client.getSessionId());
if (session != null) {
StringBuilder sessionInfo = new StringBuilder();
User user = UserManager.getInstance().getUser(session.getUserId());
if (user != null) {
sessionInfo.append(user.getName());
} else {
sessionInfo.append("[user missing] ");
}
sessionInfo.append(" at ").append(session.getHost()).append(" sessionId: ").append(session.getId());
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.getInstance().disconnect(client.getSessionId(), DisconnectReason.Disconnected);
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
logger.info("CLIENT DISCONNECTED - " + sessionInfo);
logger.debug("Stack Trace", throwable);
} else {
SessionManager.getInstance().disconnect(client.getSessionId(), DisconnectReason.LostConnection);
logger.info("LOST CONNECTION - " + sessionInfo);
if (logger.isDebugEnabled()) {
if (throwable == null) {
logger.debug("- cause: Lease expired");
} else {
logger.debug(" - cause: " + Session.getBasicCause(throwable).toString());
}
}
}
}
}
}
static class MageTransporterServer extends TransporterServer {
protected Connector connector;
public MageTransporterServer(InvokerLocator locator, Object target, String subsystem, MageServerInvocationHandler callback) throws Exception {
super(locator, target, subsystem);
connector.addInvocationHandler("callback", callback);
connector.setLeasePeriod(ConfigSettings.getInstance().getLeasePeriod());
connector.addConnectionListener(new ClientConnectionListener());
}
public Connector getConnector() throws Exception {
return connector;
}
@Override
protected Connector getConnector(InvokerLocator locator, Map config, Element xmlConfig) throws Exception {
Connector c = super.getConnector(locator, config, xmlConfig);
this.connector = c;
return c;
}
}
static class MageServerInvocationHandler implements ServerInvocationHandler {
@Override
public void setMBeanServer(MBeanServer server) {
}
@Override
public void setInvoker(ServerInvoker invoker) {
((BisocketServerInvoker) invoker).setSecondaryBindPort(ConfigSettings.getInstance().getSecondaryBindPort());
((BisocketServerInvoker) invoker).setBacklog(ConfigSettings.getInstance().getBacklogSize());
((BisocketServerInvoker) invoker).setNumAcceptThreads(ConfigSettings.getInstance().getNumAcceptThreads());
}
@Override
public Object invoke(final InvocationRequest invocation) throws Throwable {
String sessionId = invocation.getSessionId();
Map map = invocation.getRequestPayload();
String host;
if (map != null) {
InetAddress clientAddress = (InetAddress) invocation.getRequestPayload().get(Remoting.CLIENT_ADDRESS);
host = clientAddress.getHostAddress();
} else {
host = "localhost";
}
SessionManager.getInstance().getSession(sessionId).setHost(host);
return null;
}
@Override
public void addListener(InvokerCallbackHandler callbackHandler) {
ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
try {
String sessionId = handler.getClientSessionId();
SessionManager.getInstance().createSession(sessionId, callbackHandler);
} catch (Throwable ex) {
logger.fatal("", ex);
}
}
@Override
public void removeListener(InvokerCallbackHandler callbackHandler) {
ServerInvokerCallbackHandler handler = (ServerInvokerCallbackHandler) callbackHandler;
String sessionId = handler.getClientSessionId();
SessionManager.getInstance().disconnect(sessionId, DisconnectReason.Disconnected);
}
}
private static Class<?> loadPlugin(Plugin plugin) {
try {
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
logger.debug("Loading plugin: " + plugin.getClassName());
return Class.forName(plugin.getClassName(), true, classLoader);
} catch (ClassNotFoundException ex) {
logger.warn(new StringBuilder("Plugin not Found: ").append(plugin.getClassName()).append(" - ").append(plugin.getJar()).append(" - check plugin folder"), ex);
} catch (MalformedURLException ex) {
logger.fatal("Error loading plugin " + plugin.getJar(), ex);
}
return null;
}
private static MatchType loadGameType(GamePlugin plugin) {
try {
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
logger.debug("Loading game type: " + plugin.getClassName());
return (MatchType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
} catch (ClassNotFoundException ex) {
logger.warn("Game type not found:" + plugin.getJar() + " - check plugin folder", ex);
} catch (Exception ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
}
return null;
}
private static TournamentType loadTournamentType(GamePlugin plugin) {
try {
classLoader.addURL(new File(pluginFolder + "/" + plugin.getJar()).toURI().toURL());
logger.debug("Loading tournament type: " + plugin.getClassName());
return (TournamentType) Class.forName(plugin.getTypeName(), true, classLoader).newInstance();
} catch (ClassNotFoundException ex) {
logger.warn("Tournament type not found:" + plugin.getName() + " / " + plugin.getJar() + " - check plugin folder", ex);
} catch (Exception ex) {
logger.fatal("Error loading game type " + plugin.getJar(), ex);
}
return null;
}
private static void deleteSavedGames() {
File directory = new File("saved/");
if (!directory.exists()) {
directory.mkdirs();
}
File[] files = directory.listFiles(
new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".game");
}
}
);
for (File file : files) {
file.delete();
}
}
public static MageVersion getVersion() {
return version;
}
public static boolean isTestMode() {
return testMode;
}
}

View file

@ -1,28 +1,28 @@
package mage.server.challenge;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.constants.Zone;
import mage.game.match.Match;
/**
* C U R R E N T L Y U N U S E D
*
* Loads challenges from scenarios.
* Configure games by initializing starting game board.
*/
public class ChallengeManager {
public static final ChallengeManager fInstance = new ChallengeManager();
public static ChallengeManager getInstance() {
return fInstance;
}
public void prepareChallenge(UUID playerId, Match match) {
Map<Zone, String> commands = new HashMap<Zone, String>();
commands.put(Zone.OUTSIDE, "life:3");
match.getGame().cheat(playerId, commands);
}
}
package mage.server.challenge;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.constants.Zone;
import mage.game.match.Match;
/**
* C U R R E N T L Y U N U S E D
*
* Loads challenges from scenarios.
* Configure games by initializing starting game board.
*/
public class ChallengeManager {
public static final ChallengeManager fInstance = new ChallengeManager();
public static ChallengeManager getInstance() {
return fInstance;
}
public void prepareChallenge(UUID playerId, Match match) {
Map<Zone, String> commands = new HashMap<Zone, String>();
commands.put(Zone.OUTSIDE, "life:3");
match.getGame().cheat(playerId, commands);
}
}

View file

@ -1,80 +1,80 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.draft;
import java.lang.reflect.Constructor;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import mage.game.draft.DraftCube;
import org.apache.log4j.Logger;
/**
*
* @author LevelX2
*/
public class CubeFactory {
private static final CubeFactory INSTANCE = new CubeFactory();
private static final Logger logger = Logger.getLogger(CubeFactory.class);
private Map<String, Class> draftCubes = new LinkedHashMap<String, Class>();
public static CubeFactory getInstance() {
return INSTANCE;
}
private CubeFactory() {}
public DraftCube createDraftCube(String draftCubeName) {
DraftCube draftCube;
Constructor<?> con;
try {
con = draftCubes.get(draftCubeName).getConstructor(new Class[]{});
draftCube = (DraftCube)con.newInstance(new Object[] {});
} catch (Exception ex) {
logger.fatal("CubeFactory error", ex);
return null;
}
logger.debug("Draft cube created: " + draftCube.getName());
return draftCube;
}
public Set<String> getDraftCubes() {
return draftCubes.keySet();
}
public void addDraftCube(String name, Class draftCube) {
if (draftCube != null) {
this.draftCubes.put(name, draftCube);
}
}
}
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.draft;
import java.lang.reflect.Constructor;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import mage.game.draft.DraftCube;
import org.apache.log4j.Logger;
/**
*
* @author LevelX2
*/
public class CubeFactory {
private static final CubeFactory INSTANCE = new CubeFactory();
private static final Logger logger = Logger.getLogger(CubeFactory.class);
private Map<String, Class> draftCubes = new LinkedHashMap<String, Class>();
public static CubeFactory getInstance() {
return INSTANCE;
}
private CubeFactory() {}
public DraftCube createDraftCube(String draftCubeName) {
DraftCube draftCube;
Constructor<?> con;
try {
con = draftCubes.get(draftCubeName).getConstructor(new Class[]{});
draftCube = (DraftCube)con.newInstance(new Object[] {});
} catch (Exception ex) {
logger.fatal("CubeFactory error", ex);
return null;
}
logger.debug("Draft cube created: " + draftCube.getName());
return draftCube;
}
public Set<String> getDraftCubes() {
return draftCubes.keySet();
}
public void addDraftCube(String name, Class draftCube) {
if (draftCube != null) {
this.draftCubes.put(name, draftCube);
}
}
}

View file

@ -1,204 +1,204 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.util;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Handles server messages (Messages of the Day).
* Reloads messages every 5 minutes.
*
* @author nantuko
*/
public class ServerMessagesUtil {
private static final ServerMessagesUtil instance = new ServerMessagesUtil();
private static final Logger log = Logger.getLogger(ServerMessagesUtil.class);
private static final String SERVER_MSG_TXT_FILE = "server.msg.txt";
private static ScheduledExecutorService updateExecutor;
private final List<String> messages = new ArrayList<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private static String pathToExternalMessages = null;
private static boolean ignore = false;
private static long startDate;
private static final AtomicInteger gamesStarted = new AtomicInteger(0);
private static final AtomicInteger tournamentsStarted = new AtomicInteger(0);
static {
pathToExternalMessages = System.getProperty("messagesPath");
}
public ServerMessagesUtil() {
updateExecutor = Executors.newSingleThreadScheduledExecutor();
updateExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
reloadMessages();
}
}, 5, 5 * 60, TimeUnit.SECONDS);
}
public static ServerMessagesUtil getInstance() {
return instance;
}
public List<String> getMessages() {
lock.readLock().lock();
try {
return messages;
} finally {
lock.readLock().unlock();
}
}
private void reloadMessages() {
log.debug("Reading server messages...");
List<String> motdMessages = readFromFile();
List<String> newMessages = new ArrayList<>();
if (motdMessages != null) {
newMessages.addAll(motdMessages);
}
newMessages.add(getServerStatistics());
lock.writeLock().lock();
try {
messages.clear();
messages.addAll(newMessages);
} finally {
lock.writeLock().unlock();
}
}
private List<String> readFromFile() {
if (ignore) {
return null;
}
File externalFile = null;
if (pathToExternalMessages != null) {
externalFile = new File(pathToExternalMessages);
if (!externalFile.exists()) {
log.warn("Couldn't find server.msg.txt using external path: " + pathToExternalMessages);
pathToExternalMessages = null; // not to repeat error action again
externalFile = null;
} else if (!externalFile.canRead()) {
log.warn("Couldn't read (no access) server.msg.txt using external path: " + pathToExternalMessages);
pathToExternalMessages = null; // not to repeat error action again
}
}
InputStream is = null;
if (externalFile != null) {
try {
is = new FileInputStream(externalFile);
} catch (Exception f) {
log.error(f, f);
pathToExternalMessages = null; // not to repeat error action again
}
} else {
File file = new File(SERVER_MSG_TXT_FILE);
if (!file.exists() || !file.canRead()) {
log.warn("Couldn't find server.msg.txt using path: " + SERVER_MSG_TXT_FILE);
} else {
try {
is = new FileInputStream(file);
} catch (Exception f) {
log.error(f, f);
ignore = true;
}
}
}
if (is == null) {
log.warn("Couldn't find server.msg");
return null;
}
Scanner scanner = new Scanner(is);
List<String> newMessages = new ArrayList<>();
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if (!message.trim().isEmpty()) {
newMessages.add(message.trim());
}
}
return newMessages;
}
private String getServerStatistics() {
long current = System.currentTimeMillis();
long hours = ((current - startDate)/(1000*60*60));
StringBuilder statistics = new StringBuilder("Server uptime: ");
statistics.append(hours);
statistics.append(" hour(s), games played: ");
statistics.append(gamesStarted.get());
statistics.append(" tournaments started: ");
statistics.append(tournamentsStarted.get());
return statistics.toString();
}
// private Timer timer = new Timer(1000 * 60, new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// reloadMessages();
// }
// });
public void setStartDate(long milliseconds) {
this.startDate = milliseconds;
}
public void incGamesStarted() {
int value;
do {
value = gamesStarted.get();
} while (!gamesStarted.compareAndSet(value, value + 1));
}
public void incTournamentsStarted() {
int value;
do {
value = tournamentsStarted.get();
} while (!tournamentsStarted.compareAndSet(value, value + 1));
}
}
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.server.util;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* Handles server messages (Messages of the Day).
* Reloads messages every 5 minutes.
*
* @author nantuko
*/
public class ServerMessagesUtil {
private static final ServerMessagesUtil instance = new ServerMessagesUtil();
private static final Logger log = Logger.getLogger(ServerMessagesUtil.class);
private static final String SERVER_MSG_TXT_FILE = "server.msg.txt";
private static ScheduledExecutorService updateExecutor;
private final List<String> messages = new ArrayList<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private static String pathToExternalMessages = null;
private static boolean ignore = false;
private static long startDate;
private static final AtomicInteger gamesStarted = new AtomicInteger(0);
private static final AtomicInteger tournamentsStarted = new AtomicInteger(0);
static {
pathToExternalMessages = System.getProperty("messagesPath");
}
public ServerMessagesUtil() {
updateExecutor = Executors.newSingleThreadScheduledExecutor();
updateExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
reloadMessages();
}
}, 5, 5 * 60, TimeUnit.SECONDS);
}
public static ServerMessagesUtil getInstance() {
return instance;
}
public List<String> getMessages() {
lock.readLock().lock();
try {
return messages;
} finally {
lock.readLock().unlock();
}
}
private void reloadMessages() {
log.debug("Reading server messages...");
List<String> motdMessages = readFromFile();
List<String> newMessages = new ArrayList<>();
if (motdMessages != null) {
newMessages.addAll(motdMessages);
}
newMessages.add(getServerStatistics());
lock.writeLock().lock();
try {
messages.clear();
messages.addAll(newMessages);
} finally {
lock.writeLock().unlock();
}
}
private List<String> readFromFile() {
if (ignore) {
return null;
}
File externalFile = null;
if (pathToExternalMessages != null) {
externalFile = new File(pathToExternalMessages);
if (!externalFile.exists()) {
log.warn("Couldn't find server.msg.txt using external path: " + pathToExternalMessages);
pathToExternalMessages = null; // not to repeat error action again
externalFile = null;
} else if (!externalFile.canRead()) {
log.warn("Couldn't read (no access) server.msg.txt using external path: " + pathToExternalMessages);
pathToExternalMessages = null; // not to repeat error action again
}
}
InputStream is = null;
if (externalFile != null) {
try {
is = new FileInputStream(externalFile);
} catch (Exception f) {
log.error(f, f);
pathToExternalMessages = null; // not to repeat error action again
}
} else {
File file = new File(SERVER_MSG_TXT_FILE);
if (!file.exists() || !file.canRead()) {
log.warn("Couldn't find server.msg.txt using path: " + SERVER_MSG_TXT_FILE);
} else {
try {
is = new FileInputStream(file);
} catch (Exception f) {
log.error(f, f);
ignore = true;
}
}
}
if (is == null) {
log.warn("Couldn't find server.msg");
return null;
}
Scanner scanner = new Scanner(is);
List<String> newMessages = new ArrayList<>();
while (scanner.hasNextLine()) {
String message = scanner.nextLine();
if (!message.trim().isEmpty()) {
newMessages.add(message.trim());
}
}
return newMessages;
}
private String getServerStatistics() {
long current = System.currentTimeMillis();
long hours = ((current - startDate)/(1000*60*60));
StringBuilder statistics = new StringBuilder("Server uptime: ");
statistics.append(hours);
statistics.append(" hour(s), games played: ");
statistics.append(gamesStarted.get());
statistics.append(" tournaments started: ");
statistics.append(tournamentsStarted.get());
return statistics.toString();
}
// private Timer timer = new Timer(1000 * 60, new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// reloadMessages();
// }
// });
public void setStartDate(long milliseconds) {
this.startDate = milliseconds;
}
public void incGamesStarted() {
int value;
do {
value = gamesStarted.get();
} while (!gamesStarted.compareAndSet(value, value + 1));
}
public void incTournamentsStarted() {
int value;
do {
value = tournamentsStarted.get();
} while (!tournamentsStarted.compareAndSet(value, value + 1));
}
}

View file

@ -1,23 +1,23 @@
package mage.server.util;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.game.Game;
import mage.players.Player;
/**
* @author nantuko
*/
public class Splitter {
public static List<UUID> split(Game game, UUID playerId) {
List<UUID> players = new ArrayList<>();
//players.add(playerId); // add original player
Player player = game.getPlayer(playerId);
if (player != null && player.getTurnControlledBy() != null) {
players.add(player.getTurnControlledBy());
}
return players;
}
}
package mage.server.util;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.game.Game;
import mage.players.Player;
/**
* @author nantuko
*/
public class Splitter {
public static List<UUID> split(Game game, UUID playerId) {
List<UUID> players = new ArrayList<>();
//players.add(playerId); // add original player
Player player = game.getPlayer(playerId);
if (player != null && player.getTurnControlledBy() != null) {
players.add(player.getTurnControlledBy());
}
return players;
}
}

View file

@ -1,183 +1,183 @@
package mage.server.util;
import mage.cards.Card;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.io.File;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author nantuko
*/
public class SystemUtil {
private static final String INIT_FILE_PATH = "config" + File.separator + "init.txt";
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(SystemUtil.class);
/**
* Replaces cards in player's hands by specified in config/init.txt.<br/>
* <br/>
* <b>Implementation note:</b><br/>
* 1. Read init.txt line by line<br/>
* 2. Parse line using the following format: line ::= <zone>:<nickname>:<card name>:<amount><br/>
* 3. If zone equals to 'hand', add card to player's library<br/>
* 3a. Then swap added card with any card in player's hand<br/>
* 3b. Parse next line (go to 2.), If EOF go to 4.<br/>
* 4. Log message to all players that cards were added (to prevent unfair play).<br/>
* 5. Exit<br/>
* @param game
*/
public static void addCardsForTesting(Game game) {
try {
File f = new File(INIT_FILE_PATH);
Pattern pattern = Pattern.compile("([a-zA-Z]+):([\\w]+):([a-zA-Z ,\\/\\-.!'\\d:]+?):(\\d+)");
if (!f.exists()) {
logger.warn("Couldn't find init file: " + INIT_FILE_PATH);
return;
}
logger.info("Parsing init.txt... ");
Scanner scanner = new Scanner(f);
try {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.trim().length() == 0 || line.startsWith("#")) {
continue;
}
Matcher m = pattern.matcher(line);
if (!m.matches()) {
logger.warn("Init string wasn't parsed: " + line);
continue;
}
String zone = m.group(1);
String nickname = m.group(2);
Player player = findPlayer(game, nickname);
if (player == null) {
logger.warn("Was skipped: " + line);
continue;
}
Zone gameZone;
if ("hand".equalsIgnoreCase(zone)) {
gameZone = Zone.HAND;
} else if ("battlefield".equalsIgnoreCase(zone)) {
gameZone = Zone.BATTLEFIELD;
} else if ("graveyard".equalsIgnoreCase(zone)) {
gameZone = Zone.GRAVEYARD;
} else if ("library".equalsIgnoreCase(zone)) {
gameZone = Zone.LIBRARY;
} else {
continue; // go parse next line
}
String cardName = m.group(3);
Integer amount = Integer.parseInt(m.group(4));
List<CardInfo> cards = CardRepository.instance.findCards(cardName);
if (cards.isEmpty()) {
logger.warn("Couldn't find a card: " + cardName);
continue;
}
Random random = new Random();
Set<Card> cardsToLoad = new HashSet<>();
for (int i = 0; i < amount; i++) {
CardInfo cardInfo = cards.get(random.nextInt(cards.size()));
Card card = cardInfo != null ? cardInfo.getCard() : null;
if (card != null) {
cardsToLoad.add(card);
}
}
game.loadCards(cardsToLoad, player.getId());
for (Card card : cardsToLoad) {
swapWithAnyCard(game, player, card, gameZone);
}
}
}
finally {
scanner.close();
}
} catch (Exception e) {
logger.fatal("", e);
}
}
/**
* Swap cards between specified card from library and any hand card.
*
* @param game
* @param card Card to put to player's hand
*/
private static void swapWithAnyCard(Game game, Player player, Card card, Zone zone) {
if (zone.equals(Zone.BATTLEFIELD)) {
card.putOntoBattlefield(game, Zone.OUTSIDE, null, player.getId());
} else if (zone.equals(Zone.LIBRARY)) {
card.setZone(Zone.LIBRARY, game);
player.getLibrary().putOnTop(card, game);
} else {
card.moveToZone(zone, null, game, false);
}
logger.info("Added card to player's " + zone.toString() + ": " + card.getName() +", player = " + player.getName());
}
/**
* Find player by name.
*
* @param game
* @param name
* @return
*/
private static Player findPlayer(Game game, String name) {
for (Player player: game.getPlayers().values()) {
if (player.getName().equals(name)) {
return player;
}
}
return null;
}
public static String sanitize(String input) {
//Pattern pattern = Pattern.compile("[^0-9a-zA-Z]");
//Matcher matcher = pattern.matcher(input);
//return matcher.replaceAll("");
return input.replaceAll("[^a-zA-Z0-9]", "");
}
public static void main(String... args) {
System.out.println(sanitize("123"));
System.out.println(sanitize("AaAaD_123"));
System.out.println(sanitize("--sas-"));
System.out.println(sanitize("anPlsdf123_") + "|");
System.out.println(sanitize("anPlsdf123 ") + "|");
System.out.println(sanitize("anPlsdf123\r\n") + "|");
}
/**
* Get a diff between two dates
*
* @param date1 the oldest date
* @param date2 the newest date
* @param timeUnit the unit in which you want the diff
* @return the diff value, in the provided unit
*/
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
long diffInMillies = date2.getTime() - date1.getTime();
return timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
}
}
package mage.server.util;
import mage.cards.Card;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import java.io.File;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author nantuko
*/
public class SystemUtil {
private static final String INIT_FILE_PATH = "config" + File.separator + "init.txt";
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(SystemUtil.class);
/**
* Replaces cards in player's hands by specified in config/init.txt.<br/>
* <br/>
* <b>Implementation note:</b><br/>
* 1. Read init.txt line by line<br/>
* 2. Parse line using the following format: line ::= <zone>:<nickname>:<card name>:<amount><br/>
* 3. If zone equals to 'hand', add card to player's library<br/>
* 3a. Then swap added card with any card in player's hand<br/>
* 3b. Parse next line (go to 2.), If EOF go to 4.<br/>
* 4. Log message to all players that cards were added (to prevent unfair play).<br/>
* 5. Exit<br/>
* @param game
*/
public static void addCardsForTesting(Game game) {
try {
File f = new File(INIT_FILE_PATH);
Pattern pattern = Pattern.compile("([a-zA-Z]+):([\\w]+):([a-zA-Z ,\\/\\-.!'\\d:]+?):(\\d+)");
if (!f.exists()) {
logger.warn("Couldn't find init file: " + INIT_FILE_PATH);
return;
}
logger.info("Parsing init.txt... ");
Scanner scanner = new Scanner(f);
try {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (line.trim().length() == 0 || line.startsWith("#")) {
continue;
}
Matcher m = pattern.matcher(line);
if (!m.matches()) {
logger.warn("Init string wasn't parsed: " + line);
continue;
}
String zone = m.group(1);
String nickname = m.group(2);
Player player = findPlayer(game, nickname);
if (player == null) {
logger.warn("Was skipped: " + line);
continue;
}
Zone gameZone;
if ("hand".equalsIgnoreCase(zone)) {
gameZone = Zone.HAND;
} else if ("battlefield".equalsIgnoreCase(zone)) {
gameZone = Zone.BATTLEFIELD;
} else if ("graveyard".equalsIgnoreCase(zone)) {
gameZone = Zone.GRAVEYARD;
} else if ("library".equalsIgnoreCase(zone)) {
gameZone = Zone.LIBRARY;
} else {
continue; // go parse next line
}
String cardName = m.group(3);
Integer amount = Integer.parseInt(m.group(4));
List<CardInfo> cards = CardRepository.instance.findCards(cardName);
if (cards.isEmpty()) {
logger.warn("Couldn't find a card: " + cardName);
continue;
}
Random random = new Random();
Set<Card> cardsToLoad = new HashSet<>();
for (int i = 0; i < amount; i++) {
CardInfo cardInfo = cards.get(random.nextInt(cards.size()));
Card card = cardInfo != null ? cardInfo.getCard() : null;
if (card != null) {
cardsToLoad.add(card);
}
}
game.loadCards(cardsToLoad, player.getId());
for (Card card : cardsToLoad) {
swapWithAnyCard(game, player, card, gameZone);
}
}
}
finally {
scanner.close();
}
} catch (Exception e) {
logger.fatal("", e);
}
}
/**
* Swap cards between specified card from library and any hand card.
*
* @param game
* @param card Card to put to player's hand
*/
private static void swapWithAnyCard(Game game, Player player, Card card, Zone zone) {
if (zone.equals(Zone.BATTLEFIELD)) {
card.putOntoBattlefield(game, Zone.OUTSIDE, null, player.getId());
} else if (zone.equals(Zone.LIBRARY)) {
card.setZone(Zone.LIBRARY, game);
player.getLibrary().putOnTop(card, game);
} else {
card.moveToZone(zone, null, game, false);
}
logger.info("Added card to player's " + zone.toString() + ": " + card.getName() +", player = " + player.getName());
}
/**
* Find player by name.
*
* @param game
* @param name
* @return
*/
private static Player findPlayer(Game game, String name) {
for (Player player: game.getPlayers().values()) {
if (player.getName().equals(name)) {
return player;
}
}
return null;
}
public static String sanitize(String input) {
//Pattern pattern = Pattern.compile("[^0-9a-zA-Z]");
//Matcher matcher = pattern.matcher(input);
//return matcher.replaceAll("");
return input.replaceAll("[^a-zA-Z0-9]", "");
}
public static void main(String... args) {
System.out.println(sanitize("123"));
System.out.println(sanitize("AaAaD_123"));
System.out.println(sanitize("--sas-"));
System.out.println(sanitize("anPlsdf123_") + "|");
System.out.println(sanitize("anPlsdf123 ") + "|");
System.out.println(sanitize("anPlsdf123\r\n") + "|");
}
/**
* Get a diff between two dates
*
* @param date1 the oldest date
* @param date2 the newest date
* @param timeUnit the unit in which you want the diff
* @return the diff value, in the provided unit
*/
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
long diffInMillies = date2.getTime() - date1.getTime();
return timeUnit.convert(diffInMillies, TimeUnit.MILLISECONDS);
}
}