mirror of
https://github.com/magefree/mage.git
synced 2025-12-28 14:32:06 -08:00
Change all line endings to LF
This commit is contained in:
parent
13d9a56b7a
commit
430ae503c7
17069 changed files with 1263498 additions and 1263497 deletions
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue