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.File; import java.io.IOException; import java.net.BindException; import java.net.InetSocketAddress; import java.net.SocketTimeoutException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map.Entry; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.viewers.ArrayContentProvider; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; 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.custom.StackLayout; 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.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.MouseEvent; import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.events.ShellListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.List; 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.Spinner; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import pspnetparty.client.swt.IApplication.PortalQuery; import pspnetparty.client.swt.IniSettings.TransportLayer; 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.RoomLog; import pspnetparty.client.swt.message.ServerLog; import pspnetparty.lib.IniFile; import pspnetparty.lib.IniSection; import pspnetparty.lib.Utility; import pspnetparty.lib.constants.AppConstants; import pspnetparty.lib.constants.ProtocolConstants; import pspnetparty.lib.engine.IMyRoomMasterHandler; import pspnetparty.lib.engine.LobbyUserState; import pspnetparty.lib.engine.MyRoomEngine; import pspnetparty.lib.engine.PlayRoom; import pspnetparty.lib.socket.IProtocol; import pspnetparty.lib.socket.IProtocolDriver; import pspnetparty.lib.socket.IProtocolMessageHandler; import pspnetparty.lib.socket.ISocketConnection; import pspnetparty.lib.socket.PacketData; import pspnetparty.lib.socket.TextProtocolDriver; import pspnetparty.wlan.Wlan; import pspnetparty.wlan.WlanDevice; import pspnetparty.wlan.WlanNetwork; public class RoomWindow implements IMessageSource { private static final String SECTION_LAN_ADAPTERS = "LanAdapters"; private static final int MAX_SERVER_HISTORY = 10; private static final int DEFAULT_MAX_PLAYERS = 4; private static final String INI_ROOM_TITLE = "Title"; private static final String INI_ROOM_PASSWORD = "Password"; private static final String INI_ROOM_CAPACITY = "Capacity"; private static final String INI_ROOM_DESCRIPTION = "Description"; private static final String INI_ROOM_REMARKS = "Remarks"; enum SessionState { OFFLINE, MY_ROOM_MASTER, CONNECTING_ROOM_PARTICIPANT, ROOM_PARTICIPANT, CONNECTING_ROOM_MASTER, ROOM_MASTER, NEGOTIATING, }; private IApplication application; private Shell shell; private boolean isActive; private SessionState sessionState; private String roomLoginName; private String roomMasterName; private String roomServerAddressPort; private MyRoomEngine myRoomEngine; private RoomProtocol roomProtocol = new RoomProtocol(); private ISocketConnection roomConnection = ISocketConnection.NULL; private TunnelProtocol tunnelProtocol = new TunnelProtocol(); private ISocketConnection tunnelConnection = ISocketConnection.NULL; private MyRoomEntryProtocol myRoomEntryProtocol = new MyRoomEntryProtocol(); private ISocketConnection myRoomEntryConnection = ISocketConnection.NULL; private int scanIntervalMillis = 2000; private long nextSsidCheckTime = 0L; private boolean tunnelIsLinked = false; private boolean isPacketCapturing = false; private boolean isSSIDScaning = false; private boolean isRoomInfoUpdating = false; private ByteBuffer bufferForCapturing = ByteBuffer.allocateDirect(Wlan.CAPTURE_BUFFER_SIZE); private ArrayList<WlanDevice> wlanAdaptorList = new ArrayList<WlanDevice>(); private HashMap<WlanDevice, String> wlanAdaptorMacAddressMap = new HashMap<WlanDevice, String>(); private WlanDevice currentWlanDevice = Wlan.EMPTY_DEVICE; private HashMap<String, Player> roomPlayerMap = new LinkedHashMap<String, Player>(); private HashMap<String, TraficStatistics> traficStatsMap = new HashMap<String, TraficStatistics>(); public int actualSentBytes; public int actualRecievedBytes; private Thread packetMonitorThread; private Thread packetCaptureThread; private Thread wlanScannerThread; private Widgets widgets; private ComboHistoryManager roomServerHistoryManager; private ComboHistoryManager roomAddressHistoryManager; private HashSet<IMessageListener> messageListeners = new HashSet<IMessageListener>(); public RoomWindow(IApplication application) throws IOException { this.application = application; shell = new Shell(SwtUtils.DISPLAY); myRoomEngine = new MyRoomEngine(new MyRoomServerHandler()); widgets = new Widgets(); widgets.initWidgets(); IniSettings iniSettings = application.getSettings(); IniAppData iniAppData = application.getAppData(); widgets.formMyRoomModePortSpinner.setSelection(iniSettings.getMyRoomPort()); widgets.formMyRoomModeHostText.setText(iniSettings.getMyRoomHostName()); widgets.initWidgetListeners(); widgets.initMenus(); changeStateTo(SessionState.OFFLINE); refreshLanAdapterList(); String[] stringList; stringList = iniSettings.getRoomServerList(); ComboHistoryManager.addList(widgets.formManualModeRoomServerCombo, stringList); stringList = iniAppData.getRoomServerHistory(); roomServerHistoryManager = new ComboHistoryManager(widgets.formManualModeRoomServerCombo, stringList, MAX_SERVER_HISTORY, true); stringList = iniSettings.getRoomAddressList(); ComboHistoryManager.addList(widgets.formManualModeRoomAddressCombo, stringList); stringList = iniAppData.getRoomAddressHistory(); roomAddressHistoryManager = new ComboHistoryManager(widgets.formManualModeRoomAddressCombo, stringList, MAX_SERVER_HISTORY, true); initBackgroundThreads(); shell.setMinimumSize(new Point(650, 400)); iniAppData.restoreMainWindow(shell); shell.open(); if (Utility.isEmpty(iniSettings.getUserName())) { shell.setText("PSP NetParty"); TextDialog dialog = new TextDialog(shell, "? ? ", "? ", null, 300); switch (dialog.open()) { case IDialogConstants.OK_ID: iniSettings.setUserName(dialog.getUserInput()); break; default: iniSettings.setUserName(""); } } updateShellTitle(); } public Shell getShell() { return shell; } private class Widgets { private SashForm mainSashForm; private Composite formModeSwitchContainer; private StackLayout roomModeStackLayout; private Combo formModeSelectionCombo; private Composite formAutoModeContainer; private Text formAutoModeServerAddress; private Button formAutoModeRoomButton; private Composite formManualModeContainer; private Combo formManualModeRoomServerCombo; private Button formManualModeRoomServerButton; private Combo formManualModeRoomAddressCombo; private Button formManualModeRoomAddressButton; private Composite formMyRoomModeContainer; private Text formMyRoomModeHostText; private Spinner formMyRoomModePortSpinner; private Button formMyRoomModeStartButton; private Text formMyRoomModeRoomServer; private Button formMyRoomModeEntryButton; private Text formMasterNameText; private Text formTitleText; private Text formPasswordText; private Spinner formMaxPlayersSpiner; private Text formTimestampText; private Text formDescriptionText; private Text formRemarksText; private Button formEditSaveButton; private Button formEditLoadButton; private Button formEditSubmitButton; private SashForm centerSashForm; private Combo wlanAdapterListCombo; private Button wlanPspCommunicationButton; private TableViewer packetMonitorTable; private LogViewer logViewer; private Text chatText; private Button multilineChatButton; private SashForm rightSashForm; private Button ssidStartScan; private Text ssidCurrentSsidText; private Label ssidMatchLabel; private Text ssidMatchText; private Spinner ssidScanIntervalSpinner; private Button ssidAutoDetectCheck; private TableViewer ssidListTableViewer; private TableViewer roomPlayerListTable; private Button macFilteringWhiteListCheck; private List macFilteringWhiteList; private Button macFilteringBlackListCheck; private List macFilteringBlackList; private Composite statusBarContainer; private Label statusRoomServerAddressLabel; private Label statusTunnelConnectionLabel; private Label statusTraficStatusLabel; private Color colorOK, colorNG, colorAppNumber; private MenuItem playerMenuChaseSsid; private MenuItem playerMenuSetSsid; private MenuItem playerMenuCopySsid; private MenuItem playerMenuKick; private MenuItem playerMenuMasterTransfer; private MenuItem statusServerAddressMenuCopy; private MenuItem packetMonitorMenuCopy; private MenuItem packetMonitorMenuWhiteList; private MenuItem packetMonitorMenuBlackList; private MenuItem packetMonitorMenuClear; private ToolItem searchWindowItem; private ToolItem lobbyWindowItem; private ToolItem logWindowItem; private ToolItem configWindowItem; private ToolItem wikiItem; private MenuItem macFilteringWhiteListMenuRemove; private MenuItem macFilteringBlackListMenuRemove; private Menu statusTunnelConnectionMenu; private MenuItem statusTunnelConnectionMenuChangeTransport; private void initWidgets() { Display display = SwtUtils.DISPLAY; IniAppData iniAppData = application.getAppData(); try { shell.setImages(application.getShellImages()); } catch (RuntimeException e) { e.printStackTrace(); } GridLayout gridLayout; GridData gridData; colorOK = new Color(display, 0, 140, 0); colorNG = new Color(display, 200, 0, 0); colorAppNumber = new Color(display, 0, 0, 220); ImageRegistry imageRegistry = application.getImageRegistry(); gridLayout = new GridLayout(1, false); gridLayout.horizontalSpacing = 3; gridLayout.verticalSpacing = 0; gridLayout.marginWidth = 2; gridLayout.marginHeight = 1; shell.setLayout(gridLayout); ToolBar toolBar = new ToolBar(shell, SWT.FLAT | SWT.RIGHT); gridData = new GridData(GridData.FILL_HORIZONTAL); toolBar.setLayoutData(gridData); searchWindowItem = new ToolItem(toolBar, SWT.PUSH); searchWindowItem.setText(""); searchWindowItem.setToolTipText("? ? "); searchWindowItem.setImage(imageRegistry.get(PlayClient.ICON_TOOLBAR_SEARCH)); lobbyWindowItem = new ToolItem(toolBar, SWT.PUSH); lobbyWindowItem.setText(""); lobbyWindowItem.setToolTipText(" ? "); lobbyWindowItem.setImage(imageRegistry.get(PlayClient.ICON_TOOLBAR_LOBBY)); logWindowItem = new ToolItem(toolBar, SWT.PUSH); logWindowItem.setText(""); logWindowItem.setToolTipText("? "); logWindowItem.setImage(imageRegistry.get(PlayClient.ICON_TOOLBAR_LOG)); configWindowItem = new ToolItem(toolBar, SWT.PUSH); configWindowItem.setText(""); configWindowItem.setToolTipText("PSP NetParty? ? "); configWindowItem.setImage(imageRegistry.get(PlayClient.ICON_TOOLBAR_CONFIG)); wikiItem = new ToolItem(toolBar, SWT.PUSH); wikiItem.setText("Wiki"); wikiItem.setToolTipText("PSP NetParty? Wiki ? "); wikiItem.setImage(imageRegistry.get(PlayClient.ICON_TOOLBAR_WIKI)); mainSashForm = new SashForm(shell, SWT.HORIZONTAL); gridData = new GridData(SWT.FILL, SWT.FILL, true, true); gridData.verticalIndent = 3; mainSashForm.setLayoutData(gridData); Composite leftContainer = new Composite(mainSashForm, SWT.NONE); gridLayout = new GridLayout(1, false); gridLayout.horizontalSpacing = 0; gridLayout.verticalSpacing = 1; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; leftContainer.setLayout(gridLayout); Composite formModeContainer = new Composite(leftContainer, SWT.NONE); gridLayout = new GridLayout(2, false); gridLayout.horizontalSpacing = 8; gridLayout.verticalSpacing = 3; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.marginLeft = 3; formModeContainer.setLayout(gridLayout); formModeContainer.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false)); Label formModeSelectionLabel = new Label(formModeContainer, SWT.NONE); formModeSelectionLabel.setText(""); formModeSelectionLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formModeSelectionLabel); formModeSelectionCombo = new Combo(formModeContainer, SWT.READ_ONLY); formModeSelectionCombo.setItems(new String[] { "", "", "?" }); formModeSelectionCombo.select(0); formModeSelectionCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(formModeSelectionCombo); formModeSwitchContainer = new Composite(formModeContainer, SWT.NONE); roomModeStackLayout = new StackLayout(); formModeSwitchContainer.setLayout(roomModeStackLayout); formModeSwitchContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); formAutoModeContainer = new Composite(formModeSwitchContainer, SWT.NONE); gridLayout = new GridLayout(2, false); gridLayout.horizontalSpacing = 8; gridLayout.verticalSpacing = 6; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.marginTop = 2; formAutoModeContainer.setLayout(gridLayout); Label formAutoModeServerAddressLabel = new Label(formAutoModeContainer, SWT.NONE); formAutoModeServerAddressLabel.setText(""); application.initControl(formAutoModeServerAddressLabel); formAutoModeServerAddress = new Text(formAutoModeContainer, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); formAutoModeServerAddress.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(formAutoModeServerAddress); formAutoModeRoomButton = new Button(formAutoModeContainer, SWT.PUSH); formAutoModeRoomButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, true, 2, 1)); application.initControl(formAutoModeRoomButton); formManualModeContainer = new Composite(formModeSwitchContainer, SWT.NONE); gridLayout = new GridLayout(3, false); gridLayout.horizontalSpacing = 5; gridLayout.verticalSpacing = 4; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; formManualModeContainer.setLayout(gridLayout); Label formManualModeServerLabel = new Label(formManualModeContainer, SWT.NONE); formManualModeServerLabel.setText(""); application.initControl(formManualModeServerLabel); formManualModeRoomServerCombo = new Combo(formManualModeContainer, SWT.NONE); formManualModeRoomServerCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(formManualModeRoomServerCombo); formManualModeRoomServerButton = new Button(formManualModeContainer, SWT.PUSH); formManualModeRoomServerButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); application.initControl(formManualModeRoomServerButton); Label formManualModeAddressLabel = new Label(formManualModeContainer, SWT.NONE); formManualModeAddressLabel.setText(""); application.initControl(formManualModeAddressLabel); formManualModeRoomAddressCombo = new Combo(formManualModeContainer, SWT.NONE); formManualModeRoomAddressCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(formManualModeRoomAddressCombo); formManualModeRoomAddressButton = new Button(formManualModeContainer, SWT.PUSH); formManualModeRoomAddressButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); application.initControl(formManualModeRoomAddressButton); formMyRoomModeContainer = new Composite(formModeSwitchContainer, SWT.NONE); gridLayout = new GridLayout(4, false); gridLayout.horizontalSpacing = 3; gridLayout.verticalSpacing = 4; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.marginRight = 1; formMyRoomModeContainer.setLayout(gridLayout); Label formServerModeEntryLabel = new Label(formMyRoomModeContainer, SWT.NONE); formServerModeEntryLabel.setText(":?"); formServerModeEntryLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formServerModeEntryLabel); formMyRoomModeHostText = new Text(formMyRoomModeContainer, SWT.SINGLE | SWT.BORDER); formMyRoomModeHostText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); application.initControl(formMyRoomModeHostText); formMyRoomModePortSpinner = new Spinner(formMyRoomModeContainer, SWT.BORDER); formMyRoomModePortSpinner.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); formMyRoomModePortSpinner.setMinimum(1); formMyRoomModePortSpinner.setMaximum(65535); formMyRoomModePortSpinner.setSelection(30000); application.initControl(formMyRoomModePortSpinner); formMyRoomModeStartButton = new Button(formMyRoomModeContainer, SWT.PUSH); formMyRoomModeStartButton.setText("?"); formMyRoomModeStartButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); application.initControl(formMyRoomModeStartButton); Label formMyRoomModeAddressLabel = new Label(formMyRoomModeContainer, SWT.NONE); formMyRoomModeAddressLabel.setText(""); formMyRoomModeAddressLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formMyRoomModeAddressLabel); formMyRoomModeRoomServer = new Text(formMyRoomModeContainer, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); formMyRoomModeRoomServer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); application.initControl(formMyRoomModeRoomServer); formMyRoomModeEntryButton = new Button(formMyRoomModeContainer, SWT.PUSH); formMyRoomModeEntryButton.setText(" ?"); formMyRoomModeEntryButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false)); application.initControl(formMyRoomModeEntryButton); roomModeStackLayout.topControl = formAutoModeContainer; Group formEditGroup = new Group(leftContainer, SWT.NONE); formEditGroup.setText(""); formEditGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); gridLayout = new GridLayout(2, false); gridLayout.marginWidth = 3; gridLayout.marginHeight = 3; formEditGroup.setLayout(gridLayout); Label formMasterNameLabel = new Label(formEditGroup, SWT.NONE); formMasterNameLabel.setText(""); formMasterNameLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formMasterNameLabel); formMasterNameText = new Text(formEditGroup, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); formMasterNameText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(formMasterNameText); Label formTitleLabel = new Label(formEditGroup, SWT.NONE); formTitleLabel.setText(""); formTitleLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formTitleLabel); formTitleText = new Text(formEditGroup, SWT.SINGLE | SWT.BORDER); formTitleText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); formTitleText.setTextLimit(100); application.initControl(formTitleText); Label formPasswordLabel = new Label(formEditGroup, SWT.NONE); formPasswordLabel.setText(""); formPasswordLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formPasswordLabel); formPasswordText = new Text(formEditGroup, SWT.SINGLE | SWT.BORDER); formPasswordText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); formPasswordText.setTextLimit(30); application.initControl(formPasswordText); Label formMaxPlayersLabel = new Label(formEditGroup, SWT.NONE); formMaxPlayersLabel.setText("?"); formMaxPlayersLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formMaxPlayersLabel); Composite formMaxPlayerContainer = new Composite(formEditGroup, SWT.NONE); formMaxPlayerContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); gridLayout = new GridLayout(3, false); gridLayout.horizontalSpacing = 3; gridLayout.verticalSpacing = 0; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; formMaxPlayerContainer.setLayout(gridLayout); formMaxPlayersSpiner = new Spinner(formMaxPlayerContainer, SWT.READ_ONLY | SWT.BORDER); formMaxPlayersSpiner.setMinimum(2); formMaxPlayersSpiner.setMaximum(ProtocolConstants.Room.MAX_ROOM_PLAYERS); formMaxPlayersSpiner.setSelection(DEFAULT_MAX_PLAYERS); application.initControl(formMaxPlayersSpiner); Label formTimestampLabel = new Label(formMaxPlayerContainer, SWT.NONE); formTimestampLabel.setText(" ?"); formTimestampLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(formTimestampLabel); formTimestampText = new Text(formMaxPlayerContainer, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); formTimestampText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(formTimestampText); SashForm formDescriptionSashForm = new SashForm(formEditGroup, SWT.VERTICAL); gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1); gridData.verticalIndent = 1; formDescriptionSashForm.setLayoutData(gridData); Composite formDescriptionContainer = new Composite(formDescriptionSashForm, SWT.NONE); gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.marginTop = 4; gridLayout.verticalSpacing = 2; formDescriptionContainer.setLayout(gridLayout); Label formDescriptionLabel = new Label(formDescriptionContainer, SWT.NONE); formDescriptionLabel.setText("? (? ?)"); gridData = new GridData(); gridData.horizontalIndent = 3; formDescriptionLabel.setLayoutData(gridData); application.initControl(formDescriptionLabel); formDescriptionText = new Text(formDescriptionContainer, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER | SWT.WRAP); formDescriptionText.setTextLimit(1000); formDescriptionText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); application.initControl(formDescriptionText); Composite formRemarksContainer = new Composite(formDescriptionSashForm, SWT.NONE); gridLayout = new GridLayout(1, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.marginTop = 4; gridLayout.verticalSpacing = 2; formRemarksContainer.setLayout(gridLayout); Label formRemarksLabel = new Label(formRemarksContainer, SWT.NONE); formRemarksLabel.setText("(? ? )"); gridData = new GridData(); gridData.horizontalIndent = 3; formRemarksLabel.setLayoutData(gridData); application.initControl(formRemarksLabel); formRemarksText = new Text(formRemarksContainer, SWT.MULTI | SWT.V_SCROLL | SWT.BORDER | SWT.WRAP); formRemarksText.setTextLimit(1000); formRemarksText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); application.initControl(formRemarksText); Composite formEditControlContainer = new Composite(formEditGroup, SWT.NONE); formEditControlContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); gridLayout = new GridLayout(3, false); gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; gridLayout.verticalSpacing = 0; formEditControlContainer.setLayout(gridLayout); formEditSaveButton = new Button(formEditControlContainer, SWT.PUSH); formEditSaveButton.setText(""); formEditSaveButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); application.initControl(formEditSaveButton); formEditLoadButton = new Button(formEditControlContainer, SWT.PUSH); formEditLoadButton.setText("??"); formEditLoadButton.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); application.initControl(formEditLoadButton); formEditSubmitButton = new Button(formEditControlContainer, SWT.PUSH); formEditSubmitButton.setText(" "); formEditSubmitButton.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false)); application.initControl(formEditSubmitButton); centerSashForm = new SashForm(mainSashForm, SWT.VERTICAL); centerSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite centerUpperContainer = new Composite(centerSashForm, SWT.NONE); gridLayout = new GridLayout(1, false); gridLayout.verticalSpacing = 3; gridLayout.horizontalSpacing = 0; gridLayout.marginHeight = 0; gridLayout.marginWidth = 0; centerUpperContainer.setLayout(gridLayout); Composite wlanAdaptorContainer = new Composite(centerUpperContainer, SWT.NONE); gridLayout = new GridLayout(3, false); gridLayout.verticalSpacing = 0; gridLayout.horizontalSpacing = 3; gridLayout.marginHeight = 0; gridLayout.marginWidth = 2; wlanAdaptorContainer.setLayout(gridLayout); wlanAdaptorContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); Label wlanAdapterListLabel = new Label(wlanAdaptorContainer, SWT.NONE); wlanAdapterListLabel.setText(" LAN "); application.initControl(wlanAdapterListLabel); wlanAdapterListCombo = new Combo(wlanAdaptorContainer, SWT.READ_ONLY); wlanAdapterListCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(wlanAdapterListCombo); wlanPspCommunicationButton = new Button(wlanAdaptorContainer, SWT.TOGGLE); wlanPspCommunicationButton.setText("PSP "); application.initControl(wlanPspCommunicationButton); packetMonitorTable = new TableViewer(centerUpperContainer, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION); packetMonitorTable.getTable().setHeaderVisible(true); packetMonitorTable.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); application.initControl(packetMonitorTable.getTable()); TableColumn packetMonitorIsMineColumn = new TableColumn(packetMonitorTable.getTable(), SWT.CENTER); packetMonitorIsMineColumn.setText(""); SwtUtils.installSorter(packetMonitorTable, packetMonitorIsMineColumn, TraficStatistics.MINE_SORTER); TableColumn packetMonitorMacAddressColumn = new TableColumn(packetMonitorTable.getTable(), SWT.LEFT); packetMonitorMacAddressColumn.setText("MAC "); SwtUtils.installSorter(packetMonitorTable, packetMonitorMacAddressColumn, TraficStatistics.MAC_ADDRESS_SORTER); TableColumn packetMonitorPlayerNameColumn = new TableColumn(packetMonitorTable.getTable(), SWT.LEFT); packetMonitorPlayerNameColumn.setText(""); SwtUtils.installSorter(packetMonitorTable, packetMonitorPlayerNameColumn, TraficStatistics.PLAYER_NAME_SORTER); TableColumn packetMonitorInSpeedColumn = new TableColumn(packetMonitorTable.getTable(), SWT.RIGHT); packetMonitorInSpeedColumn.setText("In (Kbps)"); SwtUtils.installSorter(packetMonitorTable, packetMonitorInSpeedColumn, TraficStatistics.IN_SPEED_SORTER); TableColumn packetMonitorOutSpeedColumn = new TableColumn(packetMonitorTable.getTable(), SWT.RIGHT); packetMonitorOutSpeedColumn.setText("Out (Kbps)"); SwtUtils.installSorter(packetMonitorTable, packetMonitorOutSpeedColumn, TraficStatistics.OUT_SPEED_SORTER); TableColumn packetMonitorTotalInBytesColumn = new TableColumn(packetMonitorTable.getTable(), SWT.RIGHT); packetMonitorTotalInBytesColumn.setText("In ? ?"); SwtUtils.installSorter(packetMonitorTable, packetMonitorTotalInBytesColumn, TraficStatistics.TOTAL_IN_SORTER); TableColumn packetMonitorTotalOutBytesColumn = new TableColumn(packetMonitorTable.getTable(), SWT.RIGHT); packetMonitorTotalOutBytesColumn.setText("Out ? ?"); SwtUtils.installSorter(packetMonitorTable, packetMonitorTotalOutBytesColumn, TraficStatistics.TOTAL_OUT_SORTER); packetMonitorTable.setContentProvider(new TraficStatistics.ContentProvider()); packetMonitorTable.setLabelProvider(new TraficStatistics.LabelProvider()); SwtUtils.enableColumnDrag(packetMonitorTable.getTable()); Composite chatContainer = new Composite(centerSashForm, SWT.NONE); gridLayout = new GridLayout(1, false); gridLayout.verticalSpacing = 0; gridLayout.horizontalSpacing = 0; gridLayout.marginHeight = 0; gridLayout.marginWidth = 0; chatContainer.setLayout(gridLayout); logViewer = new LogViewer(chatContainer, application.getSettings().getMaxLogCount(), application); logViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite chatCommandContainer = new Composite(chatContainer, SWT.NONE); gridLayout = new GridLayout(2, false); gridLayout.verticalSpacing = 0; gridLayout.horizontalSpacing = 3; gridLayout.marginHeight = 0; gridLayout.marginWidth = 0; gridLayout.marginTop = 3; gridLayout.marginBottom = 1; gridLayout.marginRight = 1; chatCommandContainer.setLayout(gridLayout); chatCommandContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); chatText = new Text(chatCommandContainer, SWT.BORDER | SWT.SINGLE); chatText.setTextLimit(300); chatText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initChatControl(chatText); multilineChatButton = new Button(chatCommandContainer, SWT.PUSH); multilineChatButton.setText(""); application.initControl(multilineChatButton); rightSashForm = new SashForm(mainSashForm, SWT.VERTICAL); Composite ssidContainer = new Composite(rightSashForm, SWT.NONE); gridLayout = new GridLayout(2, false); gridLayout.horizontalSpacing = 1; gridLayout.verticalSpacing = 4; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; ssidContainer.setLayout(gridLayout); Label ssidCurrentSsidLabel = new Label(ssidContainer, SWT.NONE); ssidCurrentSsidLabel.setText("? SSID"); ssidCurrentSsidLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(ssidCurrentSsidLabel); ssidCurrentSsidText = new Text(ssidContainer, SWT.SINGLE | SWT.BORDER | SWT.READ_ONLY); ssidCurrentSsidText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(ssidCurrentSsidText); ssidMatchLabel = new Label(ssidContainer, SWT.NONE); ssidMatchLabel.setText(""); ssidMatchLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(ssidMatchLabel); ssidMatchText = new Text(ssidContainer, SWT.SINGLE | SWT.BORDER); ssidMatchText.setText("PSP_"); ssidMatchText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); application.initControl(ssidMatchText); Composite ssidControlContainer = new Composite(ssidContainer, SWT.NONE); ssidControlContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1)); gridLayout = new GridLayout(4, false); gridLayout.horizontalSpacing = 3; gridLayout.verticalSpacing = 0; gridLayout.marginWidth = 1; gridLayout.marginHeight = 0; ssidControlContainer.setLayout(gridLayout); ssidStartScan = new Button(ssidControlContainer, SWT.TOGGLE); ssidStartScan.setText(" "); ssidStartScan.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false)); ssidStartScan.setEnabled(false); application.initControl(ssidStartScan); ssidScanIntervalSpinner = new Spinner(ssidControlContainer, SWT.BORDER); ssidScanIntervalSpinner.setMinimum(500); ssidScanIntervalSpinner.setMaximum(9999); ssidScanIntervalSpinner.setSelection(scanIntervalMillis); application.initControl(ssidScanIntervalSpinner); Label ssidScanIntervalLabel = new Label(ssidControlContainer, SWT.NONE); ssidScanIntervalLabel.setText(" "); application.initControl(ssidScanIntervalLabel); ssidAutoDetectCheck = new Button(ssidControlContainer, SWT.CHECK | SWT.FLAT); ssidAutoDetectCheck.setText("?? ?"); ssidAutoDetectCheck.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false)); application.initControl(ssidAutoDetectCheck); ssidListTableViewer = new TableViewer(ssidContainer, SWT.BORDER | SWT.FULL_SELECTION); ssidListTableViewer.setContentProvider(new ArrayContentProvider()); ssidListTableViewer.setLabelProvider(new WlanUtils.LabelProvider()); Table ssidListTable = ssidListTableViewer.getTable(); ssidListTable.setHeaderVisible(true); ssidListTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1)); application.initControl(ssidListTable); TableColumn ssidListTableSsidColumn = new TableColumn(ssidListTable, SWT.LEFT); ssidListTableSsidColumn.setText("SSID"); TableColumn ssidListTableRssiColumn = new TableColumn(ssidListTable, SWT.RIGHT); ssidListTableRssiColumn.setText("?"); roomPlayerListTable = new TableViewer(rightSashForm, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION); roomPlayerListTable.getTable().setHeaderVisible(true); application.initControl(roomPlayerListTable.getTable()); TableColumn roomPlayerSsidChaseColumn = new TableColumn(roomPlayerListTable.getTable(), SWT.CENTER); SwtUtils.installSorter(roomPlayerListTable, roomPlayerSsidChaseColumn, Player.SSID_CHASE_SORTER); TableColumn roomPlayerNameColumn = new TableColumn(roomPlayerListTable.getTable(), SWT.LEFT); roomPlayerNameColumn.setText("?"); SwtUtils.installSorter(roomPlayerListTable, roomPlayerNameColumn, Player.NANE_SORTER); TableColumn roomPlayerSsidColumn = new TableColumn(roomPlayerListTable.getTable(), SWT.LEFT); roomPlayerSsidColumn.setText("SSID"); SwtUtils.installSorter(roomPlayerListTable, roomPlayerSsidColumn, Player.SSID_SORTER); TableColumn roomPlayerPingColumn = new TableColumn(roomPlayerListTable.getTable(), SWT.RIGHT); roomPlayerPingColumn.setText("PING"); SwtUtils.installSorter(roomPlayerListTable, roomPlayerPingColumn, Player.PING_SORTER); roomPlayerListTable.setContentProvider(new Player.PlayerListContentProvider()); roomPlayerListTable.setLabelProvider(new Player.RoomPlayerLabelProvider()); SwtUtils.enableColumnDrag(roomPlayerListTable.getTable()); roomPlayerListTable.setInput(roomPlayerMap); Composite macFilteringContainer = new Composite(rightSashForm, SWT.NONE); gridLayout = new GridLayout(1, false); gridLayout.horizontalSpacing = 0; gridLayout.verticalSpacing = 2; gridLayout.marginWidth = 0; gridLayout.marginHeight = 0; macFilteringContainer.setLayout(gridLayout); Label macFilteringLabel = new Label(macFilteringContainer, SWT.NONE); macFilteringLabel.setText("MAC ?"); macFilteringLabel.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)); application.initControl(macFilteringLabel); SashForm macFilteringSashForm = new SashForm(macFilteringContainer, SWT.HORIZONTAL); macFilteringSashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite macFilteringWhiteListContainer = new Composite(macFilteringSashForm, SWT.NONE); macFilteringWhiteListContainer.setLayout(gridLayout); macFilteringWhiteListCheck = new Button(macFilteringWhiteListContainer, SWT.CHECK | SWT.FLAT); macFilteringWhiteListCheck.setText("? "); application.initControl(macFilteringWhiteListCheck); macFilteringWhiteList = new List(macFilteringWhiteListContainer, SWT.BORDER | SWT.SINGLE); macFilteringWhiteList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); application.initControl(macFilteringWhiteList); Composite macFilteringBlackListContainer = new Composite(macFilteringSashForm, SWT.NONE); macFilteringBlackListContainer.setLayout(gridLayout); macFilteringBlackListCheck = new Button(macFilteringBlackListContainer, SWT.CHECK | SWT.FLAT); macFilteringBlackListCheck.setText(" "); application.initControl(macFilteringBlackListCheck); macFilteringBlackList = new List(macFilteringBlackListContainer, SWT.BORDER | SWT.SINGLE); macFilteringBlackList.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); application.initControl(macFilteringBlackList); statusBarContainer = new Composite(shell, SWT.NONE); gridData = new GridData(SWT.FILL, SWT.CENTER, false, false); gridData.verticalIndent = 3; statusBarContainer.setLayoutData(gridData); gridLayout = new GridLayout(7, false); gridLayout.marginHeight = 2; gridLayout.marginWidth = 3; statusBarContainer.setLayout(gridLayout); statusRoomServerAddressLabel = new Label(statusBarContainer, SWT.NONE); application.initControl(statusRoomServerAddressLabel); gridData = new GridData(SWT.CENTER, SWT.CENTER, false, false); gridData.heightHint = 15; new Label(statusBarContainer, SWT.SEPARATOR | SWT.VERTICAL).setLayoutData(gridData); statusTunnelConnectionLabel = new Label(statusBarContainer, SWT.NONE); statusTunnelConnectionLabel.setForeground(colorNG); statusTunnelConnectionLabel.setText("??"); application.initControl(statusTunnelConnectionLabel); new Label(statusBarContainer, SWT.SEPARATOR | SWT.VERTICAL).setLayoutData(gridData); statusTraficStatusLabel = new Label(statusBarContainer, SWT.NONE); statusTraficStatusLabel.setText("? "); application.initControl(statusTraficStatusLabel); new Label(statusBarContainer, SWT.SEPARATOR | SWT.VERTICAL).setLayoutData(gridData); Composite appVersionContainer = new Composite(statusBarContainer, SWT.NONE); appVersionContainer.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, true, false)); RowLayout rowLayout = new RowLayout(); rowLayout.marginTop = 0; rowLayout.marginBottom = 0; rowLayout.marginLeft = 0; rowLayout.marginRight = 0; appVersionContainer.setLayout(rowLayout); Label statusApplicationVersionLabel = new Label(appVersionContainer, SWT.NONE); statusApplicationVersionLabel.setText(":"); application.initControl(statusApplicationVersionLabel); Label statusApplicationVersionNumber = new Label(appVersionContainer, SWT.NONE); statusApplicationVersionNumber.setText(AppConstants.VERSION); statusApplicationVersionNumber.setForeground(colorAppNumber); application.initControl(statusApplicationVersionNumber); Label statusApplicationProtocolLabel = new Label(appVersionContainer, SWT.NONE); statusApplicationProtocolLabel.setText(":"); application.initControl(statusApplicationProtocolLabel); Label statusApplicationProtocolNumber = new Label(appVersionContainer, SWT.NONE); statusApplicationProtocolNumber.setText(IProtocol.NUMBER); statusApplicationProtocolNumber.setForeground(colorAppNumber); application.initControl(statusApplicationProtocolNumber); Label statusApplicationSSIDLabel = new Label(appVersionContainer, SWT.NONE); statusApplicationSSIDLabel.setText("SSID :"); application.initControl(statusApplicationSSIDLabel); Label statusApplicationSSIDFeature = new Label(appVersionContainer, SWT.NONE); statusApplicationSSIDFeature.setText(Wlan.isLibraryAvailable ? "On" : "Off"); statusApplicationSSIDFeature.setForeground(Wlan.isLibraryAvailable ? colorAppNumber : colorNG); application.initControl(statusApplicationSSIDFeature); try { mainSashForm.setWeights(iniAppData.getRoomSashWeights()); } catch (SWTException e) { } try { centerSashForm.setWeights(iniAppData.getRoomCenterSashWeights()); } catch (SWTException e) { } try { rightSashForm.setWeights(iniAppData.getRoomRightSashWeights()); } catch (SWTException e) { } iniAppData.restorePacketMonitorTableSetting(packetMonitorTable.getTable()); iniAppData.restoreSsidScanTableSetting(ssidListTableViewer.getTable()); iniAppData.restoreRoomPlayerTableSetting(roomPlayerListTable.getTable()); } private void initWidgetListeners() { shell.addShellListener(new ShellListener() { @Override public void shellActivated(ShellEvent e) { isActive = true; switch (sessionState) { case MY_ROOM_MASTER: case ROOM_MASTER: case ROOM_PARTICIPANT: changeLobbyStateTo(LobbyUserState.PLAYING); } } @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 shellClosed(ShellEvent e) { switch (confirmRoomDelete(true)) { case 1: break; case 0: e.doit = false; break; case -1: if (!application.getSettings().isNeedAppCloseConfirm()) { return; } ConfirmDialog dialog = new ConfirmDialog(shell); switch (dialog.open()) { case IDialogConstants.CANCEL_ID: e.doit = false; break; } break; } } }); shell.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { myRoomEngine.closeRoom(); isPacketCapturing = false; IniAppData iniAppData = application.getAppData(); iniAppData.storeMainWindow(shell.getBounds()); iniAppData.setRoomSashWeights(mainSashForm.getWeights()); iniAppData.setRoomCenterSashWeights(centerSashForm.getWeights()); iniAppData.setRoomRightSashWeights(rightSashForm.getWeights()); iniAppData.storePacketMonitorTable(packetMonitorTable.getTable()); iniAppData.storeSsidScanTable(ssidListTableViewer.getTable()); iniAppData.storeRoomPlayerTable(roomPlayerListTable.getTable()); iniAppData.setRoomServerHistory(roomServerHistoryManager.makeCSV()); iniAppData.setRoomAddressHistory(roomAddressHistoryManager.makeCSV()); int index = wlanAdapterListCombo.getSelectionIndex() - 1; if (wlanAdapterListCombo.getItemCount() < 2 || index == -1) { iniAppData.setLastLanAdapter(""); } else { WlanDevice device = wlanAdaptorList.get(index); iniAppData.setLastLanAdapter(wlanAdaptorMacAddressMap.get(device)); } } }); searchWindowItem.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { SearchWindow window = application.getSearchWindow(); window.show(); } }); lobbyWindowItem.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { LobbyWindow window = application.getLobbyWindow(true); window.show(); } }); logWindowItem.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { LogWindow window = application.getLogWindow(); window.setVisible(true); } }); configWindowItem.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { application.openConfigDialog(); updateShellTitle(); } }); wikiItem.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { Program.launch("http://wiki.team-monketsu.net/"); } }); formModeSelectionCombo.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { updateRoomModeSelection(); } }); formAutoModeRoomButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { switch (sessionState) { case OFFLINE: autoConnectAsMaster(); break; case ROOM_MASTER: confirmRoomDelete(false); break; case ROOM_PARTICIPANT: roomConnection.send(ProtocolConstants.Room.COMMAND_LOGOUT); break; } } }); formAutoModeRoomButton.addMouseListener(new MouseListener() { @Override public void mouseUp(MouseEvent e) { if (sessionState != SessionState.OFFLINE) return; if (e.button != 3) return; if (e.x < 0 || e.y < 0) return; Point size = formAutoModeRoomButton.getSize(); if (e.x > size.x || e.y > size.y) return; if (!checkConfigUserName() || !checkRoomFormTitle()) return; formAutoModeRoomButton.setEnabled(false); selectRoomServer(new ServerSelectAction() { @Override public String getOkLabel() { return "? "; } @Override public void select(String address) { autoConnectAsMaster(address); } @Override public void cancel() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { public void run() { cancel(); } }); return; } formAutoModeRoomButton.setEnabled(true); } catch (SWTException e) { } } }); } @Override public void mouseDown(MouseEvent e) { } @Override public void mouseDoubleClick(MouseEvent e) { } }); formManualModeRoomServerCombo.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; manualConnectAsMaster(); break; } } }); formManualModeRoomServerButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { if (sessionState == SessionState.OFFLINE) { manualConnectAsMaster(); } else { confirmRoomDelete(false); } } }); formManualModeRoomAddressCombo.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; manualConnectAsParticipant(); break; } } }); formManualModeRoomAddressButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { if (sessionState == SessionState.OFFLINE) { manualConnectAsParticipant(); } else { roomConnection.send(ProtocolConstants.Room.COMMAND_LOGOUT); } } }); formMyRoomModeStartButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { try { if (myRoomEngine.isStarted()) { formMyRoomModeStartButton.setEnabled(false); myRoomEngine.closeRoom(); } else { startMyRoomServer(); } } catch (IOException e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); } } }); formMyRoomModeHostText.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { String host = formMyRoomModeHostText.getText(); application.getSettings().setMyRoomHostName(host); switch (sessionState) { case MY_ROOM_MASTER: roomServerAddressPort = host + ":" + formMyRoomModePortSpinner.getSelection(); updateServerAddress(); } } }); formMyRoomModePortSpinner.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { application.getSettings().setMyRoomPort(formMyRoomModePortSpinner.getSelection()); } }); formMyRoomModeEntryButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { if (myRoomEntryConnection.isConnected()) { myRoomEntryConnection.send(ProtocolConstants.MyRoom.COMMAND_LOGOUT); } else { autoConnectAsMyRoom(); } } }); formMyRoomModeEntryButton.addMouseListener(new MouseListener() { @Override public void mouseUp(MouseEvent e) { if (myRoomEntryConnection.isConnected()) return; if (e.button != 3) return; if (e.x < 0 || e.y < 0) return; Point size = formMyRoomModeEntryButton.getSize(); if (e.x > size.x || e.y > size.y) return; if (!checkConfigUserName() || !checkRoomFormTitle()) return; formMyRoomModeEntryButton.setEnabled(false); selectRoomServer(new ServerSelectAction() { @Override public String getOkLabel() { return "? ?"; } @Override public void select(String address) { autoConnectAsMyRoom(address); } @Override public void cancel() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { public void run() { cancel(); } }); return; } formMyRoomModeEntryButton.setEnabled(true); } catch (SWTException e) { } } }); } @Override public void mouseDown(MouseEvent e) { } @Override public void mouseDoubleClick(MouseEvent e) { } }); 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 MY_ROOM_MASTER: case ROOM_MASTER: case ROOM_PARTICIPANT: MultiLineChatDialog dialog = new MultiLineChatDialog(shell, application); switch (dialog.open()) { case IDialogConstants.OK_ID: String message = dialog.getMessage(); sendChat(message); } } } }); wlanAdapterListCombo.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { int index = widgets.wlanAdapterListCombo.getSelectionIndex(); int separatorIndex = wlanAdaptorList.size() + 1; int refreshIndex = separatorIndex + 1; if (index == 0) { wlanPspCommunicationButton.setEnabled(false); } else if (index < separatorIndex) { wlanPspCommunicationButton.setEnabled(true); } else if (index == separatorIndex) { wlanAdapterListCombo.select(0); wlanPspCommunicationButton.setEnabled(false); } else if (index == refreshIndex) { refreshLanAdapterList(); } } }); wlanPspCommunicationButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { if (wlanPspCommunicationButton.getSelection()) { if (startPacketCapturing()) { wlanPspCommunicationButton.setText("PSP "); wlanAdapterListCombo.setEnabled(false); if (Wlan.isLibraryAvailable) { ssidStartScan.setEnabled(true); } } else { wlanPspCommunicationButton.setSelection(false); } } else { wlanPspCommunicationButton.setEnabled(false); isPacketCapturing = false; if (Wlan.isLibraryAvailable) { updateSsidStartScan(false); widgets.ssidStartScan.setEnabled(false); setAndSendInformNewSSID(""); nextSsidCheckTime = 0L; } } } }); ssidScanIntervalSpinner.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { scanIntervalMillis = ssidScanIntervalSpinner.getSelection(); } }); ssidStartScan.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { if (!Wlan.isLibraryAvailable || currentWlanDevice == null) { updateSsidStartScan(false); } else { updateSsidStartScan(ssidStartScan.getSelection()); } } }); ssidListTableViewer.addDoubleClickListener(new IDoubleClickListener() { @Override public void doubleClick(DoubleClickEvent e) { if (!Wlan.isLibraryAvailable || currentWlanDevice == null) { return; } IStructuredSelection sel = (IStructuredSelection) e.getSelection(); WlanNetwork network = (WlanNetwork) sel.getFirstElement(); if (network == null) return; String selectedSSID = network.getSsid(); String currentSSID = ssidCurrentSsidText.getText(); if (currentSSID.equals(selectedSSID)) return; changeSSID(selectedSSID); } }); macFilteringWhiteListCheck.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { switch (sessionState) { case MY_ROOM_MASTER: myRoomEngine.enableMacAddressWhiteList(macFilteringWhiteListCheck.getSelection()); break; case ROOM_MASTER: StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_WHITELIST_ENABLE); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(macFilteringWhiteListCheck.getSelection() ? "Y" : "N"); roomConnection.send(sb.toString()); break; } } }); macFilteringBlackListCheck.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { switch (sessionState) { case MY_ROOM_MASTER: myRoomEngine.enableMacAddressBlackList(macFilteringBlackListCheck.getSelection()); break; case ROOM_MASTER: StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_BLACKLIST_ENABLE); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(macFilteringBlackListCheck.getSelection() ? "Y" : "N"); roomConnection.send(sb.toString()); break; } } }); formEditSaveButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { FileDialog dialog = new FileDialog(shell, SWT.SAVE); dialog.setOverwrite(true); dialog.setFilterExtensions(new String[] { "*.txt" }); String filename = dialog.open(); if (Utility.isEmpty(filename)) return; try { new File(filename).delete(); IniFile file = new IniFile(filename); IniSection section = file.getSection(null); section.set(INI_ROOM_TITLE, formTitleText.getText()); section.set(INI_ROOM_PASSWORD, formPasswordText.getText()); section.set(INI_ROOM_CAPACITY, formMaxPlayersSpiner.getSelection()); String desc = widgets.formDescriptionText.getText(); desc = desc.replace(widgets.formDescriptionText.getLineDelimiter(), "\\n"); section.set(INI_ROOM_DESCRIPTION, desc); String remarks = widgets.formRemarksText.getText(); remarks = remarks.replace(widgets.formRemarksText.getLineDelimiter(), "\\n"); section.set(INI_ROOM_REMARKS, remarks); file.saveToIni(); } catch (IOException e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); } } }); formEditLoadButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { FileDialog dialog = new FileDialog(shell, SWT.OPEN); dialog.setFilterExtensions(new String[] { "*.txt" }); String filename = dialog.open(); if (Utility.isEmpty(filename)) return; try { IniFile file = new IniFile(filename); IniSection section = file.getSection(null); formTitleText.setText(section.get(INI_ROOM_TITLE, "")); formPasswordText.setText(section.get(INI_ROOM_PASSWORD, "")); formMaxPlayersSpiner.setSelection(section.get(INI_ROOM_CAPACITY, 4)); String desc = section.get(INI_ROOM_DESCRIPTION, ""); desc = desc.replace("\\n", formDescriptionText.getLineDelimiter()); formDescriptionText.setText(desc); String remarks = section.get(INI_ROOM_REMARKS, ""); remarks = remarks.replace("\\n", formRemarksText.getLineDelimiter()); formRemarksText.setText(remarks); } catch (IOException e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); } } }); formEditSubmitButton.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { commitRoomEditForm(); } }); formTitleText.addVerifyListener(SwtUtils.NOT_ACCEPT_CONTROL_CHAR_LISTENER); formPasswordText.addVerifyListener(SwtUtils.NOT_ACCEPT_CONTROL_CHAR_LISTENER); formDescriptionText.addVerifyListener(SwtUtils.NOT_ACCEPT_CONTROL_CHAR_LISTENER); formManualModeRoomAddressCombo.addVerifyListener(SwtUtils.NOT_ACCEPT_CONTROL_CHAR_LISTENER); formMyRoomModeHostText.addVerifyListener(SwtUtils.NOT_ACCEPT_CONTROL_CHAR_LISTENER); ModifyListener roomEditFormModifyDetectListener = new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (isRoomInfoUpdating) return; switch (sessionState) { case MY_ROOM_MASTER: case ROOM_MASTER: formEditSubmitButton.setEnabled(true); break; } } }; widgets.formTitleText.addModifyListener(roomEditFormModifyDetectListener); widgets.formPasswordText.addModifyListener(roomEditFormModifyDetectListener); widgets.formMaxPlayersSpiner.addModifyListener(roomEditFormModifyDetectListener); widgets.formDescriptionText.addModifyListener(roomEditFormModifyDetectListener); widgets.formRemarksText.addModifyListener(roomEditFormModifyDetectListener); } private void initMenus() { Menu playerMenu = new Menu(shell, SWT.POP_UP); playerMenuChaseSsid = new MenuItem(playerMenu, SWT.CHECK); playerMenuChaseSsid.setText("? ?? SSID ?"); playerMenuChaseSsid.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) roomPlayerListTable.getSelection(); Player player = (Player) selection.getFirstElement(); if (player == null) return; player.setSSIDChased(playerMenuChaseSsid.getSelection()); roomPlayerListTable.refresh(player); } }); playerMenuSetSsid = new MenuItem(playerMenu, SWT.PUSH); playerMenuSetSsid.setText("? SSID "); playerMenuSetSsid.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) roomPlayerListTable.getSelection(); Player player = (Player) selection.getFirstElement(); if (player == null) return; changeSSID(player.getSsid()); } }); playerMenuCopySsid = new MenuItem(playerMenu, SWT.PUSH); playerMenuCopySsid.setText("? SSID "); playerMenuCopySsid.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) roomPlayerListTable.getSelection(); Player player = (Player) selection.getFirstElement(); if (player == null) return; application.putClipboard(player.getSsid()); } }); new MenuItem(playerMenu, SWT.SEPARATOR); playerMenuKick = new MenuItem(playerMenu, SWT.PUSH); playerMenuKick.setText(""); playerMenuKick.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) roomPlayerListTable.getSelection(); Player player = (Player) selection.getFirstElement(); if (player == null || roomLoginName.equals(player.getName())) return; String kickedName = player.getName(); switch (sessionState) { case MY_ROOM_MASTER: myRoomEngine.kickPlayer(kickedName); removeKickedRoomPlayer(kickedName); break; case ROOM_MASTER: roomConnection.send(ProtocolConstants.Room.COMMAND_ROOM_KICK_PLAYER + TextProtocolDriver.ARGUMENT_SEPARATOR + kickedName); break; } } }); new MenuItem(playerMenu, SWT.SEPARATOR); playerMenuMasterTransfer = new MenuItem(playerMenu, SWT.PUSH); playerMenuMasterTransfer.setText(" "); playerMenuMasterTransfer.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) roomPlayerListTable.getSelection(); Player player = (Player) selection.getFirstElement(); if (player == null) return; String newMasterName = player.getName(); switch (sessionState) { case ROOM_MASTER: roomConnection.send(ProtocolConstants.Room.COMMAND_ROOM_MASTER_TRANSFER + TextProtocolDriver.ARGUMENT_SEPARATOR + newMasterName); if (myRoomEntryConnection.isConnected()) myRoomEntryConnection.send(ProtocolConstants.Search.COMMAND_LOGOUT); break; } } }); roomPlayerListTable.getTable().setMenu(playerMenu); roomPlayerListTable.getTable().addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { IStructuredSelection selection = (IStructuredSelection) roomPlayerListTable.getSelection(); Player player = (Player) selection.getFirstElement(); if (player == null) { playerMenuKick.setEnabled(false); playerMenuMasterTransfer.setEnabled(false); playerMenuChaseSsid.setSelection(false); playerMenuChaseSsid.setEnabled(false); playerMenuSetSsid.setEnabled(false); playerMenuCopySsid.setEnabled(false); return; } boolean isMasterAndOtherSelected = false; switch (sessionState) { case MY_ROOM_MASTER: case ROOM_MASTER: if (!roomMasterName.equals(player.getName())) { isMasterAndOtherSelected = true; } break; } playerMenuKick.setEnabled(isMasterAndOtherSelected); if (sessionState == SessionState.ROOM_MASTER) { playerMenuMasterTransfer.setEnabled(isMasterAndOtherSelected); } else { playerMenuMasterTransfer.setEnabled(false); } boolean isSelfSelected = Utility.equals(roomLoginName, player.getName()); if (isSelfSelected || !isPacketCapturing) { playerMenuChaseSsid.setEnabled(false); playerMenuChaseSsid.setSelection(false); } else { playerMenuChaseSsid.setEnabled(Wlan.isLibraryAvailable); playerMenuChaseSsid.setSelection(player.isSSIDChased()); } if (Utility.isEmpty(player.getSsid())) { playerMenuSetSsid.setEnabled(false); playerMenuCopySsid.setEnabled(false); } else { playerMenuSetSsid .setEnabled(Wlan.isLibraryAvailable && !isSelfSelected && isPacketCapturing); playerMenuCopySsid.setEnabled(true); } } }); Menu statusServerAddressMenu = new Menu(shell, SWT.POP_UP); statusServerAddressMenuCopy = new MenuItem(statusServerAddressMenu, SWT.PUSH); statusServerAddressMenuCopy.setText(" "); statusServerAddressMenuCopy.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { String roomAddress = roomServerAddressPort + ":" + roomMasterName; application.putClipboard(roomAddress); } }); statusRoomServerAddressLabel.setMenu(statusServerAddressMenu); statusRoomServerAddressLabel.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { switch (sessionState) { case MY_ROOM_MASTER: case ROOM_PARTICIPANT: case ROOM_MASTER: statusServerAddressMenuCopy.setEnabled(true); break; default: statusServerAddressMenuCopy.setEnabled(false); } } }); statusTunnelConnectionMenu = new Menu(shell, SWT.POP_UP); statusTunnelConnectionMenuChangeTransport = new MenuItem(statusTunnelConnectionMenu, SWT.PUSH); statusTunnelConnectionMenuChangeTransport.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { switch (application.getSettings().getTunnelTransportLayer()) { case TCP: application.getSettings().setTunnelTransportLayer(TransportLayer.UDP); break; case UDP: application.getSettings().setTunnelTransportLayer(TransportLayer.TCP); break; } tunnelConnection.disconnect(); } }); statusTunnelConnectionLabel.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { switch (sessionState) { case ROOM_MASTER: case ROOM_PARTICIPANT: statusTunnelConnectionLabel.setMenu(statusTunnelConnectionMenu); switch (application.getSettings().getTunnelTransportLayer()) { case TCP: statusTunnelConnectionMenuChangeTransport.setText("UDP ?"); break; case UDP: statusTunnelConnectionMenuChangeTransport.setText("TCP ?"); break; } break; default: statusTunnelConnectionLabel.setMenu(null); } } }); Menu packetMonitorMenu = new Menu(shell, SWT.POP_UP); packetMonitorMenuCopy = new MenuItem(packetMonitorMenu, SWT.PUSH); packetMonitorMenuCopy.setText("MAC ? "); packetMonitorMenuCopy.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) packetMonitorTable.getSelection(); TraficStatistics stats = (TraficStatistics) selection.getFirstElement(); if (stats == null) return; application.putClipboard(stats.macAddress + "\t" + stats.playerName); } }); packetMonitorMenuWhiteList = new MenuItem(packetMonitorMenu, SWT.CHECK); packetMonitorMenuWhiteList.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) packetMonitorTable.getSelection(); TraficStatistics stats = (TraficStatistics) selection.getFirstElement(); if (stats == null || stats.isMine) return; if (macFilteringWhiteList.indexOf(stats.macAddress) == -1) { addMacAddressToWhiteList(stats.macAddress); } else { removeMacAddressFromWhiteList(stats.macAddress); } } }); packetMonitorMenuBlackList = new MenuItem(packetMonitorMenu, SWT.CHECK); packetMonitorMenuBlackList.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { IStructuredSelection selection = (IStructuredSelection) packetMonitorTable.getSelection(); TraficStatistics stats = (TraficStatistics) selection.getFirstElement(); if (stats == null || stats.isMine) return; if (macFilteringBlackList.indexOf(stats.macAddress) == -1) { addMacAddressToBlackList(stats.macAddress); } else { removeMacAddressFromBlackList(stats.macAddress); } } }); new MenuItem(packetMonitorMenu, SWT.SEPARATOR); packetMonitorMenuClear = new MenuItem(packetMonitorMenu, SWT.PUSH); packetMonitorMenuClear.setText("? ? ?"); packetMonitorMenuClear.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { synchronized (traficStatsMap) { Iterator<Entry<String, TraficStatistics>> iter = traficStatsMap.entrySet().iterator(); while (iter.hasNext()) { Entry<String, TraficStatistics> entry = iter.next(); TraficStatistics stats = entry.getValue(); stats.totalInBytes = 0; stats.totalOutBytes = 0; } } packetMonitorTable.refresh(); } }); packetMonitorTable.getTable().setMenu(packetMonitorMenu); packetMonitorTable.getTable().addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { packetMonitorMenuClear.setEnabled(traficStatsMap.size() > 0); IStructuredSelection selection = (IStructuredSelection) packetMonitorTable.getSelection(); TraficStatistics stats = (TraficStatistics) selection.getFirstElement(); boolean validStats = stats != null && !stats.isMine && !Utility.isMacBroadCastAddress(stats.macAddress); packetMonitorMenuCopy.setEnabled(validStats); packetMonitorMenuWhiteList.setEnabled(validStats); packetMonitorMenuBlackList.setEnabled(validStats); if (validStats) { boolean onWhiteList = macFilteringWhiteList.indexOf(stats.macAddress) != -1; packetMonitorMenuWhiteList.setSelection(onWhiteList); packetMonitorMenuWhiteList.setText(onWhiteList ? "? " : "? ? "); boolean onBlackList = macFilteringBlackList.indexOf(stats.macAddress) != -1; packetMonitorMenuBlackList.setSelection(onBlackList); packetMonitorMenuBlackList.setText( onBlackList ? " " : " ? "); } else { packetMonitorMenuWhiteList.setText("? ? "); packetMonitorMenuBlackList.setText(" ? "); } } }); Menu macFilteringWhiteListMenu = new Menu(shell, SWT.POP_UP); macFilteringWhiteListMenuRemove = new MenuItem(macFilteringWhiteListMenu, SWT.PUSH); macFilteringWhiteListMenuRemove.setText(""); macFilteringWhiteListMenuRemove.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { int index = macFilteringWhiteList.getSelectionIndex(); if (index == -1) return; String address = macFilteringWhiteList.getItem(index); removeMacAddressFromWhiteList(address); } }); macFilteringWhiteList.setMenu(macFilteringWhiteListMenu); macFilteringWhiteList.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { macFilteringWhiteListMenuRemove.setEnabled(macFilteringWhiteList.getSelectionIndex() != -1); } }); Menu macFilteringBlackListMenu = new Menu(shell, SWT.POP_UP); macFilteringBlackListMenuRemove = new MenuItem(macFilteringBlackListMenu, SWT.PUSH); macFilteringBlackListMenuRemove.setText(""); macFilteringBlackListMenuRemove.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { int index = macFilteringBlackList.getSelectionIndex(); if (index == -1) return; String address = macFilteringBlackList.getItem(index); removeMacAddressFromBlackList(address); } }); macFilteringBlackList.setMenu(macFilteringBlackListMenu); macFilteringBlackList.addMenuDetectListener(new MenuDetectListener() { @Override public void menuDetected(MenuDetectEvent e) { macFilteringBlackListMenuRemove.setEnabled(macFilteringBlackList.getSelectionIndex() != -1); } }); } } private void initBackgroundThreads() { packetCaptureThread = new Thread(new Runnable() { @Override public void run() { Runnable prepareCaptureEndAction = new Runnable() { @Override public void run() { try { isPacketCapturing = false; widgets.wlanPspCommunicationButton.setEnabled(false); } catch (SWTException e) { } } }; Runnable captureEndAction = new Runnable() { @Override public void run() { try { widgets.wlanAdapterListCombo.setEnabled(true); widgets.wlanPspCommunicationButton.setText("PSP "); widgets.wlanPspCommunicationButton.setEnabled(true); if (Wlan.isLibraryAvailable) updateSsidStartScan(false); } catch (SWTException e) { } } }; try { while (!shell.isDisposed()) { synchronized (packetCaptureThread) { if (!isPacketCapturing) packetCaptureThread.wait(); } try { while (isPacketCapturing) { bufferForCapturing.clear(); int ret = currentWlanDevice.capturePacket(bufferForCapturing); if (ret > 0) { bufferForCapturing.flip(); processCapturedPacket(); } else if (ret == 0) { } else { SwtUtils.DISPLAY.syncExec(prepareCaptureEndAction); break; } } } catch (Exception e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); isPacketCapturing = false; } currentWlanDevice.close(); currentWlanDevice = Wlan.EMPTY_DEVICE; SwtUtils.DISPLAY.syncExec(captureEndAction); } } catch (SWTException e) { } catch (Exception e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); } } }, "PacketCaptureThread"); packetCaptureThread.setDaemon(true); wlanScannerThread = new Thread(new Runnable() { @Override public void run() { final ArrayList<WlanNetwork> networkList = new ArrayList<WlanNetwork>(); Runnable refreshAction = new Runnable() { @Override public void run() { try { if (widgets.ssidAutoDetectCheck.getSelection()) { String currentSSID = widgets.ssidCurrentSsidText.getText(); String match = widgets.ssidMatchText.getText(); for (WlanNetwork bssid : networkList) { String ssid = bssid.getSsid(); if (!ssid.equals(currentSSID) && ssid.startsWith(match)) { changeSSID(ssid); break; } } } else { checkSsidChange(); } widgets.ssidListTableViewer.setInput(networkList); widgets.ssidListTableViewer.refresh(); } catch (SWTException e) { } } }; Runnable clearAction = new Runnable() { @Override public void run() { try { networkList.clear(); widgets.ssidListTableViewer.setInput(networkList); widgets.ssidListTableViewer.refresh(); } catch (SWTException e) { } } }; try { while (!shell.isDisposed()) { synchronized (wlanScannerThread) { while (!isSSIDScaning) wlanScannerThread.wait(); } while (isSSIDScaning) { long nextIteration = System.currentTimeMillis() + scanIntervalMillis; networkList.clear(); currentWlanDevice.findNetworks(networkList); SwtUtils.DISPLAY.syncExec(refreshAction); currentWlanDevice.scanNetwork(); long diff = nextIteration - System.currentTimeMillis(); if (diff > 0) Thread.sleep(diff); } SwtUtils.DISPLAY.asyncExec(clearAction); } } catch (SWTException e) { } catch (InterruptedException e) { } } }, "WlanScannerThread"); wlanScannerThread.setDaemon(true); packetMonitorThread = new Thread(new Runnable() { @Override public void run() { int intervalMillis = 1000; Runnable refreshAction = new Runnable() { @Override public void run() { try { checkSsidChange(); widgets.packetMonitorTable.setInput(traficStatsMap); widgets.packetMonitorTable.refresh(); } catch (SWTException e) { } } }; Runnable clearAction = new Runnable() { @Override public void run() { try { synchronized (traficStatsMap) { traficStatsMap.clear(); } widgets.packetMonitorTable.setInput(traficStatsMap); } catch (SWTException e) { } } }; try { while (!shell.isDisposed()) { synchronized (packetMonitorThread) { if (!isPacketCapturing && !tunnelIsLinked) packetMonitorThread.wait(); } while (isPacketCapturing || tunnelIsLinked) { long deadlineTime = System.currentTimeMillis() - 10000; synchronized (traficStatsMap) { Iterator<Entry<String, TraficStatistics>> iter = traficStatsMap.entrySet() .iterator(); while (iter.hasNext()) { Entry<String, TraficStatistics> entry = iter.next(); TraficStatistics stats = entry.getValue(); if (stats.lastModified < deadlineTime) { iter.remove(); continue; } stats.currentInKbps = ((double) stats.currentInBytes) * 8 / intervalMillis; stats.currentOutKbps = ((double) stats.currentOutBytes) * 8 / intervalMillis; stats.currentInBytes = 0; stats.currentOutBytes = 0; } String text; if (actualSentBytes == 0 && actualRecievedBytes == 0) { text = " ? "; } else { double totalInKbps = ((double) actualRecievedBytes) * 8 / intervalMillis; double totalOutKbps = ((double) actualSentBytes) * 8 / intervalMillis; text = String.format(" In: %.1f Kbps Out: %.1f Kbps ", totalInKbps, totalOutKbps); actualSentBytes = 0; actualRecievedBytes = 0; } updateTraficStatus(text); } SwtUtils.DISPLAY.syncExec(refreshAction); Thread.sleep(intervalMillis); } SwtUtils.DISPLAY.syncExec(clearAction); } } catch (SWTException e) { } catch (InterruptedException e) { } } }, "PacketMonitorThread"); packetMonitorThread.setDaemon(true); } private void wakeupThread(Thread thread) { synchronized (thread) { if (thread.isAlive()) { thread.notify(); return; } } thread.start(); } @Override public void addMessageListener(IMessageListener listener) { messageListeners.add(listener); } @Override public void removeMessageListener(IMessageListener listener) { messageListeners.remove(listener); } public void reflectAppearance() { widgets.logViewer.applyAppearance(); shell.layout(true, true); } private long nextPingTime = 0L; public void cronJob() { switch (sessionState) { case ROOM_MASTER: case ROOM_PARTICIPANT: if (!tunnelConnection.isConnected()) connectRoomTunnel(); long now = System.currentTimeMillis(); if (now < nextPingTime) return; roomConnection.send(ProtocolConstants.Room.COMMAND_PING + TextProtocolDriver.ARGUMENT_SEPARATOR + now); nextPingTime = now + 5000; break; } } private void connectToRoomServer(final InetSocketAddress socketAddress) { Runnable task = new Runnable() { @Override public void run() { try { application.connectTcp(socketAddress, roomProtocol); return; } catch (SocketTimeoutException e) { ErrorLog log = new ErrorLog("? ? "); widgets.logViewer.appendMessage(log); } catch (IOException e) { ErrorLog log = new ErrorLog(e.getMessage()); widgets.logViewer.appendMessage(log); } catch (RuntimeException e) { ErrorLog log = new ErrorLog(e.getMessage()); widgets.logViewer.appendMessage(log); } changeStateTo(SessionState.OFFLINE); } }; application.execute(task); } private interface ServerSelectAction { public String getOkLabel(); public void select(String address); public void cancel(); } private void selectRoomServer(final ServerSelectAction action) { PortalQuery query = new PortalQuery() { @Override public String getCommand() { return ProtocolConstants.Portal.COMMAND_LIST_ROOM_SERVERS; } @Override public void failCallback(ErrorLog log) { action.cancel(); widgets.logViewer.appendMessage(log); } @Override public void successCallback(String message) { ArrayList<RoomServerInfo> list = new ArrayList<RoomServerInfo>(); for (String info : message.split("\n")) { try { String[] values = info.split("\t"); String address = values[0]; int currentRooms = Integer.parseInt(values[1]); int maxRooms = Integer.parseInt(values[2]); RoomServerInfo server = new RoomServerInfo(address, currentRooms, maxRooms); list.add(server); } catch (NumberFormatException e) { } } showRoomServerSelectDialog(list, action); } }; application.queryPortalServer(query); } private void showRoomServerSelectDialog(final java.util.List<RoomServerInfo> list, final ServerSelectAction action) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { showRoomServerSelectDialog(list, action); } }); return; } if (list.isEmpty()) { ErrorLog log = new ErrorLog(" ? "); widgets.logViewer.appendMessage(log); action.cancel(); } else { RoomServerSelectDialog dialog = new RoomServerSelectDialog(shell, list, action.getOkLabel()); switch (dialog.open()) { case IDialogConstants.OK_ID: RoomServerInfo selected = dialog.getSelectedServer(); action.select(selected.getAddress()); break; case IDialogConstants.CANCEL_ID: action.cancel(); break; } } } catch (SWTException e) { } } private void autoConnectAsMaster() { if (!checkConfigUserName() || !checkRoomFormTitle()) return; widgets.formAutoModeRoomButton.setEnabled(false); PortalQuery query = new PortalQuery() { @Override public String getCommand() { return ProtocolConstants.Portal.COMMAND_FIND_ROOM_SERVER; } @Override public void failCallback(ErrorLog log) { revertRoomFormAutoModeButton(); widgets.logViewer.appendMessage(log); } @Override public void successCallback(String address) { autoConnectAsMaster(address); } }; application.queryPortalServer(query); } private void autoConnectAsMaster(final String address) { try { if (SwtUtils.isNotUIThread()) { if (address == null) { revertRoomFormAutoModeButton(); ErrorLog log = new ErrorLog(" ? "); widgets.logViewer.appendMessage(log); return; } SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { autoConnectAsMaster(address); } }); return; } InetSocketAddress socketAddress = Utility.parseSocketAddress(address); if (socketAddress == null) { revertRoomFormAutoModeButton(); ErrorLog log = new ErrorLog(" "); widgets.logViewer.appendMessage(log); return; } changeStateTo(SessionState.CONNECTING_ROOM_MASTER); roomMasterName = roomLoginName; roomServerAddressPort = address; connectToRoomServer(socketAddress); } catch (SWTException e) { } } private void revertRoomFormAutoModeButton() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { revertRoomFormAutoModeButton(); } }); return; } widgets.formAutoModeRoomButton.setEnabled(true); } catch (SWTException e) { } } public void autoConnectAsParticipant(PlayRoom room) { if (shell.getMinimized()) shell.setMinimized(false); shell.open(); if (sessionState != SessionState.OFFLINE) { ErrorLog log = new ErrorLog(" ? ?"); widgets.logViewer.appendMessage(log); return; } if (!checkConfigUserName()) return; InetSocketAddress socketAddress = Utility.parseSocketAddress(room.getServerAddress()); if (socketAddress == null) { ErrorLog log = new ErrorLog(" "); widgets.logViewer.appendMessage(log); return; } widgets.formModeSelectionCombo.select(0); updateRoomModeSelection(); changeStateTo(SessionState.CONNECTING_ROOM_PARTICIPANT); roomMasterName = room.getMasterName(); roomServerAddressPort = room.getServerAddress(); connectToRoomServer(socketAddress); } private void manualConnectAsMaster() { if (!checkConfigUserName() || !checkRoomFormTitle()) return; String address = widgets.formManualModeRoomServerCombo.getText(); if (Utility.isEmpty(address)) { ErrorLog log = new ErrorLog(" "); widgets.logViewer.appendMessage(log); return; } InetSocketAddress socketAddress = Utility.parseSocketAddress(address); if (socketAddress == null) { ErrorLog log = new ErrorLog(" "); widgets.logViewer.appendMessage(log); return; } changeStateTo(SessionState.CONNECTING_ROOM_MASTER); if (socketAddress.getAddress().isLoopbackAddress()) { roomServerAddressPort = ":" + socketAddress.getPort(); } else { roomServerAddressPort = address; } roomMasterName = roomLoginName; connectToRoomServer(socketAddress); } private void manualConnectAsParticipant() { if (!checkConfigUserName()) return; String address = widgets.formManualModeRoomAddressCombo.getText(); if (Utility.isEmpty(address)) { ErrorLog log = new ErrorLog(" "); widgets.logViewer.appendMessage(log); return; } String[] tokens = address.split(":", 3); roomMasterName = null; switch (tokens.length) { case 2: roomMasterName = ""; break; case 3: roomMasterName = tokens[2]; break; default: ErrorLog log = new ErrorLog(" "); widgets.logViewer.appendMessage(log); return; } InetSocketAddress socketAddress = Utility.parseSocketAddress(tokens[0], tokens[1]); if (socketAddress == null) { ErrorLog log = new ErrorLog(" "); widgets.logViewer.appendMessage(log); return; } changeStateTo(SessionState.CONNECTING_ROOM_PARTICIPANT); if (socketAddress.getAddress().isLoopbackAddress()) { roomServerAddressPort = ":" + socketAddress.getPort(); if (roomMasterName.equals("")) { widgets.formManualModeRoomAddressCombo.setText(roomServerAddressPort); } else { widgets.formManualModeRoomAddressCombo.setText(roomServerAddressPort + ":" + roomMasterName); } } else { roomServerAddressPort = Utility.socketAddressToStringByHostName(socketAddress); } connectToRoomServer(socketAddress); } private void startMyRoomServer() throws IOException { int port = widgets.formMyRoomModePortSpinner.getSelection(); if (!checkConfigUserName()) return; String title = widgets.formTitleText.getText(); if (Utility.isEmpty(title)) { RoomLog log = new RoomLog("? "); widgets.logViewer.appendMessage(log); widgets.formTitleText.setFocus(); return; } myRoomEngine.setTitle(title); myRoomEngine.setMaxPlayers(widgets.formMaxPlayersSpiner.getSelection()); myRoomEngine.setPassword(widgets.formPasswordText.getText()); myRoomEngine.setDescription(widgets.formDescriptionText.getText()); try { myRoomEngine.openRoom(port, roomLoginName); widgets.formMasterNameText.setText(roomLoginName); roomMasterName = roomLoginName; roomServerAddressPort = widgets.formMyRoomModeHostText.getText() + ":" + port; widgets.formModeSelectionCombo.setEnabled(false); widgets.formMyRoomModePortSpinner.setEnabled(false); widgets.formMyRoomModeStartButton.setEnabled(false); } catch (BindException e) { ErrorLog log = new ErrorLog("? ? ? ? "); widgets.logViewer.appendMessage(log); } catch (RuntimeException e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); } } private void autoConnectAsMyRoom() { if (sessionState != SessionState.MY_ROOM_MASTER) { return; } if (widgets.formEditSubmitButton.getEnabled()) { if (!commitRoomEditForm()) { widgets.formMyRoomModeStartButton.setSelection(false); return; } } widgets.formMyRoomModeEntryButton.setEnabled(false); widgets.formMyRoomModeEntryButton.setSelection(true); PortalQuery query = new PortalQuery() { @Override public String getCommand() { return ProtocolConstants.Portal.COMMAND_FIND_ROOM_SERVER; } @Override public void failCallback(ErrorLog log) { updateMyRoomEntryForm(true); widgets.logViewer.appendMessage(log); } @Override public void successCallback(String address) { autoConnectAsMyRoom(address); } }; application.queryPortalServer(query); } private void autoConnectAsMyRoom(final String address) { try { if (SwtUtils.isNotUIThread()) { if (address == null) { updateMyRoomEntryForm(false); ErrorLog log = new ErrorLog(" ? "); widgets.logViewer.appendMessage(log); return; } SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { autoConnectAsMyRoom(address); } }); return; } widgets.formMyRoomModeRoomServer.setText(address); Runnable task = new Runnable() { @Override public void run() { try { InetSocketAddress socketAddress = Utility.parseSocketAddress(address); application.connectTcp(socketAddress, myRoomEntryProtocol); return; } catch (IOException e) { ErrorLog log = new ErrorLog(e.getMessage()); widgets.logViewer.appendMessage(log); } catch (RuntimeException e) { ErrorLog log = new ErrorLog(e.getMessage()); widgets.logViewer.appendMessage(log); } updateMyRoomEntryForm(false); } }; application.execute(task); } catch (SWTException e) { } } private void updateMyRoomEntryForm(final boolean entryOn) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateMyRoomEntryForm(entryOn); } }); return; } if (entryOn) { widgets.formMyRoomModeEntryButton.setText(" "); widgets.formMyRoomModeEntryButton.setSelection(true); widgets.formMyRoomModeEntryButton.setEnabled(true); widgets.formMyRoomModeHostText.setEnabled(false); } else { widgets.formMyRoomModeRoomServer.setText(""); widgets.formMyRoomModeEntryButton.setText(" ?"); widgets.formMyRoomModeEntryButton.setSelection(false); widgets.formMyRoomModeEntryButton.setEnabled(sessionState != SessionState.OFFLINE); widgets.formMyRoomModeHostText.setEnabled(true); } } catch (SWTException e) { } } private void addMacAddressToWhiteList(String macAddress) { switch (sessionState) { case MY_ROOM_MASTER: { myRoomEngine.addMacAddressToWhiteList(macAddress); break; } case ROOM_MASTER: { StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_WHITELIST_ADD); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(macAddress); roomConnection.send(sb.toString()); break; } } widgets.macFilteringWhiteList.add(macAddress); } private void removeMacAddressFromWhiteList(String macAddress) { switch (sessionState) { case MY_ROOM_MASTER: { myRoomEngine.removeMacAddressFromWhiteList(macAddress); break; } case ROOM_MASTER: { StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_WHITELIST_REMOVE); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(macAddress); roomConnection.send(sb.toString()); break; } } widgets.macFilteringWhiteList.remove(macAddress); } private void addMacAddressToBlackList(String macAddress) { switch (sessionState) { case MY_ROOM_MASTER: { myRoomEngine.addMacAddressToBlackList(macAddress); break; } case ROOM_MASTER: { StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_BLACKLIST_ADD); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(macAddress); roomConnection.send(sb.toString()); break; } } widgets.macFilteringBlackList.add(macAddress); } private void removeMacAddressFromBlackList(String macAddress) { switch (sessionState) { case MY_ROOM_MASTER: { myRoomEngine.removeMacAddressFromBlackList(macAddress); break; } case ROOM_MASTER: { StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_BLACKLIST_REMOVE); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(macAddress); roomConnection.send(sb.toString()); break; } } widgets.macFilteringBlackList.remove(macAddress); } private void updateShellTitle() { String currentName = application.getSettings().getUserName(); if (Utility.isEmpty(currentName)) { shell.setText(AppConstants.APP_NAME); } else { shell.setText(currentName + " - " + AppConstants.APP_NAME); } application.setTaskTrayTooltipText(shell.getText()); } private boolean checkConfigUserName() { IniSettings iniSettings = application.getSettings(); String name = iniSettings.getUserName(); if (Utility.isEmpty(name)) { application.openConfigDialog(); name = iniSettings.getUserName(); if (Utility.isEmpty(name)) return false; } roomLoginName = name; return true; } private boolean checkRoomFormTitle() { String title = widgets.formTitleText.getText(); if (Utility.isEmpty(title)) { RoomLog log = new RoomLog("? "); widgets.logViewer.appendMessage(log); widgets.formTitleText.setFocus(); return false; } return true; } private int confirmRoomDelete(boolean onExit) { if (sessionState == SessionState.ROOM_MASTER) { if (roomPlayerMap.size() < 2) { if (onExit) { return -1; } else { roomConnection.send(ProtocolConstants.Room.COMMAND_LOGOUT); return 1; } } RoomDeleteDialog dialog = new RoomDeleteDialog(shell); dialog.open(); switch (dialog.getSelection()) { case LOGOUT: roomConnection.send(ProtocolConstants.Room.COMMAND_LOGOUT); return 1; case DESTROY: roomConnection.send(ProtocolConstants.Room.COMMAND_ROOM_DELETE); return 1; case CANCEL: return 0; } } return -1; } private void appendRoomInfo(StringBuilder sb) { sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formMaxPlayersSpiner.getText()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formTitleText.getText()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formPasswordText.getText()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formDescriptionText.getText()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formRemarksText.getText()); } private boolean commitRoomEditForm() { String title = widgets.formTitleText.getText(); if (Utility.isEmpty(title)) { ErrorLog log = new ErrorLog("? "); widgets.logViewer.appendMessage(log); widgets.formTitleText.setFocus(); return false; } widgets.formEditSubmitButton.setEnabled(false); switch (sessionState) { case MY_ROOM_MASTER: myRoomEngine.setTitle(title); myRoomEngine.setMaxPlayers(widgets.formMaxPlayersSpiner.getSelection()); myRoomEngine.setPassword(widgets.formPasswordText.getText()); myRoomEngine.setDescription(widgets.formDescriptionText.getText()); myRoomEngine.setRemarks(widgets.formRemarksText.getText()); myRoomEngine.updateRoom(); RoomLog log = new RoomLog(" "); widgets.logViewer.appendMessage(log); widgets.chatText.setFocus(); sendMyRoomUpdate(); break; case ROOM_MASTER: StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_ROOM_UPDATE); appendRoomInfo(sb); roomConnection.send(sb.toString()); break; } return true; } private boolean sendChat(String message) { if (!Utility.isEmpty(message)) { switch (sessionState) { case MY_ROOM_MASTER: myRoomEngine.sendChat(message); return true; case ROOM_MASTER: case ROOM_PARTICIPANT: roomConnection.send( ProtocolConstants.Room.COMMAND_CHAT + TextProtocolDriver.ARGUMENT_SEPARATOR + message); return true; default: InfoLog log = new InfoLog("? ? "); widgets.logViewer.appendMessage(log); } } return false; } private void processChat(String player, String message) { boolean isMine = roomLoginName.equals(player); String name = player; for (String line : message.replace("\r", "").split("\n", -1)) { Chat chat = new Chat(name, line, isMine); widgets.logViewer.appendMessage(chat); name = ""; } Chat chat = new Chat(player, message, roomLoginName.equals(player)); if (!isMine && !isActive && application.getSettings().isBallonNotifyRoom()) { application.balloonNotify(shell, "<" + player + "> " + message); } for (IMessageListener listener : messageListeners) listener.messageReceived(chat); } private void processAdminNotify(String message) { for (String line : message.replace("\r", "").split("\n", -1)) { AdminNotify log = new AdminNotify(line); widgets.logViewer.appendMessage(log); } if (!isActive) application.balloonNotify(shell, message); } private void checkSsidChange() { if (System.currentTimeMillis() < nextSsidCheckTime) return; String latestSSID = currentWlanDevice.getSSID(); if (latestSSID == null) latestSSID = ""; String currentSSID = widgets.ssidCurrentSsidText.getText(); if (!latestSSID.equals(currentSSID)) setAndSendInformNewSSID(latestSSID); nextSsidCheckTime = System.currentTimeMillis() + 3000; } private void changeSSID(String newSSID) { if (!Utility.isEmpty(newSSID)) currentWlanDevice.setSSID(newSSID); setAndSendInformNewSSID(newSSID); updateSsidStartScan(false); nextSsidCheckTime = System.currentTimeMillis() + 7000; } private void setAndSendInformNewSSID(String latestSSID) { widgets.ssidCurrentSsidText.setText(latestSSID); updateRoomPlayerSSID(roomLoginName, latestSSID); switch (sessionState) { case MY_ROOM_MASTER: myRoomEngine.informSSID(latestSSID); break; case ROOM_MASTER: case ROOM_PARTICIPANT: if (roomConnection.isConnected()) roomConnection.send(ProtocolConstants.Room.COMMAND_INFORM_SSID + TextProtocolDriver.ARGUMENT_SEPARATOR + latestSSID); break; } } private void updateSsidStartScan(boolean startScan) { if (!Wlan.isLibraryAvailable) return; isSSIDScaning = startScan; widgets.ssidStartScan.setSelection(isSSIDScaning); widgets.ssidStartScan.setText(isSSIDScaning ? "" : " "); if (isSSIDScaning) wakeupThread(wlanScannerThread); } private void updateServerAddress() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateServerAddress(); } }); return; } switch (sessionState) { case OFFLINE: widgets.statusRoomServerAddressLabel.setText("? ? "); break; default: String roomAddress; if (roomMasterName.equals("")) { roomAddress = roomServerAddressPort; } else { roomAddress = roomServerAddressPort + ":" + roomMasterName; } widgets.statusRoomServerAddressLabel.setText(" " + roomAddress); } widgets.statusBarContainer.layout(); } catch (SWTException e) { } } private void updateTunnelStatus(final boolean isLinked) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateTunnelStatus(isLinked); } }); return; } tunnelIsLinked = isLinked; if (tunnelIsLinked) wakeupThread(packetMonitorThread); if (tunnelIsLinked) { widgets.statusTunnelConnectionLabel.setForeground(widgets.colorOK); StringBuilder sb = new StringBuilder(); if (sessionState != SessionState.MY_ROOM_MASTER) switch (application.getSettings().getTunnelTransportLayer()) { case TCP: sb.append("TCP"); break; case UDP: sb.append("UDP"); break; } sb.append("? ?"); widgets.statusTunnelConnectionLabel.setText(sb.toString()); } else { widgets.statusTunnelConnectionLabel.setForeground(widgets.colorNG); widgets.statusTunnelConnectionLabel.setText("??"); } widgets.statusBarContainer.layout(); } catch (SWTException e) { } } private void updateTraficStatus(final String text) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateTraficStatus(text); } }); return; } widgets.statusTraficStatusLabel.setText(text); widgets.statusBarContainer.layout(); } catch (SWTException e) { } } private void replaceRoomPlayerList(final String[] playerInfoList) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { replaceRoomPlayerList(playerInfoList); } }); return; } TableViewer viewer = widgets.roomPlayerListTable; viewer.getTable().clearAll(); roomPlayerMap.clear(); for (int i = 0; i < playerInfoList.length - 1; i++) { String name = playerInfoList[i]; String ssid = playerInfoList[++i]; if (Utility.isEmpty(name)) continue; Player player = new Player(name); player.setSsid(name.equals(roomLoginName) ? widgets.ssidCurrentSsidText.getText() : ssid); roomPlayerMap.put(name, player); viewer.add(player); } viewer.refresh(); } catch (SWTException e) { } } private void addRoomPlayer(final String name) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { addRoomPlayer(name); } }); return; } TableViewer viewer = widgets.roomPlayerListTable; InfoLog log = new InfoLog(name + " "); widgets.logViewer.appendMessage(log); if (!isActive && application.getSettings().isBallonNotifyRoom()) application.balloonNotify(shell, log.getMessage()); Player player = new Player(name); roomPlayerMap.put(name, player); viewer.add(player); viewer.refresh(); sendMyRoomPlayerCountChange(); } catch (SWTException e) { } } private void removeRoomPlayer(final String name) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { removeRoomPlayer(name); } }); return; } TableViewer viewer = widgets.roomPlayerListTable; Player player = roomPlayerMap.remove(name); if (player == null) return; viewer.remove(player); viewer.refresh(); sendMyRoomPlayerCountChange(); } catch (SWTException e) { } } private void removeExitingRoomPlayer(String name) { InfoLog log = new InfoLog(name + " "); widgets.logViewer.appendMessage(log); if (!isActive && application.getSettings().isBallonNotifyRoom()) application.balloonNotify(shell, log.getMessage()); removeRoomPlayer(name); } private void removeKickedRoomPlayer(String name) { switch (sessionState) { case MY_ROOM_MASTER: case ROOM_MASTER: { RoomLog log = new RoomLog(name + " "); widgets.logViewer.appendMessage(log); if (!isActive && application.getSettings().isBallonNotifyRoom()) application.balloonNotify(shell, log.getMessage()); break; } case ROOM_PARTICIPANT: { RoomLog log = new RoomLog(name + " "); widgets.logViewer.appendMessage(log); if (!isActive && application.getSettings().isBallonNotifyRoom()) application.balloonNotify(shell, log.getMessage()); break; } } removeRoomPlayer(name); } private void updateRoomPlayerPing(final String name, final int ping) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateRoomPlayerPing(name, ping); } }); return; } HashMap<String, Player> map = roomPlayerMap; Player player = map.get(name); if (player == null) return; player.setPing(ping); widgets.roomPlayerListTable.refresh(player); } catch (SWTException e) { } } private void updateRoomPlayerSSID(final String name, final String ssid) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateRoomPlayerSSID(name, ssid); } }); return; } Player player = roomPlayerMap.get(name); if (player == null) return; player.setSsid(ssid); widgets.roomPlayerListTable.refresh(player); if (player.isSSIDChased() && isPacketCapturing) { changeSSID(ssid); } } catch (SWTException e) { } } private void updateRoom(final String[] tokens, final boolean isInitialUpdate) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { updateRoom(tokens, isInitialUpdate); } }); return; } String masterName = tokens[0]; int maxPlayers = Integer.parseInt(tokens[1]); String title = tokens[2]; String password = tokens[3]; long created = Long.parseLong(tokens[4]); String description = tokens[5]; String remarks = tokens[6]; isRoomInfoUpdating = true; widgets.formMasterNameText.setText(masterName); widgets.formMaxPlayersSpiner.setSelection(maxPlayers); widgets.formTitleText.setText(title); widgets.formPasswordText.setText(password); widgets.formTimestampText.setText(PlayRoomUtils.DATE_FORMAT.format(new Date(created))); widgets.formDescriptionText.setText(description); widgets.formRemarksText.setText(remarks); isRoomInfoUpdating = false; widgets.formEditSubmitButton.setEnabled(false); if (isInitialUpdate) return; RoomLog log; log = new RoomLog(" ?"); widgets.logViewer.appendMessage(log); if (!masterName.equals(roomMasterName)) { roomMasterName = masterName; log = new RoomLog(" " + roomMasterName + " ?"); widgets.logViewer.appendMessage(log); if (!isActive && application.getSettings().isBallonNotifyRoom()) application.balloonNotify(shell, log.getMessage()); updateServerAddress(); if (masterName.equals(roomLoginName)) { changeStateTo(SessionState.ROOM_MASTER); } else if (sessionState == SessionState.ROOM_MASTER) { widgets.formManualModeRoomAddressCombo.setEnabled(false); widgets.formManualModeRoomAddressCombo.setText(roomServerAddressPort + ":" + masterName); changeStateTo(SessionState.ROOM_PARTICIPANT); } else { widgets.formManualModeRoomAddressCombo.setText(roomServerAddressPort + ":" + masterName); } } } catch (NumberFormatException e) { } catch (SWTException e) { } } private void changeLobbyStateTo(LobbyUserState userState) { LobbyWindow window = application.getLobbyWindow(false); if (window != null) window.changeLobbyStateTo(userState); } private void changeStateTo(final SessionState state) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { changeStateTo(state); } }); return; } sessionState = state; switch (state) { case OFFLINE: widgets.statusRoomServerAddressLabel.setText("? ? "); widgets.statusBarContainer.layout(); roomPlayerMap.clear(); widgets.roomPlayerListTable.refresh(); widgets.formEditSubmitButton.setEnabled(false); widgets.formEditLoadButton.setEnabled(true); setEnableRoomFormItems(true); setEnableMacFilteringControls(true); widgets.formMasterNameText.setText(""); widgets.formTimestampText.setText(""); widgets.formModeSelectionCombo.setEnabled(true); widgets.formAutoModeServerAddress.setText(""); widgets.formAutoModeRoomButton.setText("? "); widgets.formAutoModeRoomButton.setEnabled(true); widgets.formAutoModeContainer.layout(); widgets.formManualModeRoomServerCombo.setEnabled(true); widgets.formManualModeRoomServerButton.setText(""); widgets.formManualModeRoomServerButton.setEnabled(true); widgets.formManualModeRoomAddressCombo.setEnabled(true); widgets.formManualModeRoomAddressButton.setText(""); widgets.formManualModeRoomAddressButton.setEnabled(true); // window.roomFormManualModeContainer.layout(); widgets.formMyRoomModePortSpinner.setEnabled(true); widgets.formMyRoomModeStartButton.setText("?"); widgets.formMyRoomModeStartButton.setEnabled(true); widgets.formMyRoomModeEntryButton.setEnabled(false); switch (widgets.formModeSelectionCombo.getSelectionIndex()) { case 0: break; case 1: break; case 2: updateTunnelStatus(false); break; } changeLobbyStateTo(LobbyUserState.LOGIN); break; case MY_ROOM_MASTER: widgets.formMyRoomModeStartButton.setText(""); widgets.formMyRoomModeStartButton.setEnabled(true); widgets.formMyRoomModeEntryButton.setEnabled(true); updateTunnelStatus(true); if (widgets.macFilteringWhiteList.getItemCount() > 0) { for (String mac : widgets.macFilteringWhiteList.getItems()) { myRoomEngine.addMacAddressToWhiteList(mac); } } if (widgets.macFilteringBlackList.getItemCount() > 0) { for (String mac : widgets.macFilteringBlackList.getItems()) { myRoomEngine.addMacAddressToBlackList(mac); } } widgets.chatText.setFocus(); break; case CONNECTING_ROOM_MASTER: widgets.formModeSelectionCombo.setEnabled(false); widgets.formManualModeRoomServerButton.setEnabled(false); widgets.formManualModeRoomServerCombo.setEnabled(false); widgets.formManualModeRoomAddressButton.setEnabled(false); widgets.formManualModeRoomAddressCombo.setEnabled(false); break; case ROOM_MASTER: switch (widgets.formModeSelectionCombo.getSelectionIndex()) { case 0: widgets.formAutoModeRoomButton.setText(""); widgets.formAutoModeRoomButton.setEnabled(true); break; case 1: widgets.formManualModeRoomServerButton.setText(""); widgets.formManualModeRoomServerButton.setEnabled(true); widgets.formManualModeRoomAddressButton.setEnabled(false); // window.roomFormManualModeContainer.layout(); break; } widgets.formEditLoadButton.setEnabled(true); setEnableRoomFormItems(true); setEnableMacFilteringControls(true); if (widgets.macFilteringWhiteList.getItemCount() > 0) { StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_WHITELIST_ADD); for (String mac : widgets.macFilteringWhiteList.getItems()) { sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(mac); } roomConnection.send(sb.toString()); } if (widgets.macFilteringBlackList.getItemCount() > 0) { StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_BLACKLIST_ADD); for (String mac : widgets.macFilteringBlackList.getItems()) { sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(mac); } roomConnection.send(sb.toString()); } widgets.chatText.setFocus(); break; case CONNECTING_ROOM_PARTICIPANT: widgets.formModeSelectionCombo.setEnabled(false); widgets.formManualModeRoomServerButton.setEnabled(false); widgets.formManualModeRoomServerCombo.setEnabled(false); widgets.formManualModeRoomAddressButton.setEnabled(false); widgets.formManualModeRoomAddressCombo.setEnabled(false); break; case ROOM_PARTICIPANT: switch (widgets.formModeSelectionCombo.getSelectionIndex()) { case 0: widgets.formAutoModeRoomButton.setText(""); widgets.formAutoModeRoomButton.setEnabled(true); break; case 1: widgets.formManualModeRoomAddressButton.setText(""); widgets.formManualModeRoomAddressButton.setEnabled(true); widgets.formManualModeRoomServerButton.setEnabled(false); // window.roomFormManualModeContainer.layout(); break; } widgets.formEditLoadButton.setEnabled(false); setEnableRoomFormItems(false); setEnableMacFilteringControls(false); widgets.chatText.setFocus(); break; } } catch (SWTException e) { } } private void updateRoomModeSelection() { switch (widgets.formModeSelectionCombo.getSelectionIndex()) { case 0: widgets.roomModeStackLayout.topControl = widgets.formAutoModeContainer; widgets.formMaxPlayersSpiner.setMaximum(ProtocolConstants.Room.MAX_ROOM_PLAYERS); break; case 1: widgets.roomModeStackLayout.topControl = widgets.formManualModeContainer; widgets.formMaxPlayersSpiner.setMaximum(ProtocolConstants.Room.MAX_ROOM_PLAYERS); break; case 2: widgets.roomModeStackLayout.topControl = widgets.formMyRoomModeContainer; widgets.formMaxPlayersSpiner.setMaximum(Integer.MAX_VALUE); break; } widgets.formModeSwitchContainer.layout(); } private void setEnableRoomFormItems(boolean enabled) { widgets.formTitleText.setEditable(enabled); widgets.formPasswordText.setEditable(enabled); widgets.formMaxPlayersSpiner.setEnabled(enabled); widgets.formDescriptionText.setEditable(enabled); widgets.formRemarksText.setEditable(enabled); } private void clearRoomForm() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { clearRoomForm(); } }); return; } widgets.formTitleText.setText(""); widgets.formPasswordText.setText(""); widgets.formMaxPlayersSpiner.setSelection(DEFAULT_MAX_PLAYERS); widgets.formDescriptionText.setText(""); widgets.formRemarksText.setText(""); } catch (SWTException e) { } } private void setEnableMacFilteringControls(boolean enabled) { widgets.macFilteringWhiteListCheck.setEnabled(enabled); widgets.macFilteringWhiteList.setEnabled(enabled); widgets.macFilteringBlackListCheck.setEnabled(enabled); widgets.macFilteringBlackList.setEnabled(enabled); if (enabled) { widgets.macFilteringWhiteListCheck.setSelection(false); widgets.macFilteringBlackListCheck.setSelection(false); } } private void sendMyRoomUpdate() { if (!myRoomEntryConnection.isConnected()) { return; } try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { sendMyRoomUpdate(); } }); return; } StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.MyRoom.COMMAND_UPDATE); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formTitleText.getText()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formMaxPlayersSpiner.getSelection()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formPasswordText.getText().length() > 0 ? "Y" : "N"); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.formDescriptionText.getText()); myRoomEntryConnection.send(sb.toString()); } catch (SWTException e) { } } private void sendMyRoomPlayerCountChange() { if (myRoomEntryConnection.isConnected()) { myRoomEntryConnection.send(ProtocolConstants.MyRoom.COMMAND_UPDATE_PLAYER_COUNT + TextProtocolDriver.ARGUMENT_SEPARATOR + roomPlayerMap.size()); } } private class MyRoomEntryProtocol implements IProtocol { @Override public void log(String message) { } @Override public String getProtocol() { return ProtocolConstants.PROTOCOL_MY_ROOM_ENTRY; } @Override public IProtocolDriver createDriver(ISocketConnection connection) { myRoomEntryConnection = connection; init(connection); return new MyRoomEntryProtocolDriver(connection); } private void init(ISocketConnection connection) { StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.MyRoom.COMMAND_ENTRY); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(myRoomEngine.getAuthCode()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomServerAddressPort); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomLoginName); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(myRoomEngine.getTitle()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomPlayerMap.size()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(myRoomEngine.getMaxPlayers()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(Utility.isEmpty(myRoomEngine.getPassword()) ? "N" : "Y"); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(myRoomEngine.getCreatedTime()); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(myRoomEngine.getDescription()); connection.send(sb.toString()); } } private class MyRoomEntryProtocolDriver extends TextProtocolDriver { private boolean isEntryCompleted = false; public MyRoomEntryProtocolDriver(ISocketConnection connection) { super(connection, myRoomEntryHandlers); } @Override public void connectionDisconnected() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { connectionDisconnected(); } }); return; } updateMyRoomEntryForm(false); if (isEntryCompleted) { isEntryCompleted = false; roomServerHistoryManager.addCurrentItem(); RoomLog log = new RoomLog("?? ?? "); widgets.logViewer.appendMessage(log); } else { ErrorLog log = new ErrorLog("?? ? "); widgets.logViewer.appendMessage(log); } } catch (SWTException e) { } } @Override public void log(String message) { ErrorLog log = new ErrorLog(message); widgets.logViewer.appendMessage(log); } @Override public void errorProtocolNumber(String number) { String message = String.format( "? ? ? ? :%s ??? :%s", number, IProtocol.NUMBER); ErrorLog log = new ErrorLog(message); widgets.logViewer.appendMessage(log); } } private HashMap<String, IProtocolMessageHandler> myRoomEntryHandlers = new HashMap<String, IProtocolMessageHandler>(); { myRoomEntryHandlers.put(ProtocolConstants.MyRoom.COMMAND_ENTRY, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { updateMyRoomEntryForm(true); MyRoomEntryProtocolDriver myroom = (MyRoomEntryProtocolDriver) driver; myroom.isEntryCompleted = true; RoomLog log = new RoomLog("?? ?"); widgets.logViewer.appendMessage(log); return true; } }); myRoomEntryHandlers.put(ProtocolConstants.MyRoom.ERROR_TCP_PORT_NOT_OPEN, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { ErrorLog log = new ErrorLog("?? TCP ? ? "); widgets.logViewer.appendMessage(log); return false; } }); myRoomEntryHandlers.put(ProtocolConstants.MyRoom.ERROR_UDP_PORT_NOT_OPEN, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { ErrorLog log = new ErrorLog("?? UDP ? ? "); widgets.logViewer.appendMessage(log); return false; } }); myRoomEntryHandlers.put(ProtocolConstants.MyRoom.ERROR_INVALID_AUTH_CODE, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { ErrorLog log = new ErrorLog("? ?? ?? "); widgets.logViewer.appendMessage(log); return false; } }); } private class MyRoomServerHandler implements IMyRoomMasterHandler { @Override public void log(String message) { application.getLogWindow().appendLogTo(message, true, false); } @Override public void chatReceived(String player, String message) { processChat(player, message); } @Override public void playerEntered(String player) { addRoomPlayer(player); } @Override public void playerExited(String player) { removeExitingRoomPlayer(player); } @Override public void pingInformed(String player, int ping) { updateRoomPlayerPing(player, ping); } @Override public void ssidInformed(String player, String ssid) { updateRoomPlayerSSID(player, ssid); } @Override public void tunnelPacketReceived(ByteBuffer packet, String playerName) { processRemotePspPacket(packet, playerName); } @Override public void roomOpened() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { roomOpened(); } }); return; } changeStateTo(SessionState.MY_ROOM_MASTER); updateServerAddress(); changeLobbyStateTo(LobbyUserState.PLAYING); RoomLog log = new RoomLog("?? ?"); widgets.logViewer.appendMessage(log); addRoomPlayer(roomLoginName); widgets.formTimestampText .setText(PlayRoomUtils.DATE_FORMAT.format(new Date(myRoomEngine.getCreatedTime()))); String ssid = widgets.ssidCurrentSsidText.getText(); updateRoomPlayerSSID(roomLoginName, ssid); myRoomEngine.informSSID(ssid); } catch (SWTException e) { } } @Override public void roomClosed() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { roomClosed(); } }); return; } if (myRoomEntryConnection.isConnected()) myRoomEntryConnection.send(ProtocolConstants.MyRoom.COMMAND_LOGOUT); changeStateTo(SessionState.OFFLINE); RoomLog log = new RoomLog("?? "); widgets.logViewer.appendMessage(log); } catch (SWTException e) { } } } private class RoomProtocol implements IProtocol { @Override public void log(String message) { application.getLogWindow().appendLogTo(message, true, true); } @Override public String getProtocol() { return ProtocolConstants.PROTOCOL_ROOM; } @Override public IProtocolDriver createDriver(ISocketConnection connection) { roomConnection = connection; init(connection); return new RoomProtocolDriver(connection); } private void init(final ISocketConnection connection) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { init(connection); } }); return; } widgets.formAutoModeServerAddress.setText(roomServerAddressPort); StringBuilder sb = new StringBuilder(); switch (sessionState) { case CONNECTING_ROOM_MASTER: { ServerLog log = new ServerLog("? ?"); widgets.logViewer.appendMessage(log); sb.append(ProtocolConstants.Room.COMMAND_ROOM_CREATE); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomLoginName); appendRoomInfo(sb); roomConnection.send(sb.toString()); widgets.formManualModeRoomServerCombo.setText(roomServerAddressPort); sessionState = SessionState.NEGOTIATING; break; } case CONNECTING_ROOM_PARTICIPANT: { ServerLog log = new ServerLog("? ?"); widgets.logViewer.appendMessage(log); sb.append(ProtocolConstants.Room.COMMAND_LOGIN); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomLoginName); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomMasterName); sb.append(TextProtocolDriver.MESSAGE_SEPARATOR); sb.append(ProtocolConstants.Room.COMMAND_INFORM_SSID); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(widgets.ssidCurrentSsidText.getText()); roomConnection.send(sb.toString()); widgets.formManualModeRoomAddressCombo.setText(roomServerAddressPort + ":" + roomMasterName); sessionState = SessionState.NEGOTIATING; break; } } } catch (SWTException e) { } } } private class RoomProtocolDriver extends TextProtocolDriver { public RoomProtocolDriver(ISocketConnection connection) { super(connection, roomHandlers); } @Override public void connectionDisconnected() { switch (sessionState) { case CONNECTING_ROOM_PARTICIPANT: case CONNECTING_ROOM_MASTER: { ErrorLog log = new ErrorLog("? ? "); widgets.logViewer.appendMessage(log); break; } case ROOM_PARTICIPANT: clearRoomForm(); default: ServerLog log = new ServerLog(" "); widgets.logViewer.appendMessage(log); } roomConnection = ISocketConnection.NULL; tunnelConnection.disconnect(); changeStateTo(SessionState.OFFLINE); } @Override public void log(String message) { application.getLogWindow().appendLogTo(message, true, true); } @Override public void errorProtocolNumber(String number) { String message = String.format( "? ? ? ? :%s ??? :%s", number, IProtocol.NUMBER); ErrorLog log = new ErrorLog(message); widgets.logViewer.appendMessage(log); } } private void promptRoomPassword() { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { promptRoomPassword(); } }); return; } TextDialog dialog = new TextDialog(shell, " ", "? ? ", null, 180, SWT.NONE); switch (dialog.open()) { case IDialogConstants.OK_ID: String password = dialog.getUserInput(); StringBuilder sb = new StringBuilder(); sb.append(ProtocolConstants.Room.COMMAND_LOGIN); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomLoginName); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(roomMasterName); sb.append(TextProtocolDriver.ARGUMENT_SEPARATOR); sb.append(password); roomConnection.send(sb.toString()); break; case IDialogConstants.CANCEL_ID: RoomLog log = new RoomLog("? "); widgets.logViewer.appendMessage(log); roomConnection.send(ProtocolConstants.Room.COMMAND_LOGOUT); break; } } catch (SWTException e) { } } private HashMap<String, IProtocolMessageHandler> roomHandlers = new HashMap<String, IProtocolMessageHandler>(); { roomHandlers.put(ProtocolConstants.Room.COMMAND_ROOM_CREATE, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, final String argument) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { process(null, argument); } }); connectRoomTunnel(); return true; } long created = Long.parseLong(argument); widgets.formTimestampText.setText(PlayRoomUtils.DATE_FORMAT.format(new Date(created))); changeStateTo(SessionState.ROOM_MASTER); RoomLog log = new RoomLog(" ? "); widgets.logViewer.appendMessage(log); widgets.formMasterNameText.setText(roomLoginName); addRoomPlayer(roomLoginName); updateServerAddress(); changeLobbyStateTo(LobbyUserState.PLAYING); roomServerHistoryManager.addCurrentItem(); } catch (NumberFormatException e) { return false; } catch (SWTException e) { } return true; } }); roomHandlers.put(ProtocolConstants.Room.COMMAND_LOGIN, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, final String args) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { process(null, args); } }); connectRoomTunnel(); return true; } changeStateTo(SessionState.ROOM_PARTICIPANT); updateRoom(args.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1), true); updateServerAddress(); changeLobbyStateTo(LobbyUserState.PLAYING); roomAddressHistoryManager.addCurrentItem(); RoomLog log = new RoomLog("? "); widgets.logViewer.appendMessage(log); } catch (SWTException e) { } return true; } }); roomHandlers.put(ProtocolConstants.Room.COMMAND_CHAT, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { String[] tokens = argument.split(TextProtocolDriver.ARGUMENT_SEPARATOR, 2); if (tokens.length != 2) return true; processChat(tokens[0], tokens[1]); return true; } }); roomHandlers.put(ProtocolConstants.Room.COMMAND_PINGBACK, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { try { long time = Long.parseLong(argument); int ping = (int) (System.currentTimeMillis() - time); updateRoomPlayerPing(roomLoginName, ping); roomConnection.send(ProtocolConstants.Room.COMMAND_INFORM_PING + TextProtocolDriver.ARGUMENT_SEPARATOR + ping); } catch (NumberFormatException e) { } return true; } }); roomHandlers.put(ProtocolConstants.Room.COMMAND_INFORM_PING, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String args) { try { switch (sessionState) { case MY_ROOM_MASTER: case ROOM_PARTICIPANT: case ROOM_MASTER: String[] values = args.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1); if (values.length == 2) { int ping = Integer.parseInt(values[1]); updateRoomPlayerPing(values[0], ping); } } } catch (NumberFormatException e) { } return true; } }); roomHandlers.put(ProtocolConstants.Room.COMMAND_INFORM_TUNNEL_PORT, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { updateTunnelStatus(true); application.getLogWindow().appendLogTo("? ? ?? ", true, false); return true; } }); roomHandlers.put(ProtocolConstants.Room.COMMAND_MAC_ADDRESS_PLAYER, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { String[] tokens = argument.split(TextProtocolDriver.ARGUMENT_SEPARATOR); if (tokens.length != 2) return true; TraficStatistics stats = traficStatsMap.get(tokens[0]); if (stats == null) return true; stats.playerName = tokens[1]; return true; } }); roomHandlers.put(ProtocolConstants.Room.COMMAND_ROOM_UPDATE, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { @Override public void run() { process(null, null); } }); return true; } RoomLog log = new RoomLog(" "); widgets.logViewer.appendMessage(log); widgets.chatText.setFocus(); } catch (SWTException e) { } return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_USER_LIST, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String args) { // System.out.println(args); String[] playerInfoList = args.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1); replaceRoomPlayerList(playerInfoList); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_USER_ENTERED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String name) { addRoomPlayer(name); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_USER_EXITED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String name) { removeExitingRoomPlayer(name); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_ROOM_UPDATED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String args) { updateRoom(args.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1), false); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_ROOM_PLAYER_KICKED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String kickedPlayer) { if (roomLoginName.equals(kickedPlayer)) { changeStateTo(SessionState.OFFLINE); RoomLog log = new RoomLog(" "); widgets.logViewer.appendMessage(log); // appendLogTo(window.roomLogText, " ", // iniAppearance.getColorLogRoom(), true); } else { removeKickedRoomPlayer(kickedPlayer); } return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_ROOM_PASSWORD_REQUIRED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { promptRoomPassword(); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_FROM_ADMIN, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String message) { processAdminNotify(message); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_ROOM_DELETED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { RoomLog log = new RoomLog("? ?"); widgets.logViewer.appendMessage(log); if (!isActive && application.getSettings().isBallonNotifyRoom()) application.balloonNotify(shell, log.getMessage()); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_SSID_CHANGED, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { String[] values = argument.split(TextProtocolDriver.ARGUMENT_SEPARATOR, -1); if (values.length == 2) { updateRoomPlayerSSID(values[0], values[1]); } return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_ROOM_AGE_OLD, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { processAdminNotify( " . 15 ? ?? . "); return true; } }); roomHandlers.put(ProtocolConstants.Room.NOTIFY_TUNNEL_COMMUNICATION_IDLE, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver driver, String argument) { processAdminNotify(" ?. 15 ? ?? . "); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_LOGIN_DUPLICATED_NAME, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { ErrorLog log = new ErrorLog( "?? ? ? ? "); widgets.logViewer.appendMessage(log); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_LOGIN_ROOM_NOT_EXIST, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { ErrorLog log = new ErrorLog("? ? "); widgets.logViewer.appendMessage(log); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_LOGIN_BEYOND_CAPACITY, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { ErrorLog log = new ErrorLog("? ? "); widgets.logViewer.appendMessage(log); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_ROOM_CREATE_INVALID_DATA_ENTRY, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { ErrorLog log = new ErrorLog("? ? ? "); widgets.logViewer.appendMessage(log); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_LOGIN_PASSWORD_FAIL, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { RoomLog log = new RoomLog(" "); widgets.logViewer.appendMessage(log); promptRoomPassword(); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_ROOM_CREATE_DUPLICATED_NAME, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { ErrorLog log = new ErrorLog( "?? ? ? ? "); widgets.logViewer.appendMessage(log); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_ROOM_CREATE_BEYOND_LIMIT, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { RoomLog log = new RoomLog( " ?? ? ? "); widgets.logViewer.appendMessage(log); return true; } }); roomHandlers.put(ProtocolConstants.Room.ERROR_ROOM_TRANSFER_DUPLICATED_NAME, new IProtocolMessageHandler() { @Override public boolean process(IProtocolDriver client, String argument) { ErrorLog log = new ErrorLog( "?? ? ? ? "); widgets.logViewer.appendMessage(log); return true; } }); } private void connectRoomTunnel() { try { switch (application.getSettings().getTunnelTransportLayer()) { case TCP: application.connectTcp(roomConnection.getRemoteAddress(), tunnelProtocol); break; case UDP: application.connectUdp(roomConnection.getRemoteAddress(), tunnelProtocol); break; } } catch (IOException e) { ErrorLog log = new ErrorLog(e.getMessage()); widgets.logViewer.appendMessage(log); } catch (RuntimeException e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); } } private class TunnelProtocol implements IProtocol { @Override public void log(String message) { application.getLogWindow().appendLogTo(message, true, true); } @Override public String getProtocol() { return ProtocolConstants.PROTOCOL_TUNNEL; } @Override public IProtocolDriver createDriver(ISocketConnection connection) { tunnelConnection = connection; TunnelProtocolDriver driver = new TunnelProtocolDriver(connection); return driver; } } private class TunnelProtocolDriver implements IProtocolDriver { private ISocketConnection connection; private int localPort = 0; private TunnelProtocolDriver(ISocketConnection conn) { this.connection = conn; application.execute(new Runnable() { @Override public void run() { try { while (localPort == 0) { connection.send(ProtocolConstants.Tunnel.DUMMY_PACKET); Thread.sleep(10000); } } catch (InterruptedException e) { } } }); } @Override public ISocketConnection getConnection() { return connection; } @Override public boolean process(PacketData data) { ByteBuffer packet = data.getBuffer(); // System.out.println(packet.toString()); if (Utility.isPspPacket(packet)) { processRemotePspPacket(packet, null); } else { try { String port = data.getMessage(); localPort = Integer.parseInt(port); roomConnection.send(ProtocolConstants.Room.COMMAND_INFORM_TUNNEL_PORT + TextProtocolDriver.ARGUMENT_SEPARATOR + localPort); } catch (NumberFormatException e) { } } return true; } @Override public void connectionDisconnected() { updateTunnelStatus(false); tunnelConnection = ISocketConnection.NULL; application.getLogWindow().appendLogTo("? ? ?? ", true, false); if (roomConnection.isConnected()) switch (sessionState) { case ROOM_MASTER: case ROOM_PARTICIPANT: connectRoomTunnel(); } } @Override public void errorProtocolNumber(String number) { String message = String.format( "? ? ? ? :%s ??? :%s", number, IProtocol.NUMBER); application.getLogWindow().appendLogTo(message, true, true); } } private void refreshLanAdapterList() { widgets.wlanAdapterListCombo.removeAll(); widgets.wlanAdapterListCombo.add("?? "); wlanAdaptorList.clear(); try { Wlan.findDevices(wlanAdaptorList); } catch (RuntimeException e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); return; } catch (UnsatisfiedLinkError e) { try { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); } catch (NullPointerException ne) { ne.printStackTrace(); } return; } String lastUsedMacAddress = application.getAppData().getLastLanAdapter(); int lastUsedIndex = 0; IniSection nicSection = application.getIniSection(SECTION_LAN_ADAPTERS); int maxNameLength = 5; int i = 1; for (Iterator<WlanDevice> iter = wlanAdaptorList.iterator(); iter.hasNext(); i++) { WlanDevice device = iter.next(); String macAddress = Utility.macAddressToString(device.getHardwareAddress(), 0, true); if (lastUsedMacAddress.equals(macAddress)) { lastUsedIndex = i; } String description = nicSection.get(macAddress, ""); if (Utility.isEmpty(description)) { description = device.getName(); description = description.replace("(Microsoft's Packet Scheduler)", ""); description = description.replaceAll(" {2,}", " ").trim(); nicSection.set(macAddress, description); } else if (description.equals("")) { iter.remove(); continue; } description += " [" + macAddress + "]"; widgets.wlanAdapterListCombo.add(description); wlanAdaptorMacAddressMap.put(device, macAddress); maxNameLength = Math.max(description.length(), maxNameLength); } StringBuilder sb = new StringBuilder(maxNameLength); for (i = 0; i < maxNameLength; i++) sb.append('-'); widgets.wlanAdapterListCombo.add(sb.toString()); widgets.wlanAdapterListCombo.add(" ? ?"); widgets.wlanAdapterListCombo.select(lastUsedIndex); widgets.wlanPspCommunicationButton.setEnabled(lastUsedIndex != 0); } private void processRemotePspPacket(ByteBuffer packet, String playerName) { String destMac = Utility.macAddressToString(packet, 0, false); String srcMac = Utility.macAddressToString(packet, 6, false); // System.out.print("[" + playerName + "] "); // System.out.print("src: " + srcMac + " dest: " + destMac); // System.out.println(); TraficStatistics destStats, srcStats; synchronized (traficStatsMap) { destStats = traficStatsMap.get(destMac); srcStats = traficStatsMap.get(srcMac); if (srcStats == null) { srcStats = new TraficStatistics(srcMac, false); traficStatsMap.put(srcMac, srcStats); } if (destStats == null) { destStats = new TraficStatistics(destMac, !Utility.isMacBroadCastAddress(destMac)); traficStatsMap.put(destMac, destStats); } } int packetLength = packet.limit(); srcStats.lastModified = destStats.lastModified = System.currentTimeMillis(); if (!Utility.isEmpty(playerName)) { srcStats.playerName = playerName; } else if (Utility.isEmpty(srcStats.playerName) && !Utility.isMacBroadCastAddress(srcMac)) { roomConnection.send(ProtocolConstants.Room.COMMAND_MAC_ADDRESS_PLAYER + TextProtocolDriver.ARGUMENT_SEPARATOR + srcMac); } if (destStats.isMine) destStats.playerName = roomLoginName; actualRecievedBytes += packetLength; srcStats.currentInBytes += packetLength; srcStats.totalInBytes += packetLength; destStats.currentInBytes += packetLength; destStats.totalInBytes += packetLength; if (isPacketCapturing && currentWlanDevice != null) { // send packet currentWlanDevice.sendPacket(packet); } } private void processCapturedPacket() { // if (packet != null) { // System.out.println(packet.toHexdump()); // return; // } // System.out.println(bufferForCapturing); if (!Utility.isPspPacket(bufferForCapturing)) return; String srcMac = Utility.macAddressToString(bufferForCapturing, 6, false); String destMac = Utility.macAddressToString(bufferForCapturing, 0, false); TraficStatistics srcStats, destStats; synchronized (traficStatsMap) { srcStats = traficStatsMap.get(srcMac); destStats = traficStatsMap.get(destMac); if (srcStats == null) { srcStats = new TraficStatistics(srcMac, true); traficStatsMap.put(srcMac, srcStats); } else if (!srcStats.isMine) { // PSP? ? capther? return; } if (destStats == null) { destStats = new TraficStatistics(destMac, false); traficStatsMap.put(destMac, destStats); } else if (destStats.isMine) { // ? PSP?? ? return; } } int packetLength = bufferForCapturing.limit(); srcStats.lastModified = destStats.lastModified = System.currentTimeMillis(); srcStats.playerName = roomLoginName; if (Utility.isEmpty(destStats.playerName) && !Utility.isMacBroadCastAddress(destMac)) roomConnection.send(ProtocolConstants.Room.COMMAND_MAC_ADDRESS_PLAYER + TextProtocolDriver.ARGUMENT_SEPARATOR + destMac); actualSentBytes += packetLength; srcStats.currentOutBytes += packetLength; srcStats.totalOutBytes += packetLength; destStats.currentOutBytes += packetLength; destStats.totalOutBytes += packetLength; if (!tunnelIsLinked) return; // System.out.printf("%s => %s [%d]", srcMac, destMac, // packetLength); // System.out.println(packet.toHexdump()); switch (sessionState) { case MY_ROOM_MASTER: myRoomEngine.sendTunnelPacketToParticipants(bufferForCapturing, srcMac, destMac); break; case ROOM_PARTICIPANT: case ROOM_MASTER: tunnelConnection.send(bufferForCapturing); break; } } private boolean startPacketCapturing() { int index = widgets.wlanAdapterListCombo.getSelectionIndex() - 1; WlanDevice device = wlanAdaptorList.get(index); try { device.open(); } catch (RuntimeException e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); return false; } catch (Exception e) { application.getLogWindow().appendLogTo(Utility.stackTraceToString(e), true, true); return false; } currentWlanDevice = device; checkSsidChange(); isPacketCapturing = true; wakeupThread(packetCaptureThread); wakeupThread(packetMonitorThread); return true; } }