Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
a0a82f8f8c
@ -261,11 +261,19 @@ Stand 17:30 Uhr:
|
|||||||
lebt. LISTL wurde auch implementiert aber noch nicht getestet.
|
lebt. LISTL wurde auch implementiert aber noch nicht getestet.
|
||||||
|
|
||||||
|
|
||||||
|
12.04.2022 - Sebastian
|
||||||
|
Nach dem durchstöbern vieler Literatur endlich die Grundidee für den Chat-GUI. Insbesondere mit Hinblick
|
||||||
|
auf Integration in einen grösseres GUI-Modul. Wir werden wohl JavaFX(openFX) verwenden.
|
||||||
|
|
||||||
ToDo:
|
ToDo:
|
||||||
Spiellogik: - Send() methode von Passenger mit Client-Server verknüpfen(Seraina)
|
Spiellogik: - Send() methode von Passenger mit Client-Server verknüpfen(Seraina)
|
||||||
- NoiseHandler (Alex)
|
- NoiseHandler (Alex)
|
||||||
- Game Zyklus implementieren (Seraina)
|
- Game Zyklus implementieren (Seraina)
|
||||||
|
|
||||||
|
|
||||||
|
08.04.2022 - 11.04.2022 - Alex
|
||||||
|
- Implementierung NoiseHandler, Verbindung mit VoteHandler
|
||||||
|
- Verbesserung der Lesbarkeit von VoteHandler (Code-Duplikate in eine Methode zusammengefasst)
|
||||||
|
|
||||||
|
14.04.2022 - Alex
|
||||||
|
- Erste Version des Spiel-Manuals
|
||||||
|
|||||||
BIN
Meilenstein III/Manual_1.0.docx
Normal file
BIN
Meilenstein III/Manual_1.0.docx
Normal file
Binary file not shown.
14
README.md
14
README.md
@ -18,9 +18,19 @@ Votes are held in the night for the ghosts to decide who will be next and during
|
|||||||
* ...
|
* ...
|
||||||
|
|
||||||
## Console Commands
|
## Console Commands
|
||||||
* /c "message" - sends a chat message to all connected players
|
* /c _message_ - sends a chat message to all players in the same lobby. If you are not in a lobby, the message will be sent to all players who are also not in a lobby.
|
||||||
* /n "name" - changes player name
|
* /b _message_ - broadcasts a message to all connected clients, regardless of lobbies.
|
||||||
|
* /w _username$message_ - sends a message to the specified user only.
|
||||||
|
* /g - create (&join) a new lobby.
|
||||||
|
* /j _1_ - join lobby 1. To join lobby 2, use /j _2_, etc.
|
||||||
|
* /l - list all connected clients and all lobbies
|
||||||
|
* /p - list all players in your lobby.
|
||||||
|
* /e - exit your lobby
|
||||||
|
* /n _name_ - changes player name. If unavailable, it adds a fun and quirky suffix
|
||||||
* /q - quit
|
* /q - quit
|
||||||
|
* /s - start game in your current lobby.
|
||||||
|
* /v 1 - vote for person 1 (same for other numbers)
|
||||||
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
...
|
...
|
||||||
|
|||||||
@ -11,8 +11,8 @@ javafx {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group 'ch.unibas.dmi.dbis'
|
group 'ch.unibas.dmi.dbis'
|
||||||
version '0.0.1-ALPHA'
|
version '0.0.2'
|
||||||
mainClassName = 'ch.unibas.dmi.dbis.cs108.multiplayer.client.Client'
|
mainClassName = 'ch.unibas.dmi.dbis.cs108.NightTrainToBudapest'
|
||||||
|
|
||||||
java {
|
java {
|
||||||
toolchain {
|
toolchain {
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
rootProject.name = 'Night Train to Budapest'
|
rootProject.name = 'NightTrainToBudapest'
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108;
|
||||||
|
|
||||||
|
import ch.unibas.dmi.dbis.cs108.multiplayer.client.Client;
|
||||||
|
import ch.unibas.dmi.dbis.cs108.multiplayer.server.Server;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.apache.logging.log4j.core.tools.picocli.CommandLine.Help.IParameterRenderer;
|
||||||
|
|
||||||
|
public class NightTrainToBudapest {
|
||||||
|
|
||||||
|
public static void main(String[] args){
|
||||||
|
try{
|
||||||
|
String clientOrServer = args[0];
|
||||||
|
if (clientOrServer.equalsIgnoreCase("client")) {
|
||||||
|
String addrString = args[1].substring(0,args[1].indexOf(":"));
|
||||||
|
InetAddress addr = InetAddress.getByName(addrString);
|
||||||
|
int port = Integer.parseInt(args[1].substring(args[1].indexOf(":") + 1));
|
||||||
|
String username = null;
|
||||||
|
if (args.length > 2) { //if the client provided a username
|
||||||
|
//StringBuilder usernamebuilder = new StringBuilder(); todo: support username with spaces.
|
||||||
|
username = args[2];
|
||||||
|
}
|
||||||
|
Client.main(addr, port, username);
|
||||||
|
} else if (clientOrServer.equalsIgnoreCase("server")) {
|
||||||
|
int port = Integer.parseInt(args[1]);
|
||||||
|
Server.main(port);
|
||||||
|
} else {
|
||||||
|
System.out.println("invalid arguments!");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println("Please give more arguments.");
|
||||||
|
System.out.println("Syntax:");
|
||||||
|
System.out.println("client <hostadress>:<port> [<username>] | server <port>");
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ClientPinger;
|
|||||||
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
|
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
|
||||||
|
|
||||||
import ch.unibas.dmi.dbis.cs108.multiplayer.server.JServerProtocolParser;
|
import ch.unibas.dmi.dbis.cs108.multiplayer.server.JServerProtocolParser;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
@ -31,7 +32,7 @@ public class Client {
|
|||||||
int position = Integer.MAX_VALUE;
|
int position = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
|
||||||
public Client(Socket socket) {
|
public Client(Socket socket, String username) {
|
||||||
try {
|
try {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
|
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
|
||||||
@ -39,12 +40,16 @@ public class Client {
|
|||||||
|
|
||||||
//sending the initial name to server.
|
//sending the initial name to server.
|
||||||
String systemName;
|
String systemName;
|
||||||
|
if (username == null) {
|
||||||
try {
|
try {
|
||||||
systemName = System.getProperty("user.name");
|
systemName = System.getProperty("user.name");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
systemName = "U.N. Owen";
|
systemName = "U.N. Owen";
|
||||||
}
|
}
|
||||||
if (systemName == null) systemName = "U.N. Owen";
|
if (systemName == null) systemName = "U.N. Owen";
|
||||||
|
} else {
|
||||||
|
systemName = username;
|
||||||
|
}
|
||||||
sendMsgToServer(Protocol.clientLogin + "$" + systemName);
|
sendMsgToServer(Protocol.clientLogin + "$" + systemName);
|
||||||
|
|
||||||
clientPinger = new ClientPinger(this, this.socket);
|
clientPinger = new ClientPinger(this, this.socket);
|
||||||
@ -183,7 +188,7 @@ public class Client {
|
|||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Scanner sc = new Scanner(System.in);
|
Scanner sc = new Scanner(System.in);
|
||||||
String hostname;
|
String hostname;
|
||||||
int port = 42069; //can be set via argument later if needed.
|
int port = 1873;
|
||||||
if (args.length < 1) {
|
if (args.length < 1) {
|
||||||
System.out.println("Enter the host's IP address (or type l for localhost)");
|
System.out.println("Enter the host's IP address (or type l for localhost)");
|
||||||
hostname = sc.next();
|
hostname = sc.next();
|
||||||
@ -196,7 +201,7 @@ public class Client {
|
|||||||
Socket socket;
|
Socket socket;
|
||||||
try {
|
try {
|
||||||
socket = new Socket(hostname, 42069);
|
socket = new Socket(hostname, 42069);
|
||||||
Client client = new Client(socket);
|
Client client = new Client(socket, null);
|
||||||
client.chatListener();
|
client.chatListener();
|
||||||
Thread cP = new Thread(client.clientPinger);
|
Thread cP = new Thread(client.clientPinger);
|
||||||
cP.start();
|
cP.start();
|
||||||
@ -209,6 +214,22 @@ public class Client {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void main(InetAddress address, int port, String username) {
|
||||||
|
Scanner sc = new Scanner(System.in);
|
||||||
|
Socket socket;
|
||||||
|
try {
|
||||||
|
socket = new Socket(address, port);
|
||||||
|
Client client = new Client(socket, username);
|
||||||
|
client.chatListener();
|
||||||
|
Thread cP = new Thread(client.clientPinger);
|
||||||
|
cP.start();
|
||||||
|
client.userInputListener(); //this one blocks.
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
System.out.println("Invalid host IP");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Socket getSocket() {
|
public Socket getSocket() {
|
||||||
return socket;
|
return socket;
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.multiplayer.client;
|
|
||||||
|
|
||||||
public class Client_01 {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Client.main(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
package ch.unibas.dmi.dbis.cs108.multiplayer.client;
|
|
||||||
|
|
||||||
public class Client_02 {
|
|
||||||
public static void main(String[] args) {
|
|
||||||
Client.main(args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui;
|
||||||
|
|
||||||
|
public class ClientController {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui;
|
||||||
|
|
||||||
|
public class ClientModel {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui;
|
||||||
|
|
||||||
|
public class ClientView {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.collections.ObservableMap;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.Control;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.RadioButton;
|
||||||
|
import javafx.scene.control.Toggle;
|
||||||
|
import javafx.scene.control.ToggleGroup;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents toggling to broadcast to everyone
|
||||||
|
*/
|
||||||
|
public class BroadcastButton extends Node implements ControlWrapper {
|
||||||
|
|
||||||
|
private static RadioButton broadcast = new RadioButton("Broadcast");
|
||||||
|
@Override
|
||||||
|
public Control getControl() {
|
||||||
|
return broadcast;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
public class ChatController {
|
||||||
|
|
||||||
|
public void setChatView(){};
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
public interface ChatMsg {
|
||||||
|
|
||||||
|
public String display(String msg);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
public interface ChatObserver {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.beans.property.BooleanProperty;
|
||||||
|
import javafx.beans.property.ObjectProperty;
|
||||||
|
import javafx.beans.property.Property;
|
||||||
|
import javafx.collections.ObservableMap;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.RadioButton;
|
||||||
|
import javafx.scene.control.Toggle;
|
||||||
|
import javafx.scene.control.ToggleGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If this is toggled than the client chat is operating in whisper mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public abstract class ChatTargetToggle extends Node implements Toggle{
|
||||||
|
|
||||||
|
BooleanProperty isToggled;
|
||||||
|
ObjectProperty<ToggleGroup> myFriends;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns The {@link ToggleGroup} to which this {@code Toggle} belongs.
|
||||||
|
*
|
||||||
|
* @return The {@link ToggleGroup} to which this {@code Toggle} belongs.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ToggleGroup getToggleGroup() {
|
||||||
|
return myFriends.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link ToggleGroup} to which this {@code Toggle} belongs.
|
||||||
|
*
|
||||||
|
* @param toggleGroup The new {@link ToggleGroup}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setToggleGroup(ToggleGroup toggleGroup) {
|
||||||
|
myFriends.bindBidirectional((Property<ToggleGroup>) toggleGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link ToggleGroup} to which this {@code Toggle} belongs.
|
||||||
|
*
|
||||||
|
* @return the toggle group property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ObjectProperty<ToggleGroup> toggleGroupProperty() {
|
||||||
|
return myFriends;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether this {@code Toggle} is selected.
|
||||||
|
*
|
||||||
|
* @return {@code true} if this {@code Toggle} is selected.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isSelected() {
|
||||||
|
return isToggled.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets this {@code Toggle} as selected or unselected.
|
||||||
|
*
|
||||||
|
* @param selected {@code true} to make this {@code Toggle} selected.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setSelected(boolean selected) {
|
||||||
|
this.isToggled.set(selected);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The selected state for this {@code Toggle}.
|
||||||
|
*
|
||||||
|
* @return the selected property
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public BooleanProperty selectedProperty() {
|
||||||
|
return isToggled;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.geometry.Orientation;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
import javafx.scene.control.SplitPane;
|
||||||
|
import javafx.scene.control.TextArea;
|
||||||
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
import javax.print.attribute.standard.OrientationRequested;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is the view of the client chat gui.
|
||||||
|
*/
|
||||||
|
public class ChatView extends Node implements NodeWithChildren, ChildNode {
|
||||||
|
|
||||||
|
|
||||||
|
private Pane root;
|
||||||
|
|
||||||
|
public void createNodeHierarchy(){
|
||||||
|
Button send = new SendButton();
|
||||||
|
AnchorPane whereTheSendFieldLives = new AnchorPane();
|
||||||
|
whereTheSendFieldLives.getChildren().add(send);
|
||||||
|
|
||||||
|
OutMsgTargetChooserNode chooseTarget = new OutMsgTargetChooserNode();
|
||||||
|
AnchorPane whereTheTargetFieldLives = new AnchorPane();
|
||||||
|
whereTheTargetFieldLives.getChildren().add(chooseTarget.getChildren());
|
||||||
|
|
||||||
|
TextArea clientOutgoingChatMsg = new TextArea();
|
||||||
|
AnchorPane whereOutTextLives = new AnchorPane();
|
||||||
|
whereOutTextLives.getChildren().add(clientOutgoingChatMsg);
|
||||||
|
|
||||||
|
|
||||||
|
TextArea target = new TextArea();
|
||||||
|
|
||||||
|
|
||||||
|
SplitPane inputOutputSeperation = new SplitPane();
|
||||||
|
SplitPane sendAndToggleSeperation = new SplitPane();
|
||||||
|
HBox buttonAndTextSeperation = new HBox();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
sendAndToggleSeperation.setOrientation(Orientation.HORIZONTAL);
|
||||||
|
sendAndToggleSeperation.getItems().add(whereTheSendFieldLives);
|
||||||
|
sendAndToggleSeperation.getItems().add(whereTheTargetFieldLives);
|
||||||
|
/*
|
||||||
|
buttonAndTextSeperation.a
|
||||||
|
buttonAndTextSeperation.getItems().add(sendAndToggleSeperation);
|
||||||
|
buttonAndTextSeperation.getItems().add()
|
||||||
|
*/
|
||||||
|
|
||||||
|
inputOutputSeperation.setOrientation(Orientation.HORIZONTAL);
|
||||||
|
inputOutputSeperation.getItems().add(sendAndToggleSeperation);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Pane getRootPane() {
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChildNode getInstance() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getChildren() {
|
||||||
|
//TODO implement
|
||||||
|
return NodeWithChildren.super.getChildren();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
|
||||||
|
public interface ChildNode {
|
||||||
|
|
||||||
|
public Pane getRootPane();
|
||||||
|
public ChildNode getInstance();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.scene.control.Control;
|
||||||
|
|
||||||
|
public interface ControlWrapper {
|
||||||
|
|
||||||
|
public Control getControl();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
public interface InChatObserver {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,225 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.beans.InvalidationListener;
|
||||||
|
import javafx.beans.property.Property;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
|
import javafx.beans.value.ObservableValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents an incoming chat message to be displayed by the clients gui. When creating
|
||||||
|
* an instance we should make sure we are also passing a String, otherwise {@code incomingChatMsg}
|
||||||
|
* will have a null value. For now the {@code getValue()} and {@code setValue(Object value)} are the
|
||||||
|
* main focus.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class InComingChMsg implements Property {
|
||||||
|
|
||||||
|
private String incomingChatMsg;
|
||||||
|
|
||||||
|
public InComingChMsg(String incomingChatMsg) {
|
||||||
|
this.incomingChatMsg = incomingChatMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InComingChMsg() {
|
||||||
|
this.incomingChatMsg = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a unidirection binding for this {@code Property}.
|
||||||
|
* <p>
|
||||||
|
* Note that JavaFX has all the bind calls implemented through weak listeners. This means the
|
||||||
|
* bound property can be garbage collected and stopped from being updated.
|
||||||
|
*
|
||||||
|
* @param observable The observable this {@code Property} should be bound to.
|
||||||
|
* @throws NullPointerException if {@code observable} is {@code null}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void bind(ObservableValue observable) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the unidirectional binding for this {@code Property}.
|
||||||
|
* <p>
|
||||||
|
* If the {@code Property} is not bound, calling this method has no effect.
|
||||||
|
*
|
||||||
|
* @see #bind(ObservableValue)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void unbind() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to check, if a {@code Property} is bound.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the {@code Property} is bound, {@code false} otherwise
|
||||||
|
* @see #bind(ObservableValue)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean isBound() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a bidirectional binding between this {@code Property} and another one. Bidirectional
|
||||||
|
* bindings exists independently of unidirectional bindings. So it is possible to add
|
||||||
|
* unidirectional binding to a property with bidirectional binding and vice-versa. However, this
|
||||||
|
* practice is discouraged.
|
||||||
|
* <p>
|
||||||
|
* It is possible to have multiple bidirectional bindings of one Property.
|
||||||
|
* <p>
|
||||||
|
* JavaFX bidirectional binding implementation use weak listeners. This means bidirectional
|
||||||
|
* binding does not prevent properties from being garbage collected.
|
||||||
|
*
|
||||||
|
* @param other the other {@code Property}
|
||||||
|
* @throws NullPointerException if {@code other} is {@code null}
|
||||||
|
* @throws IllegalArgumentException if {@code other} is {@code this}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void bindBidirectional(Property other) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a bidirectional binding between this {@code Property} and another one.
|
||||||
|
* <p>
|
||||||
|
* If no bidirectional binding between the properties exists, calling this method has no effect.
|
||||||
|
* <p>
|
||||||
|
* It is possible to unbind by a call on the second property. This code will work:
|
||||||
|
*
|
||||||
|
* <blockquote><pre>
|
||||||
|
* property1.bindBirectional(property2);
|
||||||
|
* property2.unbindBidirectional(property1);
|
||||||
|
* </pre></blockquote>
|
||||||
|
*
|
||||||
|
* @param other the other {@code Property}
|
||||||
|
* @throws NullPointerException if {@code other} is {@code null}
|
||||||
|
* @throws IllegalArgumentException if {@code other} is {@code this}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void unbindBidirectional(Property other) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the {@code Object} that contains this property. If this property is not contained in an
|
||||||
|
* {@code Object}, {@code null} is returned.
|
||||||
|
*
|
||||||
|
* @return the containing {@code Object} or {@code null}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object getBean() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of this property. If the property does not have a name, this method returns an
|
||||||
|
* empty {@code String}.
|
||||||
|
*
|
||||||
|
* @return the name or an empty {@code String}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a {@link ChangeListener} which will be notified whenever the value of the {@code
|
||||||
|
* ObservableValue} changes. If the same listener is added more than once, then it will be
|
||||||
|
* notified more than once. That is, no check is made to ensure uniqueness.
|
||||||
|
* <p>
|
||||||
|
* Note that the same actual {@code ChangeListener} instance may be safely registered for
|
||||||
|
* different {@code ObservableValues}.
|
||||||
|
* <p>
|
||||||
|
* The {@code ObservableValue} stores a strong reference to the listener which will prevent the
|
||||||
|
* listener from being garbage collected and may result in a memory leak. It is recommended to
|
||||||
|
* either unregister a listener by calling {@link #removeListener(ChangeListener) removeListener}
|
||||||
|
* after use or to use an instance of {@link WeakChangeListener} avoid this situation.
|
||||||
|
*
|
||||||
|
* @param listener The listener to register
|
||||||
|
* @throws NullPointerException if the listener is null
|
||||||
|
* @see #removeListener(ChangeListener)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addListener(ChangeListener listener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given listener from the list of listeners that are notified whenever the value of
|
||||||
|
* the {@code ObservableValue} changes.
|
||||||
|
* <p>
|
||||||
|
* If the given listener has not been previously registered (i.e. it was never added) then this
|
||||||
|
* method call is a no-op. If it had been previously added then it will be removed. If it had been
|
||||||
|
* added more than once, then only the first occurrence will be removed.
|
||||||
|
*
|
||||||
|
* @param listener The listener to remove
|
||||||
|
* @throws NullPointerException if the listener is null
|
||||||
|
* @see #addListener(ChangeListener)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removeListener(ChangeListener listener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current value of this {@code ObservableValue}
|
||||||
|
*
|
||||||
|
* @return The current value
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getValue() {
|
||||||
|
return this.incomingChatMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the wrapped value.
|
||||||
|
*
|
||||||
|
* @param value The new value
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setValue(Object value) {
|
||||||
|
this.incomingChatMsg = (String) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an {@link InvalidationListener} which will be notified whenever the {@code Observable}
|
||||||
|
* becomes invalid. If the same listener is added more than once, then it will be notified more
|
||||||
|
* than once. That is, no check is made to ensure uniqueness.
|
||||||
|
* <p>
|
||||||
|
* Note that the same actual {@code InvalidationListener} instance may be safely registered for
|
||||||
|
* different {@code Observables}.
|
||||||
|
* <p>
|
||||||
|
* The {@code Observable} stores a strong reference to the listener which will prevent the
|
||||||
|
* listener from being garbage collected and may result in a memory leak. It is recommended to
|
||||||
|
* either unregister a listener by calling {@link #removeListener(InvalidationListener)
|
||||||
|
* removeListener} after use or to use an instance of {@link WeakInvalidationListener} avoid this
|
||||||
|
* situation.
|
||||||
|
*
|
||||||
|
* @param listener The listener to register
|
||||||
|
* @throws NullPointerException if the listener is null
|
||||||
|
* @see #removeListener(InvalidationListener)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void addListener(InvalidationListener listener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the given listener from the list of listeners, that are notified whenever the value of
|
||||||
|
* the {@code Observable} becomes invalid.
|
||||||
|
* <p>
|
||||||
|
* If the given listener has not been previously registered (i.e. it was never added) then this
|
||||||
|
* method call is a no-op. If it had been previously added then it will be removed. If it had been
|
||||||
|
* added more than once, then only the first occurrence will be removed.
|
||||||
|
*
|
||||||
|
* @param listener The listener to remove
|
||||||
|
* @throws NullPointerException if the listener is null
|
||||||
|
* @see #addListener(InvalidationListener)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void removeListener(InvalidationListener listener) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.scene.Node;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any class that represents a JavaFX node and has children should implement this interface
|
||||||
|
*/
|
||||||
|
public interface NodeWithChildren {
|
||||||
|
|
||||||
|
void create();
|
||||||
|
|
||||||
|
public default Node getChildren() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createNodeHierarchy();
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
public interface OutChatObserver {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Toggle;
|
||||||
|
import javafx.scene.control.ToggleGroup;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
|
||||||
|
public class OutMsgTargetChooserNode extends ToggleGroup implements NodeWithChildren {
|
||||||
|
|
||||||
|
private Pane root;
|
||||||
|
private ObservableList<Node> targets;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void create() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node getChildren() {
|
||||||
|
return NodeWithChildren.super.getChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createNodeHierarchy() {
|
||||||
|
this.root = new HBox();
|
||||||
|
for(Node n : targets)
|
||||||
|
root.getChildren().add(n);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
public interface PropertyButton {
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.scene.Node;
|
||||||
|
import javafx.scene.control.Button;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the button in the chat to send a chat message.
|
||||||
|
*/
|
||||||
|
public class SendButton extends Button implements UINode {
|
||||||
|
|
||||||
|
|
||||||
|
public SendButton() {
|
||||||
|
super("Send");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void listen() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any class that represents a JavaFX node that takes user input should implement this interface.
|
||||||
|
*/
|
||||||
|
public interface UINode {
|
||||||
|
|
||||||
|
void listen();
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
|
||||||
|
|
||||||
|
import javafx.scene.control.Control;
|
||||||
|
import javafx.scene.control.RadioButton;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the toggle for a whisper chat.
|
||||||
|
*/
|
||||||
|
public class WhisperButton implements ControlWrapper {
|
||||||
|
|
||||||
|
private static RadioButton whisper = new RadioButton("Whisper");
|
||||||
|
@Override
|
||||||
|
public Control getControl() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -86,7 +86,7 @@ public class Protocol {
|
|||||||
public static final String clientQuitRequest = "QUITR";
|
public static final String clientQuitRequest = "QUITR";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client sends this message when they want to create a new game.
|
* Client sends this message when they want to create a new lobby (& automatically join it).
|
||||||
* Client issues this command in {@link ch.unibas.dmi.dbis.cs108.multiplayer.client.MessageFormatter}
|
* Client issues this command in {@link ch.unibas.dmi.dbis.cs108.multiplayer.client.MessageFormatter}
|
||||||
* using "/g".
|
* using "/g".
|
||||||
* First a lobby {@link Lobby} is created of which the requesting client is the admin of.
|
* First a lobby {@link Lobby} is created of which the requesting client is the admin of.
|
||||||
@ -94,7 +94,7 @@ public class Protocol {
|
|||||||
public static final String createNewLobby = "CRTLB";
|
public static final String createNewLobby = "CRTLB";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a clients' request for a list of lobbies
|
* Represents a clients' request for a list of lobbies, plus what players are in them.
|
||||||
*/
|
*/
|
||||||
public static final String listLobbies = "LISTL";
|
public static final String listLobbies = "LISTL";
|
||||||
|
|
||||||
|
|||||||
@ -115,6 +115,7 @@ public class Lobby {
|
|||||||
*/
|
*/
|
||||||
public synchronized boolean addPlayer(ClientHandler client) {
|
public synchronized boolean addPlayer(ClientHandler client) {
|
||||||
if (lobbyClients.size() < MAX_NO_OF_CLIENTS) {
|
if (lobbyClients.size() < MAX_NO_OF_CLIENTS) {
|
||||||
|
//todo: check that game hasn't started yet
|
||||||
if (clientIsInLobby(client) == -1) {
|
if (clientIsInLobby(client) == -1) {
|
||||||
lobbyClients.add(client);
|
lobbyClients.add(client);
|
||||||
ClientHandler.broadcastAnnouncementToAll(client.getClientUserName() + " has joined lobby " + this.getLobbyID());
|
ClientHandler.broadcastAnnouncementToAll(client.getClientUserName() + " has joined lobby " + this.getLobbyID());
|
||||||
|
|||||||
@ -14,7 +14,7 @@ public class Server {
|
|||||||
public static final Logger LOGGER = LogManager.getLogger();
|
public static final Logger LOGGER = LogManager.getLogger();
|
||||||
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
|
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
|
||||||
|
|
||||||
private static final int gamePort = 42069;
|
private static int gamePort;
|
||||||
private HashSet<ClientHandler> connectedClients = new HashSet<>();
|
private HashSet<ClientHandler> connectedClients = new HashSet<>();
|
||||||
private ServerSocket serverSocket;
|
private ServerSocket serverSocket;
|
||||||
Scanner sc = new Scanner(System.in);
|
Scanner sc = new Scanner(System.in);
|
||||||
@ -28,7 +28,7 @@ public class Server {
|
|||||||
*/
|
*/
|
||||||
public void startServer() {
|
public void startServer() {
|
||||||
try {
|
try {
|
||||||
System.out.println("Port 42069 is open.");
|
System.out.println("Port " + gamePort + " is open.");
|
||||||
while (!serverSocket.isClosed()) {
|
while (!serverSocket.isClosed()) {
|
||||||
Socket socket = serverSocket.accept();
|
Socket socket = serverSocket.accept();
|
||||||
ClientHandler nextClient = new ClientHandler(socket, socket.getInetAddress());
|
ClientHandler nextClient = new ClientHandler(socket, socket.getInetAddress());
|
||||||
@ -53,6 +53,19 @@ public class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
ServerSocket serverSocket = null;
|
||||||
|
gamePort = 1873;
|
||||||
|
try {
|
||||||
|
serverSocket = new ServerSocket(gamePort);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Server server = new Server(serverSocket);
|
||||||
|
server.startServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(int port) {
|
||||||
|
gamePort = port;
|
||||||
ServerSocket serverSocket = null;
|
ServerSocket serverSocket = null;
|
||||||
try {
|
try {
|
||||||
serverSocket = new ServerSocket(gamePort);
|
serverSocket = new ServerSocket(gamePort);
|
||||||
|
|||||||
Reference in New Issue
Block a user