Added "info [username]" command to get history for offline players. Remove user info column.

This commit is contained in:
LevelX2 2016-01-23 16:59:15 +01:00
parent 151e678e84
commit e31b12325e
6 changed files with 84 additions and 94 deletions

View file

@ -26,7 +26,7 @@
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
/* /*
* ChatPanel.java * ChatPanel.java
* *
* Created on 15-Dec-2009, 11:04:31 PM * Created on 15-Dec-2009, 11:04:31 PM
@ -61,7 +61,7 @@ public class PlayersChatPanel extends javax.swing.JPanel {
private final List<String> players = new ArrayList<>(); private final List<String> players = new ArrayList<>();
private final UserTableModel userTableModel; private final UserTableModel userTableModel;
private static final int[] defaultColumnsWidth = {20, 100, 100, 100, 80, 80}; private static final int[] DEFAULT_COLUMNS_WIDTH = {20, 100, 100, 80, 80};
/* /*
@ -78,7 +78,7 @@ public class PlayersChatPanel extends javax.swing.JPanel {
jTablePlayers.setForeground(Color.white); jTablePlayers.setForeground(Color.white);
jTablePlayers.setRowSorter(new MageTableRowSorter(userTableModel)); jTablePlayers.setRowSorter(new MageTableRowSorter(userTableModel));
TableUtil.setColumnWidthAndOrder(jTablePlayers, defaultColumnsWidth, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER); TableUtil.setColumnWidthAndOrder(jTablePlayers, DEFAULT_COLUMNS_WIDTH, KEY_USERS_COLUMNS_WIDTH, KEY_USERS_COLUMNS_ORDER);
jTablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer()); jTablePlayers.setDefaultRenderer(Icon.class, new CountryCellRenderer());
jScrollPaneTalk.setSystemMessagesPane(colorPaneSystem); jScrollPaneTalk.setSystemMessagesPane(colorPaneSystem);
@ -118,7 +118,7 @@ public class PlayersChatPanel extends javax.swing.JPanel {
class UserTableModel extends AbstractTableModel { class UserTableModel extends AbstractTableModel {
private final String[] columnNames = new String[]{"Loc", "Players", "History", "Info", "Games", "Connection"}; private final String[] columnNames = new String[]{"Loc", "Players", "History", "Games", "Connection"};
private UsersView[] players = new UsersView[0]; private UsersView[] players = new UsersView[0];
public void loadData(Collection<RoomUsersView> roomUserInfoList) throws MageRemoteException { public void loadData(Collection<RoomUsersView> roomUserInfoList) throws MageRemoteException {
@ -128,7 +128,7 @@ public class PlayersChatPanel extends javax.swing.JPanel {
TableColumnModel tcm = th.getColumnModel(); TableColumnModel tcm = th.getColumnModel();
tcm.getColumn(jTablePlayers.convertColumnIndexToView(1)).setHeaderValue("Players (" + this.players.length + ")"); tcm.getColumn(jTablePlayers.convertColumnIndexToView(1)).setHeaderValue("Players (" + this.players.length + ")");
tcm.getColumn(jTablePlayers.convertColumnIndexToView(4)).setHeaderValue( tcm.getColumn(jTablePlayers.convertColumnIndexToView(3)).setHeaderValue(
"Games " + roomUserInfo.getNumberActiveGames() "Games " + roomUserInfo.getNumberActiveGames()
+ (roomUserInfo.getNumberActiveGames() != roomUserInfo.getNumberGameThreads() ? " (T:" + roomUserInfo.getNumberGameThreads() : " (") + (roomUserInfo.getNumberActiveGames() != roomUserInfo.getNumberGameThreads() ? " (T:" + roomUserInfo.getNumberGameThreads() : " (")
+ " limit: " + roomUserInfo.getNumberMaxGames() + ")"); + " limit: " + roomUserInfo.getNumberMaxGames() + ")");
@ -156,10 +156,8 @@ public class PlayersChatPanel extends javax.swing.JPanel {
case 2: case 2:
return players[arg0].getHistory(); return players[arg0].getHistory();
case 3: case 3:
return players[arg0].getInfoState();
case 4:
return players[arg0].getInfoGames(); return players[arg0].getInfoGames();
case 5: case 4:
return players[arg0].getInfoPing(); return players[arg0].getInfoPing();
} }
return ""; return "";

View file

@ -24,7 +24,7 @@
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.view; package mage.view;
import java.io.Serializable; import java.io.Serializable;
@ -40,15 +40,13 @@ public class UsersView implements Serializable {
private final String flagName; private final String flagName;
private final String userName; private final String userName;
private final String history; private final String history;
private final String infoState;
private final String infoGames; private final String infoGames;
private final String infoPing; private final String infoPing;
public UsersView(String flagName, String userName, String history, String infoState, String infoGames, String infoPing) { public UsersView(String flagName, String userName, String history, String infoGames, String infoPing) {
this.flagName = flagName; this.flagName = flagName;
this.history = history; this.history = history;
this.userName = userName; this.userName = userName;
this.infoState = infoState;
this.infoGames = infoGames; this.infoGames = infoGames;
this.infoPing = infoPing; this.infoPing = infoPing;
} }
@ -65,10 +63,6 @@ public class UsersView implements Serializable {
return history; return history;
} }
public String getInfoState() {
return infoState;
}
public String getInfoGames() { public String getInfoGames() {
return infoGames; return infoGames;
} }

View file

@ -24,8 +24,7 @@
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.server; package mage.server;
import java.util.ArrayList; import java.util.ArrayList;
@ -44,14 +43,15 @@ import org.apache.log4j.Logger;
public class ChatManager { public class ChatManager {
private static final Logger logger = Logger.getLogger(ChatManager.class); private static final Logger logger = Logger.getLogger(ChatManager.class);
private static final ChatManager INSTANCE = new ChatManager(); private static final ChatManager INSTANCE = new ChatManager();
public static ChatManager getInstance() { public static ChatManager getInstance() {
return INSTANCE; return INSTANCE;
} }
private ChatManager() {} private ChatManager() {
}
private final ConcurrentHashMap<UUID, ChatSession> chatSessions = new ConcurrentHashMap<>(); private final ConcurrentHashMap<UUID, ChatSession> chatSessions = new ConcurrentHashMap<>();
@ -66,16 +66,16 @@ public class ChatManager {
if (chatSession != null) { if (chatSession != null) {
chatSession.join(userId); chatSession.join(userId);
} else { } else {
logger.trace("Chat to join not found - chatId: " + chatId +" userId: " + userId); logger.trace("Chat to join not found - chatId: " + chatId + " userId: " + userId);
} }
} }
public void leaveChat(UUID chatId, UUID userId) { public void leaveChat(UUID chatId, UUID userId) {
ChatSession chatSession = chatSessions.get(chatId); ChatSession chatSession = chatSessions.get(chatId);
if (chatSession != null && chatSession.hasUser(userId)) { if (chatSession != null && chatSession.hasUser(userId)) {
chatSession.kill(userId, DisconnectReason.CleaningUp); chatSession.kill(userId, DisconnectReason.CleaningUp);
} }
} }
public void destroyChatSession(UUID chatId) { public void destroyChatSession(UUID chatId) {
@ -88,7 +88,7 @@ public class ChatManager {
logger.trace("Chat removed - chatId: " + chatId); logger.trace("Chat removed - chatId: " + chatId);
} else { } else {
logger.trace("Chat to destroy does not exist - chatId: " + chatId); logger.trace("Chat to destroy does not exist - chatId: " + chatId);
} }
} }
} }
} }
@ -119,63 +119,56 @@ public class ChatManager {
} }
} }
private boolean performUserCommand(User user, String message, UUID chatId) { private boolean performUserCommand(User user, String message, UUID chatId) {
String command = message.substring(1).trim().toUpperCase(Locale.ENGLISH); String command = message.substring(1).trim().toUpperCase(Locale.ENGLISH);
if (command.equals("I") || command.equals("INFO")) {
user.setInfo("");
chatSessions.get(chatId).broadcastInfoToUser(user,message);
return true;
}
if (command.startsWith("I ") || command.startsWith("INFO ")) { if (command.startsWith("I ") || command.startsWith("INFO ")) {
user.setInfo(message.substring(command.startsWith("I ") ? 3 : 6)); message = UserManager.getInstance().getUserHistory(message.substring(command.startsWith("I ") ? 3 : 6));
chatSessions.get(chatId).broadcastInfoToUser(user,message); chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true; return true;
} }
if (command.startsWith("W ") || command.startsWith("WHISPER ")) { if (command.startsWith("W ") || command.startsWith("WHISPER ")) {
String rest = message.substring(command.startsWith("W ")? 3 : 9); String rest = message.substring(command.startsWith("W ") ? 3 : 9);
int first = rest.indexOf(" "); int first = rest.indexOf(" ");
if (first > 1) { if (first > 1) {
String userToName = rest.substring(0,first); String userToName = rest.substring(0, first);
rest = rest.substring(first + 1).trim(); rest = rest.substring(first + 1).trim();
User userTo = UserManager.getInstance().getUserByName(userToName); User userTo = UserManager.getInstance().getUserByName(userToName);
if (userTo != null) { if (userTo != null) {
if (!chatSessions.get(chatId).broadcastWhisperToUser(user, userTo, rest)) { if (!chatSessions.get(chatId).broadcastWhisperToUser(user, userTo, rest)) {
message += new StringBuilder("<br/>User ").append(userToName).append(" not found").toString(); message += new StringBuilder("<br/>User ").append(userToName).append(" not found").toString();
chatSessions.get(chatId).broadcastInfoToUser(user,message); chatSessions.get(chatId).broadcastInfoToUser(user, message);
} }
} else { } else {
message += new StringBuilder("<br/>User ").append(userToName).append(" not found").toString(); message += new StringBuilder("<br/>User ").append(userToName).append(" not found").toString();
chatSessions.get(chatId).broadcastInfoToUser(user,message); chatSessions.get(chatId).broadcastInfoToUser(user, message);
} }
return true; return true;
} }
} }
if (command.equals("L") || command.equals("LIST")) { if (command.equals("L") || command.equals("LIST")) {
message += new StringBuilder("<br/>List of commands:") message += new StringBuilder("<br/>List of commands:")
.append("<br/>\\info [text] - set a info text to your player") .append("<br/>\\info [username] - shows the history of a player")
.append("<br/>\\list - Show a list of commands") .append("<br/>\\list - Show a list of commands")
.append("<br/>\\whisper [player name] [text] - whisper to the player with the given name").toString(); .append("<br/>\\whisper [player name] [text] - whisper to the player with the given name").toString();
chatSessions.get(chatId).broadcastInfoToUser(user,message); chatSessions.get(chatId).broadcastInfoToUser(user, message);
return true; return true;
} }
return false; return false;
} }
/** /**
* *
* use mainly for announcing that a user connection was lost or that a user has reconnected * use mainly for announcing that a user connection was lost or that a user
* * has reconnected
*
* @param userId * @param userId
* @param message * @param message
* @param color * @param color
*/ */
public void broadcast(UUID userId, String message, MessageColor color) { public void broadcast(UUID userId, String message, MessageColor color) {
User user = UserManager.getInstance().getUser(userId); User user = UserManager.getInstance().getUser(userId);
if (user != null) { if (user != null) {
for (ChatSession chat: chatSessions.values()) { for (ChatSession chat : chatSessions.values()) {
if (chat.hasUser(userId)) { if (chat.hasUser(userId)) {
chat.broadcast(user.getName(), message, color); chat.broadcast(user.getName(), message, color);
} }
@ -186,16 +179,16 @@ public class ChatManager {
public void sendReconnectMessage(UUID userId) { public void sendReconnectMessage(UUID userId) {
User user = UserManager.getInstance().getUser(userId); User user = UserManager.getInstance().getUser(userId);
if (user != null) { if (user != null) {
for (ChatSession chat: chatSessions.values()) { for (ChatSession chat : chatSessions.values()) {
if (chat.hasUser(userId)) { 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);
} }
} }
} }
} }
public void removeUser(UUID userId, DisconnectReason reason) { public void removeUser(UUID userId, DisconnectReason reason) {
for (ChatSession chatSession: chatSessions.values()) { for (ChatSession chatSession : chatSessions.values()) {
if (chatSession.hasUser(userId)) { if (chatSession.hasUser(userId)) {
chatSession.kill(userId, reason); chatSession.kill(userId, reason);
} }

View file

@ -82,7 +82,6 @@ public class User {
private final Map<UUID, Deck> sideboarding; private final Map<UUID, Deck> sideboarding;
private final List<UUID> watchedGames; private final List<UUID> watchedGames;
private String sessionId; private String sessionId;
private String info = "";
private String pingInfo = ""; private String pingInfo = "";
private Date lastActivity; private Date lastActivity;
private UserState userState; private UserState userState;
@ -509,14 +508,6 @@ public class User {
return sb.toString(); return sb.toString();
} }
public String getInfo() {
return info;
}
public void setInfo(String Info) {
this.info = Info;
}
public void addGameWatchInfo(UUID gameId) { public void addGameWatchInfo(UUID gameId) {
watchedGames.add(gameId); watchedGames.add(gameId);
} }
@ -561,7 +552,7 @@ public class User {
return "<not available>"; return "<not available>";
} }
private static String userStatsToString(ResultProtos.UserStatsProto proto) { public static String userStatsToString(ResultProtos.UserStatsProto proto) {
List<StringBuilder> builders = new ArrayList<>(); List<StringBuilder> builders = new ArrayList<>();
if (proto.getMatches() > 0) { if (proto.getMatches() > 0) {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();

View file

@ -1,16 +1,16 @@
/* /*
* Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved. * Copyright 2011 BetaSteward_at_googlemail.com. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without modification, are * Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met: * permitted provided that the following conditions are met:
* *
* 1. Redistributions of source code must retain the above copyright notice, this list of * 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer. * conditions and the following disclaimer.
* *
* 2. Redistributions in binary form must reproduce the above copyright notice, this list * 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 * of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution. * provided with the distribution.
* *
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED * 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 * 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 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
@ -20,7 +20,7 @@
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * 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 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* The views and conclusions contained in the software and documentation are those of the * 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 * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
@ -38,6 +38,8 @@ import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import mage.server.User.UserState; import mage.server.User.UserState;
import mage.server.record.UserStats;
import mage.server.record.UserStatsRepository;
import mage.server.util.ThreadExecutor; import mage.server.util.ThreadExecutor;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -45,7 +47,7 @@ import org.apache.log4j.Logger;
* *
* manages users - if a user is disconnected and 10 minutes have passed with no * manages users - if a user is disconnected and 10 minutes have passed with no
* activity the user is removed * activity the user is removed
* *
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public class UserManager { public class UserManager {
@ -56,7 +58,7 @@ public class UserManager {
private final ConcurrentHashMap<UUID, User> users = new ConcurrentHashMap<>(); private final ConcurrentHashMap<UUID, User> users = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, User> usersByName = new ConcurrentHashMap<>(); private final ConcurrentHashMap<String, User> usersByName = new ConcurrentHashMap<>();
private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor(); private static final ExecutorService callExecutor = ThreadExecutor.getInstance().getCallExecutor();
private static final UserManager INSTANCE = new UserManager(); private static final UserManager INSTANCE = new UserManager();
@ -64,8 +66,8 @@ public class UserManager {
public static UserManager getInstance() { public static UserManager getInstance() {
return INSTANCE; return INSTANCE;
} }
private UserManager() { private UserManager() {
expireExecutor.scheduleAtFixedRate(new Runnable() { expireExecutor.scheduleAtFixedRate(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -113,7 +115,7 @@ public class UserManager {
public void disconnect(UUID userId, DisconnectReason reason) { public void disconnect(UUID userId, DisconnectReason reason) {
if (userId != null) { if (userId != null) {
User user = users.get(userId); User user = users.get(userId);
if (user != null) { if (user != null) {
user.setSessionId(""); // Session will be set again with new id if user reconnects user.setSessionId(""); // Session will be set again with new id if user reconnects
} }
ChatManager.getInstance().removeUser(userId, reason); ChatManager.getInstance().removeUser(userId, reason);
@ -123,44 +125,44 @@ public class UserManager {
public boolean isAdmin(UUID userId) { public boolean isAdmin(UUID userId) {
if (userId != null) { if (userId != null) {
User user = users.get(userId); User user = users.get(userId);
if (user != null) { if (user != null) {
return user.getName().equals("Admin"); return user.getName().equals("Admin");
} }
} }
return false; return false;
} }
public void removeUser(final UUID userId, final DisconnectReason reason) { public void removeUser(final UUID userId, final DisconnectReason reason) {
if (userId != null) { if (userId != null) {
final User user = users.get(userId); final User user = users.get(userId);
if (user != null) { if (user != null) {
callExecutor.execute( callExecutor.execute(
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
try { try {
logger.info("USER REMOVE - " + user.getName() + " (" + reason.toString() + ") userId: " + userId); logger.info("USER REMOVE - " + user.getName() + " (" + reason.toString() + ") userId: " + userId);
user.remove(reason); user.remove(reason);
logger.debug("USER REMOVE END - " + user.getName()); logger.debug("USER REMOVE END - " + user.getName());
} catch (Exception ex) { } catch (Exception ex) {
handleException(ex); handleException(ex);
} finally { } finally {
users.remove(userId); users.remove(userId);
usersByName.remove(user.getName()); usersByName.remove(user.getName());
}
} }
} }
}
); );
} else { } else {
logger.warn("Trying to remove userId: " + userId + " - but it does not exist."); logger.warn("Trying to remove userId: " + userId + " - but it does not exist.");
} }
} }
} }
public boolean extendUserSession(UUID userId, String pingInfo) { public boolean extendUserSession(UUID userId, String pingInfo) {
if (userId != null) { if (userId != null) {
User user = users.get(userId); User user = users.get(userId);
if (user != null) { if (user != null) {
user.updateLastActivity(pingInfo); user.updateLastActivity(pingInfo);
return true; return true;
} }
@ -169,7 +171,8 @@ public class UserManager {
} }
/** /**
* Is the connection lost for more than 3 minutes, the user will be removed (within 3 minutes the user can reconnect) * Is the connection lost for more than 3 minutes, the user will be removed
* (within 3 minutes the user can reconnect)
*/ */
private void checkExpired() { private void checkExpired() {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
@ -185,13 +188,25 @@ public class UserManager {
public void handleException(Exception ex) { public void handleException(Exception ex) {
if (ex != null) { if (ex != null) {
logger.fatal("User manager exception " + (ex.getMessage() == null ? "null":ex.getMessage())); logger.fatal("User manager exception " + (ex.getMessage() == null ? "null" : ex.getMessage()));
if (ex.getCause() != null) { if (ex.getCause() != null) {
logger.debug("- Cause: " + (ex.getCause().getMessage() == null ? "null":ex.getCause().getMessage())); logger.debug("- Cause: " + (ex.getCause().getMessage() == null ? "null" : ex.getCause().getMessage()));
} }
ex.printStackTrace(); ex.printStackTrace();
}else { } else {
logger.fatal("User manager exception - null"); logger.fatal("User manager exception - null");
} }
} }
public String getUserHistory(String userName) {
User user = getUserByName(userName);
if (user == null) {
UserStats userStats = UserStatsRepository.instance.getUser(userName);
if (userStats == null) {
return "User " + userName + " not found";
}
return User.userStatsToString(userStats.getProto());
}
return "History of user " + userName + ": " + user.getUserData().getHistory();
}
} }

View file

@ -114,14 +114,13 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
List<UsersView> users = new ArrayList<>(); List<UsersView> users = new ArrayList<>();
for (User user : UserManager.getInstance().getUsers()) { for (User user : UserManager.getInstance().getUsers()) {
try { try {
users.add(new UsersView(user.getUserData().getFlagName(), user.getName(), user.getHistory(), user.getInfo(), user.getGameInfo(), user.getPingInfo())); users.add(new UsersView(user.getUserData().getFlagName(), user.getName(), user.getHistory(), user.getGameInfo(), user.getPingInfo()));
} catch (Exception ex) { } catch (Exception ex) {
logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex); logger.fatal("User update exception: " + user.getName() + " - " + ex.toString(), ex);
users.add(new UsersView( users.add(new UsersView(
(user.getUserData() != null && user.getUserData().getFlagName() != null) ? user.getUserData().getFlagName() : "world", (user.getUserData() != null && user.getUserData().getFlagName() != null) ? user.getUserData().getFlagName() : "world",
user.getName() != null ? user.getName() : "<no name>", user.getName() != null ? user.getName() : "<no name>",
user.getHistory() != null ? user.getHistory() : "<no history>", user.getHistory() != null ? user.getHistory() : "<no history>",
user.getInfo() != null ? user.getInfo() : "<no info>",
"[exception]", "[exception]",
user.getPingInfo() != null ? user.getPingInfo() : "<no ping>")); user.getPingInfo() != null ? user.getPingInfo() : "<no ping>"));
} }