Java tutorial
/* Copyright (C) 2011 monte This file is part of PSP NetParty. PSP NetParty is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pspnetparty.client.swt; import java.io.IOException; import java.net.InetSocketAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.custom.SashForm; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.MenuDetectEvent; import org.eclipse.swt.events.MenuDetectListener; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.events.ShellListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.MenuItem; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import pspnetparty.client.swt.IApplication.PortalQuery; import pspnetparty.client.swt.message.AdminNotify; import pspnetparty.client.swt.message.Chat; import pspnetparty.client.swt.message.ErrorLog; import pspnetparty.client.swt.message.IMessageListener; import pspnetparty.client.swt.message.IMessageSource; import pspnetparty.client.swt.message.InfoLog; import pspnetparty.client.swt.message.LogViewer; import pspnetparty.client.swt.message.PrivateChat; import pspnetparty.client.swt.message.ServerLog; import pspnetparty.lib.Utility; import pspnetparty.lib.constants.ProtocolConstants; import pspnetparty.lib.engine.LobbyUserState; import pspnetparty.lib.socket.IProtocol; import pspnetparty.lib.socket.IProtocolDriver; import pspnetparty.lib.socket.IProtocolMessageHandler; import pspnetparty.lib.socket.ISocketConnection; import pspnetparty.lib.socket.TextProtocolDriver; public class LobbyWindow implements IMessageSource { enum SessionState { OFFLINE, CONNECTING, LOGIN, } private SessionState sessionState = SessionState.OFFLINE; private LobbyUserState userState = LobbyUserState.OFFLINE; private LobbyProtocol lobbyProtocol = new LobbyProtocol(); private ISocketConnection lobbyConnection = ISocketConnection.NULL; private HashMap<String, LobbyUser> lobbyUserMap = new HashMap<String, LobbyUser>(); private String loginUserName; private long lastLobbyActivity = 0L; private IApplication application; private Shell shell; private boolean isActive; private SashForm sashForm; private Button serverLoginButton; private Combo userStateCombo; private TableViewer userListTableViewer; private LogViewer chatLogViewer; private Label userNameLabel; private Text chatText; private Button multilineChatButton; private Label statusServerAddressLabel; private Label statusLobbyNameLabel; private MenuItem menuLoginNameChange; private MenuItem menuPrivateChat; private HashSet<IMessageListener> messageListeners = new HashSet<IMessageListener>(); public LobbyWindow(IApplication application) { this.application = application; // Shell parentShell = application.getShell(); shell = new Shell(SWT.SHELL_TRIM);// | SWT.TOOL); shell.setText(""); try { shell.setImages(application.getShellImages()); } catch (RuntimeException e) { e.printStackTrace(); } GridData gridData; GridLayout gridLayout = new GridLayout(1, false); gridLayout.horizontalSpacing = 0; gridLayout.verticalSpacing = 3; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.marginTop = 2; shell.setLayout(gridLayout); sashForm = new SashForm(shell, SWT.HORIZONTAL); sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); chatLogViewer = new LogViewer(sashForm, application.getSettings().getMaxLogCount(), application); Composite infoContainer = new Composite(sashForm, SWT.NONE); gridLayout = new GridLayout(2, false); gridLayout.horizontalSpacing = 3; gridLayout.verticalSpacing = 3; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.marginTop = 0; infoContainer.setLayout(gridLayout); serverLoginButton = new Button(infoContainer, SWT.PUSH); serverLoginButton.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(serverLoginButton); userStateCombo = new Combo(infoContainer, SWT.BORDER | SWT.READ_ONLY); userStateCombo.setItems(new String[] { "", "? ", "?", "" }); userStateCombo.setEnabled(false); userStateCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(userStateCombo); userListTableViewer = new TableViewer(infoContainer, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION); Table userListTable = userListTableViewer.getTable(); userListTable.setHeaderVisible(true); userListTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); application.initControl(userListTable); TableColumn columnUserNameColumn = new TableColumn(userListTable, SWT.LEFT); columnUserNameColumn.setText("?"); SwtUtils.installSorter(userListTableViewer, columnUserNameColumn, LobbyUser.NAME_SORTER); TableColumn columnUserState = new TableColumn(userListTable, SWT.LEFT); columnUserState.setText("?"); SwtUtils.installSorter(userListTableViewer, columnUserState, LobbyUser.STATE_SORTER); userListTableViewer.setLabelProvider(LobbyUser.LABEL_PROVIDER); userListTableViewer.setContentProvider(LobbyUser.CONTENT_PROVIDER); userListTableViewer.setInput(lobbyUserMap); SwtUtils.enableColumnDrag(userListTable); Composite chatContainer = new Composite(shell, SWT.NONE); gridLayout = new GridLayout(3, false); gridLayout.verticalSpacing = 0; gridLayout.horizontalSpacing = 3; gridLayout.marginHeight = 0; gridLayout.marginWidth = 0; gridLayout.marginTop = 0; gridLayout.marginBottom = 1; gridLayout.marginRight = 1; chatContainer.setLayout(gridLayout); chatContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); userNameLabel = new Label(chatContainer, SWT.NONE); userNameLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(userNameLabel); chatText = new Text(chatContainer, SWT.BORDER | SWT.SINGLE); chatText.setTextLimit(300); chatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initChatControl(chatText); multilineChatButton = new Button(chatContainer, SWT.PUSH); multilineChatButton.setText(""); application.initControl(multilineChatButton); Composite statusBarContainer = new Composite(shell, SWT.NONE); statusBarContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); gridLayout = new GridLayout(4, false); gridLayout.marginWidth = 3; gridLayout.marginHeight = 2; statusBarContainer.setLayout(gridLayout); statusServerAddressLabel = new Label(statusBarContainer, SWT.NONE); statusServerAddressLabel.setText(" : "); gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); gridData.heightHint = 15; new Label(statusBarContainer, SWT.SEPARATOR | SWT.VERTICAL).setLayoutData(gridData); statusLobbyNameLabel = new Label(statusBarContainer, SWT.NONE); statusLobbyNameLabel.setText("? "); new Label(statusBarContainer, SWT.SEPARATOR | SWT.VERTICAL).setLayoutData(gridData); initWidgetListeners(); updateLobbyServerLoginButton(false); IniAppData appData = application.getAppData(); sashForm.setWeights(appData.getArenaLobbySashFormWeights()); appData.restoreLobbyUserTableSetting(userListTable); appData.restoreLobbyWindow(shell); } private void initWidgetListeners() { serverLoginButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { if (lobbyConnection.isConnected()) { lobbyConnection.send(ProtocolConstants.Lobby.COMMAND_LOGOUT); } else { selectLobbyServer(); } } }); chatText.addKeyListener(new KeyListener() { @Override public void keyReleased(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { switch (e.character) { case SWT.CR: case SWT.LF: e.doit = false; if (sendChat(chatText.getText())) { chatText.setText(""); } } } }); multilineChatButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { switch (sessionState) { case LOGIN: MultiLineChatDialog dialog = new MultiLineChatDialog(shell, application); switch (dialog.open()) { case IDialogConstants.OK_ID: String message = dialog.getMessage(); sendChat(message); } } } }); userStateCombo.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { sendLobbyState(); chatText.setFocus(); } }); shell.addShellListener(new ShellListener() { @Override public void shellIconified(ShellEvent e) { isActive = false; } @Override public void shellDeiconified(ShellEvent e) { isActive = true; } @Override public void shellDeactivated(ShellEvent e) { isActive = false; } @Override public void shellActivated(ShellEvent e) { isActive = true; } @Override public void shellClosed(ShellEvent e) { e.doit = false; shell.setVisible(false); isActive = false; } }); shell.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { storeAppData(); } }); Menu lobbyUserMenu = new Menu(shell, SWT.POP_UP); menuPrivateChat = new MenuItem(lobbyUserMenu, SWT.PUSH); menuPrivateChat.setText("?? "); menuPrivateChat.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) userListTableViewer.getSelection(); LobbyUser user = (LobbyUser) selection.getFirstElement(); String myName = userNameLabel.getText(); if (user == null || myName.equals(user.getName())) return; TextDialog dialog = new TextDialog(shell, "?? ? ", user.getName() + " ? ", "", 250); switch (dialog.open()) { case IDialogConstants.OK_ID: String message = dialog.getUserInput(); StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Lobby.COMMAND_PRIVATE_CHAT); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(user.getName()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(message); lobbyConnection.send(sb.toString()); PrivateChat chat = new PrivateChat(loginUserName, user.getName(), message, true); chatLogViewer.appendMessage(chat); break; } } }); Table userListTable = userListTableViewer.getTable(); userListTable.setMenu(lobbyUserMenu); userListTable.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { IStructuredSelection selection = (IStructuredSelection) userListTableViewer.getSelection(); LobbyUser user = (LobbyUser) selection.getFirstElement(); String myName = userNameLabel.getText(); if (user == null || myName.equals(user.getName())) menuPrivateChat.setEnabled(false); else menuPrivateChat.setEnabled(true); } }); Menu lobbyLoginNameMenu = new Menu(shell, SWT.POP_UP); menuLoginNameChange = new MenuItem(lobbyLoginNameMenu, SWT.PUSH); menuLoginNameChange.setText(" "); menuLoginNameChange.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { LobbyChangeNameDialog dialog = new LobbyChangeNameDialog(shell, userNameLabel.getText()); switch (dialog.open()) { case IDialogConstants.OK_ID: String newName = dialog.getNewName(); StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Lobby.COMMAND_CHANGE_NAME); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(newName); lobbyConnection.send(sb.toString()); break; case IDialogConstants.CANCEL_ID: break; } } }); userNameLabel.setMenu(lobbyLoginNameMenu); userNameLabel.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { menuLoginNameChange.setEnabled(lobbyConnection.isConnected()); } }); } private void storeAppData() { IniAppData appData = application.getAppData(); appData.storeLobbyWindow(shell.getBounds()); appData.storeLobbyUserTableSetting(userListTableViewer.getTable()); appData.setArenaLobbySashFormWeights(sashForm.getWeights()); } public void reflectAppearance() { chatLogViewer.applyAppearance(); shell.layout(true, true); } public void show() { if (shell.getMinimized()) shell.setMinimized(false); shell.open(); } public void hide() { shell.setVisible(false); } @Override public void addMessageListener(IMessageListener listener) { messageListeners.add(listener); } @Override public void removeMessageListener(IMessageListener listener) { messageListeners.remove(listener); } private void updateLobbyServerLoginButton(final boolean loginSuccess) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateLobbyServerLoginButton(loginSuccess); } }); return; } if (loginSuccess) { serverLoginButton.setText(""); } else { serverLoginButton.setText("?"); } serverLoginButton.getParent().layout(); serverLoginButton.setEnabled(true); } catch (SWTException e) { } } private void selectLobbyServer() { loginUserName = application.getSettings().getUserName(); PortalQuery query = new PortalQuery() { @Override public String getCommand() { return ProtocolConstants.Portal.COMMAND_LIST_LOBBY_SERVERS; } @Override public void failCallback(ErrorLog log) { chatLogViewer.appendMessage(log); } @Override public void successCallback(String message) { ArrayList<LobbyServerInfo> list = new ArrayList<LobbyServerInfo>(); for (String info : message.split("\n")) { try { String[] values = info.split("\t"); String address = values[0]; int currentUsers = Integer.parseInt(values[1]); String title = values[2]; LobbyServerInfo server = new LobbyServerInfo(address, currentUsers, title); list.add(server); } catch (NumberFormatException e) { } } showLobbyServerSelectDialog(list); } }; application.queryPortalServer(query); } private void showLobbyServerSelectDialog(final List<LobbyServerInfo> list) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { showLobbyServerSelectDialog(list); } }); return; } if (list.isEmpty()) { ErrorLog log = new ErrorLog(" ? "); chatLogViewer.appendMessage(log); } else { LobbyServerSelectDialog dialog = new LobbyServerSelectDialog(shell, list); switch (dialog.open()) { case IDialogConstants.OK_ID: LobbyServerInfo selected = dialog.getSelectedServer(); connectToLobbyServer(selected.getAddress()); break; case IDialogConstants.CANCEL_ID: break; } } } catch (SWTException e) { } } private void connectToLobbyServer(String address) { loginUserName = application.getSettings().getUserName(); serverLoginButton.setEnabled(false); statusServerAddressLabel.setText(" : " + address); try { InetSocketAddress socketAddress = Utility.parseSocketAddress(address); application.connectTcp(socketAddress, lobbyProtocol); } catch (IOException e) { updateLobbyServerLoginButton(false); ErrorLog log = new ErrorLog(e.getMessage()); chatLogViewer.appendMessage(log); } } private boolean sendChat(String message) { if (!Utility.isEmpty(message)) { switch (sessionState) { case LOGIN: changeLobbyStateTo(LobbyUserState.LOGIN); lobbyConnection.send( ProtocolConstants.Lobby.COMMAND_CHAT + TextProtocolDriver.ARGUMENT_SEPARATOR + message); return true; default: InfoLog log = new InfoLog("? ? "); chatLogViewer.appendMessage(log); } } return false; } public void changeLobbyStateTo(final LobbyUserState state) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { changeLobbyStateTo(state); } }); return; } if (!lobbyConnection.isConnected() || sessionState != SessionState.LOGIN) return; userState = state; int index; switch (state) { case LOGIN: index = 0; break; case AFK: index = 1; break; case PLAYING: index = 2; break; case INACTIVE: index = 3; break; default: return; } lastLobbyActivity = System.currentTimeMillis(); if (userStateCombo.getSelectionIndex() == index) return; userStateCombo.select(index); sendLobbyState(); } catch (SWTException e) { } } private void sendLobbyState() { switch (userStateCombo.getSelectionIndex()) { case 0: userState = LobbyUserState.LOGIN; break; case 1: userState = LobbyUserState.AFK; break; case 2: userState = LobbyUserState.PLAYING; break; case 3: userState = LobbyUserState.INACTIVE; break; default: return; } lobbyConnection.send(ProtocolConstants.Lobby.COMMAND_CHANGE_STATE + TextProtocolDriver.ARGUMENT_SEPARATOR + userState.getAbbreviation()); } private void updateLobbyTitle(final String title) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateLobbyTitle(title); } }); return; } if (Utility.isEmpty(title)) { statusLobbyNameLabel.setText("? "); shell.setText(""); } else { statusLobbyNameLabel.setText(": " + title); shell.setText(" (" + title + ")"); } statusLobbyNameLabel.getParent().layout(); } catch (SWTException e) { } } private void setLobbyLoginUserName(final String name) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { setLobbyLoginUserName(name); } }); return; } loginUserName = name; userNameLabel.setText(name); userNameLabel.getParent().layout(); lastLobbyActivity = System.currentTimeMillis(); } catch (SWTException e) { } } private void replaceLobbyUserList(final String[] userInfoList) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { replaceLobbyUserList(userInfoList); } }); return; } TableViewer viewer = userListTableViewer; viewer.getTable().clearAll(); lobbyUserMap.clear(); for (int i = 0; i < userInfoList.length - 1; i++) { String name = userInfoList[i]; LobbyUserState state = LobbyUserState.findState(userInfoList[++i]); if (Utility.isEmpty(name) || state == null) continue; LobbyUser user = new LobbyUser(name, state); lobbyUserMap.put(name, user); viewer.add(user); } viewer.refresh(); } catch (SWTException e) { } } private void updateLobbyUser(final String name, final LobbyUserState state) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateLobbyUser(name, state); } }); return; } LobbyUser user = lobbyUserMap.get(name); if (user == null) { user = new LobbyUser(name, state); lobbyUserMap.put(name, user); userListTableViewer.add(user); userListTableViewer.refresh(user); IniSettings settings = application.getSettings(); if (!name.equals(userNameLabel.getText()) && settings.isLogLobbyEnterExit()) { InfoLog log = new InfoLog(name + " ?"); chatLogViewer.appendMessage(log); if (settings.isBallonNotifyLobby()) application.balloonNotify(shell, log.getMessage()); } } else { user.setState(state); userListTableViewer.refresh(user); } } catch (SWTException e) { } } private void removeLobbyUser(final String name) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { removeLobbyUser(name); } }); return; } LobbyUser user = lobbyUserMap.remove(name); if (user == null) return; userListTableViewer.remove(user); userListTableViewer.refresh(); IniSettings settings = application.getSettings(); if (settings.isLogLobbyEnterExit()) { InfoLog log = new InfoLog(name + " "); chatLogViewer.appendMessage(log); if (settings.isBallonNotifyLobby() && settings.isLogLobbyEnterExit()) application.balloonNotify(shell, log.getMessage()); } } catch (SWTException e) { } } private void renameLobbyUser(final String oldName, final String newName) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { renameLobbyUser(oldName, newName); } }); return; } LobbyUser user = lobbyUserMap.get(oldName); if (user == null) return; if (oldName.equals(userNameLabel.getText())) { setLobbyLoginUserName(newName); InfoLog log = new InfoLog(newName + " ?? "); chatLogViewer.appendMessage(log); } else { InfoLog log = new InfoLog(oldName + " " + newName + " ?? "); chatLogViewer.appendMessage(log); } user.setName(newName); lobbyUserMap.remove(oldName); lobbyUserMap.put(newName, user); TableViewer viewer = userListTableViewer; viewer.remove(user); viewer.add(user); viewer.refresh(); } catch (SWTException e) { } } private final long lobbyInactivityInterval = 30 * 60 * 1000; public void cronJob() { if (sessionState != SessionState.LOGIN || userState != LobbyUserState.LOGIN) return; long deadline = System.currentTimeMillis() - lobbyInactivityInterval; if (deadline < lastLobbyActivity) return; changeLobbyStateTo(LobbyUserState.INACTIVE); } private class LobbyProtocol implements IProtocol { @Override public void log(String message) { ErrorLog log = new ErrorLog(message); chatLogViewer.appendMessage(log); } @Override public String getProtocol() { return ProtocolConstants.PROTOCOL_LOBBY; } @Override public IProtocolDriver createDriver(ISocketConnection connection) { lobbyConnection = connection; connection.send( ProtocolConstants.Lobby.COMMAND_LOGIN + TextProtocolDriver.ARGUMENT_SEPARATOR + loginUserName); return new LobbyProtocolDriver(connection); } } private class LobbyProtocolDriver extends TextProtocolDriver { public LobbyProtocolDriver(ISocketConnection connection) { super(connection, lobbyHandlers); } @Override public void log(String message) { ErrorLog log = new ErrorLog(message); chatLogViewer.appendMessage(log); } @Override public void errorProtocolNumber(String number) { String error = String.format( "? ? ? ? :%s ??? :%s", number, IProtocol.NUMBER); ErrorLog log = new ErrorLog(error); chatLogViewer.appendMessage(log); } @Override public void connectionDisconnected() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { connectionDisconnected(); } }); return; } lobbyConnection = ISocketConnection.NULL; sessionState = SessionState.OFFLINE; userState = LobbyUserState.OFFLINE; updateLobbyServerLoginButton(false); setLobbyLoginUserName(""); userStateCombo.setEnabled(false); userStateCombo.deselect(0); statusServerAddressLabel.setText(" : "); updateLobbyTitle(""); lobbyUserMap.clear(); userListTableViewer.refresh(); ServerLog log = new ServerLog(" "); chatLogViewer.appendMessage(log); if (application.getSettings().isBallonNotifyLobby()) application.balloonNotify(shell, log.getMessage()); } catch (SWTException e) { } } } private HashMap<String, IProtocolMessageHandler> lobbyHandlers = new HashMap<String, IProtocolMessageHandler>(); { lobbyHandlers.put(ProtocolConstants.Lobby.COMMAND_LOGIN, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String name) { sessionState = SessionState.LOGIN; userState = LobbyUserState.LOGIN; login(name); lastLobbyActivity = System.currentTimeMillis(); return true; } private void login(final String name) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { login(name); } }); return; } setLobbyLoginUserName(name); updateLobbyServerLoginButton(true); updateLobbyUser(name, LobbyUserState.LOGIN); userStateCombo.setEnabled(true); userStateCombo.select(0); chatText.setFocus(); ServerLog log = new ServerLog(name + " ?"); chatLogViewer.appendMessage(log); } catch (SWTException e) { } } }); lobbyHandlers.put(ProtocolConstants.Lobby.COMMAND_CHAT, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { String[] tokens = argument.split(TextProtocolDriver.ARGUMENT_SEPARATOR, 2); if (tokens.length != 2) return true; String name = tokens[0]; String message = tokens[1]; boolean isMine = name.equals(loginUserName); for (String line : message.replace("\r", "").split("\n", -1)) { Chat chat = new Chat(name, line, isMine); chatLogViewer.appendMessage(chat); name = ""; } name = tokens[0]; Chat chat = new Chat(name, message, isMine); if (!isMine && !isActive && application.getSettings().isBallonNotifyLobby()) application.balloonNotify(shell, "<" + name + "> " + message); for (IMessageListener listener : messageListeners) listener.messageReceived(chat); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.COMMAND_PRIVATE_CHAT, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { String[] tokens = argument.split(TextProtocolDriver.ARGUMENT_SEPARATOR, 2); if (tokens.length != 2) return true; String sender = tokens[0]; String message = tokens[1]; boolean isMine = sender.equals(loginUserName); for (String line : message.replace("\r", "").split("\n", -1)) { PrivateChat chat = new PrivateChat(sender, loginUserName, line, false); chatLogViewer.appendMessage(chat); } PrivateChat chat = new PrivateChat(sender, loginUserName, message, isMine); if (!isActive) application.balloonNotify(shell, "(" + sender + " " + loginUserName + ") " + message); for (IMessageListener listener : messageListeners) listener.messageReceived(chat); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.NOTIFY_FROM_ADMIN, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String message) { for (String line : message.replace("\r", "").split("\n", -1)) { AdminNotify log = new AdminNotify(line); chatLogViewer.appendMessage(log); } if (!isActive) application.balloonNotify(shell, message); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.NOTIFY_LOBBY_INFO, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String title) { updateLobbyTitle(title); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.NOTIFY_USER_LIST, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String args) { String[] userInfoList = args.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1); replaceLobbyUserList(userInfoList); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.NOTIFY_USER_INFO, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { String[] tokens = argument.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1); if (tokens.length != 2) return true; String name = tokens[0]; LobbyUserState state = LobbyUserState.findState(tokens[1]); if (state == null) return true; updateLobbyUser(name, state); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.NOTIFY_USER_LOGOUT, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String name) { removeLobbyUser(name); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.NOTIFY_USER_NAME_CHANGED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { String[] tokens = argument.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1); if (tokens.length != 2) return true; String oldName = tokens[0]; String newName = tokens[1]; renameLobbyUser(oldName, newName); return true; } }); lobbyHandlers.put(ProtocolConstants.Lobby.ERROR_LOGIN_USER_BEYOND_CAPACITY, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { ErrorLog log = new ErrorLog(" ? "); chatLogViewer.appendMessage(log); return false; } }); lobbyHandlers.put(ProtocolConstants.Lobby.ERROR_LOGIN_USER_DUPLICATED_NAME, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { switch (sessionState) { case CONNECTING: { ErrorLog log = new ErrorLog( "?? ? ? ? "); chatLogViewer.appendMessage(log); break; } case LOGIN: { ErrorLog log = new ErrorLog( "?? ? ? ?? ? "); chatLogViewer.appendMessage(log); break; } } return false; } }); } }