From 63013dc82cc8718e40e9557cfd83991e72d72dae Mon Sep 17 00:00:00 2001 From: Jannis Harder Date: Wed, 22 Jun 2011 01:08:54 +0200 Subject: Integrated dedicated server git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@563 72836036-5685-4462-b002-a69064685172 --- src/jrummikub/control/ApplicationControl.java | 61 ++++++++++++-- src/jrummikub/control/LoginControl.java | 13 ++- .../control/network/ConnectionControl.java | 40 ++++++---- src/jrummikub/server/DedicatedServer.java | 93 ++++++++++++++++------ src/jrummikub/view/ILoginPanel.java | 31 ++++++++ src/jrummikub/view/IView.java | 8 ++ src/jrummikub/view/impl/LoginPanel.java | 73 +++++++++++++---- src/jrummikub/view/impl/View.java | 68 +++++++++------- 8 files changed, 300 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/jrummikub/control/ApplicationControl.java b/src/jrummikub/control/ApplicationControl.java index 7f5cf6d..6909ce1 100644 --- a/src/jrummikub/control/ApplicationControl.java +++ b/src/jrummikub/control/ApplicationControl.java @@ -5,6 +5,8 @@ import jrummikub.control.network.NetworkControl; import jrummikub.model.GameSettings; import jrummikub.model.GameState; import jrummikub.model.IRoundState; +import jrummikub.server.DedicatedServer; +import jrummikub.server.DedicatedServer.ServerStatus; import jrummikub.util.Connection; import jrummikub.util.IListener; import jrummikub.util.IListener1; @@ -25,6 +27,7 @@ public class ApplicationControl { private SaveControl saveControl; private GameControl gameControl; private Connection tempConnection; + private DedicatedServer server; private IView view; @@ -32,7 +35,7 @@ public class ApplicationControl { * Creates a new application control * * @param view - * the view to use + * the view to use */ public ApplicationControl(final IView view) { this.view = view; @@ -52,10 +55,11 @@ public class ApplicationControl { saveControl.getLoadEvent().add( new IListener3() { @Override - public void handle(GameSettings settings, GameState gameState, - IRoundState roundState) { + public void handle(GameSettings settings, + GameState gameState, IRoundState roundState) { abortControls(); - gameControl = new GameControl(settings, saveControl, view); + gameControl = new GameControl(settings, saveControl, + view); addGameControlListeners(gameControl); gameControl.continueGame(gameState, roundState); } @@ -132,7 +136,7 @@ public class ApplicationControl { * Create a new network login control */ private void createLoginControl(boolean reset) { - loginControl = new LoginControl(view); + loginControl = new LoginControl(view, this); loginControl.getLoginEvent().add(new IListener1() { @Override public void handle(LoginData loginData) { @@ -250,4 +254,51 @@ public class ApplicationControl { networkControl.startNetwork(); } + + /** + * Ensure the dedicated server is running + * + * @param password + * password to use, if empty "jrummikub" is used + * @return whether the server could be started + */ + public boolean startDedicatedServer(String password) { + if (password == "") { + password = "jrummikub"; + } + if (server == null) { + DedicatedServer newServer = new DedicatedServer(password); + ServerStatus status = newServer.start(); + switch (status) { + case STARTED: + server = newServer; + break; + case ALREADY_RUNNING: + view.showServerStartupError(true); + return false; + case ERROR: + view.showServerStartupError(false); + return false; + } + } + server.setServerPassword(password); + view.getLoginPanel().setServer(server.getHostName()); + view.getLoginPanel().setChannel( + "jrummikub@play." + server.getHostName()); + view.getLoginPanel().setDedicatedServerRunning(true); + return true; + } + + /** + * If the login given is to our own dedicated server, update it's password + * to match + * + * @param loginData + * login data of user trying to connect + */ + public void updateDedicatedServerPassword(LoginData loginData) { + if (server != null && server.getHostName() == loginData.getServerName()) { + server.setServerPassword(loginData.getPassword()); + } + } } diff --git a/src/jrummikub/control/LoginControl.java b/src/jrummikub/control/LoginControl.java index 8908c0d..d13eb97 100644 --- a/src/jrummikub/control/LoginControl.java +++ b/src/jrummikub/control/LoginControl.java @@ -18,6 +18,7 @@ import jrummikub.view.IView; * */ public class LoginControl { + private ApplicationControl appControl; private IView view; private Event1 loginEvent = new Event1(); private Event cancelEvent = new Event(); @@ -28,14 +29,18 @@ public class LoginControl { * * @param view * for events which need handling + * @param applicationControl + * the application control */ - public LoginControl(final IView view) { + public LoginControl(final IView view, ApplicationControl applicationControl) { + this.appControl = applicationControl; this.view = view; connections.add(view.getLoginPanel().getLoginEvent() .add(new IListener1() { @Override public void handle(LoginData loginData) { abort(); + appControl.updateDedicatedServerPassword(loginData); loginEvent.emit(loginData); } })); @@ -48,6 +53,12 @@ public class LoginControl { cancelEvent.emit(); } })); + connections.add(view.getLoginPanel().getUseDedicatedServerEvent().add(new IListener1() { + @Override + public void handle(String value) { + appControl.startDedicatedServer(value); + } + })); } /** diff --git a/src/jrummikub/control/network/ConnectionControl.java b/src/jrummikub/control/network/ConnectionControl.java index b5886ca..39fabf7 100644 --- a/src/jrummikub/control/network/ConnectionControl.java +++ b/src/jrummikub/control/network/ConnectionControl.java @@ -2,6 +2,8 @@ package jrummikub.control.network; import java.awt.Color; import java.io.Serializable; +import java.util.Collection; +import java.util.Iterator; import java.util.UUID; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; @@ -88,7 +90,7 @@ public class ConnectionControl implements IConnectionControl { } } - private final LoginData loginData; + private LoginData loginData; private volatile Connection connection; private volatile MultiUserChat muc; @@ -125,7 +127,7 @@ public class ConnectionControl implements IConnectionControl { * Creates new connection control * * @param loginData - * player's login data + * player's login data */ public ConnectionControl(LoginData loginData) { this.loginData = loginData; @@ -346,7 +348,8 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "change_color"); extension.setValue("uuid", uuid.toString()); - extension.setValue("color", Base64.encodeObject(color, Base64.GZIP)); + extension.setValue("color", + Base64.encodeObject(color, Base64.GZIP)); } }); } @@ -409,7 +412,8 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "table_update"); extension.setValue("uuid", uuid.toString()); - extension.setValue("table", Base64.encodeObject(table, Base64.GZIP)); + extension.setValue("table", + Base64.encodeObject(table, Base64.GZIP)); } }); } @@ -423,8 +427,8 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "turn_end"); extension.setValue("uuid", uuid.toString()); - extension.setValue("data", Base64.encodeObject(new TurnEndData(state, - invalidTurnInfo), Base64.GZIP)); + extension.setValue("data", Base64.encodeObject(new TurnEndData( + state, invalidTurnInfo), Base64.GZIP)); } }); } @@ -460,8 +464,8 @@ public class ConnectionControl implements IConnectionControl { protected void addData(DefaultPacketExtension extension) { extension.setValue("messageType", "game_offer"); extension.setValue("uuid", data.getGameID().toString()); - extension.setValue("gameSettings", - Base64.encodeObject(data.getGameSettings(), Base64.GZIP)); + extension.setValue("gameSettings", Base64.encodeObject( + data.getGameSettings(), Base64.GZIP)); } }); } @@ -512,8 +516,8 @@ public class ConnectionControl implements IConnectionControl { .getExtension(ELEMENT_NAME, NAMESPACE); if (((Message) packet).getType() == Message.Type.error) { - System.err.println("Received error message from '" + packet.getFrom() - + "'"); + System.err.println("Received error message from '" + + packet.getFrom() + "'"); return; } @@ -529,14 +533,15 @@ public class ConnectionControl implements IConnectionControl { String sender, String messageType) { if (messageType.equals("game_offer")) { UUID uuid = UUID.fromString(extension.getValue("uuid")); - GameSettings settings = (GameSettings) Base64.decodeToObject(extension - .getValue("gameSettings")); + GameSettings settings = (GameSettings) Base64 + .decodeToObject(extension.getValue("gameSettings")); fixGameSettings(settings); GameData gameData = new GameData(uuid, settings, sender); gameOfferEvent.emit(gameData); } else if (messageType.equals("game_withdrawal")) { - gameWithdrawalEvent.emit(UUID.fromString(extension.getValue("uuid"))); + gameWithdrawalEvent + .emit(UUID.fromString(extension.getValue("uuid"))); } else if (messageType.equals("game_request")) { if (offeredGame != null) { sendGameOffer(); @@ -649,7 +654,8 @@ public class ConnectionControl implements IConnectionControl { XMPPError xmppError = e.getXMPPError(); if (xmppError != null) { - if (xmppError.getType() == Type.WAIT && xmppError.getCode() == 504) { + if (xmppError.getType() == Type.WAIT + && xmppError.getCode() == 504) { return LoginError.UNKNOWN_HOST; } } @@ -661,7 +667,8 @@ public class ConnectionControl implements IConnectionControl { private LoginError doLogin() { try { - connection.login(loginData.getUserName(), loginData.getPassword(), + connection.login(loginData.getUserName(), + loginData.getPassword(), "JRummikub-" + StringUtils.randomString(8)); return null; } catch (XMPPException e) { @@ -691,7 +698,8 @@ public class ConnectionControl implements IConnectionControl { continue; } else { // An unknown error has occurred, cancel connect - if (xmppError != null && xmppError.getType() == Type.CANCEL + if (xmppError != null + && xmppError.getType() == Type.CANCEL && xmppError.getCode() == 404) { return LoginError.UNKNOWN_CHANNEL; } diff --git a/src/jrummikub/server/DedicatedServer.java b/src/jrummikub/server/DedicatedServer.java index e27c74c..ae071f0 100644 --- a/src/jrummikub/server/DedicatedServer.java +++ b/src/jrummikub/server/DedicatedServer.java @@ -1,5 +1,6 @@ package jrummikub.server; +import java.net.BindException; import java.net.InetAddress; import org.apache.vysper.mina.TCPEndpoint; @@ -16,8 +17,8 @@ import org.apache.vysper.xmpp.server.XMPPServer; * Implements a simple XMPP server with a global server password */ public class DedicatedServer { - String serverPassword; - String hostName; + private volatile String serverPassword; + private String hostName; /** * Creates a new dedicated server with the specified password @@ -36,6 +37,25 @@ public class DedicatedServer { } + /** + * Change the current server password + * + * @param password + * the new server password + */ + public void setServerPassword(String password) { + serverPassword = password; + } + + /** + * Get the current server password + * + * @return the current server password + */ + public String getServerPassword() { + return serverPassword; + } + /** * Getter for host name * @@ -46,31 +66,50 @@ public class DedicatedServer { } /** - * Start the server, this blocks + * Result of server startup attempt + */ + public enum ServerStatus { + /** Server successfully started */ + STARTED, + /** Server already running on this machine */ + ALREADY_RUNNING, + /** Other error */ + ERROR + } + + /** + * Start the server * - * @throws Exception - * when there is an error during startup + * @return Whether we could start the server */ - public void start() throws Exception { - XMPPServer server = new XMPPServer(hostName); + public ServerStatus start() { + try { + XMPPServer server = new XMPPServer(hostName); - OpenStorageProviderRegistry providerRegistry = new OpenStorageProviderRegistry(); - providerRegistry.add(new ServerPasswordAuthorization()); - providerRegistry.add(new MemoryRosterManager()); - providerRegistry.add(new InMemoryRoomStorageProvider()); - providerRegistry.add(new InMemoryOccupantStorageProvider()); + OpenStorageProviderRegistry providerRegistry = new OpenStorageProviderRegistry(); + providerRegistry.add(new ServerPasswordAuthorization()); + providerRegistry.add(new MemoryRosterManager()); + providerRegistry.add(new InMemoryRoomStorageProvider()); + providerRegistry.add(new InMemoryOccupantStorageProvider()); - server.setStorageProviderRegistry(providerRegistry); - server.addEndpoint(new TCPEndpoint()); + server.setStorageProviderRegistry(providerRegistry); + server.addEndpoint(new TCPEndpoint()); - server.setTLSCertificateInfo( - getClass().getResource( - "/jrummikub/resource/bogus_mina_tls.cert").openStream(), - "boguspw"); + server.setTLSCertificateInfo( + getClass().getResource( + "/jrummikub/resource/bogus_mina_tls.cert") + .openStream(), "boguspw"); - server.start(); - MUCModule muc = new MUCModule("play"); - server.addModule(muc); + server.start(); + MUCModule muc = new MUCModule("play"); + server.addModule(muc); + return ServerStatus.STARTED; + } catch (BindException e) { + return ServerStatus.ALREADY_RUNNING; + } catch (Exception e) { + e.printStackTrace(); + return ServerStatus.ERROR; + } } @@ -95,15 +134,21 @@ public class DedicatedServer { * Main for a simple command line dedicated server * * @param args - * first argument specifies the server password, it is "jrummikub" - * when none is specified + * first argument specifies the server password, it is + * "jrummikub" when none is specified */ public static void main(String[] args) { DedicatedServer server = new DedicatedServer(args.length >= 1 ? args[0] : "jrummikub"); System.out.println("Server hostname is " + server.getHostName()); try { - server.start(); + switch (server.start()) { + case ALREADY_RUNNING: + System.out.println("Server already running"); + // fall through + case ERROR: + System.exit(1); + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/jrummikub/view/ILoginPanel.java b/src/jrummikub/view/ILoginPanel.java index 34978aa..6a18502 100644 --- a/src/jrummikub/view/ILoginPanel.java +++ b/src/jrummikub/view/ILoginPanel.java @@ -24,4 +24,35 @@ public interface ILoginPanel { */ public IEvent getCancelEvent(); + /** + * Emitted when the user presses the use dedicated server button + * + * @return the event + */ + IEvent1 getUseDedicatedServerEvent(); + + /** + * Set the server info in the login panel + * + * @param server + * the server's hostname + */ + void setServer(String server); + + /** + * Set the channel to use + * + * @param channel + * channel to use + */ + void setChannel(String channel); + + /** + * Sets whether the dedicated server is running + * + * @param running + * whether the dedicated server is running + */ + void setDedicatedServerRunning(boolean running); + } \ No newline at end of file diff --git a/src/jrummikub/view/IView.java b/src/jrummikub/view/IView.java index 6394ee0..91a2e23 100644 --- a/src/jrummikub/view/IView.java +++ b/src/jrummikub/view/IView.java @@ -284,6 +284,14 @@ public interface IView { */ public void showLoadingError(); + /** + * Show an error message when the server couldn't be started + * + * @param alreadyRunning + * true when the server is already running on this machine + */ + public void showServerStartupError(boolean alreadyRunning); + /** * Enables/disables saving in menu bar * diff --git a/src/jrummikub/view/impl/LoginPanel.java b/src/jrummikub/view/impl/LoginPanel.java index 43c7550..1ea49da 100644 --- a/src/jrummikub/view/impl/LoginPanel.java +++ b/src/jrummikub/view/impl/LoginPanel.java @@ -1,6 +1,7 @@ package jrummikub.view.impl; import java.awt.Color; +import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; @@ -27,11 +28,13 @@ import jrummikub.view.ILoginPanel; class LoginPanel extends JPanel implements ILoginPanel { private Event1 loginEvent = new Event1(); private Event cancelEvent = new Event(); + private Event1 useDedicatedServer = new Event1(); private JTextField userNameField; private JTextField serverNameField; private JTextField passwordField; private JTextField channelNameField; - + private JButton startDedicatedServerButton; + LoginPanel() { setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); @@ -40,21 +43,18 @@ class LoginPanel extends JPanel implements ILoginPanel { c.weightx = 1; c.weighty = 1; - ActionListener loginAction = new ActionListener() { + ActionListener loginAction = createInputFields(); + + c.weighty = 0; + add(startDedicatedServerButton, c); + startDedicatedServerButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { - login(); + useDedicatedServer.emit(passwordField.getText()); } - }; - - userNameField = addInputRow("Benutzername:", new JTextField()); - userNameField.addActionListener(loginAction); - serverNameField = addInputRow("Server:", new JTextField()); - serverNameField.addActionListener(loginAction); - passwordField = addInputRow("Passwort:", new JPasswordField()); - passwordField.addActionListener(loginAction); - channelNameField = addInputRow("Channel:", new JTextField()); - channelNameField.addActionListener(loginAction); + }); + + c.weighty = 1; add(Box.createVerticalGlue(), c); c.gridwidth = 1; @@ -81,7 +81,30 @@ class LoginPanel extends JPanel implements ILoginPanel { 10, 10, 10, 10))); } + private ActionListener createInputFields() { + ActionListener loginAction = new ActionListener() { + @Override + public void actionPerformed(ActionEvent arg0) { + login(); + } + }; + + userNameField = addInputRow("Benutzername:", new JTextField()); + userNameField.addActionListener(loginAction); + serverNameField = addInputRow("Server:", new JTextField()); + serverNameField.addActionListener(loginAction); + passwordField = addInputRow("Passwort:", new JPasswordField()); + passwordField.addActionListener(loginAction); + channelNameField = addInputRow("Channel:", new JTextField()); + channelNameField.addActionListener(loginAction); + startDedicatedServerButton = new JButton("Dedizierten Server starten"); + // this fixes some strange layouting bug + startDedicatedServerButton.setPreferredSize(new Dimension(500,10)); + return loginAction; + } + void resetLoginPanel() { + // TODO leer machen userNameField.setText("test1"); serverNameField.setText("universe-factory.net"); passwordField.setText(""); @@ -98,15 +121,22 @@ class LoginPanel extends JPanel implements ILoginPanel { return cancelEvent; } + @Override + public IEvent1 getUseDedicatedServerEvent() { + return useDedicatedServer; + } + private JTextField addInputRow(String label, JTextField textField) { GridBagConstraints c = new GridBagConstraints(); - c.fill = GridBagConstraints.BOTH; + c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 1; c.weightx = 1; c.weighty = 0; add(new JLabel(label), c); + c.weightx = 1; + c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = GridBagConstraints.REMAINDER; add(textField, c); return textField; @@ -116,4 +146,19 @@ class LoginPanel extends JPanel implements ILoginPanel { loginEvent.emit(new LoginData(userNameField.getText(), serverNameField .getText(), passwordField.getText(), channelNameField.getText())); } + + @Override + public void setServer(String server) { + serverNameField.setText(server); + } + + @Override + public void setChannel(String channel) { + channelNameField.setText(channel); + } + + @Override + public void setDedicatedServerRunning(boolean running) { + startDedicatedServerButton.setText(running ? "Dedizierten Server nutzen" : "Dedizierten Server starten"); + } } diff --git a/src/jrummikub/view/impl/View.java b/src/jrummikub/view/impl/View.java index 2829b1b..15142e3 100644 --- a/src/jrummikub/view/impl/View.java +++ b/src/jrummikub/view/impl/View.java @@ -187,7 +187,8 @@ public class View extends JFrame implements IView { showSettingsPanel(false); showLoginPanel(false); showGameListPanel(false); - getHandPanel().setStones(Collections.> emptyList()); + getHandPanel().setStones( + Collections.> emptyList()); getTablePanel().setStoneSets( Collections.> emptyList()); setSelectedStones(Collections. emptyList()); @@ -199,6 +200,17 @@ public class View extends JFrame implements IView { "Fehler", JOptionPane.ERROR_MESSAGE); } + @Override + public void showServerStartupError(boolean alreadyRunning) { + JOptionPane + .showMessageDialog( + this, + alreadyRunning ? "Ein XMPP-Server l\u00e4ft bereits auf diesem Computer" + : "Der Server konnte nicht gestartet werden", + "Fehler", JOptionPane.ERROR_MESSAGE); + + } + private void createFileChooser() { chooser = new JFileChooser(); FileNameExtensionFilter filter = new FileNameExtensionFilter( @@ -384,7 +396,8 @@ public class View extends JFrame implements IView { table = new TablePanel(); mainLayer.add(table); - table.setBorder(new MatteBorder(0, 0, TABLE_BORDER_WIDTH, 0, Color.BLACK)); + table.setBorder(new MatteBorder(0, 0, TABLE_BORDER_WIDTH, 0, + Color.BLACK)); playerPanel = new PlayerPanel(); mainLayer.add(playerPanel); @@ -404,9 +417,9 @@ public class View extends JFrame implements IView { sidePanel = new SidePanel(); sidePanel.setVisible(false); mainLayer.add(sidePanel); - sidePanel - .setBorder(new CompoundBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK), - new MatteBorder(0, 0, TABLE_BORDER_WIDTH, 0, Color.GRAY))); + sidePanel.setBorder(new CompoundBorder(new MatteBorder(0, 0, 0, 1, + Color.BLACK), new MatteBorder(0, 0, TABLE_BORDER_WIDTH, 0, + Color.GRAY))); } @Override @@ -599,24 +612,24 @@ public class View extends JFrame implements IView { @SuppressWarnings("unchecked") private List> createDecorationStones() { - Pair stoneJ = new Pair(new Stone(-'J', - StoneColor.BLACK), new Position(2.5f, 0)); - Pair stoneR = new Pair(new Stone(-'R', - StoneColor.ORANGE), new Position(3.5f, 0)); - Pair stoneu1 = new Pair(new Stone(-'u', - StoneColor.BLUE), new Position(4.5f, 0)); - Pair stonem1 = new Pair(new Stone(-'m', - StoneColor.RED), new Position(5.5f, 0)); - Pair stonem2 = new Pair(new Stone(-'m', - StoneColor.GREEN), new Position(6.5f, 0)); - Pair stonei = new Pair(new Stone(-'i', - StoneColor.VIOLET), new Position(7.5f, 0)); - Pair stonek = new Pair(new Stone(-'k', - StoneColor.AQUA), new Position(8.5f, 0)); - Pair stoneu2 = new Pair(new Stone(-'u', - StoneColor.GRAY), new Position(9.5f, 0)); - Pair stoneb = new Pair(new Stone(-'b', - StoneColor.BLACK), new Position(10.5f, 0)); + Pair stoneJ = new Pair(new Stone( + -'J', StoneColor.BLACK), new Position(2.5f, 0)); + Pair stoneR = new Pair(new Stone( + -'R', StoneColor.ORANGE), new Position(3.5f, 0)); + Pair stoneu1 = new Pair(new Stone( + -'u', StoneColor.BLUE), new Position(4.5f, 0)); + Pair stonem1 = new Pair(new Stone( + -'m', StoneColor.RED), new Position(5.5f, 0)); + Pair stonem2 = new Pair(new Stone( + -'m', StoneColor.GREEN), new Position(6.5f, 0)); + Pair stonei = new Pair(new Stone( + -'i', StoneColor.VIOLET), new Position(7.5f, 0)); + Pair stonek = new Pair(new Stone( + -'k', StoneColor.AQUA), new Position(8.5f, 0)); + Pair stoneu2 = new Pair(new Stone( + -'u', StoneColor.GRAY), new Position(9.5f, 0)); + Pair stoneb = new Pair(new Stone( + -'b', StoneColor.BLACK), new Position(10.5f, 0)); Pair stone1 = new Pair(new Stone( StoneColor.RED), new Position(2, 1)); @@ -631,9 +644,9 @@ public class View extends JFrame implements IView { Pair stone6 = new Pair(new Stone( StoneColor.BLACK), new Position(11, 1)); - return Arrays - .asList(stoneJ, stoneR, stoneu1, stonem1, stonem2, stonei, stonek, - stoneu2, stoneb, stone1, stone2, stone3, stone4, stone5, stone6); + return Arrays.asList(stoneJ, stoneR, stoneu1, stonem1, stonem2, stonei, + stonek, stoneu2, stoneb, stone1, stone2, stone3, stone4, + stone5, stone6); } @Override @@ -655,7 +668,8 @@ public class View extends JFrame implements IView { && (!showWinPanel) && type != null); if (type == BottomPanelType.START_GAME_PANEL) { - table.setStoneSets(Collections.> emptyList()); + table.setStoneSets(Collections + .> emptyList()); playerPanel.getHandPanel().setStones(createDecorationStones()); } -- cgit v1.2.3