Added chat mute and user (de)activation actions to the Mage server console.

This commit is contained in:
LevelX2 2016-10-05 00:59:51 +02:00
parent 7c4b40073c
commit c46f75ac28
18 changed files with 511 additions and 213 deletions

View file

@ -1,20 +1,22 @@
package mage.server;
import com.j256.ormlite.field.DataType;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.table.DatabaseTable;
import java.util.Date;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.crypto.hash.Hash;
import org.apache.shiro.util.ByteSource;
@DatabaseTable(tableName = "authorized_user")
public class AuthorizedUser {
@DatabaseField(indexName = "name_index", unique = true)
@DatabaseField(id = true, indexName = "name_index", unique = true)
protected String name;
@DatabaseField
@ -32,6 +34,18 @@ public class AuthorizedUser {
@DatabaseField(indexName = "email_index", unique = true)
protected String email;
@DatabaseField
protected boolean active; // the user can't sign in
@DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss")
protected Date lockedUntil; // the user can't sign in until timestamp
@DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss")
protected Date chatLockedUntil; // the user can't use the chat until timestamp
@DatabaseField(dataType = DataType.DATE_STRING, format = "yyyy-MM-dd HH:mm:ss")
protected Date lastConnection; // time of the last user connect
public AuthorizedUser() {
}
@ -42,6 +56,9 @@ public class AuthorizedUser {
this.hashAlgorithm = hash.getAlgorithmName();
this.hashIterations = hash.getIterations();
this.email = email;
this.chatLockedUntil = null;
this.active = true;
this.lockedUntil = null;
}
public boolean doCredentialsMatch(String name, String password) {

View file

@ -12,6 +12,7 @@ import com.j256.ormlite.table.TableUtils;
import java.io.File;
import java.sql.SQLException;
import java.util.List;
import mage.cards.repository.CardRepository;
import mage.cards.repository.RepositoryUtil;
import org.apache.log4j.Logger;
import org.apache.shiro.crypto.RandomNumberGenerator;
@ -27,7 +28,7 @@ public enum AuthorizedUserRepository {
private static final String JDBC_URL = "jdbc:h2:file:./db/authorized_user.h2;AUTO_SERVER=TRUE";
private static final String VERSION_ENTITY_NAME = "authorized_user";
// raise this if db structure was changed
private static final long DB_VERSION = 1;
private static final long DB_VERSION = 2;
private static final RandomNumberGenerator rng = new SecureRandomNumberGenerator();
private Dao<AuthorizedUser, Object> dao;
@ -39,16 +40,10 @@ public enum AuthorizedUserRepository {
}
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
boolean obsolete = RepositoryUtil.isDatabaseObsolete(connectionSource, VERSION_ENTITY_NAME, DB_VERSION);
if (obsolete) {
TableUtils.dropTable(connectionSource, AuthorizedUser.class, true);
}
TableUtils.createTableIfNotExists(connectionSource, AuthorizedUser.class);
dao = DaoManager.createDao(connectionSource, AuthorizedUser.class);
} catch (SQLException ex) {
Logger.getLogger(AuthorizedUserRepository.class).error("Error creating authorized_user repository - ", ex);
Logger.getLogger(AuthorizedUserRepository.class).error("Error creating / assigning authorized_user repository - ", ex);
}
}
@ -87,6 +82,14 @@ public enum AuthorizedUserRepository {
return null;
}
public void update(AuthorizedUser authorizedUser) {
try {
dao.update(authorizedUser);
} catch (SQLException ex) {
Logger.getLogger(AuthorizedUserRepository.class).error("Error updating authorized_user", ex);
}
}
public AuthorizedUser getByEmail(String userName) {
try {
QueryBuilder<AuthorizedUser, Object> qb = dao.queryBuilder();
@ -112,4 +115,38 @@ public enum AuthorizedUserRepository {
Logger.getLogger(AuthorizedUserRepository.class).error("Error closing authorized_user repository - ", ex);
}
}
public long getDBVersionFromDB() {
try {
ConnectionSource connectionSource = new JdbcConnectionSource(JDBC_URL);
return RepositoryUtil.getDatabaseVersion(connectionSource, VERSION_ENTITY_NAME);
} catch (SQLException ex) {
Logger.getLogger(CardRepository.class).error("Error getting DB version from DB - ", ex);
}
return 0;
}
public boolean checkAlterAndMigrateAuthorizedUser() {
long currentDBVersion = getDBVersionFromDB();
if (currentDBVersion == 1 && DB_VERSION == 2) {
return migrateFrom1To2();
}
return true;
}
private boolean migrateFrom1To2() {
try {
Logger.getLogger(AuthorizedUserRepository.class).info("Starting " + VERSION_ENTITY_NAME + " DB migration from version 1 to version 2");
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN active BOOLEAN DEFAULT true;");
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN lockedUntil DATETIME;");
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN chatLockedUntil DATETIME;");
dao.executeRaw("ALTER TABLE authorized_user ADD COLUMN lastConnection DATETIME;");
RepositoryUtil.updateVersion(dao.getConnectionSource(), VERSION_ENTITY_NAME, DB_VERSION);
Logger.getLogger(AuthorizedUserRepository.class).info("Migration finished.");
return true;
} catch (SQLException ex) {
Logger.getLogger(AuthorizedUserRepository.class).error("Error while migrating from version 1 to version 2 - ", ex);
return false;
}
}
}

View file

@ -28,9 +28,11 @@
package mage.server;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import mage.server.util.SystemUtil;
import mage.view.ChatMessage.MessageColor;
import mage.view.ChatMessage.MessageType;
import mage.view.ChatMessage.SoundToPlay;
@ -94,10 +96,6 @@ public class ChatManager {
}
}
public void broadcast(UUID chatId, String userName, String message, MessageColor color) {
this.broadcast(chatId, userName, message, color, true);
}
public void broadcast(UUID chatId, String userName, String message, MessageColor color, boolean withTime) {
this.broadcast(chatId, userName, message, color, withTime, MessageType.TALK);
}
@ -121,8 +119,25 @@ public class ChatManager {
}
}
if (!messageType.equals(MessageType.GAME) && message.equals(lastMessage)) {
return;
if (!messageType.equals(MessageType.GAME)) {
if (message.equals(lastMessage)) {
// prevent identical messages
return;
}
if (messageType.equals(MessageType.TALK)) {
User user = UserManager.getInstance().getUserByName(userName);
if (user != null) {
if (user.getChatLockedUntil() != null) {
if (user.getChatLockedUntil().compareTo(Calendar.getInstance().getTime()) > 0) {
chatSessions.get(chatId).broadcastInfoToUser(user, "Your chat is muted until " + SystemUtil.dateFormat.format(user.getChatLockedUntil()));
return;
} else {
user.setChatLockedUntil(null);
}
}
}
}
}
lastMessage = message;
chatSession.broadcast(userName, message, color, withTime, messageType, soundToPlay);
@ -195,7 +210,7 @@ public class ChatManager {
if (user != null) {
for (ChatSession chat : chatSessions.values()) {
if (chat.hasUser(userId)) {
chat.broadcast(user.getName(), message, color);
chat.broadcast(user.getName(), message, color, true, MessageType.TALK, null);
}
}
}
@ -206,7 +221,7 @@ public class ChatManager {
if (user != null) {
for (ChatSession chat : chatSessions.values()) {
if (chat.hasUser(userId)) {
chat.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, MessageType.STATUS);
chat.broadcast(null, user.getName() + " has reconnected", MessageColor.BLUE, true, MessageType.STATUS, null);
}
}
}

View file

@ -65,7 +65,7 @@ public class ChatSession {
if (user != null && !clients.containsKey(userId)) {
String userName = user.getName();
clients.put(userId, userName);
broadcast(null, userName + " has joined", MessageColor.BLUE, true, MessageType.STATUS);
broadcast(null, userName + " has joined", MessageColor.BLUE, true, MessageType.STATUS, null);
logger.trace(userName + " joined chat " + chatId);
}
}
@ -107,7 +107,7 @@ public class ChatSession {
message = " left (" + reason.toString() + ")";
}
if (message != null) {
broadcast(null, userName + message, MessageColor.BLUE, true, MessageType.STATUS);
broadcast(null, userName + message, MessageColor.BLUE, true, MessageType.STATUS, null);
}
}
} catch (Exception ex) {
@ -136,18 +136,6 @@ public class ChatSession {
return false;
}
public void broadcast(String userName, String message, MessageColor color) {
this.broadcast(userName, message, color, true);
}
public void broadcast(String userName, String message, MessageColor color, boolean withTime) {
this.broadcast(userName, message, color, withTime, MessageType.TALK);
}
public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType) {
this.broadcast(userName, message, color, withTime, messageType, null);
}
public void broadcast(String userName, String message, MessageColor color, boolean withTime, MessageType messageType, SoundToPlay soundToPlay) {
if (!message.isEmpty()) {
boolean remove = false;

View file

@ -28,8 +28,6 @@
package mage.server;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@ -77,6 +75,7 @@ import mage.server.tournament.TournamentFactory;
import mage.server.tournament.TournamentManager;
import mage.server.util.ConfigSettings;
import mage.server.util.ServerMessagesUtil;
import mage.server.util.SystemUtil;
import mage.server.util.ThreadExecutor;
import mage.utils.ActionWithBooleanResult;
import mage.utils.ActionWithNullNegativeResult;
@ -105,8 +104,6 @@ public class MageServerImpl implements MageServer {
private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor();
private static final SecureRandom RANDOM = new SecureRandom();
private static final DateFormat dateFormat = new SimpleDateFormat("yyyy-M-dd hh:mm:ss");
private final String adminPassword;
private final boolean testMode;
private final LinkedHashMap<String, String> activeAuthTokens = new LinkedHashMap<String, String>() {
@ -540,7 +537,7 @@ public class MageServerImpl implements MageServer {
new Runnable() {
@Override
public void run() {
ChatManager.getInstance().broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE);
ChatManager.getInstance().broadcast(chatId, userName, StringEscapeUtils.escapeHtml4(message), MessageColor.BLUE, true, ChatMessage.MessageType.TALK, null);
}
}
);
@ -1075,7 +1072,9 @@ public class MageServerImpl implements MageServer {
user.getSessionId(),
user.getConnectionTime(),
user.getGameInfo(),
user.getUserState().toString()));
user.getUserState().toString(),
user.getChatLockedUntil()
));
}
return users;
}
@ -1100,8 +1099,38 @@ public class MageServerImpl implements MageServer {
User user = UserManager.getInstance().getUserByName(userName);
if (user != null) {
Date muteUntil = new Date(Calendar.getInstance().getTimeInMillis() + (durationMinutes * Timer.ONE_MINUTE));
user.showUserMessage("Admin info", "You were muted for chat messages until " + dateFormat.format(muteUntil) + ".");
// user.setChatMuteUntil(new Date() + duationMinutes);
user.showUserMessage("Admin info", "You were muted for chat messages until " + SystemUtil.dateFormat.format(muteUntil) + ".");
user.setChatLockedUntil(muteUntil);
}
}
});
}
@Override
public void lockUser(String sessionId, final String userName, final long durationMinutes) throws MageException {
execute("muteUser", sessionId, new Action() {
@Override
public void execute() {
User user = UserManager.getInstance().getUserByName(userName);
if (user != null) {
Date lockUntil = new Date(Calendar.getInstance().getTimeInMillis() + (durationMinutes * Timer.ONE_MINUTE));
user.showUserMessage("Admin info", "Your user profile was locked until " + SystemUtil.dateFormat.format(lockUntil) + ".");
user.setLockedUntil(lockUntil);
}
}
});
}
@Override
public void toggleActivation(String sessionId, final String userName) throws MageException {
execute("muteUser", sessionId, new Action() {
@Override
public void execute() {
User user = UserManager.getInstance().getUserByName(userName);
if (user != null) {
user.setActive(!user.isActive());
}
}

View file

@ -37,7 +37,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.management.MBeanServer;
import mage.cards.ExpansionSet;
import mage.cards.Sets;
import mage.cards.repository.CardScanner;
@ -118,25 +117,42 @@ public class Main {
}
}
if (ConfigSettings.getInstance().isAuthenticationActivated()) {
logger.info("Check authorized user DB version ...");
if (!AuthorizedUserRepository.instance.checkAlterAndMigrateAuthorizedUser()) {
logger.fatal("Failed to start server.");
return;
}
logger.info("Done.");
}
logger.info("Loading extension packages...");
List<ExtensionPackage> extensions = new ArrayList<>();
if(!extensionFolder.exists()) if(!extensionFolder.mkdirs())
logger.error("Could not create extensions directory.");
File[] extensionDirectories = extensionFolder.listFiles();
if(extensionDirectories != null) for(File f : extensionDirectories) if(f.isDirectory())
try {
logger.info(" - Loading extension from "+f);
extensions.add(ExtensionPackageLoader.loadExtension(f));
} catch (IOException e) {
logger.error("Could not load extension in "+f+"!", e);
if (!extensionFolder.exists()) {
if (!extensionFolder.mkdirs()) {
logger.error("Could not create extensions directory.");
}
}
File[] extensionDirectories = extensionFolder.listFiles();
if (extensionDirectories != null) {
for (File f : extensionDirectories) {
if (f.isDirectory()) {
try {
logger.info(" - Loading extension from " + f);
extensions.add(ExtensionPackageLoader.loadExtension(f));
} catch (IOException e) {
logger.error("Could not load extension in " + f + "!", e);
}
}
}
}
logger.info("Done.");
if(!extensions.isEmpty()) {
if (!extensions.isEmpty()) {
logger.info("Registering custom sets...");
for(ExtensionPackage pkg : extensions) {
for(ExpansionSet set : pkg.getSets()) {
logger.info("- Loading "+set.getName()+" ("+set.getCode()+")");
for (ExtensionPackage pkg : extensions) {
for (ExpansionSet set : pkg.getSets()) {
logger.info("- Loading " + set.getName() + " (" + set.getCode() + ")");
Sets.getInstance().addSet(set);
}
PluginClassloaderRegistery.registerPluginClassloader(pkg.getClassLoader());
@ -155,7 +171,6 @@ public class Main {
logger.info("Updating user stats DB...");
UserStatsRepository.instance.updateUserStats();
logger.info("Done.");
deleteSavedGames();
ConfigSettings config = ConfigSettings.getInstance();
for (GamePlugin plugin : config.getGameTypes()) {
@ -177,12 +192,12 @@ public class Main {
for (ExtensionPackage pkg : extensions) {
Map<String, Class> draftCubes = pkg.getDraftCubes();
for (String name : draftCubes.keySet()) {
logger.info("Loading extension: ["+name+"] "+draftCubes.get(name).toString());
logger.info("Loading extension: [" + name + "] " + draftCubes.get(name).toString());
CubeFactory.getInstance().addDraftCube(name, draftCubes.get(name));
}
Map<String, Class> deckTypes = pkg.getDeckTypes();
for (String name : deckTypes.keySet()) {
logger.info("Loading extension: ["+name+"] "+deckTypes.get(name));
logger.info("Loading extension: [" + name + "] " + deckTypes.get(name));
DeckValidatorFactory.getInstance().addDeckType(name, deckTypes.get(name));
}
}
@ -408,11 +423,11 @@ public class Main {
}
File[] files = directory.listFiles(
new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".game");
}
}
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".game");
}
}
);
for (File file : files) {
file.delete();

View file

@ -180,14 +180,15 @@ public class Session {
public String connectUserHandling(String userName, String password) throws MageException {
this.isAdmin = false;
AuthorizedUser authorizedUser = null;
if (ConfigSettings.getInstance().isAuthenticationActivated()) {
AuthorizedUser authorizedUser = AuthorizedUserRepository.instance.getByName(userName);
authorizedUser = AuthorizedUserRepository.instance.getByName(userName);
if (authorizedUser == null || !authorizedUser.doCredentialsMatch(userName, password)) {
return "Wrong username or password. In case you haven't, please register your account first.";
}
}
User user = UserManager.getInstance().createUser(userName, host);
User user = UserManager.getInstance().createUser(userName, host, authorizedUser);
boolean reconnect = false;
if (user == null) { // user already exists
user = UserManager.getInstance().getUserByName(userName);
@ -223,7 +224,7 @@ public class Session {
public void connectAdmin() {
this.isAdmin = true;
User user = UserManager.getInstance().createUser("Admin", host);
User user = UserManager.getInstance().createUser("Admin", host, null);
if (user == null) {
user = UserManager.getInstance().getUserByName("Admin");
}

View file

@ -91,15 +91,30 @@ public class User {
private UserState userState;
private UserData userData;
private UserStats userStats;
private Date chatLockedUntil;
private boolean active;
private Date lockedUntil;
private final AuthorizedUser authorizedUser;
public User(String userName, String host) {
public User(String userName, String host, AuthorizedUser authorizedUser) {
this.userId = UUID.randomUUID();
this.userName = userName;
this.host = host;
this.userState = UserState.Created;
this.connectionTime = new Date();
this.lastActivity = new Date();
if (authorizedUser != null) {
this.active = authorizedUser.active;
this.chatLockedUntil = authorizedUser.chatLockedUntil;
this.lockedUntil = authorizedUser.lockedUntil;
this.authorizedUser = authorizedUser;
updateAuthorizedUser();
} else {
this.active = true;
this.chatLockedUntil = null;
this.lockedUntil = null;
this.authorizedUser = null;
}
this.tables = new ConcurrentHashMap<>();
this.gameSessions = new ConcurrentHashMap<>();
@ -128,6 +143,18 @@ public class User {
return sessionId;
}
public Date getChatLockedUntil() {
return chatLockedUntil;
}
public boolean isActive() {
return active;
}
public Date getLockedUntil() {
return lockedUntil;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
if (sessionId.isEmpty()) {
@ -145,6 +172,21 @@ public class User {
}
}
public void setChatLockedUntil(Date chatLockedUntil) {
this.chatLockedUntil = chatLockedUntil;
updateAuthorizedUser();
}
public void setActive(boolean active) {
this.active = active;
updateAuthorizedUser();
}
public void setLockedUntil(Date lockedUntil) {
this.lockedUntil = lockedUntil;
updateAuthorizedUser();
}
public void lostConnection() {
// Because watched games don't get restored after reconnection call stop watching
for (Iterator<UUID> iterator = watchedGames.iterator(); iterator.hasNext();) {
@ -731,4 +773,12 @@ public class User {
}
return number;
}
private void updateAuthorizedUser() {
if (authorizedUser != null) {
authorizedUser.lastConnection = this.connectionTime;
authorizedUser.chatLockedUntil = this.chatLockedUntil;
AuthorizedUserRepository.instance.update(authorizedUser);
}
}
}

View file

@ -76,11 +76,11 @@ public class UserManager {
}, 60, 60, TimeUnit.SECONDS);
}
public User createUser(String userName, String host) {
public User createUser(String userName, String host, AuthorizedUser authorizedUser) {
if (getUserByName(userName) != null) {
return null; //user already exists
}
User user = new User(userName, host);
User user = new User(userName, host, authorizedUser);
users.put(user.getId(), user);
usersByName.put(userName, user);
return user;

View file

@ -166,11 +166,11 @@ public class GameController implements GameCallback {
updateGame();
break;
case INFO:
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, ChatMessage.MessageType.GAME);
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, ChatMessage.MessageType.GAME, null);
logger.trace(game.getId() + " " + event.getMessage());
break;
case STATUS:
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), ChatMessage.MessageType.GAME);
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.ORANGE, event.getWithTime(), ChatMessage.MessageType.GAME, null);
logger.trace(game.getId() + " " + event.getMessage());
break;
case ERROR:
@ -346,7 +346,7 @@ public class GameController implements GameCallback {
}
user.addGame(playerId, gameSession);
logger.debug("Player " + player.getName() + " " + playerId + " has " + joinType + " gameId: " + game.getId());
ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, MessageType.GAME);
ChatManager.getInstance().broadcast(chatId, "", game.getPlayer(playerId).getLogName() + " has " + joinType + " the game", MessageColor.ORANGE, true, MessageType.GAME, null);
checkStart();
}
@ -372,7 +372,7 @@ public class GameController implements GameCallback {
GameManager.getInstance().joinGame(game.getId(), user.getId());
logger.debug("Player " + player.getName() + " (disconnected) has joined gameId: " + game.getId());
}
ChatManager.getInstance().broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
ChatManager.getInstance().broadcast(chatId, player.getName(), user.getPingInfo() + " is pending to join the game", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
if (user.getSecondsDisconnected() > 240) {
// Cancel player join possibility lately after 4 minutes
logger.debug("Player " + player.getName() + " - canceled game (after 240 seconds) gameId: " + game.getId());
@ -443,7 +443,7 @@ public class GameController implements GameCallback {
watchers.put(userId, gameWatcher);
gameWatcher.init();
user.addGameWatchInfo(game.getId());
ChatManager.getInstance().broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
ChatManager.getInstance().broadcast(chatId, user.getName(), " has started watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
}
}
@ -451,7 +451,7 @@ public class GameController implements GameCallback {
watchers.remove(userId);
User user = UserManager.getInstance().getUser(userId);
if (user != null) {
ChatManager.getInstance().broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS);
ChatManager.getInstance().broadcast(chatId, user.getName(), " has stopped watching", MessageColor.BLUE, true, ChatMessage.MessageType.STATUS, null);
}
}
@ -678,7 +678,7 @@ public class GameController implements GameCallback {
String sb = player.getLogName()
+ " has timed out (player had priority and was not active for "
+ ConfigSettings.getInstance().getMaxSecondsIdle() + " seconds ) - Auto concede.";
ChatManager.getInstance().broadcast(chatId, "", sb, MessageColor.BLACK, true, MessageType.STATUS);
ChatManager.getInstance().broadcast(chatId, "", sb, MessageColor.BLACK, true, MessageType.STATUS, null);
game.idleTimeout(playerId);
}
}

View file

@ -89,73 +89,73 @@ public class TournamentController {
private void init() {
tournament.addTableEventListener(
new Listener<TableEvent>() {
@Override
public void event(TableEvent event) {
switch (event.getEventType()) {
case CHECK_STATE_PLAYERS:
checkPlayersState();
break;
case INFO:
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS);
logger.debug(tournament.getId() + " " + event.getMessage());
break;
case START_DRAFT:
startDraft(event.getDraft());
break;
case CONSTRUCT:
if (!isAbort()) {
construct();
} else {
endTournament();
}
break;
case START_MATCH:
if (!isAbort()) {
initTournament(); // set state
startMatch(event.getPair(), event.getMatchOptions());
}
break;
case START_MULTIPLAYER_MATCH:
if (!isAbort()) {
initTournament(); // set state
MatchOptions matchOptions = event.getMatchOptions();
if (matchOptions != null && event.getMultiplayerRound() != null) {
for (TournamentPlayer player : event.getMultiplayerRound().getAllPlayers()) {
matchOptions.getPlayerTypes().add(player.getPlayerType());
}
}
startMultiplayerMatch(event.getMultiplayerRound(), event.getMatchOptions());
}
break;
case END:
endTournament();
break;
@Override
public void event(TableEvent event) {
switch (event.getEventType()) {
case CHECK_STATE_PLAYERS:
checkPlayersState();
break;
case INFO:
ChatManager.getInstance().broadcast(chatId, "", event.getMessage(), MessageColor.BLACK, true, MessageType.STATUS, null);
logger.debug(tournament.getId() + " " + event.getMessage());
break;
case START_DRAFT:
startDraft(event.getDraft());
break;
case CONSTRUCT:
if (!isAbort()) {
construct();
} else {
endTournament();
}
}
break;
case START_MATCH:
if (!isAbort()) {
initTournament(); // set state
startMatch(event.getPair(), event.getMatchOptions());
}
break;
case START_MULTIPLAYER_MATCH:
if (!isAbort()) {
initTournament(); // set state
MatchOptions matchOptions = event.getMatchOptions();
if (matchOptions != null && event.getMultiplayerRound() != null) {
for (TournamentPlayer player : event.getMultiplayerRound().getAllPlayers()) {
matchOptions.getPlayerTypes().add(player.getPlayerType());
}
}
startMultiplayerMatch(event.getMultiplayerRound(), event.getMatchOptions());
}
break;
case END:
endTournament();
break;
}
}
}
);
tournament.addPlayerQueryEventListener(
new Listener<PlayerQueryEvent>() {
@Override
public void event(PlayerQueryEvent event) {
try {
switch (event.getQueryType()) {
case CONSTRUCT:
construct(event.getPlayerId(), event.getMax());
break;
}
} catch (MageException ex) {
logger.fatal("Player event listener error", ex);
}
@Override
public void event(PlayerQueryEvent event) {
try {
switch (event.getQueryType()) {
case CONSTRUCT:
construct(event.getPlayerId(), event.getMax());
break;
}
} catch (MageException ex) {
logger.fatal("Player event listener error", ex);
}
}
}
);
for (TournamentPlayer player : tournament.getPlayers()) {
if (!player.getPlayer().isHuman()) {
player.setJoined();
logger.debug("player " + player.getPlayer().getId() + " has joined tournament " + tournament.getId());
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS);
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS, null);
}
}
checkStart();
@ -185,7 +185,7 @@ public class TournamentController {
TournamentPlayer player = tournament.getPlayer(playerId);
player.setJoined();
logger.debug("player " + player.getPlayer().getName() + " - client has joined tournament " + tournament.getId());
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS);
ChatManager.getInstance().broadcast(chatId, "", player.getPlayer().getLogName() + " has joined the tournament", MessageColor.BLACK, true, MessageType.STATUS, null);
checkStart();
} else {
logger.error("User not found userId: " + userId + " tournamentId: " + tournament.getId());
@ -209,11 +209,11 @@ public class TournamentController {
if (!started && allJoined()) {
ThreadExecutor.getInstance().getCallExecutor().execute(
new Runnable() {
@Override
public void run() {
startTournament();
}
});
@Override
public void run() {
startTournament();
}
});
}
}
@ -278,7 +278,7 @@ public class TournamentController {
logger.fatal("TournamentController startMatch error", ex);
}
}
private void startMultiplayerMatch(MultiplayerRound round, MatchOptions matchOptions) {
try {
TableManager tableManager = TableManager.getInstance();
@ -286,7 +286,7 @@ public class TournamentController {
table.setTournamentSubTable(true);
table.setTournament(tournament);
table.setState(TableState.WAITING);
for (TournamentPlayer player : round.getAllPlayers()) {
tableManager.addPlayer(getPlayerUserId(player.getPlayer().getId()), table.getId(), player.getPlayer(), player.getPlayerType(), player.getDeck());
}
@ -302,7 +302,7 @@ public class TournamentController {
} catch (GameException ex) {
logger.fatal("TournamentController startMatch error", ex);
}
}
}
private void startDraft(Draft draft) {
TableManager.getInstance().startDraft(tableId, draft);
@ -447,7 +447,7 @@ public class TournamentController {
user.removeTable(leavingPlayer.getPlayer().getId());
user.removeTournament(leavingPlayer.getPlayer().getId());
}
ChatManager.getInstance().broadcast(chatId, "", leavingPlayer.getPlayer().getLogName() + " was replaced by draftbot", MessageColor.BLACK, true, MessageType.STATUS);
ChatManager.getInstance().broadcast(chatId, "", leavingPlayer.getPlayer().getLogName() + " was replaced by draftbot", MessageColor.BLACK, true, MessageType.STATUS, null);
}
return true;
}

View file

@ -1,5 +1,16 @@
package mage.server.util;
import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import mage.cards.Card;
import mage.cards.repository.CardInfo;
import mage.cards.repository.CardRepository;
@ -8,36 +19,30 @@ import mage.game.Game;
import mage.players.Player;
import mage.util.RandomUtil;
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 {
public static final DateFormat dateFormat = new SimpleDateFormat("yy-M-dd HH:mm:ss");
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);
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/>
* 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/>
* 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) {
@ -109,8 +114,7 @@ public class SystemUtil {
swapWithAnyCard(game, player, card, gameZone);
}
}
}
finally {
} finally {
scanner.close();
}
} catch (Exception e) {
@ -137,7 +141,7 @@ public class SystemUtil {
} else {
card.moveToZone(zone, null, game, false);
}
logger.info("Added card to player's " + zone.toString() + ": " + card.getName() +", player = " + player.getName());
logger.info("Added card to player's " + zone.toString() + ": " + card.getName() + ", player = " + player.getName());
}
/**
@ -148,7 +152,7 @@ public class SystemUtil {
* @return
*/
private static Player findPlayer(Game game, String name) {
for (Player player: game.getPlayers().values()) {
for (Player player : game.getPlayers().values()) {
if (player.getName().equals(name)) {
return player;
}
@ -162,7 +166,7 @@ public class SystemUtil {
//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"));