Integrated dedicated server

git-svn-id: svn://sunsvr01.isp.uni-luebeck.de/swproj13/trunk@563 72836036-5685-4462-b002-a69064685172
This commit is contained in:
Jannis Harder 2011-06-22 01:08:54 +02:00
parent 8c6bf9781f
commit 63013dc82c
11 changed files with 332 additions and 90 deletions

View file

@ -11,7 +11,8 @@ public class MockLoginPanel implements ILoginPanel {
public MockEvent1<LoginData> loginEvent = new MockEvent1<LoginData>(); public MockEvent1<LoginData> loginEvent = new MockEvent1<LoginData>();
/** */ /** */
public MockEvent cancelEvent = new MockEvent(); public MockEvent cancelEvent = new MockEvent();
/** */
public MockEvent1<String> useDedicatedServerEvent = new MockEvent1<String>();
@Override @Override
public IEvent1<LoginData> getLoginEvent() { public IEvent1<LoginData> getLoginEvent() {
return loginEvent; return loginEvent;
@ -22,4 +23,26 @@ public class MockLoginPanel implements ILoginPanel {
return cancelEvent; return cancelEvent;
} }
@Override
public IEvent1<String> getUseDedicatedServerEvent() {
return useDedicatedServerEvent;
}
@Override
public void setServer(String server) {
// TODO Auto-generated method stub
}
@Override
public void setDedicatedServerRunning(boolean running) {
// TODO Auto-generated method stub
}
@Override
public void setChannel(String channel) {
// TODO Auto-generated method stub
}
} }

View file

@ -314,4 +314,10 @@ public class MockView implements IView {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override
public void showServerStartupError(boolean alreadyRunning) {
// TODO Auto-generated method stub
}
} }

View file

@ -5,6 +5,8 @@ import jrummikub.control.network.NetworkControl;
import jrummikub.model.GameSettings; import jrummikub.model.GameSettings;
import jrummikub.model.GameState; import jrummikub.model.GameState;
import jrummikub.model.IRoundState; import jrummikub.model.IRoundState;
import jrummikub.server.DedicatedServer;
import jrummikub.server.DedicatedServer.ServerStatus;
import jrummikub.util.Connection; import jrummikub.util.Connection;
import jrummikub.util.IListener; import jrummikub.util.IListener;
import jrummikub.util.IListener1; import jrummikub.util.IListener1;
@ -25,6 +27,7 @@ public class ApplicationControl {
private SaveControl saveControl; private SaveControl saveControl;
private GameControl gameControl; private GameControl gameControl;
private Connection tempConnection; private Connection tempConnection;
private DedicatedServer server;
private IView view; private IView view;
@ -32,7 +35,7 @@ public class ApplicationControl {
* Creates a new application control * Creates a new application control
* *
* @param view * @param view
* the view to use * the view to use
*/ */
public ApplicationControl(final IView view) { public ApplicationControl(final IView view) {
this.view = view; this.view = view;
@ -52,10 +55,11 @@ public class ApplicationControl {
saveControl.getLoadEvent().add( saveControl.getLoadEvent().add(
new IListener3<GameSettings, GameState, IRoundState>() { new IListener3<GameSettings, GameState, IRoundState>() {
@Override @Override
public void handle(GameSettings settings, GameState gameState, public void handle(GameSettings settings,
IRoundState roundState) { GameState gameState, IRoundState roundState) {
abortControls(); abortControls();
gameControl = new GameControl(settings, saveControl, view); gameControl = new GameControl(settings, saveControl,
view);
addGameControlListeners(gameControl); addGameControlListeners(gameControl);
gameControl.continueGame(gameState, roundState); gameControl.continueGame(gameState, roundState);
} }
@ -132,7 +136,7 @@ public class ApplicationControl {
* Create a new network login control * Create a new network login control
*/ */
private void createLoginControl(boolean reset) { private void createLoginControl(boolean reset) {
loginControl = new LoginControl(view); loginControl = new LoginControl(view, this);
loginControl.getLoginEvent().add(new IListener1<LoginData>() { loginControl.getLoginEvent().add(new IListener1<LoginData>() {
@Override @Override
public void handle(LoginData loginData) { public void handle(LoginData loginData) {
@ -250,4 +254,51 @@ public class ApplicationControl {
networkControl.startNetwork(); 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());
}
}
} }

View file

@ -18,6 +18,7 @@ import jrummikub.view.IView;
* *
*/ */
public class LoginControl { public class LoginControl {
private ApplicationControl appControl;
private IView view; private IView view;
private Event1<LoginData> loginEvent = new Event1<LoginData>(); private Event1<LoginData> loginEvent = new Event1<LoginData>();
private Event cancelEvent = new Event(); private Event cancelEvent = new Event();
@ -28,14 +29,18 @@ public class LoginControl {
* *
* @param view * @param view
* for events which need handling * 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; this.view = view;
connections.add(view.getLoginPanel().getLoginEvent() connections.add(view.getLoginPanel().getLoginEvent()
.add(new IListener1<LoginData>() { .add(new IListener1<LoginData>() {
@Override @Override
public void handle(LoginData loginData) { public void handle(LoginData loginData) {
abort(); abort();
appControl.updateDedicatedServerPassword(loginData);
loginEvent.emit(loginData); loginEvent.emit(loginData);
} }
})); }));
@ -48,6 +53,12 @@ public class LoginControl {
cancelEvent.emit(); cancelEvent.emit();
} }
})); }));
connections.add(view.getLoginPanel().getUseDedicatedServerEvent().add(new IListener1<String>() {
@Override
public void handle(String value) {
appControl.startDedicatedServer(value);
}
}));
} }
/** /**

View file

@ -2,6 +2,8 @@ package jrummikub.control.network;
import java.awt.Color; import java.awt.Color;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue; 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 Connection connection;
private volatile MultiUserChat muc; private volatile MultiUserChat muc;
@ -125,7 +127,7 @@ public class ConnectionControl implements IConnectionControl {
* Creates new connection control * Creates new connection control
* *
* @param loginData * @param loginData
* player's login data * player's login data
*/ */
public ConnectionControl(LoginData loginData) { public ConnectionControl(LoginData loginData) {
this.loginData = loginData; this.loginData = loginData;
@ -346,7 +348,8 @@ public class ConnectionControl implements IConnectionControl {
protected void addData(DefaultPacketExtension extension) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "change_color"); extension.setValue("messageType", "change_color");
extension.setValue("uuid", uuid.toString()); 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) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "table_update"); extension.setValue("messageType", "table_update");
extension.setValue("uuid", uuid.toString()); 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) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "turn_end"); extension.setValue("messageType", "turn_end");
extension.setValue("uuid", uuid.toString()); extension.setValue("uuid", uuid.toString());
extension.setValue("data", Base64.encodeObject(new TurnEndData(state, extension.setValue("data", Base64.encodeObject(new TurnEndData(
invalidTurnInfo), Base64.GZIP)); state, invalidTurnInfo), Base64.GZIP));
} }
}); });
} }
@ -460,8 +464,8 @@ public class ConnectionControl implements IConnectionControl {
protected void addData(DefaultPacketExtension extension) { protected void addData(DefaultPacketExtension extension) {
extension.setValue("messageType", "game_offer"); extension.setValue("messageType", "game_offer");
extension.setValue("uuid", data.getGameID().toString()); extension.setValue("uuid", data.getGameID().toString());
extension.setValue("gameSettings", extension.setValue("gameSettings", Base64.encodeObject(
Base64.encodeObject(data.getGameSettings(), Base64.GZIP)); data.getGameSettings(), Base64.GZIP));
} }
}); });
} }
@ -512,8 +516,8 @@ public class ConnectionControl implements IConnectionControl {
.getExtension(ELEMENT_NAME, NAMESPACE); .getExtension(ELEMENT_NAME, NAMESPACE);
if (((Message) packet).getType() == Message.Type.error) { 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; return;
} }
@ -529,14 +533,15 @@ public class ConnectionControl implements IConnectionControl {
String sender, String messageType) { String sender, String messageType) {
if (messageType.equals("game_offer")) { if (messageType.equals("game_offer")) {
UUID uuid = UUID.fromString(extension.getValue("uuid")); UUID uuid = UUID.fromString(extension.getValue("uuid"));
GameSettings settings = (GameSettings) Base64.decodeToObject(extension GameSettings settings = (GameSettings) Base64
.getValue("gameSettings")); .decodeToObject(extension.getValue("gameSettings"));
fixGameSettings(settings); fixGameSettings(settings);
GameData gameData = new GameData(uuid, settings, sender); GameData gameData = new GameData(uuid, settings, sender);
gameOfferEvent.emit(gameData); gameOfferEvent.emit(gameData);
} else if (messageType.equals("game_withdrawal")) { } 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")) { } else if (messageType.equals("game_request")) {
if (offeredGame != null) { if (offeredGame != null) {
sendGameOffer(); sendGameOffer();
@ -649,7 +654,8 @@ public class ConnectionControl implements IConnectionControl {
XMPPError xmppError = e.getXMPPError(); XMPPError xmppError = e.getXMPPError();
if (xmppError != null) { if (xmppError != null) {
if (xmppError.getType() == Type.WAIT && xmppError.getCode() == 504) { if (xmppError.getType() == Type.WAIT
&& xmppError.getCode() == 504) {
return LoginError.UNKNOWN_HOST; return LoginError.UNKNOWN_HOST;
} }
} }
@ -661,7 +667,8 @@ public class ConnectionControl implements IConnectionControl {
private LoginError doLogin() { private LoginError doLogin() {
try { try {
connection.login(loginData.getUserName(), loginData.getPassword(), connection.login(loginData.getUserName(),
loginData.getPassword(),
"JRummikub-" + StringUtils.randomString(8)); "JRummikub-" + StringUtils.randomString(8));
return null; return null;
} catch (XMPPException e) { } catch (XMPPException e) {
@ -691,7 +698,8 @@ public class ConnectionControl implements IConnectionControl {
continue; continue;
} else { } else {
// An unknown error has occurred, cancel connect // An unknown error has occurred, cancel connect
if (xmppError != null && xmppError.getType() == Type.CANCEL if (xmppError != null
&& xmppError.getType() == Type.CANCEL
&& xmppError.getCode() == 404) { && xmppError.getCode() == 404) {
return LoginError.UNKNOWN_CHANNEL; return LoginError.UNKNOWN_CHANNEL;
} }

View file

@ -1,5 +1,6 @@
package jrummikub.server; package jrummikub.server;
import java.net.BindException;
import java.net.InetAddress; import java.net.InetAddress;
import org.apache.vysper.mina.TCPEndpoint; 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 * Implements a simple XMPP server with a global server password
*/ */
public class DedicatedServer { public class DedicatedServer {
String serverPassword; private volatile String serverPassword;
String hostName; private String hostName;
/** /**
* Creates a new dedicated server with the specified password * 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 * Getter for host name
* *
@ -46,31 +66,50 @@ public class DedicatedServer {
} }
/** /**
* Start the server, this blocks * Result of server startup attempt
*
* @throws Exception
* when there is an error during startup
*/ */
public void start() throws Exception { public enum ServerStatus {
XMPPServer server = new XMPPServer(hostName); /** Server successfully started */
STARTED,
/** Server already running on this machine */
ALREADY_RUNNING,
/** Other error */
ERROR
}
OpenStorageProviderRegistry providerRegistry = new OpenStorageProviderRegistry(); /**
providerRegistry.add(new ServerPasswordAuthorization()); * Start the server
providerRegistry.add(new MemoryRosterManager()); *
providerRegistry.add(new InMemoryRoomStorageProvider()); * @return Whether we could start the server
providerRegistry.add(new InMemoryOccupantStorageProvider()); */
public ServerStatus start() {
try {
XMPPServer server = new XMPPServer(hostName);
server.setStorageProviderRegistry(providerRegistry); OpenStorageProviderRegistry providerRegistry = new OpenStorageProviderRegistry();
server.addEndpoint(new TCPEndpoint()); providerRegistry.add(new ServerPasswordAuthorization());
providerRegistry.add(new MemoryRosterManager());
providerRegistry.add(new InMemoryRoomStorageProvider());
providerRegistry.add(new InMemoryOccupantStorageProvider());
server.setTLSCertificateInfo( server.setStorageProviderRegistry(providerRegistry);
getClass().getResource( server.addEndpoint(new TCPEndpoint());
"/jrummikub/resource/bogus_mina_tls.cert").openStream(),
"boguspw");
server.start(); server.setTLSCertificateInfo(
MUCModule muc = new MUCModule("play"); getClass().getResource(
server.addModule(muc); "/jrummikub/resource/bogus_mina_tls.cert")
.openStream(), "boguspw");
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 * Main for a simple command line dedicated server
* *
* @param args * @param args
* first argument specifies the server password, it is "jrummikub" * first argument specifies the server password, it is
* when none is specified * "jrummikub" when none is specified
*/ */
public static void main(String[] args) { public static void main(String[] args) {
DedicatedServer server = new DedicatedServer(args.length >= 1 ? args[0] DedicatedServer server = new DedicatedServer(args.length >= 1 ? args[0]
: "jrummikub"); : "jrummikub");
System.out.println("Server hostname is " + server.getHostName()); System.out.println("Server hostname is " + server.getHostName());
try { 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) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View file

@ -24,4 +24,35 @@ public interface ILoginPanel {
*/ */
public IEvent getCancelEvent(); public IEvent getCancelEvent();
/**
* Emitted when the user presses the use dedicated server button
*
* @return the event
*/
IEvent1<String> 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);
} }

View file

@ -284,6 +284,14 @@ public interface IView {
*/ */
public void showLoadingError(); 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 * Enables/disables saving in menu bar
* *

View file

@ -1,6 +1,7 @@
package jrummikub.view.impl; package jrummikub.view.impl;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.GridBagLayout; import java.awt.GridBagLayout;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -27,11 +28,13 @@ import jrummikub.view.ILoginPanel;
class LoginPanel extends JPanel implements ILoginPanel { class LoginPanel extends JPanel implements ILoginPanel {
private Event1<LoginData> loginEvent = new Event1<LoginData>(); private Event1<LoginData> loginEvent = new Event1<LoginData>();
private Event cancelEvent = new Event(); private Event cancelEvent = new Event();
private Event1<String> useDedicatedServer = new Event1<String>();
private JTextField userNameField; private JTextField userNameField;
private JTextField serverNameField; private JTextField serverNameField;
private JTextField passwordField; private JTextField passwordField;
private JTextField channelNameField; private JTextField channelNameField;
private JButton startDedicatedServerButton;
LoginPanel() { LoginPanel() {
setLayout(new GridBagLayout()); setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints(); GridBagConstraints c = new GridBagConstraints();
@ -40,21 +43,18 @@ class LoginPanel extends JPanel implements ILoginPanel {
c.weightx = 1; c.weightx = 1;
c.weighty = 1; c.weighty = 1;
ActionListener loginAction = new ActionListener() { ActionListener loginAction = createInputFields();
c.weighty = 0;
add(startDedicatedServerButton, c);
startDedicatedServerButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent arg0) { public void actionPerformed(ActionEvent arg0) {
login(); useDedicatedServer.emit(passwordField.getText());
} }
}; });
userNameField = addInputRow("Benutzername:", new JTextField()); c.weighty = 1;
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);
add(Box.createVerticalGlue(), c); add(Box.createVerticalGlue(), c);
c.gridwidth = 1; c.gridwidth = 1;
@ -81,7 +81,30 @@ class LoginPanel extends JPanel implements ILoginPanel {
10, 10, 10, 10))); 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() { void resetLoginPanel() {
// TODO leer machen
userNameField.setText("test1"); userNameField.setText("test1");
serverNameField.setText("universe-factory.net"); serverNameField.setText("universe-factory.net");
passwordField.setText(""); passwordField.setText("");
@ -98,15 +121,22 @@ class LoginPanel extends JPanel implements ILoginPanel {
return cancelEvent; return cancelEvent;
} }
@Override
public IEvent1<String> getUseDedicatedServerEvent() {
return useDedicatedServer;
}
private JTextField addInputRow(String label, JTextField textField) { private JTextField addInputRow(String label, JTextField textField) {
GridBagConstraints c = new GridBagConstraints(); GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.BOTH; c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 1; c.gridwidth = 1;
c.weightx = 1; c.weightx = 1;
c.weighty = 0; c.weighty = 0;
add(new JLabel(label), c); add(new JLabel(label), c);
c.weightx = 1;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = GridBagConstraints.REMAINDER; c.gridwidth = GridBagConstraints.REMAINDER;
add(textField, c); add(textField, c);
return textField; return textField;
@ -116,4 +146,19 @@ class LoginPanel extends JPanel implements ILoginPanel {
loginEvent.emit(new LoginData(userNameField.getText(), serverNameField loginEvent.emit(new LoginData(userNameField.getText(), serverNameField
.getText(), passwordField.getText(), channelNameField.getText())); .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");
}
} }

View file

@ -187,7 +187,8 @@ public class View extends JFrame implements IView {
showSettingsPanel(false); showSettingsPanel(false);
showLoginPanel(false); showLoginPanel(false);
showGameListPanel(false); showGameListPanel(false);
getHandPanel().setStones(Collections.<Pair<Stone, Position>> emptyList()); getHandPanel().setStones(
Collections.<Pair<Stone, Position>> emptyList());
getTablePanel().setStoneSets( getTablePanel().setStoneSets(
Collections.<Pair<StoneSet, Position>> emptyList()); Collections.<Pair<StoneSet, Position>> emptyList());
setSelectedStones(Collections.<Stone> emptyList()); setSelectedStones(Collections.<Stone> emptyList());
@ -199,6 +200,17 @@ public class View extends JFrame implements IView {
"Fehler", JOptionPane.ERROR_MESSAGE); "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() { private void createFileChooser() {
chooser = new JFileChooser(); chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter( FileNameExtensionFilter filter = new FileNameExtensionFilter(
@ -384,7 +396,8 @@ public class View extends JFrame implements IView {
table = new TablePanel(); table = new TablePanel();
mainLayer.add(table); 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(); playerPanel = new PlayerPanel();
mainLayer.add(playerPanel); mainLayer.add(playerPanel);
@ -404,9 +417,9 @@ public class View extends JFrame implements IView {
sidePanel = new SidePanel(); sidePanel = new SidePanel();
sidePanel.setVisible(false); sidePanel.setVisible(false);
mainLayer.add(sidePanel); mainLayer.add(sidePanel);
sidePanel sidePanel.setBorder(new CompoundBorder(new MatteBorder(0, 0, 0, 1,
.setBorder(new CompoundBorder(new MatteBorder(0, 0, 0, 1, Color.BLACK), Color.BLACK), new MatteBorder(0, 0, TABLE_BORDER_WIDTH, 0,
new MatteBorder(0, 0, TABLE_BORDER_WIDTH, 0, Color.GRAY))); Color.GRAY)));
} }
@Override @Override
@ -599,24 +612,24 @@ public class View extends JFrame implements IView {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private List<Pair<Stone, Position>> createDecorationStones() { private List<Pair<Stone, Position>> createDecorationStones() {
Pair<Stone, Position> stoneJ = new Pair<Stone, Position>(new Stone(-'J', Pair<Stone, Position> stoneJ = new Pair<Stone, Position>(new Stone(
StoneColor.BLACK), new Position(2.5f, 0)); -'J', StoneColor.BLACK), new Position(2.5f, 0));
Pair<Stone, Position> stoneR = new Pair<Stone, Position>(new Stone(-'R', Pair<Stone, Position> stoneR = new Pair<Stone, Position>(new Stone(
StoneColor.ORANGE), new Position(3.5f, 0)); -'R', StoneColor.ORANGE), new Position(3.5f, 0));
Pair<Stone, Position> stoneu1 = new Pair<Stone, Position>(new Stone(-'u', Pair<Stone, Position> stoneu1 = new Pair<Stone, Position>(new Stone(
StoneColor.BLUE), new Position(4.5f, 0)); -'u', StoneColor.BLUE), new Position(4.5f, 0));
Pair<Stone, Position> stonem1 = new Pair<Stone, Position>(new Stone(-'m', Pair<Stone, Position> stonem1 = new Pair<Stone, Position>(new Stone(
StoneColor.RED), new Position(5.5f, 0)); -'m', StoneColor.RED), new Position(5.5f, 0));
Pair<Stone, Position> stonem2 = new Pair<Stone, Position>(new Stone(-'m', Pair<Stone, Position> stonem2 = new Pair<Stone, Position>(new Stone(
StoneColor.GREEN), new Position(6.5f, 0)); -'m', StoneColor.GREEN), new Position(6.5f, 0));
Pair<Stone, Position> stonei = new Pair<Stone, Position>(new Stone(-'i', Pair<Stone, Position> stonei = new Pair<Stone, Position>(new Stone(
StoneColor.VIOLET), new Position(7.5f, 0)); -'i', StoneColor.VIOLET), new Position(7.5f, 0));
Pair<Stone, Position> stonek = new Pair<Stone, Position>(new Stone(-'k', Pair<Stone, Position> stonek = new Pair<Stone, Position>(new Stone(
StoneColor.AQUA), new Position(8.5f, 0)); -'k', StoneColor.AQUA), new Position(8.5f, 0));
Pair<Stone, Position> stoneu2 = new Pair<Stone, Position>(new Stone(-'u', Pair<Stone, Position> stoneu2 = new Pair<Stone, Position>(new Stone(
StoneColor.GRAY), new Position(9.5f, 0)); -'u', StoneColor.GRAY), new Position(9.5f, 0));
Pair<Stone, Position> stoneb = new Pair<Stone, Position>(new Stone(-'b', Pair<Stone, Position> stoneb = new Pair<Stone, Position>(new Stone(
StoneColor.BLACK), new Position(10.5f, 0)); -'b', StoneColor.BLACK), new Position(10.5f, 0));
Pair<Stone, Position> stone1 = new Pair<Stone, Position>(new Stone( Pair<Stone, Position> stone1 = new Pair<Stone, Position>(new Stone(
StoneColor.RED), new Position(2, 1)); StoneColor.RED), new Position(2, 1));
@ -631,9 +644,9 @@ public class View extends JFrame implements IView {
Pair<Stone, Position> stone6 = new Pair<Stone, Position>(new Stone( Pair<Stone, Position> stone6 = new Pair<Stone, Position>(new Stone(
StoneColor.BLACK), new Position(11, 1)); StoneColor.BLACK), new Position(11, 1));
return Arrays return Arrays.asList(stoneJ, stoneR, stoneu1, stonem1, stonem2, stonei,
.asList(stoneJ, stoneR, stoneu1, stonem1, stonem2, stonei, stonek, stonek, stoneu2, stoneb, stone1, stone2, stone3, stone4,
stoneu2, stoneb, stone1, stone2, stone3, stone4, stone5, stone6); stone5, stone6);
} }
@Override @Override
@ -655,7 +668,8 @@ public class View extends JFrame implements IView {
&& (!showWinPanel) && type != null); && (!showWinPanel) && type != null);
if (type == BottomPanelType.START_GAME_PANEL) { if (type == BottomPanelType.START_GAME_PANEL) {
table.setStoneSets(Collections.<Pair<StoneSet, Position>> emptyList()); table.setStoneSets(Collections
.<Pair<StoneSet, Position>> emptyList());
playerPanel.getHandPanel().setStones(createDecorationStones()); playerPanel.getHandPanel().setStones(createDecorationStones());
} }

View file

@ -19,7 +19,7 @@ public class LoginControlTest {
@Before @Before
public void setup() { public void setup() {
view = new MockView(); view = new MockView();
loginControl = new LoginControl(view); loginControl = new LoginControl(view, new ApplicationControl(view));
loginControl.startLogin(true); loginControl.startLogin(true);
} }