Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java
This commit is contained in:
Sebastian Lenzlinger 2022-05-02 00:17:18 +02:00
commit 802b8d1154
30 changed files with 1748 additions and 450 deletions

View File

@ -340,4 +340,21 @@ Paralleles Arbeiten an zugewiesenen Aufgaben, ggf. mit gegenseitiger Unterstütz
Alex: unit tests
30.04.2022 - Alex
Finished creating unit tests for noise handling in the game (do players the ghosts walk by in the night receive the right amount of noise notifications?). Might be final version for milestone 4 if noone objects.
Habe Unit Tests zum NoiseHandler abgeschlossen (bekommen die Spieler, an denen nachts Geister vorbeilaufen, die richtige Anzahl an noise-Benachrichtigungen?).
29.04.2022 - Seraina
Habe die GUI View für das Game erstellt und die Controllerklasse mit allen relevanten methoden für das Spielen des Spiels via GUI ausgestattet.
TODO: Testen der Funktionalitäten und verschmelzung mit den weiternen Views (Sebi) und der Applikation
30.04.2022 - Seraina und Sebi
Gemeinsames arbeiten an Gui.
Seraina: Zu früh gefreut, fast alle der Methoden im GameController mussten überarbeitet werden. Habe nach etlichen Stunden aber alle wichtigen Funktionen zum Laufen gebracht. TODO: Glätte die Bugs v.A. in den noiseNotifications.
Sebi: Habe die implementation der LobbyView fast fertig TODO: Testen der Lobby
01.04.2022 - Seraina & Sebi
Geimeinsames Troubleshooting der GUI.
Alle Views sind verschmolzen und das Gameplay funktioniert soweit ganz gut. Hatten Probleme bei der darstellung der LobbyListView, war
wiedermal ein Problem das mit static gelöst werden konnte. Die ClientListe und die Aktualisierung der LobbyListe funktioniert aber noch nicht (TODO).
01.04.2022 - Seraina
Habe Highscore und Players in Lobbies auf die einfachst mögliche Art mit Textflow implementiret, falls die ListViews bis morgen nicht funktionieren sollten.

View File

@ -1 +1,4 @@
B
serai
serai
serai

View File

@ -19,7 +19,7 @@ public class BudaLogConfig {
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration config = ctx.getConfiguration();
LoggerConfig loggerConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
loggerConfig.setLevel(Level.INFO); // change level here
loggerConfig.setLevel(Level.DEBUG); // change level here
ctx.updateLoggers(); // This causes all Loggers to refetch information from their LoggerConfig.
}

View File

@ -17,8 +17,8 @@ public class ClientGameInfoHandler {
public static final String ghostVoteRequest = "Vote on who to ghostify!";
public static final String humanVoteRequest = "Vote for a ghost to kick off!";
public static final String noiseNotification = "Someone passed by you ";
public static final String gameOverHumansWin = "Game over: humans win!";
public static final String gameOverGhostsWin = "Game over: ghosts win!";
public static final String gameOverHumansWin = "Game over, humans win!";
public static final String gameOverGhostsWin = "Game over, ghosts win!";
//relevant for gui
public static final String itsNightTime = "Please wait, ghosts are active";

View File

@ -95,7 +95,7 @@ public class Game implements Runnable {
passenger.send(GuiParameters.updateGameState, getGame());
}
try {
Thread.sleep(4000); //TODO: Is this a good intervall?
Thread.sleep(2000); //TODO: Is this a good intervall?
} catch (InterruptedException e) {
e.printStackTrace();
}
@ -148,27 +148,33 @@ public class Game implements Runnable {
}
LOGGER.info(gameState.toString());
gameStateModelUpdater(); //TODO: does that work?
for(Passenger passenger : gameState.getPassengerTrain()) {
passenger.send(Protocol.positionOfClient + "$" + passenger.getPosition(), this);
}
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.night + "$");
i = 0;
while (isOngoing) {//game cycle TODO: maybe check that more often inside game loop?!
if (!isDay) {
LOGGER.info("NIGHT");
gameOverCheck = voteHandler.ghostVote(gameState.getPassengerTrain(), this);
setDay(true);
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + ClientGameInfoHandler.itsDayTime + "$");
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.day + "$");
} else {
LOGGER.info("DAY");
gameOverCheck = voteHandler.humanVote(gameState.getPassengerTrain(), this);
setDay(false);
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + ClientGameInfoHandler.itsNightTime + "$");
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.night + "$");
}
if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) || gameOverCheck.equals(
ClientGameInfoHandler.gameOverHumansWin)) {
if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) && getOgGhost().getIsPlayer()) {
OgGhostHighScore.addOgGhostWinner(getOgGhost().getName());
}
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToLobby + "$");
lobby.getAdmin().broadcastAnnouncementToLobby(gameOverCheck);
isOngoing = false;
Timer.ghostAfterVoteTimer();
lobby.getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToLobby + "$");
isOngoing = true;
lobby.removeGameFromRunningGames(this);
lobby.addGameToFinishedGames(this);
return;

View File

@ -167,13 +167,14 @@ public class GameState {
} else if (array[i].getIsGhost()) {
print[i] = array[i].getName() + ":g:" + array[i].getKickedOff();
} else {
print[i] = "| " + array[i].getName() + ":h:" + array[i].getKickedOff();
print[i] = array[i].getName() + ":h:" + array[i].getKickedOff();
}
}
for (int i = 0; i < array.length; i++) {
stringBuilder.append("$").append(print[i]);
}
stringBuilder.append("$");
return stringBuilder.toString();
}
@ -194,6 +195,7 @@ public class GameState {
for (int i = 0; i < array.length; i++) {
stringBuilder.append("$").append(print[i]);
}
stringBuilder.append("$");
return stringBuilder.toString();
}

View File

@ -30,15 +30,19 @@ public class ServerGameInfoHandler {
public static String format(String msg, Passenger passenger, Game game) {
switch (msg) {
case ClientGameInfoHandler.ghostVoteRequest:
msg = Protocol.serverRequestsGhostVote + "$" + passenger.getPosition() + "$"
+ game.gameState.toString();
msg = Protocol.serverRequestsGhostVote + "$" + passenger.getPosition() + "$";
passenger.getClientHandler().sendMsgToClient(Protocol.printToClientConsole + "$" + ClientGameInfoHandler.ghostVoteRequest);
break;
case ClientGameInfoHandler.humanVoteRequest:
msg = Protocol.serverRequestsHumanVote + "$" + passenger.getPosition() + "$"
+ game.gameState.humanToString();
msg = Protocol.serverRequestsHumanVote + "$" + passenger.getPosition() + "$";
passenger.getClientHandler().sendMsgToClient(Protocol.printToClientConsole + "$" + ClientGameInfoHandler.humanVoteRequest);
break;
default:
if(!msg.contains("$")) {
msg = Protocol.printToClientConsole + "$" + msg;
} else {
msg = msg;
}
}
LOGGER.debug(msg);
return msg;
@ -56,17 +60,21 @@ public class ServerGameInfoHandler {
switch (msg) {
case ClientGameInfoHandler.ghostVoteRequest:
case ClientGameInfoHandler.itsNightTime:
msg = Protocol.printToClientConsole + "$Ghosts are voting: " + game.gameState.toString();
msg = Protocol.printToClientConsole + "$Ghosts are voting";
break;
case ClientGameInfoHandler.humanVoteRequest:
case ClientGameInfoHandler.itsDayTime:
msg = Protocol.printToClientConsole + "$Humans are voting:" + game.gameState.toString();
msg = Protocol.printToClientConsole + "$Humans are voting";
break;
case GuiParameters.updateGameState:
msg = Protocol.printToGUI + "$" + GuiParameters.updateGameState + game.getGameState().toString();
break;
default:
if(!msg.contains("$")) {
msg = Protocol.printToClientConsole + "$" + msg;
} else {
msg = msg;
}
}
LOGGER.debug(msg);
return msg;
@ -114,9 +122,12 @@ public class ServerGameInfoHandler {
case ClientGameInfoHandler.noiseNotification + 5 + " time(s)":
String outMsg = npc.getName() + ": " + noiseRandomizer();
//TODO: add likelyhood
if(!npc.getKickedOff()) {
game.getLobby().getAdmin().broadcastNpcChatMessageToLobby(outMsg);
game.getLobby().getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + GuiParameters.noiseHeardAtPosition
+ "$" + npc.getPosition() + "$");
game.getLobby().getAdmin().sendMsgToClientsInLobby(
Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition
+ "$" + npc.getPosition());
}
break;
case ClientGameInfoHandler.ghostVoteRequest:
npc.vote(game);
@ -138,9 +149,12 @@ public class ServerGameInfoHandler {
case ClientGameInfoHandler.noiseNotification + 4 + " time(s)":
case ClientGameInfoHandler.noiseNotification + 5 + " time(s)":
String outMsg = npc.getName() + ": " + noiseRandomizer();
if(!npc.getKickedOff()) {
game.getLobby().getAdmin().broadcastNpcChatMessageToLobby(outMsg);
game.getLobby().getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + GuiParameters.noiseHeardAtPosition
+ "$" + npc.getPosition() + "$");
game.getLobby().getAdmin().sendMsgToClientsInLobby(
Protocol.printToGUI + "$" + GuiParameters.noiseHeardAtPosition
+ "$" + npc.getPosition());
}
break;
case ClientGameInfoHandler.humanVoteRequest:
npc.vote(game);

View File

@ -22,7 +22,7 @@ public class Timer {
* The length of time in seconds after the ghost vote during which the ghosts visually walk to /
* from their victim and the timespan within which humans will hear a noise. After this, the day starts.
*/
public static final int ghostAfterVoteTime = 7;
public static final int ghostAfterVoteTime = 4;
/**
* The maximum length of the human vote in the day, in seconds
*/
@ -39,6 +39,11 @@ public class Timer {
*/
public static final int interval = 1;
/**
* The minimal vote time, in seconds
*/
public static final int minVoteTime = 5;
/**
* The timer for the ghost vote. Checks every {@code interval} seconds if every ghost has already voted.
* If all have voted or if the {@code ghostVoteTime} value is reached, the timer ends
@ -47,7 +52,7 @@ public class Timer {
public static void ghostVoteTimer(Game game) {
int counter = 0;
while(counter < ghostVoteTime) {
if(haveAllGhostsVoted(game)) { //if all ghost have voted
if(haveAllGhostsVoted(game) && counter > minVoteTime) { //if all ghost have voted
return;
}
try {
@ -62,7 +67,7 @@ public class Timer {
public static void humanVoteTimer(Game game) {
int counter = 0;
while (counter < humanVoteTime) {
if (haveAllHumansVoted(game)) return;
if (haveAllHumansVoted(game) && counter > minVoteTime) return;
try {
Thread.sleep(interval*1000);
} catch (InterruptedException e) {
@ -107,6 +112,8 @@ public class Timer {
/**
* Checks if all humans have already voted, returns true if so, else returns false
* @param game the game this is called in
* @return returns true if all humans have voted
*/
public static boolean haveAllHumansVoted(Game game) {
boolean[] whoHasVoted = game.getGameState().getClientVoteData().getHasVoted();

View File

@ -2,6 +2,8 @@ package ch.unibas.dmi.dbis.cs108.gamelogic;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -66,7 +68,6 @@ public class VoteHandler {
}
}
LOGGER.info("Most votes for: " + newGhostPosition);
for(Passenger passenger : passengers) {
if(passenger.getIsGhost() || passenger.getIsSpectator()) {
passenger.send(passengers[newGhostPosition].getName() + ClientGameInfoHandler.gotGhostyfied, game);
@ -85,7 +86,6 @@ public class VoteHandler {
walk by is being updated. Finally, each passenger receives information about how often he heard something during
this night. The player who's just been ghostified is ignored since he didn't participate in this night's
ghostification. */
int[] noiseAmount = new int[6];
for (int i = 0; i < passengers.length; i++) {
if (passengers[i].getIsGhost() && i != newGhostPosition) {
@ -152,6 +152,7 @@ public class VoteHandler {
}
Timer.humanVoteTimer(game);
game.getLobby().getAdmin().sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.VoteIsOver + "$");
int currentMax = humanVoteEvaluation(passengers, votesForPlayers, game.getGameState().getClientVoteData(), game);
@ -170,6 +171,7 @@ public class VoteHandler {
ClientGameInfoHandler.humansVotedFor + voteIndex + ClientGameInfoHandler.isAHuman, game);
}
}
Timer.ghostAfterVoteTimer();
if (passengers[voteIndex].getIsGhost()) { // if player is a ghost
if (passengers[voteIndex].getIsOG()) { // if ghost is OG --> end game, humans win
System.out.println(ClientGameInfoHandler.gameOverHumansWin);

View File

@ -31,8 +31,9 @@ public class HumanNPC extends Human {
}
/**
* Sends a msg to the ServerGameInfoHandler.humanNpcParser to decide what has to happen now, if the
* npc hasn't been kicked off 8(should never happen to a human though)
* Sends a msg to the ServerGameInfoHandler.humanNpcParser to decide what has to happen now, if
* the npc hasn't been kicked off 8(should never happen to a human though)
*
* @param msg the message that is sent to this player.
* @param game the game the HumanNPC lives on (in game.gameState.passengerTrain)
*/
@ -44,22 +45,23 @@ public class HumanNPC extends Human {
}
/**
* Currently returns a random integer for voting, but only for passengers that haven't been
* kicked off yet
* Currently returns a random integer for voting, but only for passengers that haven't been kicked
* off yet
*
* @param game the game this NPC lives on
*/
public void vote(Game game) {
Passenger[] passengers = game.getGameState().getPassengerTrain();
int kickedOffCounter = 0;
for(Passenger passenger : passengers) {
if(passenger.getKickedOff()) {
for (Passenger passenger : passengers) {
if (passenger.getKickedOff()) {
kickedOffCounter++;
}
}
int[] inGamePositions = new int[passengers.length - kickedOffCounter];
int i = 0;
for(Passenger passenger : passengers) {
if(!passenger.getKickedOff()) {
for (Passenger passenger : passengers) {
if (!passenger.getKickedOff()) {
inGamePositions[i] = passenger.getPosition();
i++;
}
@ -67,7 +69,7 @@ public class HumanNPC extends Human {
int randomNr = (int) (Math.random() * inGamePositions.length);
vote = inGamePositions[randomNr];
hasVoted = true;
game.getGameState().getClientVoteData().setHasVoted(position,hasVoted);
game.getGameState().getClientVoteData().setHasVoted(position, hasVoted);
LOGGER.info("HumanNPC at Position: " + this.getPosition() + " has voted for: " + vote);
}
}

View File

@ -1,6 +1,7 @@
package ch.unibas.dmi.dbis.cs108.highscore;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@ -43,6 +44,7 @@ public class OgGhostHighScore {
/**
* adds the given name to the list of og ghost winners and updates the file listing the og ghost
* winners via writeOgGhostWinnersToFile
* @param name the name of the OG Winner
*/
public static void addOgGhostWinner(String name){
ogGhostWinners.add(name);
@ -51,7 +53,7 @@ public class OgGhostHighScore {
/**
* outputs the highscore list as it could be shown to clients.
* @return
* @return a well formated list in a String
*/
public static String formatGhostHighscoreList() {
@ -83,12 +85,13 @@ public class OgGhostHighScore {
hm.remove(firstplace);
}
}
return sb.toString();
}
/**
* reads the highscore file (or if not yet present create it) and reads the ogGhostWinners;
* @param args The system arguments, parsed as a string
*/
public static void main(String[] args) {
try {

View File

@ -5,15 +5,18 @@ import ch.unibas.dmi.dbis.cs108.gamelogic.ClientGameInfoHandler;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ClientModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.GUI;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.GameStateModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ClientPinger;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import com.google.inject.Guice;
import java.net.InetAddress;
import java.net.Socket;
import java.io.*;
@ -38,11 +41,17 @@ public class Client {
public ClientPinger clientPinger;
private ChatApp chatApp;
private GUI chatGui;
//private GUI chatGui;
private ClientModel clientModel;
private GameStateModel gameStateModel;
private GameController gameController;
private GUI gui;
private LoungeApp loungeApp;
//private GUI loungeGui;
private LoungeSceneViewController loungeSceneViewController;
/**
* Saves the position of the client, gets refreshed everytime the client gets a vote request.
*/
@ -71,10 +80,16 @@ public class Client {
}
sendMsgToServer(Protocol.clientLogin + "$" + systemName);
this.chatApp = new ChatApp(new ClientModel(systemName, this));
this.chatGui = new GUI(this.chatApp);
this.gui = new GUI(this.chatApp);
clientPinger = new ClientPinger(this, this.socket);
this.gameStateModel = new GameStateModel();
this.chatApp = new ChatApp(new ClientModel(systemName, this));
ChatApp.setGameController(new GameController(ChatApp.getClientModel(), gameStateModel));
this.gui = new GUI(this.chatApp);
this.gameController = new GameController(ChatApp.getClientModel(), gameStateModel);
this.loungeApp = new LoungeApp(ChatApp.getClientModel());
this.loungeSceneViewController = new LoungeSceneViewController();
LoungeSceneViewController.setClient(ChatApp.getClientModel());
} catch (IOException e) {
e.printStackTrace();
}
@ -136,17 +151,12 @@ public class Client {
//LOGGER.debug("just checked next line");
}
/**
* Extracts infromation about names and positions and roles from string and adds it to the
* GameStateModel
*
* @param msg
*/
public void gameStateModelSetter(String msg) {
public void setPosition(int position) {
this.position = position;
}
/**
* Starts a thread which listens for incoming chat messages / other messages that the user has to
* see
@ -283,7 +293,7 @@ public class Client {
cP.start();
client.userInputListener(); //this one blocks.
LOGGER.info("7.1");
Thread guiThread = new Thread(client.chatGui);
Thread guiThread = new Thread(client.gui);
LOGGER.info("8");
guiThread.start();
LOGGER.info("9");
@ -323,75 +333,129 @@ public class Client {
* @param parameter a string according to {@link GuiParameters} and {@link ClientGameInfoHandler}
* can be empty
* @param data some information in a string, separators can be $ or :
* TODO(Seraina&Sebi): evtl. auslagern?
* TODO(Seraina Sebi): evtl. auslagern?
*/
public void sendToGUI(String parameter, String data) {
try {
if (!parameter.equals(GuiParameters.updateGameState)) {
LOGGER.debug("GUI: PARAMETER:" + parameter + ", DATA: " + data);
}
switch (parameter) {
case ClientGameInfoHandler.itsNightTime: //ClientGameInfoHandler
case GuiParameters.night: //ClientGameInfoHandler;
gameStateModel.setDayClone(false);
chatApp.getGameController().setNoiseButtonInvisible();
break;
case ClientGameInfoHandler.itsDayTime: //ClientGameInfoHandler
case GuiParameters.day: //ClientGameInfoHandler
gameStateModel.setDayClone(true);
chatApp.getGameController().setNoiseButtonVisible();
break;
case GuiParameters.updateGameState:
gameStateModel.setGSFromString(data);
gameController.updateRoomLabels();
chatApp.getGameController().updateRoomLabels();
break;
case GuiParameters.noiseHeardAtPosition:
try {
int position = Integer.parseInt(data);
determineNoiseDisplay(position);
} catch (Exception e) {
LOGGER.warn("Not a position given for noise");
LOGGER.warn("Not a position given for noise " + e.getMessage());
}
break;
case GuiParameters.listOfLobbies:
//updateListOfLobbies(data); (commented out due to compiling error)
updateListOfLobbies(data);
//TODO
break;
case GuiParameters.VoteIsOver:
chatApp.getGameController().clearAllNoiseDisplay();
break;
case GuiParameters.listOfPLayers:
updateListOfClients(data);
//TODO
break;
//case GuiParameters.viewChangeToGame: (commented out due to compiling error)
case GuiParameters.getMembersInLobby:
updateLobbyMembers(data);
break;
case GuiParameters.viewChangeToGame:
chatApp.getLoungeSceneViewController().addGameView();
//TODO
//break; (commented out due to compiling error)
//case GuiParameters.viewChangeToStart: (commented out due to compiling error)
break;
/*case GuiParameters.viewChangeToStart:
//TODO
//break; (commented out due to compiling error)
//case GuiParameters.viewChangeToLobby: (commented out due to compiling error)
break;*/
case GuiParameters.viewChangeToLobby:
chatApp.getLoungeSceneViewController().removeGameView();
//TODO
//break; (commented out due to compiling error)
break;
case GuiParameters.addNewMemberToLobby:
addPlayerToLobby(data);
break;
case GuiParameters.newLobbyCreated:
makeNewLobby(data);
break;
case GuiParameters.newPlayerOnServer:
addNewPlayerToGui(data);
break;
case GuiParameters.updateHighScore:
chatApp.getLoungeSceneViewController().addHighScore(data);
break;
case GuiParameters.updatePrintLobby:
chatApp.getLoungeSceneViewController().clearLobbyPrint();
chatApp.getLoungeSceneViewController().addLobbyPrint(data);
break;
default:
notificationTextDisplay(data);
//TODO(Sebi,Seraina): should the gameController be in the Application just like the ChatController?
}
} catch (Exception e) {
LOGGER.warn("Communication with GUI currently not possible: " + e.getMessage());
LOGGER.debug(e.getCause() + " " + e.getStackTrace().toString());
}
}
//TODO decide if necessary
// private void updateListOfLobbies(String data) {
// String[] arr = data.split(":");
// ObservableList<SimpleStringProperty> list = new SimpleListProperty<>();
// int n = arr.length;
// for (int i = 0; i < n; i = i + 2) {
// list.add(new SimpleStringProperty(arr[i]));
// ChatController.getClient().addLobbyToList(new SimpleStringProperty(arr[i]));
// }
// }
private void updateListOfClients(String data) {
private void addNewPlayerToGui(String data) {
loungeSceneViewController.addClientToList(data);
LOGGER.debug("addNewPlayerToGui() seems to have finished");
}
private void makeNewLobby(String data) {
String[] params = data.split(":");
loungeSceneViewController.newLobby(params[0], params[1]);
LOGGER.debug("makeNewLobby() seems to have finished");
}
private void addPlayerToLobby(String data) {
String[] params = data.split(":");
loungeSceneViewController.addPlayerToLobby(params[0], params[1]);
LOGGER.debug("addPlayerToLobby() seems to have finished");
}
private void updateLobbyMembers(String data) {
String[] dataArr = data.split(":");
String lobbyID = dataArr[0];
String adminName = dataArr[1];
}
private void updateListOfLobbies(String data) {
String[] arr = data.split(":");
ObservableList<SimpleStringProperty> list = new SimpleListProperty<>();
int n = arr.length;
for (int i = 0; i < n; i = i + 2) {
list.add(new SimpleStringProperty(arr[i]));
//ChatController.getClient().addLobbyToList(new SimpleStringProperty(arr[i]));
}
//TODO
}
private void updateListOfClients(String data) {
String[] arr = data.split(":");
ObservableList<SimpleStringProperty> list = new SimpleListProperty<>();
int n = arr.length;
for (int i = 0; i < n; i = i + 1) {
loungeSceneViewController.addClientToList(arr[i]);
}
ChatController.getClient().getAllClients().setAll();
}
/**
@ -403,9 +467,9 @@ public class Client {
public void notificationTextDisplay(String data) {
new Thread(() -> {
try {
gameController.addMessageToNotificationText(data);
Thread.sleep(3000);
gameController.clearNotificationText();
chatApp.getGameController().addMessageToNotificationText(data);
Thread.sleep(5000);
chatApp.getGameController().clearNotificationText();
} catch (InterruptedException e) {
LOGGER.warn(e.getMessage());
}
@ -414,19 +478,26 @@ public class Client {
}
public void determineNoiseDisplay(int position) {
LOGGER.debug(position);
switch (position) {
case 0:
gameController.noiseDisplay0();
chatApp.getGameController().noiseDisplay0();
break;
case 1:
gameController.noiseDisplay1();
chatApp.getGameController().noiseDisplay1();
break;
case 2:
gameController.noiseDisplay2();
chatApp.getGameController().noiseDisplay2();
break;
case 3:
gameController.noiseDisplay3();
chatApp.getGameController().noiseDisplay3();
break;
case 4:
gameController.noiseDisplay4();
chatApp.getGameController().noiseDisplay4();
break;
case 5:
gameController.noiseDisplay5();
chatApp.getGameController().noiseDisplay5();
break;
}
}

View File

@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.gamelogic.ClientGameInfoHandler;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import java.io.OutputStreamWriter;
import org.apache.logging.log4j.LogManager;
@ -28,7 +29,6 @@ public class JClientProtocolParser {
header = msg.substring(0, 5);
} catch (IndexOutOfBoundsException e) {
System.out.println("Received unknown command");
e.printStackTrace();
}
switch (header) {
case Protocol.pingFromServer:
@ -38,7 +38,11 @@ public class JClientProtocolParser {
c.clientPinger.setGotPingBack(true);
break;
case Protocol.printToClientConsole:
LOGGER.debug(msg);
System.out.println(msg.substring(6));
if (!msg.substring(6).equals("Your vote was invalid")) {
c.notificationTextDisplay(msg.substring(6));
}
break;
case Protocol.printToClientChat:
//todo: handle chat separately from console.
@ -60,20 +64,32 @@ public class JClientProtocolParser {
c.changeUsername(msg.substring(6));
break;
case Protocol.printToGUI:
LOGGER.info("First line of printToGui case!");
String substring = msg.substring(6);
int index = msg.indexOf("$");
LOGGER.debug("Following parameters where recieved: " + substring);
int index = substring.indexOf("$");
LOGGER.debug("Index of $: " + index);
String parameter = "";
String data = substring;
try {
parameter = msg.substring(0,index);
data = msg.substring(index+1);
parameter = substring.substring(0, index);
data = substring.substring(index + 1);
LOGGER.debug("Parameter: " + parameter + ". Data: " + data);
} catch (Exception e) {
LOGGER.warn("No parameter in PTGUI");
}
c.sendToGUI(parameter,data);
c.sendToGUI(parameter, data);
break;
case Protocol.positionOfClient:
try {
int position = Integer.parseInt(msg.substring(6));
GameController.getClient().getClient().setPosition(position);
} catch (Exception e) {
LOGGER.warn(msg.substring(6));
}
break;
default:
System.out.println("Received unknown command");
System.out.println("Received unknown command: " + msg);
}
}
}

View File

@ -0,0 +1,192 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ClientModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController;
import java.net.URL;
import java.util.Objects;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ChatApp extends Application {
public static final Logger LOGGER = LogManager.getLogger(ChatApp.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
private static ClientModel clientModel;
private static ChatController chatController;
private static GameController gameController;
private ClientModel cModel;
private GameController gameC;
private static LoungeSceneViewController loungeSceneViewController;
private LoungeSceneViewController lSVController;
public Node chat;
public Node game;
public ChatApp() {
super();
LOGGER.info("Empty ChatApp constructor got called: ");
}
public ChatApp(ClientModel clientM) {
clientModel = clientM;
chatController = new ChatController(clientM);
}
/**
* Sets the ChatController for the Application, needs to be static, but only one application can
* be launched per programm
*
* @param chatC the ChatController to be linked to this chatApp
*/
public static void setChatController(ChatController chatC) {
chatController = chatC;
}
/**
* Sets the non-static ClientModel field of this class
*
* @param cModel the non static ClientModel to be added
*/
public void setcModel(ClientModel cModel) {
this.cModel = cModel;
}
public void setGameC(GameController gameC) {
this.gameC = gameC;
}
/**
* are u sure this is the field you want to get?
* @param lSVController a LoungeSceneViewController
*/
public void setlSVController(
LoungeSceneViewController lSVController) {
this.lSVController = lSVController;
}
/**
* are u sure this is the field you want to get?
* @return the clientModel of this chatApp
*/
public ClientModel getcModel() {
return cModel;
}
public static void setGameController(
GameController gameController) {
ChatApp.gameController = gameController;
}
/**
* needs to be called, if the gameController needs to be accessed from outside the application thread
* @return the relevant GameController
*/
public GameController getGameController() {
return gameController;
}
public GameController getGameC() {
return gameC;
}
public static void setClientModel(ClientModel clientM) {
clientModel = clientM;
}
public static ClientModel getClientModel() {
return clientModel;
}
/**
* needs to be called, if the chatController needs to be accessed from outside the application thread
* @return the relevant ChatController
*/
public ChatController getChatController() {
return chatController;
}
/**
* needs to be called, if the LoungeSceneViewController needs to be accessed from outside the application thread
* @return the relevant LoungeSceneViewController
*/
public LoungeSceneViewController getLoungeSceneViewController() {
return loungeSceneViewController;
}
/**
* Sure this is the field u want? not the static one?
* @return a LoungeSceneViewController
*/
public LoungeSceneViewController getlSVController() {
return lSVController;
}
public static void setLoungeSceneViewController(LoungeSceneViewController controller) {
loungeSceneViewController = controller;
}
/**
* The main entry point for all JavaFX applications. The start method is called after the init
* method has returned, and after the system is ready for the application to begin running.
*
* <p>
* NOTE: This method is called on the JavaFX Application Thread.
* </p>
*
* @param primaryStage the primary stage for this application, onto which the application scene
* can be set. Applications may create other stages, if needed, but they will
* not be primary stages.
* @throws Exception if something goes wrong
*/
@Override
public void start(Stage primaryStage) throws Exception {
this.setcModel(clientModel);
this.setGameC(gameController);
gameC.setClient(cModel);
gameC.setGameStateModel(GameController.getGameStateModel());
try {
URL chatResource = ChatApp.class.getResource("chat/ChatView.fxml");
URL gameResource = ChatApp.class.getResource("game/GameDayAll.fxml");
this.chat = FXMLLoader.load(Objects.requireNonNull(chatResource));
this.game = FXMLLoader.load(Objects.requireNonNull(gameResource));
} catch (Exception e) {
LOGGER.warn(e.getMessage());
}
URL loungeResource = ChatApp.class.getResource(
"lounge/LoungeSceneView.fxml");
try {
Parent lounge = FXMLLoader.load(
Objects.requireNonNull(loungeResource));
this.setlSVController(loungeSceneViewController);
lSVController.setChatApp(this);
// TODO bin chatController.getChatPaneRoot() border to root border for rezising
Scene scene = new Scene(lounge);
scene.setRoot(lounge);
primaryStage.setScene(scene);
} catch (Exception e) {
e.printStackTrace();
}
primaryStage.setResizable(false);
primaryStage.setTitle("Night Train To Budapest");
primaryStage.setResizable(true);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

View File

@ -70,6 +70,10 @@ public class ClientModel {
this.allClients.add(nameAndId);
}
public void updateClientList(ObservableList<SimpleStringProperty> clients) {
}
public void removeClientFromList(String id){
Iterator<SimpleStringProperty> it = allClients.iterator();
while(it.hasNext()){

View File

@ -1,7 +1,7 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import javafx.application.Application;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -12,12 +12,21 @@ public class GUI implements Runnable {
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
private ChatApp chatApp;
//private LoungeApp loungeApp;
public GUI(ChatApp chatApp) {
this.chatApp = chatApp;
}
/*public GUI(LoungeApp loungeApp) {
this.loungeApp = loungeApp;
}*/
/*public GUI(ChatApp chatApp,
LoungeApp loungeApp) {
this.chatApp = chatApp;
this.loungeApp = loungeApp;
}*/
/**
* When an object implementing interface {@code Runnable} is used to create a thread, starting the
@ -32,6 +41,7 @@ public class GUI implements Runnable {
@Override
public void run() {
LOGGER.info("here");
//Application.launch(this.chatApp.getClass());
Application.launch(this.chatApp.getClass());
}
}

View File

@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ClientModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.utils.ChatLabelConfigurator;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;

View File

@ -1,44 +1,34 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.Client;
import static javafx.scene.AccessibleRole.PARENT;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.GameStateModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters;
import javafx.event.EventHandler;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ClientModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ListChangeListener;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Background;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class GameController {
public class GameController implements Initializable {
public static final Logger LOGGER = LogManager.getLogger(GameController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
@ -47,6 +37,9 @@ public class GameController {
private static GameStateModel gameStateModel;
public GameController() {
super();
}
//TODO(Seraina, Sebi): Same issue as ChatController? do with setters?
public GameController(ClientModel c, GameStateModel g) {
@ -54,6 +47,18 @@ public class GameController {
gameStateModel = g;
}
public void setClient(ClientModel c) {
client = c;
}
public static ClientModel getClient() {
return client;
}
public static GameStateModel getGameStateModel() {
return gameStateModel;
}
@FXML
private AnchorPane gameBG;
@FXML
@ -102,14 +107,25 @@ public class GameController {
@FXML
private Button noiseButton;
@FXML
private TextFlow notificationText;
public TextFlow notificationText;
@FXML
private AnchorPane chatAreaGame;
public void addToChatArea(Node n) {
chatAreaGame.getChildren().add(n);
}
public AnchorPane getChatAreaGame() {
return chatAreaGame;
}
/**
* If button 0 is clicked, send the vote message 0 to the server
*/
public void sendVote0() {
client.getClient()
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + 0);
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + "$" + 0);
}
/**
@ -117,7 +133,7 @@ public class GameController {
*/
public void sendVote1() {
client.getClient()
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + 1);
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + "$" + 1);
}
/**
@ -125,7 +141,7 @@ public class GameController {
*/
public void sendVote2() {
client.getClient()
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + 2);
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + "$" + 2);
}
/**
@ -133,7 +149,7 @@ public class GameController {
*/
public void sendVote3() {
client.getClient()
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + 3);
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + "$" + 3);
}
/**
@ -141,7 +157,7 @@ public class GameController {
*/
public void sendVote4() {
client.getClient()
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + 4);
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + "$" + 4);
}
/**
@ -149,30 +165,54 @@ public class GameController {
*/
public void sendVote5() {
client.getClient()
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + 5);
.sendMsgToServer(Protocol.votedFor + "$" + client.getClient().getPosition() + "$" + 5);
}
/**
* Sends a noise message, to the server, should be a gui message?
*/
public void noise() {
LOGGER.info("Do you even get here");
LOGGER.info(client.getClient());
LOGGER.info(client.getClient().getPosition());
if (client.getClient() == null) {
LOGGER.info("But why???");
}
client.getClient().sendMsgToServer(
Protocol.sendMessageToAllClients + "$" + Protocol.printToGUI + GuiParameters.noiseHeardAtPosition + "$"
Protocol.sendMessageToAllClients + "$" + Protocol.printToGUI + "$"
+ GuiParameters.noiseHeardAtPosition + "$"
+ client.getClient().getPosition()); //TODO: Test!!
}
public void setNoiseButtonInvisible() {
noiseButton.setVisible(false);
}
public void setNoiseButtonVisible() {
noiseButton.setVisible(true);
}
/**
* Takes a given message and displays it in the notificationText Flow in the game Scene
*
* @param msg the message to be displayed
*/
public void addMessageToNotificationText(String msg){
Text notification = new Text(msg);
public void addMessageToNotificationText(String msg) {
LOGGER.trace("addMessage " + msg);
Text notification = new Text(System.lineSeparator() + msg);
notification.setFill(Color.BLACK);
notification.setStyle("-fx-font: 50 arial;");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
notificationText.getChildren().clear();
notificationText.getChildren().add(notification);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
LOGGER.debug(e.getMessage());
}
}
});
//TODO: Wait for a certain time, then clear all again
}
@ -180,32 +220,99 @@ public class GameController {
* Clears all children from notificationText TextFlow
*/
public void clearNotificationText() {
LOGGER.trace("clear notify");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
notificationText.getChildren().clear();
notificationText.getChildren().remove(0);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
LOGGER.debug("Not yet initialized");
}
}
});
}
/**
* Updates the labels of the rooms accordingly to the datastructures in GameStateModel
* TODO(Seraina): use a method to shorten, its madness
*/
public void updateRoomLabels() {
LOGGER.debug("roomlables update");
String[] names = gameStateModel.getPassengerTrainClone()[0];
String[] roles = gameStateModel.getPassengerTrainClone()[1];
boolean[] kickedOff = gameStateModel.getKickedOff();
Text name0 = new Text(names[0]);
name0.setStyle("-fx-font: 25 arial;");
name0.setFill(Color.WHITE);
Text name1 = new Text(names[1]);
name1.setStyle("-fx-font: 25 arial;");
name1.setFill(Color.WHITE);
Text name2 = new Text(names[2]);
name2.setStyle("-fx-font: 25 arial;");
name2.setFill(Color.WHITE);
Text name3 = new Text(names[3]);
name3.setStyle("-fx-font: 25 arial;");
name3.setFill(Color.WHITE);
Text name4 = new Text(names[4]);
name4.setStyle("-fx-font: 25 arial;");
name4.setFill(Color.WHITE);
Text name5 = new Text(names[5]);
Text role0 = new Text(roles[0]);
Text role1 = new Text(roles[1]);
Text role2 = new Text(roles[2]);
Text role3 = new Text(roles[3]);
Text role4 = new Text(roles[4]);
Text role5 = new Text(roles[5]);
name5.setStyle("-fx-font: 25 arial;");
name5.setFill(Color.WHITE);
Text role0;
if (kickedOff[0]) {
role0 = new Text("\nkicked off");
} else {
role0 = new Text("\n" + roles[0]);
}
role0.setStyle("-fx-font: 25 arial;");
role0.setFill(Color.WHITE);
Text role1;
if (kickedOff[1]) {
role1 = new Text("\nkicked off");
} else {
role1 = new Text("\n" + roles[1]);
}
role1.setStyle("-fx-font: 25 arial;");
role1.setFill(Color.WHITE);
Text role2;
if (kickedOff[2]) {
role2 = new Text("\nkicked off");
} else {
role2 = new Text("\n" + roles[2]);
}
role2.setStyle("-fx-font: 25 arial;");
role2.setFill(Color.WHITE);
Text role3;
if (kickedOff[3]) {
role3 = new Text("\nkicked off");
} else {
role3 = new Text("\n" + roles[3]);
}
role3.setStyle("-fx-font: 25 arial;");
role3.setFill(Color.WHITE);
Text role4;
if (kickedOff[4]) {
role4 = new Text("\nkicked off");
} else {
role4 = new Text("\n" + roles[4]);
}
role4.setStyle("-fx-font: 25 arial;");
role4.setFill(Color.WHITE);
Text role5;
if (kickedOff[5]) {
role5 = new Text("\nkicked off");
} else {
role5 = new Text("\n" + roles[5]);
}
role5.setStyle("-fx-font: 25 arial;");
role5.setFill(Color.WHITE);
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
lableRoom0.getChildren().clear();
lableRoom0.getChildren().add(name0);
@ -229,83 +336,162 @@ public class GameController {
LOGGER.trace("Not yet initialized");
}
}
});
}
/**
* loads the notification Bell from resource
* @return the Image node containing the BellImage
*/
public Image loadBellImage() {
Image bell = new Image("ch/unibas/dmi/dbis/cs108/multiplayer/client/gui/game/DayOpen/bell.png");
return bell;
}
/**
* Adds an image of a bell on top of button0
*/
public void noiseDisplay0(){
Image bell = new Image("ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.DayOpen.bell.png");
public void noiseDisplay0() {
LOGGER.debug("noise0 called");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
noiseImage0.setImage(bell);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
if(!gameStateModel.getKickedOff()[0]) {
noiseImage0.setImage(loadBellImage());
}
} catch (Exception e) {
LOGGER.debug(e.getMessage());
}
}
});
}
/**
* Adds an image of a bell on top of button1
*/
public void noiseDisplay1(){
Image bell = new Image("ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.DayOpen.bell.png");
public void noiseDisplay1() {
LOGGER.debug("noise1 called");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
noiseImage0.setImage(bell);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
if(!gameStateModel.getKickedOff()[1]) {
noiseImage1.setImage(loadBellImage());
}
} catch (Exception e) {
LOGGER.debug(e.getMessage());
}
}
});
}
/**
* Adds an image of a bell on top of button2
*/
public void noiseDisplay2(){
Image bell = new Image("ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.DayOpen.bell.png");
public void noiseDisplay2() {
LOGGER.debug("noise2 called");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
noiseImage0.setImage(bell);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
if(!gameStateModel.getKickedOff()[2]) {
noiseImage2.setImage(loadBellImage());
}
} catch (Exception e) {
LOGGER.debug(e.getMessage());
;
}
}
});
}
/**
* Adds an image of a bell on top of button3
*/
public void noiseDisplay3(){
Image bell = new Image("ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.DayOpen.bell.png");
public void noiseDisplay3() {
LOGGER.debug("noise3 called");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
noiseImage0.setImage(bell);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
if(!gameStateModel.getKickedOff()[3]) {
noiseImage3.setImage(loadBellImage());
}
} catch (Exception e) {
LOGGER.debug(e.getMessage());
}
}
});
}
/**
* Adds an image of a bell on top of button4
*/
public void noiseDisplay4(){
Image bell = new Image("ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.DayOpen.bell.png");
public void noiseDisplay4() {
LOGGER.debug("noise4 called");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
noiseImage0.setImage(bell);
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
if(!gameStateModel.getKickedOff()[4]) {
noiseImage4.setImage(loadBellImage());
}
} catch (Exception e) {
LOGGER.debug(e.getMessage());
}
}
});
}
/**
* Adds an image of a bell on top of button5
*/
public void noiseDisplay5(){
Image bell = new Image("ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.DayOpen.bell.png");
public void noiseDisplay5() {
LOGGER.debug("noise5 called");
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
noiseImage0.setImage(bell);
if(!gameStateModel.getKickedOff()[5]) {
noiseImage5.setImage(loadBellImage());
}
} catch (Exception e) {
LOGGER.trace("Not yet initialized");
LOGGER.debug(e.getMessage());
}
}
});
}
/**
* Clears all bells from the view
*/
public void clearAllNoiseDisplay() {
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
noiseImage0.setImage(null);
noiseImage1.setImage(null);
noiseImage2.setImage(null);
noiseImage3.setImage(null);
noiseImage4.setImage(null);
noiseImage5.setImage(null);
} catch (Exception e) {
LOGGER.debug(e.getMessage());
}
}
});
}
public void setGameStateModel(
GameStateModel gameStateModel) {
GameController.gameStateModel = gameStateModel;
}
@Override
public void initialize(URL location, ResourceBundle resources) {
ChatApp.setGameController(this);
}
}

View File

@ -6,15 +6,21 @@ import javafx.beans.property.SimpleStringProperty;
public class ClientListItem {
private SimpleStringProperty name;
private final SimpleIntegerProperty id;
private final int id;
public ClientListItem(SimpleStringProperty name, SimpleIntegerProperty id) {
this.name = name;
private static int uid = 0;
public ClientListItem(String name, int id) {
this.name = new SimpleStringProperty(name);
this.id = id;
}
public ClientListItem(String name) {
this(name, uid++);
}
@Override
public String toString(){
public String toString() {
return name + " ID: " + id;
}
@ -31,10 +37,11 @@ public class ClientListItem {
}
public int getId() {
return id.get();
}
public SimpleIntegerProperty idProperty() {
return id;
}
public int clientID() {
return id;
}
}

View File

@ -1,22 +1,121 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge;
import java.util.Set;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ObservableList;
import javafx.collections.ObservableSet;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ToggleButton;
public class LobbyListItem {
private final Label lobbyID;
private final Label adminName;
private Set<StringProperty> clientsInLobby;
private final ToggleButton button;
private final SimpleStringProperty lobbyID;
private final SimpleStringProperty adminName;
private ObservableList<ClientListItem> clientsInLobby;
public LobbyListItem(Label lobbyID, Label adminName,
Set<StringProperty> clientsInLobby, ToggleButton button) {
private SimpleBooleanProperty ownedByClient;
private SimpleBooleanProperty isOpen;
private final int MAX_CAPACITY = 6;
private SimpleIntegerProperty noOfPlayersInLobby;
public LobbyListItem(SimpleStringProperty lobbyID, SimpleStringProperty adminName,
SimpleBooleanProperty ownedByClient, SimpleBooleanProperty isOpen,
SimpleIntegerProperty noOfPlayersInLobby) {
this.lobbyID = lobbyID;
this.adminName = adminName;
this.clientsInLobby = clientsInLobby;
this.button = button;
this.ownedByClient = ownedByClient;
this.isOpen = isOpen;
this.noOfPlayersInLobby = noOfPlayersInLobby;
}
public String getLobbyID() {
return lobbyID.get();
}
public SimpleStringProperty lobbyIDProperty() {
return lobbyID;
}
public void setLobbyID(String lobbyID) {
this.lobbyID.set(lobbyID);
}
public String getAdminName() {
return adminName.get();
}
public SimpleStringProperty adminNameProperty() {
return adminName;
}
public void setAdminName(String adminName) {
this.adminName.set(adminName);
}
public ObservableList<ClientListItem> getClientsInLobby() {
return clientsInLobby;
}
public void setClientsInLobby(ObservableList<ClientListItem> clientsInLobby) {
this.clientsInLobby = clientsInLobby;
}
public boolean isOwnedByClient() {
return ownedByClient.get();
}
public SimpleBooleanProperty ownedByClientProperty() {
return ownedByClient;
}
public void setOwnedByClient(boolean ownedByClient) {
this.ownedByClient.set(ownedByClient);
}
public boolean isIsOpen() {
return isOpen.get();
}
public SimpleBooleanProperty isOpenProperty() {
return isOpen;
}
public void setIsOpen(boolean isOpen) {
this.isOpen.set(isOpen);
}
public int getMAX_CAPACITY() {
return MAX_CAPACITY;
}
public int getNoOfPlayersInLobby() {
return noOfPlayersInLobby.get();
}
public SimpleIntegerProperty noOfPlayersInLobbyProperty() {
return noOfPlayersInLobby;
}
public void setNoOfPlayersInLobby(int noOfPlayersInLobby) {
this.noOfPlayersInLobby.set(noOfPlayersInLobby);
}
@Override
public String toString() {
return "LobbyListItem{" + "lobbyID=" + lobbyID + ", adminName=" + adminName
+ ", clientsInLobby=" + clientsInLobby + ", ownedByClient=" + ownedByClient + ", isOpen="
+ isOpen + ", MAX_CAPACITY=" + MAX_CAPACITY + ", noOfPlayersInLobby=" + noOfPlayersInLobby
+ '}';
}
}

View File

@ -1,7 +1,9 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat;
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ClientModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController;
import java.net.URL;
import java.util.Objects;
import javafx.application.Application;
@ -12,7 +14,10 @@ import javafx.stage.Stage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class ChatApp extends Application {
/**
* Class for debugging the lounge gui scene
*/
public class LoungeApp extends Application {
public static final Logger LOGGER = LogManager.getLogger(ChatApp.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
@ -21,12 +26,14 @@ public class ChatApp extends Application {
private static ChatController chatController;
private ClientModel cModel;
public ChatApp() {
private static LoungeSceneViewController loungeSceneViewController;
public LoungeApp() {
super();
LOGGER.info("Empty ChatApp constructor got called: ");
}
public ChatApp(ClientModel clientM) {
public LoungeApp(ClientModel clientM) {
clientModel = clientM;
chatController = new ChatController(clientM);
}
@ -66,6 +73,10 @@ public class ChatApp extends Application {
return chatController;
}
public static void setLoungeSceneViewController(LoungeSceneViewController controller) {
loungeSceneViewController = controller;
}
/**
* The main entry point for all JavaFX applications. The start method is called after the init
@ -84,16 +95,18 @@ public class ChatApp extends Application {
public void start(Stage primaryStage) throws Exception {
this.setcModel(clientModel);
URL resource = ChatApp.class.getResource(
"ChatView.fxml");
"LoungeSceneView.fxml");
if (resource == null) {
System.out.println("File wasnt found");
LOGGER.info("File wasnt found. Name: LoungeSceneView.fxml");
}
//ChatApp chatApp = new ChatApp(new ClientModel());
try {
Parent root = FXMLLoader.load(
Objects.requireNonNull(ChatApp.class.getResource(
"ChatView.fxml")));
Objects.requireNonNull(LoungeApp.class.getResource(
"LoungeSceneView.fxml")));
// TODO bin chatController.getChatPaneRoot() border to root border for rezising
// loungeSceneViewController.getChatAreaHBox().getChildren()
// .add(FXMLLoader.load(Objects.requireNonNull(ChatApp.class.getResource("ChatView.fxml"))));
Scene scene = new Scene(root);
scene.setRoot(root);
primaryStage.setScene(scene);
@ -101,7 +114,7 @@ public class ChatApp extends Application {
e.printStackTrace();
}
primaryStage.setResizable(true);
primaryStage.setTitle("Chat");
primaryStage.setTitle("Lounge");
primaryStage.show();
@ -112,3 +125,4 @@ public class ChatApp extends Application {
}
}

View File

@ -1,37 +1,82 @@
package ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge;
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ClientModel;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.events.ChangeNameButtonPressedEventHandler;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.events.LeaveServerButtonPressedEventHandler;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.ChatApp;
import ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.LobbyListView;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import ch.unibas.dmi.dbis.cs108.multiplayer.server.JServerProtocolParser;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class LoungeSceneViewController implements Initializable {
Protocol protocol;
public static final Logger LOGGER = LogManager.getLogger(LoungeSceneViewController.class);
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
public Button newGameButton;
@FXML
private ListView LobbyListView;
private TextFlow highScore;
@FXML
private ListView ClientListView;
public TextFlow lobbyPrint;
@FXML
private SplitPane chatSplitPane;
@FXML
private AnchorPane chatAnchorPane;
@FXML
private AnchorPane otherNotificationAnchorPane;
@FXML
public Button highScoreButton;
@FXML
private Button leaveLobbyButton;
@FXML
private Button lobbyPrintButton;
@FXML
private Button startGame;
@FXML
private Button newGameButton;
@FXML
private AnchorPane gameAnchorPane;
@FXML
public ListView<LobbyListItem> LobbyListView;
@FXML
public ListView<ClientListItem> ClientListView;
@FXML
private Button ChangeNameButton;
@FXML
@ -39,14 +84,37 @@ public class LoungeSceneViewController implements Initializable {
@FXML
private AnchorPane ChatArea;
@FXML
private HBox ChatAreaHBox;
@FXML
private BorderPane LoungeSceneBorderPane;
@FXML
private ToolBar NTtBToolBar;
public static ClientModel client;
public static ListView<LobbyListItem> lListView;
public static ListView<ClientListItem> cListView;
public static ClientModel client;
private static ChatApp chatApp;
private ChatApp cApp;
ObservableList<ClientListItem> clients = FXCollections.observableArrayList();
ObservableList<LobbyListItem> lobbies = FXCollections.observableArrayList();
private ObservableMap<String, ObservableList<String>> lobbyToMemberssMap;
private HashMap<String, String> clientToLobbyMap;
private HashMap<String, LobbyListItem> lobbyIDtoLobbyMop;
public LoungeSceneViewController() {
super();
lobbyToMemberssMap = FXCollections.observableHashMap();
lobbyIDtoLobbyMop = new HashMap<>();
}
public void setChatApp(ChatApp chatApp) {
LoungeSceneViewController.chatApp = chatApp;
}
public void setcApp(ChatApp cApp) {
this.cApp = cApp;
}
/**
* Called to initialize a controller after its root element has been completely processed.
@ -57,43 +125,396 @@ public class LoungeSceneViewController implements Initializable {
*/
@Override
public void initialize(URL location, ResourceBundle resources) {
this.protocol = new Protocol();
ChatApp.setLoungeSceneViewController(this);
setcApp(chatApp);
ChangeNameButton.setOnAction(event -> changeName());
LeaveServerButton.setOnAction(new LeaveServerButtonPressedEventHandler());
LeaveServerButton.setOnAction(event -> leaveServer());
newGameButton.setOnAction(event -> newGame());
LobbyListView.setVisible(true);
lListView = LobbyListView;
cListView = ClientListView;
LOGGER.debug("Lobby in initialize" + LobbyListView);
ClientListView.setVisible(true);
ClientListView.setItems(clients);
addChatView();
ClientListView.setItems(client.getAllClients());
ClientListView.setItems(clients);
ClientListView.setCellFactory(param -> {
ListCell<ClientListItem> cell = new ListCell<>() {
Label name = new Label();
Label id = new Label();
HBox nameAndId = new HBox(name, id);
{
nameAndId.setAlignment(Pos.CENTER_LEFT);
}
/**
* The updateItem method should not be called by developers, but it is the
* best method for developers to override to allow for them to customise the
* visuals of the cell. To clarify, developers should never call this method
* in their code (they should leave it up to the UI control, such as the
* {@link ListView} control) to call this method. However, the purpose of
* having the updateItem method is so that developers, when specifying
* custom cell factories (again, like the ListView {@link
* ListView#cellFactoryProperty() cell factory}), the updateItem method can
* be overridden to allow for complete customisation of the cell.
*
* <p>It is <strong>very important</strong> that subclasses
* of Cell override the updateItem method properly, as failure to do so will
* lead to issues such as blank cells or cells with unexpected content
* appearing within them. Here is an example of how to properly override the
* updateItem method:
*
* <pre>
* protected void updateItem(T item, boolean empty) {
* super.updateItem(item, empty);
*
* if (empty || item == null) {
* setText(null);
* setGraphic(null);
* } else {
* setText(item.toString());
* }
* }
* </pre>
*
* <p>Note in this code sample two important points:
* <ol>
* <li>We call the super.updateItem(T, boolean) method. If this is not
* done, the item and empty properties are not correctly set, and you are
* likely to end up with graphical issues.</li>
* <li>We test for the <code>empty</code> condition, and if true, we
* set the text and graphic properties to null. If we do not do this,
* it is almost guaranteed that end users will see graphical artifacts
* in cells unexpectedly.</li>
* </ol>
* @param item The new item for the cell.
*
* @param empty whether or not this cell represents data from the list. If
* it is empty, then it does not represent any domain data, but
* is a cell
*/
@Override
protected void updateItem(ClientListItem item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
LOGGER.debug("In updateItem(item, empty) Method. Else branch -> nonnull item");
name.setText(item.getName());
name.setTextFill(Color.BLACK);
id.setText(String.valueOf(item.getId()));
id.setTextFill(Color.BLACK);
setGraphic(nameAndId);
}
}
};
return cell;
});
LobbyListView.setItems(lobbies);
LOGGER.debug("In Initialize 2 LobbyListView" + LobbyListView);
LobbyListView.setCellFactory(param -> {
ListCell<LobbyListItem> cell = new ListCell<>() {
Label lobbyID = new Label();
Label adminName = new Label();
Label lobbyIsOpen = new Label();
Label noOfPlayersInLobby = new Label();
Button startOrJoin = new Button();
HBox head = new HBox(lobbyID, adminName, noOfPlayersInLobby, lobbyIsOpen, startOrJoin);
VBox playerList = new VBox();
TitledPane headParent = new TitledPane(head.toString(), playerList);
{
head.setAlignment(Pos.CENTER_LEFT);
head.setSpacing(5);
playerList.setAlignment(Pos.CENTER_LEFT);
headParent.setCollapsible(true);
}
/**
* The updateItem method should not be called by developers, but it is the
* best method for developers to override to allow for them to customise the
* visuals of the cell. To clarify, developers should never call this method
* in their code (they should leave it up to the UI control, such as the
* {@link ListView} control) to call this method. However, the purpose of
* having the updateItem method is so that developers, when specifying
* custom cell factories (again, like the ListView {@link
* ListView#cellFactoryProperty() cell factory}), the updateItem method can
* be overridden to allow for complete customisation of the cell.
*
* <p>It is <strong>very important</strong> that subclasses
* of Cell override the updateItem method properly, as failure to do so will
* lead to issues such as blank cells or cells with unexpected content
* appearing within them. Here is an example of how to properly override the
* updateItem method:
*
* <pre>
* protected void updateItem(T item, boolean empty) {
* super.updateItem(item, empty);
*
* if (empty || item == null) {
* setText(null);
* setGraphic(null);
* } else {
* setText(item.toString());
* }
* }
* </pre>
*
* <p>Note in this code sample two important points:
* <ol>
* <li>We call the super.updateItem(T, boolean) method. If this is not
* done, the item and empty properties are not correctly set, and you are
* likely to end up with graphical issues.</li>
* <li>We test for the <code>empty</code> condition, and if true, we
* set the text and graphic properties to null. If we do not do this,
* it is almost guaranteed that end users will see graphical artifacts
* in cells unexpectedly.</li>
* </ol>
* @param item The new item for the cell.
*
* @param empty whether or not this cell represents data from the list. If
* it is empty, then it does not represent any domain data, but
* is a cell
*/
@Override
protected void updateItem(LobbyListItem item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic((null));
} else {
LOGGER.debug("In ELSE part of LobbyView Update item()");
lobbyID.setText(item.getLobbyID());
adminName.setText(item.getAdminName());
startOrJoin.setOnAction(event -> {
if (item.isOwnedByClient()) {
startGame();
} else {
joinGame(item.lobbyIDProperty().getValue());
}
});
startOrJoin.setText(item.isOwnedByClient() ? "Start" : "Join");
lobbyID.setTextFill(Color.BLACK);
adminName.setTextFill(Color.BLACK);
startOrJoin.setTextFill(Color.BLACK);
setGraphic(head);
}
}
};
return cell;
});
LOGGER.debug("In Initialize 3 LobbyListView" + LobbyListView);
LobbyListView.setPlaceholder(new Text("No open lobbies!"));
LobbyListView.setVisible(true);
}
public void updateLobbyListView() {
//TODO
/**
* Adds the gameView to the existing LobbyView
*/
public void addGameView() {
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
newGameButton.setVisible(false);
startGame.setVisible(false);
gameAnchorPane.getChildren().add(chatApp.game);
} catch (Exception e) {
LOGGER.debug("Not yet initialized");
}
}
});
}
public void updateClientListView(ObservableList<SimpleStringProperty> names) {
this.ClientListView.setItems(names);
/**
* Removes the GameView again - needed when a game is over or a lobby is left
*/
public void removeGameView() {
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
newGameButton.setVisible(true);
startGame.setVisible(true);
gameAnchorPane.getChildren().clear();
} catch (Exception e) {
LOGGER.debug("Not yet initialized");
}
}
});
}
public void addLobby(LobbyListItem lobby) {
//TODO
/**
* Adds the ChatView to the LobbyView, should be done right in the initialisation
*/
public void addChatView() {
Platform.runLater(new Runnable() {
@Override
public void run() {
try {
chatAnchorPane.getChildren().add(chatApp.chat);
} catch (Exception e) {
LOGGER.debug("Not yet initialized: chatAnchorPane");
}
}
});
}
/**
* Adds players to a lobby
* "NMEMB" {@link ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters}
* @param lobbyID the Id the Player belongs to
* @param player the player to be added
*/
public void addPlayerToLobby(String lobbyID, String player) {
LOGGER.debug("Lobby ID: " + lobbyID + " player: " + player);
Platform.runLater(new Runnable() {
@Override
public void run() {
Iterator<ClientListItem> itr = clients.iterator();
while(itr.hasNext()){
ClientListItem cl = itr.next();
if(cl.getName().equals(player)){
LobbyListItem li = lobbyIDtoLobbyMop.get(lobbyID);
li.getClientsInLobby().add(cl);
}
}
}
});
}
/**
* Used when a new lobby shall be added to the view. "NLOBBY" {@link
* ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters}
*
* @param lobbyID the ID of the new lobby
* @param adminName the name of the Lobby admin
*/
public void newLobby(String lobbyID, String adminName) {
LobbyListView = lListView;
LOGGER.debug("In newLobby()0 LobbyListView" + lListView);
LOGGER.debug("New lobby with ID " + lobbyID + " and admin " + adminName);
SimpleStringProperty id = new SimpleStringProperty(lobbyID);
SimpleStringProperty admin = new SimpleStringProperty((adminName));
LOGGER.debug("In newLobby()1 LobbyListView" + LobbyListView);
boolean ownedByClient = false;
if (adminName.equals(client.getUsername())) {
LOGGER.debug("Client is admin. Name: " + adminName);
ownedByClient = true;
} else {
LOGGER.debug("Different admin case. ADMIN Name: " + adminName);
}
LobbyListItem item = new LobbyListItem(id, admin, new SimpleBooleanProperty(ownedByClient),
new SimpleBooleanProperty(true), new SimpleIntegerProperty(0));
lobbyIDtoLobbyMop.put(lobbyID,item);
LOGGER.debug("In newLobby()2 LobbyListView" + LobbyListView);
Platform.runLater(new Runnable() {
@Override
public void run() {
lobbies.add(item);
LobbyListView.getItems().add(item);
LOGGER.debug("within newLobby() run() thread");
LOGGER.debug(item.toString());
LOGGER.debug("In newLobby() run() " + LobbyListView);
}
});
LOGGER.debug("newLobby() in LoungeSceneViewController seems to have reached end.");
LOGGER.debug(lobbies.toString());
LOGGER.debug("In newLobby()3 LobbyListView" + LobbyListView);
}
/**
* Send the joinLobby Protocol message
* @param lobbyID the Lobby to be joinded
*/
public void joinGame(String lobbyID) {
client.getClient().sendMsgToServer(Protocol.joinLobby + "$" + lobbyID);
}
/**
* Sends the startNewGame Protocol message
*/
public void startGame() {
client.getClient().sendMsgToServer(Protocol.startANewGame);
//addGameView();
}
/**
* Sends the leaveLobby protocol message
*/
public void leaveLobby() {
client.getClient().sendMsgToServer(Protocol.leaveLobby);
removeGameView();
}
/**
* Sends the Quit protocol message
*/
public void leaveServer() {
client.getClient().sendMsgToServer(Protocol.clientQuitRequest);
}
/**
* Used to add a new player to the list of players. "NPLOS" {@link ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters}
*
* @param s the information corresponding to to the client in String from
*/
public void addClientToList(String s) {
ClientListView.getItems().add(new SimpleStringProperty(s));
ClientListItem cl = new ClientListItem(s);
ClientListView = cListView;
Platform.runLater(new Runnable() {
@Override
public void run() {
clients.add(cl);
LOGGER.debug("in addClientToList() in run()");
LOGGER.debug(cl.toString() + " in run()");
}
});
}
/**
* Sould remove a client of a certain name from the ListView
* @param name the name of the client to be removed
*/
public void removeClientFromList(String name){
Iterator<ClientListItem> it = clients.iterator();
while (it.hasNext()) {
String uid = it.next().getName();
if (uid.equals(name)) {
it.remove();
break;
}
} }
public void removeClientFromLobby(String s){
//todo
}
/**
* Sends the create New Lobby Protocol message
*/
public void newGame() {
client.getClient().sendMsgToServer(Protocol.createNewLobby);
}
/**
* Sends the nameChange command, taking the new Name from the TextFlied
*/
public void changeName() {
TextField name = new TextField("Enter new name!");
TextField name = new TextField();
name.setPromptText("Enter new Nickname!");
this.NTtBToolBar.getItems().add(name);
name.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
client.getClient().sendMsgToServer(Protocol.nameChange + "$" + name.getText());
NTtBToolBar.getItems().remove(NTtBToolBar.getItems().size());
NTtBToolBar.getItems().remove(name);
}
});
}
@ -106,4 +527,72 @@ public class LoungeSceneViewController implements Initializable {
public static void setClient(ClientModel client) {
LoungeSceneViewController.client = client;
}
/**
* Sends the highScore request message
*/
public void sendHIghScore() {
client.getClient().sendMsgToServer(Protocol.highScoreList);
}
/**
* Sends the listLobbies protocol message
*/
public void sendLilstle() {
client.getClient().sendMsgToServer(Protocol.listLobbies);
}
/**
* Adds a String to the highScore Text Flow
* @param data the String to be added
*/
public void addHighScore(String data) {
String[] arguments = data.split("/n");
LOGGER.debug(arguments.length);
Platform.runLater(new Runnable() {
@Override
public void run() {
highScore.getChildren().clear();
for(String argument : arguments) {
LOGGER.debug("HighScore " + argument);
Text text = new Text(argument + System.lineSeparator());
text.setFill(Color.BLACK);
highScore.getChildren().add(text);
}
}
});
}
/**
* Adds a String to the lobbyPrint TextFlow
* @param data the String to be added
* */
public void addLobbyPrint(String data) {
String[] arguments = data.split("/n");
LOGGER.debug(arguments.length);
Platform.runLater(new Runnable() {
@Override
public void run() {
for(String argument : arguments) {
LOGGER.debug("HighScore " + argument);
Text text = new Text(argument + System.lineSeparator());
text.setFill(Color.BLACK);
lobbyPrint.getChildren().add(text);
}
}
});
}
/**
* Clears the lobbyPrint TextFlow
*/
public void clearLobbyPrint() {
Platform.runLater(new Runnable() {
@Override
public void run() {
lobbyPrint.getChildren().clear();
}
});
}
}

View File

@ -11,7 +11,7 @@ import javafx.scene.paint.Color;
import javafx.scene.text.Text;
/**
* Provides utilities to configure Labels for the ChatView {@see ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatView.fxml}
* Provides utilities to configure Labels for the ChatView {@code ChatView.fxml}
* within {@link ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController}
*/
public class ChatLabelConfigurator {

View File

@ -6,7 +6,8 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.helpers;
public class GuiParameters {
/**
* Tells GUI to update the gameStateModel, in the form {@code UPDATE$name:role:kickedOff$name:role:kickedOff} ... usw.
* Tells GUI to update the gameStateModel, in the form {@code UPDATE$name:role:kickedOff$name:role:kickedOff}
* ... usw.
*/
public static final String updateGameState = "UPDATE";
/**
@ -20,8 +21,8 @@ public class GuiParameters {
public static final String listOfPLayers = "PLAYERS";
/**
* Tells Gui, that the passenger at position {@code position} has heard some noise
* Form: {@code NOISE$position$}
* Tells Gui, that the passenger at position {@code position} has heard some noise Form: {@code
* NOISE$position$}
*/
public static final String noiseHeardAtPosition = "NOISE";
@ -41,10 +42,58 @@ public class GuiParameters {
public static final String viewChangeToGame = "VCGAME";
/**
* Tells Gui, who the members of a specified Lobby are. Form: {@code LMEMBS$<lobbyID>:<ADMIN
* NAME>:<member names>:<..>}
*/
public static final String getMembersInLobby = "LMEMBS";
/**
* Tells, Gui, who the members of a specified Lobby are.
* Form: {@code LMEMBS$<lobbyID>$<member names>$..}
* Informs the GUI, that a vote is over
*/
public static String changeToLobby = "LMEMBS";
public static final String VoteIsOver = "VOTEOVER";
/**
* Informes Gui, that its the night
*/
public static final String night = "NIGHT";
/**
* Informes Gui, that its the day
*/
public static final String day = "DAY";
public static final String newLobbyCreated = "NLOBBY";
/**
* Tells Gui, to add a player to a lobby. Form: {@code NMEMB$<LobbyIS>:<PlayerNamse>}
*/
public static final String addNewMemberToLobby = "NMEMB";
/**
* Indicates a player changed their username. Form: {@code NCHANG$<oldName>:<newName>}
*/
public static final String nameChanged = "NCHANG";
/**
* Indicates a player has joined the server. Form: {@code NPLOS$<playerName>}
*/
public static final String newPlayerOnServer = "NPLOS";
/**
* Tells gui to remove a certain player from the list of clients based on user name. Form: {@code
* RMVLST$<playerName>}
*/
public static final String removePlayerFromList = "RMVLST";
/**
* Tells Gui to update its HighScore TextFlow according to the following data
*/
public static final String updateHighScore = "HISCR";
/**
* Tells Gui to add a String to printLobby TextFlow - a provisory solution in case ListeView won't
* pan out
*/
public static final String updatePrintLobby = "PRLOBB";
}

View File

@ -207,5 +207,11 @@ public class Protocol {
*/
public static final String printToGUI = "PTGUI";
/**
* Sends an information to client at which position in the train from the game (0 to 5) they sit, as soon as the game starts
* {@code POSOF$position}
*/
public static final String positionOfClient = "POSOF";
}

View File

@ -5,6 +5,7 @@ import ch.unibas.dmi.dbis.cs108.gamelogic.Game;
import ch.unibas.dmi.dbis.cs108.gamelogic.TrainOverflow;
import ch.unibas.dmi.dbis.cs108.gamelogic.VoteHandler;
import ch.unibas.dmi.dbis.cs108.highscore.OgGhostHighScore;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.GuiParameters;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol;
import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ServerPinger;
@ -126,8 +127,12 @@ public class ClientHandler implements Runnable {
*/
public void changeUsername(String newName) {
String helper = this.getClientUserName();
String oldName = getClientUserName();
this.clientUserName = nameDuplicateChecker.checkName(newName);
guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.nameChanged + "$" + oldName + ":"
+ getClientUserName());
sendMsgToClient(Protocol.changedUserName + "$" + newName);
broadcastAnnouncementToAll(helper + " has changed their nickname to " + clientUserName);
try {
getLobby().getGame().getGameState().changeUsername(helper, newName);
@ -245,6 +250,13 @@ public class ClientHandler implements Runnable {
}
}
public static void guiUpdateAll(String msg) {
System.out.println(msg);
for (ClientHandler client : connectedClients) {
client.sendMsgToClient(msg);
}
}
/**
* Broadcasts a non-chat Message to all clients in the same lobby. This can be used for server
* messages / announcements rather than chat messages. The message will be printed to the user
@ -306,7 +318,8 @@ public class ClientHandler implements Runnable {
}
/**
* Sends a given message to all connected client. The message has to already be protocol-formatted.
* Sends a given message to all connected client. The message has to already be
* protocol-formatted.
*
* @param msg the given message. Should already be protocol-formatted.
*/
@ -317,7 +330,9 @@ public class ClientHandler implements Runnable {
}
/**
* Sends a Message to all clients in the same lobby. The message has to already be protocol-formatted.
* Sends a Message to all clients in the same lobby. The message has to already be
* protocol-formatted.
*
* @param msg the given message. Should already be protocol-formatted.
*/
public void sendMsgToClientsInLobby(String msg) {
@ -376,9 +391,13 @@ public class ClientHandler implements Runnable {
}
LOGGER.debug("Vote is:" + vote);
if (vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid
try {
getLobby().getGame().getGameState().getClientVoteData().setVote(position, vote);
LOGGER.debug("Player vote: " + vote);
getLobby().getGame().getGameState().getClientVoteData().setHasVoted(position, true);
} catch (NullPointerException e) {
LOGGER.info("Client not in Lobby");
}
}
}
@ -456,6 +475,10 @@ public class ClientHandler implements Runnable {
public void createNewLobby() {
if (Lobby.clientIsInLobby(this) == -1) {
Lobby newGame = new Lobby(this);
guiUpdateAll(
Protocol.printToGUI + "$" + GuiParameters.newLobbyCreated + "$" + getLobby().getLobbyID()
+ ":" + getClientUserName());
LOGGER.debug("Lobby: " + getLobby().getLobbyID() + ". In method createNewLobby()");
} else {
sendAnnouncementToClient("You are already in lobby nr. " + Lobby.clientIsInLobby(this));
}
@ -472,6 +495,8 @@ public class ClientHandler implements Runnable {
if (l != null) {
if (l.getLobbyIsOpen()) {
l.addPlayer(this);
guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.addNewMemberToLobby + "$" + i + ":"
+ getClientUserName());
} else {
sendAnnouncementToClient("The game in Lobby " + l.getLobbyID()
+ " has already started, or the lobby is already full.");
@ -538,6 +563,46 @@ public class ClientHandler implements Runnable {
}
}
/**
* Lists all lobbies and their members, along with players outside lobbies to this clientHandler's
* client a GUI message in a form, the gui can decode.
*/
public void listLobbiesGuiFormat() {
StringBuilder stringBuilder = new StringBuilder();
if (Lobby.lobbies.isEmpty()) {
stringBuilder.append("No Lobbies.").append("/n");
} else {
for (Lobby l : Lobby.lobbies) {
String lobbyStatus = "closed";
if (l.getLobbyIsOpen()) {
lobbyStatus = "open";
}
stringBuilder.append("Lobby nr. " + l.getLobbyID() + ": (" + lobbyStatus + ")").append("/n");
for (ClientHandler c : l.getLobbyClients()) {
if (c.equals(l.getAdmin())) {
stringBuilder.append(" -" + c.getClientUserName() + " (admin)").append("/n");
} else {
stringBuilder.append(" -" + c.getClientUserName()).append("/n");
}
}
}
}
boolean helper = false; //used to print "Clients not in lobbies" only once, if needed.
for (ClientHandler c : connectedClients) {
if (Lobby.clientIsInLobby(c) == -1) {
if (!helper) {
helper = true;
stringBuilder.append("Clients not in lobbies:").append("/n");
}
stringBuilder.append(" -").append(c.getClientUserName()).append("/n");
}
}
if (!helper) {
stringBuilder.append("No clients outside of lobbies").append("/n");
}
sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.updatePrintLobby + "$" + stringBuilder.toString());
}
/**
* Lists all players in the client's lobby. If the client is not in a Lobby, it will say "You are
* not in a lobby."
@ -627,8 +692,15 @@ public class ClientHandler implements Runnable {
public void sendHighScoreList() {
String list = OgGhostHighScore.formatGhostHighscoreList();
String[] listarray = list.split("\\R");
for (String s: listarray) {
StringBuilder forGui = new StringBuilder();
for (String s : listarray) {
sendAnnouncementToClient(s);
forGui.append(s).append("/n");
}
sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.updateHighScore + "$" + forGui.toString());
}
}

View File

@ -65,6 +65,8 @@ public class JServerProtocolParser {
} catch (Exception e) {
h.setUsernameOnLogin("U.N. Owen");
}
h.guiUpdateAll(Protocol.printToGUI + "$" + GuiParameters.newPlayerOnServer + "$"
+ h.getClientUserName());
break;
case Protocol.nameChange:
h.changeUsername(msg.substring(6));
@ -82,7 +84,7 @@ public class JServerProtocolParser {
try {
int i = Integer.parseInt(msg.substring(6, 7));
h.joinLobby(i);
h.sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.viewChangeToLobby + "$");
//h.guiUpdateAll(Protocol.printToGUI+"$"+GuiParameters.addNewMemberToLobby+"$"+i+":"+h.getClientUserName()); handled in joinLobby()
} catch (Exception e) {
h.sendMsgToClient(Protocol.printToClientConsole
+ "$Invalid input. Please use JOINL$1 to join Lobby 1, for example.");
@ -90,17 +92,21 @@ public class JServerProtocolParser {
break;
case Protocol.createNewLobby:
h.createNewLobby();
h.sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.viewChangeToLobby+ "$");
h.guiUpdateAll(
Protocol.printToGUI + "$" + GuiParameters.newLobbyCreated + "$" + h.getLobby()
.getLobbyID() + ":" + h.getClientUserName());
LOGGER.info("Here");
break;
case Protocol.listLobbies:
h.listLobbies();
h.listLobbiesGuiFormat();
break;
case Protocol.listPlayersInLobby:
h.listPlayersInLobby();
break;
case Protocol.leaveLobby:
h.leaveLobby();
//h.sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.viewChangeToStart + "$"); (commented out due to compiling error)
h.sendMsgToClient(Protocol.printToGUI + "$" + GuiParameters.viewChangeToLobby + "$");
break;
case Protocol.votedFor:
LOGGER.debug("Made it here");
@ -109,7 +115,7 @@ public class JServerProtocolParser {
break;
case Protocol.startANewGame:
h.startNewGame();
//h.sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToGame + "$"); (commented out due to compiling error)
h.sendMsgToClientsInLobby(Protocol.printToGUI + "$" + GuiParameters.viewChangeToGame + "$");
break;
case Protocol.listGames:
h.listGames();
@ -119,7 +125,7 @@ public class JServerProtocolParser {
break;
case Protocol.sendMessageToAllClients:
msg = msg.substring(6);
h.sendMsgToClient(msg);
h.sendMsgToClientsInLobby(msg);
default:
System.out.println("Received unknown command");
}

View File

@ -12,9 +12,9 @@
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.text.Font?>
<AnchorPane fx:id="chatPaneRoot" prefHeight="251.0" prefWidth="343.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController">
<AnchorPane fx:id="chatPaneRoot" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.chat.ChatController">
<children>
<GridPane alignment="CENTER" layoutY="149.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="251.0" prefWidth="343.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<GridPane alignment="CENTER" layoutY="149.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="273.5" prefWidth="2072.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="100.0" />
</columnConstraints>
@ -34,19 +34,19 @@
</AnchorPane>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" GridPane.rowIndex="1">
<children>
<GridPane alignment="CENTER" layoutX="10.0" layoutY="20.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="75.0" prefWidth="343.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<GridPane alignment="CENTER" layoutX="10.0" layoutY="20.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="82.0" prefWidth="2072.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="7.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="67.0" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="3.0" />
<ColumnConstraints hgrow="SOMETIMES" percentWidth="10.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="20.0" percentWidth="87.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" percentHeight="90.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="92.0" prefWidth="98.0" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="56.0" prefWidth="125.0" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<children>
<Button fx:id="sendButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="157.0" prefWidth="223.5" text="Send" textOverrun="CENTER_WORD_ELLIPSIS" wrapText="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<Button fx:id="sendButton" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" prefHeight="56.0" prefWidth="178.0" text="Send" textOverrun="CENTER_WORD_ELLIPSIS" wrapText="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<font>
<Font size="10.0" />
</font></Button>
@ -57,7 +57,7 @@
</AnchorPane>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="92.0" prefWidth="85.0" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<children>
<TextField fx:id="whisperTargetSelectField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="50.0" prefWidth="79.0" promptText="whisper..." AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<TextField fx:id="whisperTargetSelectField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="56.0" prefWidth="488.0" promptText="whisper..." AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
<GridPane.margin>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
@ -65,7 +65,7 @@
</AnchorPane>
<AnchorPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="92.0" prefWidth="366.0" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.hgrow="ALWAYS" GridPane.valignment="CENTER" GridPane.vgrow="ALWAYS">
<children>
<TextField fx:id="chatMsgField" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="50.0" prefWidth="213.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<TextField fx:id="chatMsgField" layoutX="-420.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="56.0" prefWidth="1372.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
<GridPane.margin>
<Insets bottom="3.0" left="3.0" right="3.0" top="3.0" />
@ -86,7 +86,7 @@
</AnchorPane>
</children>
</GridPane>
<GridPane fx:id="vBoxGridPane" alignment="CENTER" disable="true" layoutX="-14.0" layoutY="-235.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="167.0" prefWidth="331.0">
<GridPane fx:id="vBoxGridPane" alignment="CENTER" disable="true" layoutX="-14.0" layoutY="-235.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
<columnConstraints>
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="10.0" percentWidth="73.0" prefWidth="100.0" />
<ColumnConstraints hgrow="ALWAYS" maxWidth="1.7976931348623157E308" minWidth="10.0" percentWidth="66.0" prefWidth="100.0" />

View File

@ -9,18 +9,18 @@
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.TextFlow?>
<AnchorPane id="BG" fx:id="gameBG" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1080.0" prefWidth="1920.0" styleClass="theme" stylesheets="@GameDay.css" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController">
<AnchorPane id="BG" fx:id="gameBG" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" styleClass="theme" stylesheets="@GameDay.css" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.game.GameController">
<children>
<Group fx:id="roomButtonGroupDay" layoutX="230.5" layoutY="220.0">
<children>
<HBox fx:id="notificationHBox" layoutX="50.0" layoutY="-74.0" rotate="12.4">
<HBox fx:id="notificationHBox" layoutX="20.0" layoutY="-55.0" rotate="12.4">
<children>
<ImageView fx:id="noiseImage0" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="noiseImage1" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="noiseImage2" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="noiseImage3" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="noiseImage4" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="noiseImage5" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" />
<ImageView fx:id="noiseImage0" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" rotate="-12.4" />
<ImageView fx:id="noiseImage1" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" rotate="-12.4" />
<ImageView fx:id="noiseImage2" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" rotate="-12.4" />
<ImageView fx:id="noiseImage3" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" rotate="-12.4" />
<ImageView fx:id="noiseImage4" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" rotate="-12.4" />
<ImageView fx:id="noiseImage5" fitHeight="150.0" fitWidth="125.0" pickOnBounds="true" preserveRatio="true" rotate="-12.4" />
</children>
</HBox>
<Button id="room1" fx:id="buttonRoom0" accessibleRole="RADIO_BUTTON" alignment="TOP_CENTER" contentDisplay="GRAPHIC_ONLY" layoutX="21.5" minWidth="-Infinity" mnemonicParsing="false" onAction="#sendVote0" prefHeight="110.0" prefWidth="90.0" text="room0">
@ -95,22 +95,23 @@
</ImageView>
</graphic>
</Button>
<HBox fx:id="roomLables" alignment="CENTER" layoutY="80.0" prefHeight="62.0" prefWidth="747.0" rotate="12.4">
<HBox fx:id="roomLables" alignment="CENTER" layoutY="82.0" prefHeight="62.0" prefWidth="747.0" rotate="12.2">
<children>
<TextFlow fx:id="lableRoom0" prefHeight="200.0" prefWidth="200.0" />
<TextFlow fx:id="lableRoom1" prefHeight="200.0" prefWidth="200.0" />
<TextFlow fx:id="lableRoom2" prefHeight="200.0" prefWidth="200.0" />
<TextFlow fx:id="lableRoom3" prefHeight="200.0" prefWidth="200.0" />
<TextFlow fx:id="lableRoom4" prefHeight="200.0" prefWidth="200.0" />
<TextFlow fx:id="lableRoom5" prefHeight="200.0" prefWidth="200.0" />
<TextFlow fx:id="lableRoom0" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
<TextFlow fx:id="lableRoom1" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
<TextFlow fx:id="lableRoom2" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
<TextFlow fx:id="lableRoom3" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
<TextFlow fx:id="lableRoom4" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
<TextFlow fx:id="lableRoom5" prefHeight="200.0" prefWidth="200.0" textAlignment="CENTER" />
</children>
</HBox>
</children>
</Group>
<Button fx:id="noiseButton" alignment="CENTER" layoutX="267.0" layoutY="636.0" mnemonicParsing="false" onAction="#noise" prefHeight="114.0" prefWidth="217.0" text="I heard some noise">
<Button fx:id="noiseButton" alignment="CENTER" layoutX="267.0" layoutY="482.0" mnemonicParsing="false" onAction="#noise" prefHeight="114.0" prefWidth="217.0" text="I heard some noise">
<font>
<Font name="System Bold" size="21.0" />
</font></Button>
<TextFlow fx:id="notificationText" layoutX="581.0" layoutY="386.0" prefHeight="200.0" prefWidth="800.0" textAlignment="CENTER" />
<TextFlow fx:id="notificationText" accessibleRole="PARENT" layoutX="210.0" layoutY="20.0" prefHeight="200.0" prefWidth="800.0" textAlignment="CENTER" />
<AnchorPane fx:id="chatAreaGame" />
</children>
</AnchorPane>

View File

@ -1,44 +1,63 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.ToolBar?>
<?import javafx.scene.control.TreeView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.shape.Line?>
<?import javafx.scene.text.TextFlow?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="1080.0" prefWidth="1920.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController">
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ch.unibas.dmi.dbis.cs108.multiplayer.client.gui.lounge.LoungeSceneViewController">
<children>
<BorderPane fx:id="LoungeSceneBorderPane" layoutX="860.0" layoutY="440.0" prefHeight="1080.0" prefWidth="1920.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<BorderPane fx:id="LoungeSceneBorderPane" layoutX="860.0" layoutY="440.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<top>
<ToolBar fx:id="NTtBToolBar" prefHeight="77.0" prefWidth="1913.0" BorderPane.alignment="CENTER">
<ToolBar fx:id="NTtBToolBar" prefHeight="77.0" BorderPane.alignment="CENTER">
<items>
<Button fx:id="ChangeNameButton" mnemonicParsing="false" text="Change Name" />
<Button fx:id="highScoreButton" mnemonicParsing="false" onAction="#sendHIghScore" text="High Score" />
<Button fx:id="lobbyPrintButton" mnemonicParsing="false" onAction="#sendLilstle" text="Lobby List" />
<Button fx:id="LeaveServerButton" mnemonicParsing="false" text="Leave server" />
<Button fx:id="leaveLobbyButton" mnemonicParsing="false" onAction="#leaveLobby" text="Leave Lobby" />
<Button fx:id="ChangeNameButton" mnemonicParsing="false" text="Change Name" />
</items>
</ToolBar>
</top>
<center>
<AnchorPane prefHeight="661.0" prefWidth="600.0" BorderPane.alignment="CENTER">
<AnchorPane BorderPane.alignment="CENTER">
<children>
<Button fx:id="newGameButton" mnemonicParsing="false" text="New Game" />
<Button fx:id="newGameButton" layoutX="34.0" layoutY="101.0" mnemonicParsing="false" text="New Lobby" />
<AnchorPane fx:id="gameAnchorPane" />
<Button fx:id="startGame" layoutX="68.0" layoutY="156.0" mnemonicParsing="false" onAction="#startGame" opacity="0.0" text="Start Game" />
</children>
</AnchorPane>
</center>
<bottom>
<AnchorPane fx:id="ChatArea" prefHeight="342.0" prefWidth="1920.0" BorderPane.alignment="CENTER">
<AnchorPane fx:id="ChatArea" BorderPane.alignment="CENTER">
<children>
<HBox fx:id="ChatAreaHBox" layoutX="394.0" layoutY="-9.0" prefHeight="322.0" prefWidth="1920.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
<SplitPane fx:id="chatSplitPane" dividerPositions="0.46467817896389324" minHeight="50.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane fx:id="chatAnchorPane" minHeight="0.0" minWidth="0.0" />
<AnchorPane fx:id="otherNotificationAnchorPane" minHeight="0.0" minWidth="0.0">
<children>
<Label text="High Score:" />
<TextFlow fx:id="highScore" layoutY="18.0" prefHeight="30.0" prefWidth="99.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="239.0" AnchorPane.topAnchor="18.0" />
<Label layoutX="120.0" text="Lobbies:" />
<TextFlow fx:id="lobbyPrint" layoutX="120.0" layoutY="18.0" />
<Line endX="-6.5" endY="-24.0" layoutX="120.0" layoutY="24.0" startX="-6.5" startY="48.5" AnchorPane.bottomAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</bottom>
<left>
<ListView fx:id="ClientListView" prefHeight="681.0" prefWidth="661.0" BorderPane.alignment="CENTER" />
<ListView fx:id="ClientListView" BorderPane.alignment="CENTER" />
</left>
<right>
<ListView fx:id="LobbyListView" prefHeight="681.0" prefWidth="641.0" BorderPane.alignment="CENTER" />
<ListView fx:id="LobbyListView" BorderPane.alignment="CENTER" />
</right>
</BorderPane>
</children>