From b297c9edda387c94e2f1369c81ca166c210b228b Mon Sep 17 00:00:00 2001 From: Seraina Date: Fri, 8 Apr 2022 20:00:00 +0200 Subject: [PATCH 01/26] Implemented the GhostNPC vote and noise functions had to add Game game as a parameter in a couple of constructors, so everybody can always access the current game and its gamestate --- .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 19 ++++++- .../dbis/cs108/gamelogic/GameFunctions.java | 5 +- .../dbis/cs108/gamelogic/GhostifyHandler.java | 2 +- .../gamelogic/ServerGameInfoHandler.java | 31 ++++++++++++ .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 2 +- .../gamelogic/klassenstruktur/Ghost.java | 5 ++ .../gamelogic/klassenstruktur/GhostNPC.java | 49 ++++++++++++++++++- .../klassenstruktur/GhostPlayer.java | 4 +- .../gamelogic/klassenstruktur/Human.java | 5 ++ .../gamelogic/klassenstruktur/HumanNPC.java | 12 ++++- .../klassenstruktur/HumanPlayer.java | 4 +- .../gamelogic/klassenstruktur/Passenger.java | 32 +++++++++--- .../cs108/multiplayer/helpers/Protocol.java | 2 + 13 files changed, 154 insertions(+), 18 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 7b11695..8e39508 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -23,14 +23,29 @@ public class Game { * @param nrOfGhosts is the number of OG Ghosts you want to start with and * @param nrOfUsers is the number of active users at the time (non NPCs) */ - Game(int nrOfPlayers, int nrOfGhosts, int nrOfUsers) + public Game(int nrOfPlayers, int nrOfGhosts, int nrOfUsers) throws TrainOverflow { //ToDo: Who handles Exception how and where this.nrOfPlayers = nrOfPlayers; this.nrOfGhosts = nrOfGhosts; this.nrOfUsers = nrOfUsers; - this.gameFunctions = new GameFunctions(nrOfPlayers, nrOfGhosts, nrOfUsers); + this.gameFunctions = new GameFunctions(nrOfPlayers, nrOfGhosts, nrOfUsers, this); } + public GameFunctions getGameFunctions() { + return gameFunctions; + } + + public int getNrOfGhosts() { + return nrOfGhosts; + } + + public int getNrOfPlayers() { + return nrOfPlayers; + } + + public int getNrOfUsers() { + return nrOfUsers; + } public static void main(String[] args) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java index 0ca27de..6d50294 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java @@ -18,6 +18,7 @@ public class GameFunctions { int nrOfUsers; // safes how many clients are active in this Game Train train; // safes who sits where public Passenger[] passengerTrain; + protected Game game; /** * Constructs a GameFunctions instance where nrOfPlayers >= nrOfUsers. Fills passengerTrain with @@ -28,7 +29,7 @@ public class GameFunctions { * @param nrOfUsers is the number of active users at the time (non NPCs) * @throws TrainOverflow if nrOfPlayers < nrOfUsers */ - GameFunctions(int nrOfPlayers, int nrOfGhosts, int nrOfUsers) + GameFunctions(int nrOfPlayers, int nrOfGhosts, int nrOfUsers, Game game) throws TrainOverflow { //ToDo: where will Exception be handled? this.nrOfPlayers = nrOfPlayers; this.nrOfGhosts = nrOfGhosts; @@ -36,7 +37,7 @@ public class GameFunctions { this.train = new Train(nrOfPlayers, nrOfUsers); Passenger[] passengerTrain = new Passenger[nrOfPlayers]; //Creates an array with Passengers with correlation positions (Train) for (int i = 0; i < nrOfPlayers; i++) { - Human h = new Human(); + Human h = new Human(game); h.setPosition(train.orderOfTrain[i]); passengerTrain[train.orderOfTrain[i]] = h; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java index f3ea707..9d40480 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java @@ -21,7 +21,7 @@ public class GhostifyHandler { LOGGER.debug("Passenger Position " + p.getPosition()); p.setGhost(); Ghost g; - g = new Ghost(); + g = new Ghost(game); g.setGhost(); g.setPosition(p.getPosition()); game.gameFunctions.passengerTrain[g.getPosition()] = g; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index 63740eb..6599e46 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -1,6 +1,10 @@ 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.Protocol; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; /** * Handles all communications Server to Client concerning game state or game state related requests @@ -10,6 +14,28 @@ import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; */ public class ServerGameInfoHandler { + public static final Logger LOGGER = LogManager.getLogger(); + public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + + /** + * Gets a string msg from somewhere and formats it into protocol messages + * @param msg the message to be formatted + * @return a message in a protocol format + */ + public static String format(String msg) { + switch (msg) { + case "Vote on who to ghostify!": + msg = Protocol.serverRequestsGhostVote; + break; + case "Vote for a ghost to kick off!": + msg = Protocol.serverRequestsHumanVote; + break; + default: + msg = Protocol.printToClientConsole + "$" + msg; + } + LOGGER.info(msg); + return msg; + } /** * TODO(Seraina): Handle NPC's Maybe do that in Passenger send methode! @@ -32,4 +58,9 @@ public class ServerGameInfoHandler { passenger.getClientHandler().sendMsgToClient("HVOTR"); } + public static void main(String[] args) { + ServerGameInfoHandler s = new ServerGameInfoHandler(); + s.format("jhbvdwfzu"); + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index f2ed804..0168544 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -222,7 +222,7 @@ public class VoteHandler { VoteHandler voteHandler = new VoteHandler(); Passenger[] testArray = game.gameFunctions.passengerTrain; - Passenger ghost = new Ghost(); + Passenger ghost = new Ghost(game); testArray[3] = ghost; testArray[3].setGhost(); testArray[3].setIsOg(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java index 2b7a53b..42b61e2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -8,6 +9,10 @@ public class Ghost extends Passenger { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + public Ghost(Game game) { + super(game); + } + public boolean getIsOG() { return isOG; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index 678659b..012d796 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -1,6 +1,8 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.TrainOverflow; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -15,7 +17,8 @@ public class GhostNPC extends Ghost { * @param name player name. if null, then a default name is used. * @param isOG true if the ghost is the original ghost. */ - public GhostNPC(int position, String name, boolean isOG) { + public GhostNPC(int position, String name, boolean isOG, Game game) { + super(game); this.isOG = isOG; this.position = position; this.clientHandler = null; @@ -28,4 +31,48 @@ public class GhostNPC extends Ghost { this.name = name; } } + + /** + * Sets vote of this Ghost position on a number between 0 and 5, + * but only for positions where there aren't any ghosts and sets hasVoted to true + */ + public void vote(Game game){ + int ghostCounter = 0; + Passenger[] train = game.getGameFunctions().passengerTrain; + for(Passenger passenger : train) { + if(passenger.isGhost) { + ghostCounter++; + } + } + int[] humanPositions = new int[game.getNrOfPlayers() - ghostCounter ]; + int j = 0; + for (int i = 0; i < train.length; i++) { + if (!train[i].isGhost) { //is human + humanPositions[j] = train[i].getPosition(); + j++; + } + } + int randomPosition = (int) (Math.random()*humanPositions.length); + vote = humanPositions[randomPosition]; + hasVoted = true; + LOGGER.info("GhostNPC at Position: " + this.getPosition() + " has voted for: " + vote); + } + + public void noise() { + clientHandler.broadcastChatMessage("I heard some noise tonight"); + } + + public static void main(String[] args) { + + try { + Game game = new Game(6,1,1); + Passenger p = new Passenger(game); + GhostNPC ghostNPC = new GhostNPC(2,"peter", false, game); + p = ghostNPC; + ghostNPC.vote(game); + } catch (TrainOverflow e) { + LOGGER.warn(e.getMessage()); + } + + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index 86f7634..b1cf476 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -17,7 +18,8 @@ public class GhostPlayer extends Ghost { * @param name name. if null, then a default name is used. * @param isOG true if the ghost is the original ghost. */ - public GhostPlayer(int position, String name, ClientHandler clientHandler, boolean isOG) { + public GhostPlayer(int position, String name, ClientHandler clientHandler, boolean isOG, Game game) { + super(game); this.position = position; this.clientHandler = clientHandler; this.isOG = isOG; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java index 32cf43c..f0aa39d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -8,4 +9,8 @@ public class Human extends Passenger { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + public Human(Game game) { + super(game); + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java index de59581..f637160 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -14,7 +15,8 @@ public class HumanNPC extends Human { * @param position position on the train * @param name player name. if null, then a default name is used. */ - public HumanNPC(int position, String name) { + public HumanNPC(int position, String name, Game game) { + super(game); this.position = position; this.clientHandler = null; isGhost = false; @@ -26,4 +28,12 @@ public class HumanNPC extends Human { this.name = name; } } + + /** + * Currently returns a random integer for voting + * @return integer between 0 and 5 + */ + public int vote(){ + return (int) (Math.random()*6); + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index ae57655..167c7fc 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -16,7 +17,8 @@ public class HumanPlayer extends Human { * @param position position on the train * @param name name. if null, then a default name is used. */ - public HumanPlayer(int position, String name, ClientHandler clientHandler, boolean isOG) { + public HumanPlayer(int position, String name, ClientHandler clientHandler, boolean isOG, Game game) { + super(game); this.position = position; this.clientHandler = clientHandler; isGhost = false; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index aa52c83..6328509 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -1,7 +1,9 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; +import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -19,13 +21,18 @@ public class Passenger { protected ClientHandler clientHandler;//the socket for the client associated with this Passenger, for NPCs, this can be null. protected boolean hasVoted; //true if the player gave his vote during voting time protected int vote; //saves the number of the player this passenger voted for during voting (0-5) - int sendcounter = 0; + protected Game game; + + Passenger(Game game) { + this.game = game; + } + /** * Sends a protocol message to the respective player or NPC. * @param msg the message that is sent to this player. **/ public void send(String msg) { - sendcounter++; + /*sendcounter++; if (msg.equals("Vote on who to ghostify!")) { vote = 1*sendcounter; hasVoted = true; // for testing, when is it set to false again? @@ -37,13 +44,21 @@ public class Passenger { } else { LOGGER.debug(msg); - } - /*if (isPlayer) { - //TODO: maybe put a formatter here, so protocol msg are only send between sever-client - clientHandler.sendMsgToClient(msg); //ToDO(Seraina): Make sure only the right kind of messages are sent - } else { //is a NPC - //TODO: call a method that identifies message for NPC and calls respective methode NPCParser }*/ + if (isPlayer) { + String formattedMsg = ServerGameInfoHandler.format(msg); + clientHandler.sendMsgToClient(formattedMsg); + } else { //is a NPC + if(isGhost) { + + + + } else { //is a human + + } + + //TODO: call a method that identifies message for NPC and calls respective methode NPCParser + } } /** @@ -116,4 +131,5 @@ public class Passenger { public ClientHandler getClientHandler() { return clientHandler; } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java index e845d8d..72153c4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java @@ -128,4 +128,6 @@ public class Protocol { public static final String serverRequestsHumanVote = "HVOTR"; + + } From f878bee40d6b70e6f19651e26d5ded0ff207dea2 Mon Sep 17 00:00:00 2001 From: Seraina Date: Fri, 8 Apr 2022 20:52:36 +0200 Subject: [PATCH 02/26] added return for humanvote to know when the game ends --- .../ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 0168544..08e1817 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -104,10 +104,11 @@ public class VoteHandler { * ghosts are waiting. Votes are being collected, vote results are being handled in three possible * ways: if passenger who was voted for is a human, continue with next ghost vote; if it's a * normal ghost, kick him off; if it's the OG ghost, end game, humans win. - * + * @return Returns an empty String by default, returns a complex string when game is over: + * "Game over: ghosts win!" or "Game over: humans win!" * @param passengers: train passengers */ - public void humanVote(Passenger[] passengers, Game game) { + public String humanVote(Passenger[] passengers, Game game) { // array to collect votes for all players during voting, i.e. votes for player 1 are saved in @@ -163,6 +164,7 @@ public class VoteHandler { if (passengers[voteIndex].getIsGhost()) { // if player is a ghost if (passengers[voteIndex].getIsOG()) { // if ghost is OG --> end game, humans win System.out.println("Game over: humans win!"); // TODO: correctly handle end of game + return "Game over: humans win!"; } else { /* Special case: if ghost is not OG and if only one human is left (--> last human didn't vote for OG ghost), ghosts win. @@ -175,6 +177,7 @@ public class VoteHandler { } if (humans == 1) { System.out.println("Game over: ghosts win!"); + return "Game over: ghosts win!"; } // Usual case: there is more than one human left and a normal ghost has been voted for --> // kick this ghost off @@ -188,6 +191,7 @@ public class VoteHandler { for (Passenger passenger : passengers) { passenger.setHasVoted(false); } + return ""; } /** From 5b4a06dd753988bfeb91db41efe2318bbdeae074 Mon Sep 17 00:00:00 2001 From: Seraina Date: Fri, 8 Apr 2022 21:00:57 +0200 Subject: [PATCH 03/26] Implemented a run method in game, that goes through a game until it ends --- .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 26 ++++++++++++ .../dbis/cs108/gamelogic/GameFunctions.java | 30 ++++++++----- .../gamelogic/ServerGameInfoHandler.java | 42 +++++++++++-------- .../gamelogic/klassenstruktur/GhostNPC.java | 8 +++- .../klassenstruktur/GhostPlayer.java | 6 ++- .../gamelogic/klassenstruktur/HumanNPC.java | 10 +++++ .../klassenstruktur/HumanPlayer.java | 7 +++- .../gamelogic/klassenstruktur/Passenger.java | 24 +---------- 8 files changed, 100 insertions(+), 53 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 8e39508..d0b58e9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.*; public class Game { @@ -15,6 +16,8 @@ public class Game { protected int nrOfGhosts; // sets how many Ghosts we start witch protected int nrOfUsers; // safes how many clients are active in this Game protected GameFunctions gameFunctions; + protected boolean isDay; //false means it is night, it is night by default + protected VoteHandler voteHandler; //TODO: Figure out where Day/Night game state is saved maybe think about a game state class or smt. /** * Constructs a Game instance where: @@ -47,12 +50,35 @@ public class Game { return nrOfUsers; } + public void setDay(boolean day) { + isDay = day; + } + + public void run(ClientHandler clientHandler) { + int i = 0; + String gameOverCheck = ""; + while (true) { //ToDo: was ist die Abbruchbedingung? VoteHandler muss das schicken. + if (!isDay) { + voteHandler.ghostVote(gameFunctions.getPassengerTrain(), this); + setDay(true); + } else { + gameOverCheck = voteHandler.humanVote(gameFunctions.getPassengerTrain(), this); + } + if (gameOverCheck.equals("Game over: ghosts win!") || gameOverCheck.equals("Game over: humans win!")){ + clientHandler.broadcastAnnouncement(gameOverCheck); + return; + } + } + + } + public static void main(String[] args) { try { Game game1 = new Game(6, 1, 1); + } catch (TrainOverflow e) { System.out.println(e.getMessage()); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java index 6d50294..1a4358e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Ghost; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Human; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import org.apache.logging.log4j.LogManager; @@ -13,11 +14,11 @@ public class GameFunctions { /** * Can be extended for optional Game-settings **/ - int nrOfPlayers; //sets the length of the train - int nrOfGhosts; // sets how many Ghosts we start witch - int nrOfUsers; // safes how many clients are active in this Game - Train train; // safes who sits where - public Passenger[] passengerTrain; + protected int nrOfPlayers; //sets the length of the train + protected int nrOfGhosts; // sets how many Ghosts we start witch + protected int nrOfUsers; // safes how many clients are active in this Game + protected Train train; // safes who sits where + protected Passenger[] passengerTrain; protected Game game; /** @@ -37,10 +38,18 @@ public class GameFunctions { this.train = new Train(nrOfPlayers, nrOfUsers); Passenger[] passengerTrain = new Passenger[nrOfPlayers]; //Creates an array with Passengers with correlation positions (Train) for (int i = 0; i < nrOfPlayers; i++) { - Human h = new Human(game); - h.setPosition(train.orderOfTrain[i]); - passengerTrain[train.orderOfTrain[i]] = h; + if (i == 3) { + Ghost g = new Ghost(game); + g.setPosition(train.orderOfTrain[i]); + g.setIsOG(true); + passengerTrain[train.orderOfTrain[i]] = g; + } else { + Human h = new Human(game); + h.setPosition(train.orderOfTrain[i]); + passengerTrain[train.orderOfTrain[i]] = h; + } } + this.passengerTrain = passengerTrain; } @@ -56,6 +65,7 @@ public class GameFunctions { return nrOfUsers; } - - + public Passenger[] getPassengerTrain() { + return passengerTrain; + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index 6599e46..f5a104e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -1,6 +1,9 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Ghost; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.GhostNPC; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.HumanNPC; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import org.apache.logging.log4j.LogManager; @@ -37,26 +40,31 @@ public class ServerGameInfoHandler { return msg; } - /** - * TODO(Seraina): Handle NPC's Maybe do that in Passenger send methode! - * Send a message "GVOTR" to a passenger urging them to vote for a human to infect - * Currently only handles only Players, so send a message to corresponding client - * @param passenger the passenger the message is meant to, should be a Ghost - */ - public void sendVoteRequestGhosts(Passenger passenger){ - passenger.getClientHandler().sendMsgToClient("GVOTR"); + public static void ghostNpcParser(GhostNPC npc, String msg, Game game) { + switch (msg) { + case "noise": + npc.noise(); + break; + case "Vote on who to ghostify!": + npc.vote(game); + } + + + } + + public static void humanNpcParser(HumanNPC npc, String msg, Game game) { + switch (msg) { + case "noise": + npc.noise(); + break; + case "Vote for a ghost to kick off!": + npc.vote(); + } + + } - /** - * TODO(Seraina): Handle NPC's - * Send a message "HVOTR" to a passenger urging them to vote for sm to kick off the train. - * Currently only handles only Players, so send a message to corresponding client - * @param passenger the passenger the message is meant to, can be either human or ghost - */ - public void sendVoteRequestHumans(Passenger passenger){ - passenger.getClientHandler().sendMsgToClient("HVOTR"); - } public static void main(String[] args) { ServerGameInfoHandler s = new ServerGameInfoHandler(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index 012d796..4a500ba 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; import ch.unibas.dmi.dbis.cs108.gamelogic.TrainOverflow; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -32,13 +33,18 @@ public class GhostNPC extends Ghost { } } + @Override + public void send(String msg) { + ServerGameInfoHandler.ghostNpcParser(this, msg, game); + } + /** * Sets vote of this Ghost position on a number between 0 and 5, * but only for positions where there aren't any ghosts and sets hasVoted to true */ public void vote(Game game){ int ghostCounter = 0; - Passenger[] train = game.getGameFunctions().passengerTrain; + Passenger[] train = game.getGameFunctions().getPassengerTrain(); for(Passenger passenger : train) { if(passenger.isGhost) { ghostCounter++; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index b1cf476..cfdcc6c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -34,7 +35,10 @@ public class GhostPlayer extends Ghost { } + @Override public void send(String msg) { - //todo(Jonas): pass message along to client. + String formattedMsg = ServerGameInfoHandler.format(msg); + clientHandler.sendMsgToClient(formattedMsg); } } + diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java index f637160..4616ded 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -29,6 +30,11 @@ public class HumanNPC extends Human { } } + @Override + public void send(String msg) { + ServerGameInfoHandler.humanNpcParser(this, msg, game); + } + /** * Currently returns a random integer for voting * @return integer between 0 and 5 @@ -36,4 +42,8 @@ public class HumanNPC extends Human { public int vote(){ return (int) (Math.random()*6); } + + public void noise() { + clientHandler.broadcastChatMessage("I heard some noise tonight"); + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index 167c7fc..80a8d6f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -31,5 +32,9 @@ public class HumanPlayer extends Human { } } - + @Override + public void send(String msg) { + String formattedMsg = ServerGameInfoHandler.format(msg); + clientHandler.sendMsgToClient(formattedMsg); + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index 6328509..bde4cb4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -32,33 +32,11 @@ public class Passenger { * @param msg the message that is sent to this player. **/ public void send(String msg) { - /*sendcounter++; - if (msg.equals("Vote on who to ghostify!")) { - vote = 1*sendcounter; - hasVoted = true; // for testing, when is it set to false again? - LOGGER.info("Voted for Position " + vote); - } else if(msg.equals("Vote for a ghost to kick off!")) { - vote = (int) (0.5*sendcounter); - hasVoted = true; // for testing, when is it set to false again? - LOGGER.info("Voted for Position " + vote); - } else { - - LOGGER.debug(msg); - }*/ if (isPlayer) { String formattedMsg = ServerGameInfoHandler.format(msg); clientHandler.sendMsgToClient(formattedMsg); - } else { //is a NPC - if(isGhost) { - - - - } else { //is a human - - } - - //TODO: call a method that identifies message for NPC and calls respective methode NPCParser } + LOGGER.warn("This object should not just be a passenger"); } /** From 3b0bc40ad04b69d4c2f41ade33f37cf8e80375f4 Mon Sep 17 00:00:00 2001 From: Seraina Date: Fri, 8 Apr 2022 22:23:00 +0200 Subject: [PATCH 04/26] Tried implementing a simple command for server that starts up a game, didn't work so I had to readjust some things --- Meilenstein II/Protocol.txt | 1 + .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 75 ++++++++++++++----- .../{GameFunctions.java => GameState.java} | 52 +++++++------ .../dbis/cs108/gamelogic/GhostifyHandler.java | 4 +- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 18 ++--- .../gamelogic/klassenstruktur/Ghost.java | 4 +- .../gamelogic/klassenstruktur/GhostNPC.java | 8 +- .../klassenstruktur/GhostPlayer.java | 8 +- .../gamelogic/klassenstruktur/Human.java | 3 - .../gamelogic/klassenstruktur/HumanNPC.java | 3 +- .../klassenstruktur/HumanPlayer.java | 8 +- .../gamelogic/klassenstruktur/Passenger.java | 7 +- .../cs108/multiplayer/helpers/Protocol.java | 5 ++ .../cs108/multiplayer/helpers/Protocol.txt | 1 + .../server/JServerProtocolParser.java | 10 +++ 15 files changed, 127 insertions(+), 80 deletions(-) rename src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/{GameFunctions.java => GameState.java} (62%) diff --git a/Meilenstein II/Protocol.txt b/Meilenstein II/Protocol.txt index 77ecf57..4471166 100644 --- a/Meilenstein II/Protocol.txt +++ b/Meilenstein II/Protocol.txt @@ -6,6 +6,7 @@ Implemented: * CPING Ping from client to server. * PINGB Pingback from client to server. * NAMEC$name Change name to whatever is specified + * STGAM start the Game Future / planned: * CRTGM Create a new game diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index d0b58e9..e3de4b7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -2,7 +2,13 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.GhostNPC; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.GhostPlayer; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.HumanNPC; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.HumanPlayer; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; +import java.util.HashSet; import org.apache.logging.log4j.*; public class Game { @@ -15,7 +21,7 @@ public class Game { protected int nrOfPlayers; //sets the length of the train protected int nrOfGhosts; // sets how many Ghosts we start witch protected int nrOfUsers; // safes how many clients are active in this Game - protected GameFunctions gameFunctions; + protected GameState gameState; protected boolean isDay; //false means it is night, it is night by default protected VoteHandler voteHandler; //TODO: Figure out where Day/Night game state is saved maybe think about a game state class or smt. @@ -31,11 +37,11 @@ public class Game { this.nrOfPlayers = nrOfPlayers; this.nrOfGhosts = nrOfGhosts; this.nrOfUsers = nrOfUsers; - this.gameFunctions = new GameFunctions(nrOfPlayers, nrOfGhosts, nrOfUsers, this); + this.gameState = new GameState(nrOfPlayers, nrOfGhosts, nrOfUsers); } - public GameFunctions getGameFunctions() { - return gameFunctions; + public GameState getGameState() { + return gameState; } public int getNrOfGhosts() { @@ -55,20 +61,53 @@ public class Game { } public void run(ClientHandler clientHandler) { - int i = 0; - String gameOverCheck = ""; - while (true) { //ToDo: was ist die Abbruchbedingung? VoteHandler muss das schicken. - if (!isDay) { - voteHandler.ghostVote(gameFunctions.getPassengerTrain(), this); - setDay(true); - } else { - gameOverCheck = voteHandler.humanVote(gameFunctions.getPassengerTrain(), this); - } - if (gameOverCheck.equals("Game over: ghosts win!") || gameOverCheck.equals("Game over: humans win!")){ - clientHandler.broadcastAnnouncement(gameOverCheck); - return; - } - } + int i = 0; + HashSet clients = ClientHandler.getConnectedClients(); + String gameOverCheck = ""; + int[] order = gameState.getTrain().orderOfTrain; + Passenger[] passengerTrain = gameState.getPassengerTrain(); + + + for (ClientHandler client : clients) { + int index = order[i]; + if (passengerTrain[index].getIsGhost()) { //if there is a ghost + GhostPlayer ghostPlayer = new GhostPlayer(passengerTrain[index].getPosition(), + client.getClientUserName(), client, passengerTrain[index].getIsOG()); + gameState.getPassengerTrain()[index] = ghostPlayer; + } else { + HumanPlayer humanPlayer = new HumanPlayer(passengerTrain[index].getPosition(), + client.getClientUserName(), client, passengerTrain[index].getIsOG()); + gameState.getPassengerTrain()[index] = humanPlayer; + } + i++; + } + while (i < order.length) { + int index = order[i]; + if (passengerTrain[index].getIsGhost()) { //if there is a ghost + GhostNPC ghostNPC = new GhostNPC(passengerTrain[index].getPosition(), "NPC" + passengerTrain[index].getPosition(),passengerTrain[index].getIsOG() ,this); + gameState.getPassengerTrain()[index] = ghostNPC; + } else { + //ToDo: give NPC nice usernames + HumanNPC humanNPC = new HumanNPC(passengerTrain[index].getPosition(), "NPC" + passengerTrain[index].getPosition(),this); + gameState.getPassengerTrain()[index] = humanNPC; + } + i++; + } + + i = 0; + while (true) { //ToDo: was ist die Abbruchbedingung? VoteHandler muss das schicken. + if (!isDay) { + voteHandler.ghostVote(gameState.getPassengerTrain(), this); + setDay(true); + } else { + gameOverCheck = voteHandler.humanVote(gameState.getPassengerTrain(), this); + } + if (gameOverCheck.equals("Game over: ghosts win!") || gameOverCheck.equals( + "Game over: humans win!")) { + clientHandler.broadcastAnnouncement(gameOverCheck); + return; + } + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java similarity index 62% rename from src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java rename to src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index 1a4358e..cd69c3f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameFunctions.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -7,22 +7,25 @@ import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -public class GameFunctions { +public class GameState { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); /** * Can be extended for optional Game-settings **/ - protected int nrOfPlayers; //sets the length of the train - protected int nrOfGhosts; // sets how many Ghosts we start witch - protected int nrOfUsers; // safes how many clients are active in this Game - protected Train train; // safes who sits where - protected Passenger[] passengerTrain; - protected Game game; + public final int nrOfPlayers; //sets the length of the train + public final int nrOfGhosts; // sets how many Ghosts we start witch + public final int nrOfUsers; // safes how many clients are active in this Game + public final Train train; // safes who sits where + /** + * contains all Passengers on train, needs to be updated + */ + private Passenger[] passengerTrain; + /** - * Constructs a GameFunctions instance where nrOfPlayers >= nrOfUsers. Fills passengerTrain with + * Constructs a GameState instance where nrOfPlayers >= nrOfUsers. Fills passengerTrain with * only humans * * @param nrOfPlayers is the length of the Train @@ -30,7 +33,7 @@ public class GameFunctions { * @param nrOfUsers is the number of active users at the time (non NPCs) * @throws TrainOverflow if nrOfPlayers < nrOfUsers */ - GameFunctions(int nrOfPlayers, int nrOfGhosts, int nrOfUsers, Game game) + GameState(int nrOfPlayers, int nrOfGhosts, int nrOfUsers) throws TrainOverflow { //ToDo: where will Exception be handled? this.nrOfPlayers = nrOfPlayers; this.nrOfGhosts = nrOfGhosts; @@ -39,12 +42,12 @@ public class GameFunctions { Passenger[] passengerTrain = new Passenger[nrOfPlayers]; //Creates an array with Passengers with correlation positions (Train) for (int i = 0; i < nrOfPlayers; i++) { if (i == 3) { - Ghost g = new Ghost(game); + Ghost g = new Ghost(); g.setPosition(train.orderOfTrain[i]); g.setIsOG(true); passengerTrain[train.orderOfTrain[i]] = g; } else { - Human h = new Human(game); + Human h = new Human(); h.setPosition(train.orderOfTrain[i]); passengerTrain[train.orderOfTrain[i]] = h; } @@ -53,19 +56,22 @@ public class GameFunctions { this.passengerTrain = passengerTrain; } - public int getNrOfGhosts() { - return nrOfGhosts; - } - - public int getNrOfPlayers() { - return nrOfPlayers; - } - - public int getNrOfUsers() { - return nrOfUsers; - } - public Passenger[] getPassengerTrain() { return passengerTrain; } + + public Train getTrain() { + return train; + } + + /** + * Takes a given Passenger and puts it into the passengerTrain at a certain position + * @param passenger the new passenger being put into the train + * @param position the position of the passenger + */ + public void addNewPassenger(Passenger passenger, int position) { + passengerTrain[position] = passenger; + + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java index 9d40480..ff2a088 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java @@ -21,10 +21,10 @@ public class GhostifyHandler { LOGGER.debug("Passenger Position " + p.getPosition()); p.setGhost(); Ghost g; - g = new Ghost(game); + g = new Ghost(); g.setGhost(); g.setPosition(p.getPosition()); - game.gameFunctions.passengerTrain[g.getPosition()] = g; + game.gameState.addNewPassenger(g, g.getPosition()); LOGGER.info("Passenger at position " + p.getPosition() + "has been ghostified"); return g; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 08e1817..f96132f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -43,10 +43,10 @@ public class VoteHandler { for (Passenger passenger : passengers) { if (passenger.getIsGhost()) { - passenger.send("Vote on who to ghostify!"); + passenger.send("Vote on who to ghostify!", game); } else { passenger.send( - "Please wait, ghosts are active"); // TODO(Seraina): make sure whatever clients send in + "Please wait, ghosts are active", game); // TODO(Seraina): make sure whatever clients send in // this time, except chat is ignored } @@ -91,7 +91,7 @@ public class VoteHandler { Ghost g = gh.ghost(passengers[ghostPosition], game); passengers[ghostPosition] = g; passengers[ghostPosition].send( - "You are now a ghost!"); // TODO: ServerGameInfoHandler might deal with this one + "You are now a ghost!", game); // TODO: ServerGameInfoHandler might deal with this one // set hasVoted to false for all passengers for future votings for (Passenger passenger : passengers) { @@ -119,9 +119,9 @@ public class VoteHandler { // TODO: Messages in for-loop should probably be handled by ServerGameInfoHandler for (Passenger passenger : passengers) { if (passenger.getIsGhost()) { - passenger.send("Please wait, humans are active"); + passenger.send("Please wait, humans are active", game); } else { - passenger.send("Vote for a ghost to kick off!"); + passenger.send("Vote for a ghost to kick off!", game); } } @@ -158,7 +158,7 @@ public class VoteHandler { .getIsGhost()) { // if player with most votes is human, notify everyone about it for (Passenger passenger : passengers) { passenger.send( - "You voted for a human!"); // TODO: ServerGameInfoHandler might be better to use here + "You voted for a human!", game); // TODO: ServerGameInfoHandler might be better to use here } } if (passengers[voteIndex].getIsGhost()) { // if player is a ghost @@ -183,7 +183,7 @@ public class VoteHandler { // kick this ghost off passengers[voteIndex].setKickedOff(true); for (Passenger passenger : passengers) { - passenger.send("Player " + voteIndex + " has been kicked off!"); + passenger.send("Player " + voteIndex + " has been kicked off!", game); } } } @@ -225,8 +225,8 @@ public class VoteHandler { Game game = new Game(6,1, 6); VoteHandler voteHandler = new VoteHandler(); - Passenger[] testArray = game.gameFunctions.passengerTrain; - Passenger ghost = new Ghost(game); + Passenger[] testArray = game.gameState.getPassengerTrain(); + Passenger ghost = new Ghost(); testArray[3] = ghost; testArray[3].setGhost(); testArray[3].setIsOg(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java index 42b61e2..ad6e2e4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Ghost.java @@ -9,9 +9,7 @@ public class Ghost extends Passenger { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); - public Ghost(Game game) { - super(game); - } + public boolean getIsOG() { return isOG; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index 4a500ba..a201d4a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.GameState; import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; import ch.unibas.dmi.dbis.cs108.gamelogic.TrainOverflow; import org.apache.logging.log4j.LogManager; @@ -19,7 +20,6 @@ public class GhostNPC extends Ghost { * @param isOG true if the ghost is the original ghost. */ public GhostNPC(int position, String name, boolean isOG, Game game) { - super(game); this.isOG = isOG; this.position = position; this.clientHandler = null; @@ -34,7 +34,7 @@ public class GhostNPC extends Ghost { } @Override - public void send(String msg) { + public void send(String msg, Game game) { ServerGameInfoHandler.ghostNpcParser(this, msg, game); } @@ -44,7 +44,7 @@ public class GhostNPC extends Ghost { */ public void vote(Game game){ int ghostCounter = 0; - Passenger[] train = game.getGameFunctions().getPassengerTrain(); + Passenger[] train = game.getGameState().getPassengerTrain(); for(Passenger passenger : train) { if(passenger.isGhost) { ghostCounter++; @@ -72,7 +72,7 @@ public class GhostNPC extends Ghost { try { Game game = new Game(6,1,1); - Passenger p = new Passenger(game); + Passenger p = new Passenger(); GhostNPC ghostNPC = new GhostNPC(2,"peter", false, game); p = ghostNPC; ghostNPC.vote(game); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index cfdcc6c..d197ca0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -14,13 +14,11 @@ public class GhostPlayer extends Ghost { /** * Creates a new GhostPlayer. Should be used at game start or if a HumanPlayer is turned into a * ghost. - * - * @param position position on the train + * @param position position on the train * @param name name. if null, then a default name is used. * @param isOG true if the ghost is the original ghost. */ - public GhostPlayer(int position, String name, ClientHandler clientHandler, boolean isOG, Game game) { - super(game); + public GhostPlayer(int position, String name, ClientHandler clientHandler, boolean isOG) { this.position = position; this.clientHandler = clientHandler; this.isOG = isOG; @@ -36,7 +34,7 @@ public class GhostPlayer extends Ghost { @Override - public void send(String msg) { + public void send(String msg, Game game) { String formattedMsg = ServerGameInfoHandler.format(msg); clientHandler.sendMsgToClient(formattedMsg); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java index f0aa39d..ff86df7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Human.java @@ -9,8 +9,5 @@ public class Human extends Passenger { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); - public Human(Game game) { - super(game); - } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java index 4616ded..4c24749 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java @@ -17,7 +17,6 @@ public class HumanNPC extends Human { * @param name player name. if null, then a default name is used. */ public HumanNPC(int position, String name, Game game) { - super(game); this.position = position; this.clientHandler = null; isGhost = false; @@ -31,7 +30,7 @@ public class HumanNPC extends Human { } @Override - public void send(String msg) { + public void send(String msg, Game game) { ServerGameInfoHandler.humanNpcParser(this, msg, game); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index 80a8d6f..8b16cb0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -14,12 +14,10 @@ public class HumanPlayer extends Human { /** * Creates a new GhostPlayer. Should be used at game start or if a HumanPlayer is turned into a * ghost. - * - * @param position position on the train + * @param position position on the train * @param name name. if null, then a default name is used. */ - public HumanPlayer(int position, String name, ClientHandler clientHandler, boolean isOG, Game game) { - super(game); + public HumanPlayer(int position, String name, ClientHandler clientHandler, boolean isOG) { this.position = position; this.clientHandler = clientHandler; isGhost = false; @@ -33,7 +31,7 @@ public class HumanPlayer extends Human { } @Override - public void send(String msg) { + public void send(String msg, Game game) { String formattedMsg = ServerGameInfoHandler.format(msg); clientHandler.sendMsgToClient(formattedMsg); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index bde4cb4..c7e6573 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -21,17 +21,12 @@ public class Passenger { protected ClientHandler clientHandler;//the socket for the client associated with this Passenger, for NPCs, this can be null. protected boolean hasVoted; //true if the player gave his vote during voting time protected int vote; //saves the number of the player this passenger voted for during voting (0-5) - protected Game game; - - Passenger(Game game) { - this.game = game; - } /** * Sends a protocol message to the respective player or NPC. * @param msg the message that is sent to this player. **/ - public void send(String msg) { + public void send(String msg, Game game) { if (isPlayer) { String formattedMsg = ServerGameInfoHandler.format(msg); clientHandler.sendMsgToClient(formattedMsg); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java index 72153c4..658a0fd 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java @@ -92,6 +92,11 @@ public class Protocol { */ public static final String listLobbies = "LISTL"; + /** + * A Client decides to start the game + */ + public static final String startANewGame = "STGAM"; + //SERVER TO CLIENT COMMANDS diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.txt b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.txt index b050d31..550996a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.txt +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.txt @@ -11,6 +11,7 @@ Implemented: * PINGB Pingback from client to server. * NAMEC$name Change name to whatever is specified * CRTGM Create a new game + * Future / planned: diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index 0983bd4..d5d4309 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -2,6 +2,8 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.server; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.TrainOverflow; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; @@ -67,6 +69,14 @@ public class JServerProtocolParser { //TODO: add action LOGGER.debug(Protocol.listLobbies + " command recieved from: " + h.getClientUserName()); break; + case Protocol.startANewGame: + try { + Game game = new Game(6,1, h.getConnectedClients().size()); + game.run(h); + } catch (TrainOverflow e) { + LOGGER.warn(e.getMessage()); + } + default: System.out.println("Received unknown command"); } From ce3fa4dde11e86334979f7f6ebe2a9d5b1f558e6 Mon Sep 17 00:00:00 2001 From: Seraina Date: Fri, 8 Apr 2022 23:23:31 +0200 Subject: [PATCH 05/26] A very basic command now starts a game in the JServerProtocolParser (needs to bee relocated and but does the job for now) The game runs, now the Clients need to be able to give inputs (so it ends at some point) --- .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 37 ++++++++----------- .../dmi/dbis/cs108/gamelogic/GameState.java | 31 ++++++++++++++++ .../gamelogic/ServerGameInfoHandler.java | 10 +---- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 5 ++- .../gamelogic/klassenstruktur/GhostNPC.java | 4 +- .../klassenstruktur/GhostPlayer.java | 2 +- .../klassenstruktur/HumanPlayer.java | 2 +- .../gamelogic/klassenstruktur/Passenger.java | 2 +- .../dbis/cs108/multiplayer/client/Client.java | 9 +++++ .../server/JServerProtocolParser.java | 6 ++- 10 files changed, 70 insertions(+), 38 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index e3de4b7..3702db6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -11,19 +11,20 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import java.util.HashSet; import org.apache.logging.log4j.*; -public class Game { +public class Game implements Runnable { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); /** * Can be extended for optional Game-settings **/ - protected int nrOfPlayers; //sets the length of the train - protected int nrOfGhosts; // sets how many Ghosts we start witch + protected final int nrOfPlayers; //sets the length of the train + protected final int nrOfGhosts; // sets how many Ghosts we start witch protected int nrOfUsers; // safes how many clients are active in this Game protected GameState gameState; - protected boolean isDay; //false means it is night, it is night by default - protected VoteHandler voteHandler; + protected boolean isDay = false; //false means it is night, it is night by default + protected VoteHandler voteHandler = new VoteHandler(); + private ClientHandler clientHandler; //TODO: Figure out where Day/Night game state is saved maybe think about a game state class or smt. /** * Constructs a Game instance where: @@ -32,12 +33,13 @@ public class Game { * @param nrOfGhosts is the number of OG Ghosts you want to start with and * @param nrOfUsers is the number of active users at the time (non NPCs) */ - public Game(int nrOfPlayers, int nrOfGhosts, int nrOfUsers) + public Game(ClientHandler clientHandler, int nrOfPlayers, int nrOfGhosts, int nrOfUsers) throws TrainOverflow { //ToDo: Who handles Exception how and where this.nrOfPlayers = nrOfPlayers; this.nrOfGhosts = nrOfGhosts; this.nrOfUsers = nrOfUsers; this.gameState = new GameState(nrOfPlayers, nrOfGhosts, nrOfUsers); + this.clientHandler = clientHandler; } public GameState getGameState() { @@ -60,7 +62,9 @@ public class Game { isDay = day; } - public void run(ClientHandler clientHandler) { + @Override + public void run() { + LOGGER.info("the run-method has been called"); int i = 0; HashSet clients = ClientHandler.getConnectedClients(); String gameOverCheck = ""; @@ -68,6 +72,7 @@ public class Game { Passenger[] passengerTrain = gameState.getPassengerTrain(); + LOGGER.info(gameState.toString()); for (ClientHandler client : clients) { int index = order[i]; if (passengerTrain[index].getIsGhost()) { //if there is a ghost @@ -93,6 +98,7 @@ public class Game { } i++; } + LOGGER.info(gameState.toString()); i = 0; while (true) { //ToDo: was ist die Abbruchbedingung? VoteHandler muss das schicken. @@ -111,18 +117,7 @@ public class Game { } - public static void main(String[] args) { - - try { - - Game game1 = new Game(6, 1, 1); - - - } catch (TrainOverflow e) { - System.out.println(e.getMessage()); - } - - } - - } + + + diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index cd69c3f..70e00e1 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -44,6 +44,7 @@ public class GameState { if (i == 3) { Ghost g = new Ghost(); g.setPosition(train.orderOfTrain[i]); + g.setGhost(); g.setIsOG(true); passengerTrain[train.orderOfTrain[i]] = g; } else { @@ -74,4 +75,34 @@ public class GameState { } + public String toString() { + Passenger[] array = passengerTrain; + StringBuilder stringBuilder = new StringBuilder(); + String[] print = new String[6]; + for (int i = 0; i < array.length; i++) { + if (array[i].getKickedOff()) { + print[i] = "| kicked off " + array[i].getPosition() + "|"; + } else { + if (array[i].getIsPlayer()) { + if (array[i].getIsGhost()) { + print[i] = "| ghostPlayer " + array[i].getPosition() + "|"; + } else { + print[i] = "| humanPlayer " + array[i].getPosition() + "|"; + } + } else { + if (array[i].getIsGhost()) { + print[i] = "| ghostNPC " + array[i].getPosition() + "|"; + } else { + print[i] = "| humanNPC " + array[i].getPosition() + "|"; + } + } + } + } + + for (int i = 0; i < array.length; i++) { + stringBuilder.append(print[i]); + } + return stringBuilder.toString(); + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index f5a104e..3613ce6 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -25,10 +25,10 @@ public class ServerGameInfoHandler { * @param msg the message to be formatted * @return a message in a protocol format */ - public static String format(String msg) { + public static String format(String msg, Game game) { switch (msg) { case "Vote on who to ghostify!": - msg = Protocol.serverRequestsGhostVote; + msg = Protocol.serverRequestsGhostVote + "$" + game.gameState.toString(); break; case "Vote for a ghost to kick off!": msg = Protocol.serverRequestsHumanVote; @@ -65,10 +65,4 @@ public class ServerGameInfoHandler { } - - public static void main(String[] args) { - ServerGameInfoHandler s = new ServerGameInfoHandler(); - s.format("jhbvdwfzu"); - } - } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index f96132f..7be4084 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -32,6 +32,7 @@ public class VoteHandler { * @param passengers: passengers on the train */ public void ghostVote(Passenger[] passengers, Game game) { + LOGGER.debug("ghostVote has been called"); // array to collect votes for all players during voting, i.e. votes for player 1 (passengers[0]) // are saved in @@ -220,7 +221,7 @@ public class VoteHandler { } - public static void main(String[] args) { + /*public static void main(String[] args) { try { Game game = new Game(6,1, 6); VoteHandler voteHandler = new VoteHandler(); @@ -253,5 +254,5 @@ public class VoteHandler { - } + }*/ } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index a201d4a..78e2cd8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -68,7 +68,7 @@ public class GhostNPC extends Ghost { clientHandler.broadcastChatMessage("I heard some noise tonight"); } - public static void main(String[] args) { + /*public static void main(String[] args) { try { Game game = new Game(6,1,1); @@ -80,5 +80,5 @@ public class GhostNPC extends Ghost { LOGGER.warn(e.getMessage()); } - } + }*/ } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index d197ca0..450961d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -35,7 +35,7 @@ public class GhostPlayer extends Ghost { @Override public void send(String msg, Game game) { - String formattedMsg = ServerGameInfoHandler.format(msg); + String formattedMsg = ServerGameInfoHandler.format(msg, game); clientHandler.sendMsgToClient(formattedMsg); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index 8b16cb0..54bce95 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -32,7 +32,7 @@ public class HumanPlayer extends Human { @Override public void send(String msg, Game game) { - String formattedMsg = ServerGameInfoHandler.format(msg); + String formattedMsg = ServerGameInfoHandler.format(msg, game); clientHandler.sendMsgToClient(formattedMsg); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index c7e6573..7ccfdec 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -31,7 +31,7 @@ public class Passenger { String formattedMsg = ServerGameInfoHandler.format(msg); clientHandler.sendMsgToClient(formattedMsg); } - LOGGER.warn("This object should not just be a passenger"); + LOGGER.warn("This object should not just be a passenger. Position:" + position); } /** diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index 122c17a..e809771 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -72,6 +72,15 @@ public class Client { }).start(); } + /** + * Tells user to enter a position to vote for passenger at that position + */ + + public void voteGetter() { + //TODO(Seraina): implement + + } + /** * Starts a thread which listens for incoming chat messages / other messages that the user diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index d5d4309..7fefb40 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -71,8 +71,10 @@ public class JServerProtocolParser { break; case Protocol.startANewGame: try { - Game game = new Game(6,1, h.getConnectedClients().size()); - game.run(h); + + Game game = new Game(h,6,1, ClientHandler.getConnectedClients().size()); + Thread t = new Thread(game); + game.run(); } catch (TrainOverflow e) { LOGGER.warn(e.getMessage()); } From 316619d06757a4ec08837537b906c230d63c0c92 Mon Sep 17 00:00:00 2001 From: Seraina Date: Fri, 8 Apr 2022 23:24:24 +0200 Subject: [PATCH 06/26] added a forgotten parameter --- .../dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index 7ccfdec..a8d527c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -28,7 +28,7 @@ public class Passenger { **/ public void send(String msg, Game game) { if (isPlayer) { - String formattedMsg = ServerGameInfoHandler.format(msg); + String formattedMsg = ServerGameInfoHandler.format(msg,game); clientHandler.sendMsgToClient(formattedMsg); } LOGGER.warn("This object should not just be a passenger. Position:" + position); From d37324248615d3b1fe83ff3699ae70b84c9c58bf Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 00:13:34 +0200 Subject: [PATCH 07/26] Started communication between voteHandler and user - implemented a new method in client, that collects votes - started ading parser entries - added timer to votehandler(20 s) --- Meilenstein II/Protocol.txt | 1 + .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 2 +- .../dmi/dbis/cs108/gamelogic/GameState.java | 24 +++++++++++++++---- .../gamelogic/ServerGameInfoHandler.java | 2 +- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 14 ++++++++++- .../gamelogic/klassenstruktur/Passenger.java | 4 ++++ .../dbis/cs108/multiplayer/client/Client.java | 18 +++++++++++++- .../cs108/multiplayer/helpers/Protocol.java | 10 ++++++-- .../server/JServerProtocolParser.java | 5 ++++ 9 files changed, 69 insertions(+), 11 deletions(-) diff --git a/Meilenstein II/Protocol.txt b/Meilenstein II/Protocol.txt index 4471166..d53d36c 100644 --- a/Meilenstein II/Protocol.txt +++ b/Meilenstein II/Protocol.txt @@ -7,6 +7,7 @@ Implemented: * PINGB Pingback from client to server. * NAMEC$name Change name to whatever is specified * STGAM start the Game + * CVOTE$position Client has voted for position Future / planned: * CRTGM Create a new game diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 3702db6..380f4da 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -88,7 +88,7 @@ public class Game implements Runnable { } while (i < order.length) { int index = order[i]; - if (passengerTrain[index].getIsGhost()) { //if there is a ghost + if (passengerTrain[index].getIsGhost()) { //if they are a ghost GhostNPC ghostNPC = new GhostNPC(passengerTrain[index].getPosition(), "NPC" + passengerTrain[index].getPosition(),passengerTrain[index].getIsOG() ,this); gameState.getPassengerTrain()[index] = ghostNPC; } else { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index 70e00e1..495cfb0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -81,19 +81,19 @@ public class GameState { String[] print = new String[6]; for (int i = 0; i < array.length; i++) { if (array[i].getKickedOff()) { - print[i] = "| kicked off " + array[i].getPosition() + "|"; + print[i] = "| kicked off: " + array[i].getPosition() + "|"; } else { if (array[i].getIsPlayer()) { if (array[i].getIsGhost()) { - print[i] = "| ghostPlayer " + array[i].getPosition() + "|"; + print[i] = "| ghostPlayer: " + array[i].getPosition() + "|"; } else { - print[i] = "| humanPlayer " + array[i].getPosition() + "|"; + print[i] = "| humanPlayer: " + array[i].getPosition() + "|"; } } else { if (array[i].getIsGhost()) { - print[i] = "| ghostNPC " + array[i].getPosition() + "|"; + print[i] = "| ghostNPC: " + array[i].getPosition() + "|"; } else { - print[i] = "| humanNPC " + array[i].getPosition() + "|"; + print[i] = "| humanNPC: " + array[i].getPosition() + "|"; } } } @@ -105,4 +105,18 @@ public class GameState { return stringBuilder.toString(); } + public String humanToString() { + Passenger[] array = passengerTrain; + StringBuilder stringBuilder = new StringBuilder(); + String[] print = new String[6]; + for (int i = 0; i < array.length; i++) { + print[i] = "| " + array[i].getName() + ": " + array[i].getPosition() + "|"; + } + + for (int i = 0; i < array.length; i++) { + stringBuilder.append(print[i]); + } + return stringBuilder.toString(); + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index 3613ce6..68576d9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -31,7 +31,7 @@ public class ServerGameInfoHandler { msg = Protocol.serverRequestsGhostVote + "$" + game.gameState.toString(); break; case "Vote for a ghost to kick off!": - msg = Protocol.serverRequestsHumanVote; + msg = Protocol.serverRequestsHumanVote + "$" + game.gameState.humanToString(); break; default: msg = Protocol.printToClientConsole + "$" + msg; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 7be4084..9dedf84 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -53,6 +53,12 @@ public class VoteHandler { } } + try { // waits 20 seconds before votes get collected + Thread.sleep(30*1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + for (Passenger passenger : passengers) { // collecting the votes - distribute them among the vote counters for all players // Note: Each voting collects votes for all players even though some might not be concerned @@ -62,7 +68,7 @@ public class VoteHandler { for (int i = 0; i < votesForPlayers.length; i++) { if (passenger.getVote() == i) { votesForPlayers[i]++; - LOGGER.info(passengers[i] + " has received the most votes"); + LOGGER.info(passengers[i] + " has received a vote"); } } } @@ -126,6 +132,12 @@ public class VoteHandler { } } + try { // waits 20 seconds before votes get collected + Thread.sleep(30*1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + for (Passenger passenger : passengers) { // collecting the votes - distribute them among the vote counters for all players // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index a8d527c..ef40ce9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -70,6 +70,10 @@ public class Passenger { hasVoted = voted; } + public void setVote(int vote) { + this.vote = vote; + } + public void setIsOg() { isOG = true; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index e809771..9771c76 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -76,8 +76,24 @@ public class Client { * Tells user to enter a position to vote for passenger at that position */ - public void voteGetter() { + public void voteGetter(String msg) { + Scanner userInput = new Scanner(System.in); //TODO(Seraina): implement + System.out.println(msg); + System.out.println("Please enter your vote"); + int vote; + String input = ""; + try { + input = userInput.nextLine(); + vote = Integer.parseInt(input); + LOGGER.info("input is: " + vote); + } catch (Exception e) { + LOGGER.warn(e.getMessage()); + System.out.println("Invalid vote"); + input = String.valueOf(Integer.MAX_VALUE); + } finally { + sendMsgToServer(Protocol.votedFor + "$" + input); + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java index 658a0fd..c19a11a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java @@ -93,10 +93,15 @@ public class Protocol { public static final String listLobbies = "LISTL"; /** - * A Client decides to start the game + * A Client decides to start the game. */ public static final String startANewGame = "STGAM"; + /** + * Client informs server that they have voted and delivers this vote in the form of "CVOTE$position" + */ + public static final String votedFor = "CVOTE"; + //SERVER TO CLIENT COMMANDS @@ -122,7 +127,8 @@ public class Protocol { public static final String serverConfirmQuit = "QUITC"; /** - * The server requests the client (who should be a ghost) to vote on the victim. + * The server requests the client (who should be a ghost) to vote on the victim. in the format GVOTR$string + * the current train will be shown as a string to the client */ public static final String serverRequestsGhostVote = "GVOTR"; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index 7fefb40..f8306ac 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -69,6 +69,11 @@ public class JServerProtocolParser { //TODO: add action LOGGER.debug(Protocol.listLobbies + " command recieved from: " + h.getClientUserName()); break; + case Protocol.votedFor: + int vote = Integer.parseInt(msg.substring(6)); + if(vote != Integer.MAX_VALUE) { + //TODO(SERAINA): do smt + } case Protocol.startANewGame: try { From 370e1e97fe292698bd3bd5a5068a13db72e9e096 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 08:22:28 +0200 Subject: [PATCH 08/26] Added vote and hasVoted fields to ClientHandler for later transmission to corresponding Passenger --- .../multiplayer/server/ClientHandler.java | 26 ++++++++++++++++--- .../server/JServerProtocolParser.java | 2 +- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index 60d6ee3..1a70a38 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -21,6 +21,7 @@ public class ClientHandler implements Runnable { private Socket socket; private InetAddress ip; + /** * notes if the client has formally logged in yet. If connecting through the normal Client class, * the client is logged in automatically, if connecting though some external application, the @@ -34,6 +35,8 @@ public class ClientHandler implements Runnable { public static HashSet disconnectedClients = new HashSet<>(); //todo: implement re-connection public static HashSet lobby = new HashSet<>(); public static HashSet ghostClients = new HashSet<>(); + private int vote; //saves vote of clientHandler for later transmission to passenger, by default MAX_VALUE + private boolean hasVoted; //saves hasVoted status of clientHandler for later transmission to passenger, by default false /** * Implements the login logic in client-server architecture. @@ -48,6 +51,8 @@ public class ClientHandler implements Runnable { this.in = new BufferedReader(new InputStreamReader((socket.getInputStream()))); this.loggedIn = false; this.clientUserName = nameDuplicateChecker.checkName("U.N. Owen"); + this.vote = Integer.MAX_VALUE; + this.hasVoted = false; connectedClients.add(this); serverPinger = new ServerPinger(socket, this); Thread sP = new Thread(serverPinger); @@ -86,15 +91,30 @@ public class ClientHandler implements Runnable { return loggedIn; } + public int getVote() { + return vote; + } + + public boolean getHasVoted() { + return hasVoted; + } + + public String getClientUserName() { + return clientUserName; + } + //Setters: + public void setLoggedIn(boolean loggedIn) { this.loggedIn = loggedIn; } - //Setters: - public String getClientUserName() { - return clientUserName; + public void setVote(int vote) { + this.vote = vote; } + public void setHasVoted(boolean hasVoted) { + this.hasVoted = hasVoted; + } @Override public void run() { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index f8306ac..bd8ae30 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -67,7 +67,7 @@ public class JServerProtocolParser { break; case Protocol.listLobbies: //TODO: add action - LOGGER.debug(Protocol.listLobbies + " command recieved from: " + h.getClientUserName()); + LOGGER.debug(Protocol.listLobbies + " command received from: " + h.getClientUserName()); break; case Protocol.votedFor: int vote = Integer.parseInt(msg.substring(6)); From 09024dbfada3d91ee25384f6ab593696329b95fe Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 08:38:59 +0200 Subject: [PATCH 09/26] Parser sets the clientHandler fields vote and hasVoted after a vote from a client has come in --- .../multiplayer/server/JServerProtocolParser.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index bd8ae30..eddceed 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -70,10 +70,18 @@ public class JServerProtocolParser { LOGGER.debug(Protocol.listLobbies + " command received from: " + h.getClientUserName()); break; case Protocol.votedFor: - int vote = Integer.parseInt(msg.substring(6)); - if(vote != Integer.MAX_VALUE) { - //TODO(SERAINA): do smt + int vote = Integer.MAX_VALUE; + try { + vote = Integer.parseInt(msg.substring(6)); + } catch (Exception e) { + LOGGER.warn("Invalid vote " + e.getMessage()); + } finally { + if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid + h.setVote(vote); + h.setHasVoted(true); + } } + break; case Protocol.startANewGame: try { From 96b0fa70ef0ebbeabad329325f50209ca8913195 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 08:45:57 +0200 Subject: [PATCH 10/26] Added getVoteFromClient method to superclass Passenger so when NPC vote, nothing happens when this method is called --- .../klassenstruktur/GhostPlayer.java | 19 +++++++++++++++++++ .../klassenstruktur/HumanPlayer.java | 18 ++++++++++++++++++ .../gamelogic/klassenstruktur/Passenger.java | 3 +++ 3 files changed, 40 insertions(+) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index 450961d..c89bce0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -38,5 +38,24 @@ public class GhostPlayer extends Ghost { String formattedMsg = ServerGameInfoHandler.format(msg, game); clientHandler.sendMsgToClient(formattedMsg); } + + /** + * Gets the voting information vote and hasVoted from clientHandler and this values to those values. + * Sets clientHandler fields to default: vote = Integer.MAX_VALUE , hasVoted = false + */ + @Override + public void getVoteFromClientHandler() { + vote = clientHandler.getVote(); + hasVoted = clientHandler.getHasVoted(); + clientHandler.setVote(Integer.MAX_VALUE); + clientHandler.setHasVoted(false); + /* + * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry + */ + if(vote == Integer.MAX_VALUE) { + hasVoted = false; + } + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index 54bce95..07469ac 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -35,4 +35,22 @@ public class HumanPlayer extends Human { String formattedMsg = ServerGameInfoHandler.format(msg, game); clientHandler.sendMsgToClient(formattedMsg); } + + /** + * Gets the voting information vote and hasVoted from clientHandler and this values to those values. + * Sets clientHandler fields to default: vote = Integer.MAX_VALUE , hasVoted = false + */ + @Override + public void getVoteFromClientHandler() { + vote = clientHandler.getVote(); + hasVoted = clientHandler.getHasVoted(); + clientHandler.setVote(Integer.MAX_VALUE); + clientHandler.setHasVoted(false); + /* + * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry + */ + if(vote == Integer.MAX_VALUE) { + hasVoted = false; + } + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index ef40ce9..12167e9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -109,4 +109,7 @@ public class Passenger { return clientHandler; } + public void getVoteFromClientHandler() { + } + } From 67cd93403a4d62db5a715c39f30c5e77368aee92 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 09:11:51 +0200 Subject: [PATCH 11/26] Tried adding smt to avoid being kicked off the Server --- .../multiplayer/helpers/ClientPinger.java | 37 +++++++++++-------- .../multiplayer/helpers/ServerPinger.java | 1 + 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java index 6e0f2c2..52d0b11 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java @@ -35,28 +35,33 @@ public class ClientPinger implements Runnable { @Override public void run() { + Thread.currentThread().setPriority(10); try { Thread.sleep(20000); - while (socket.isConnected() && !socket.isClosed()) { - gotPingBack = false; - client.sendMsgToServer(Protocol.pingFromClient); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + while (socket.isConnected() && !socket.isClosed()) { + gotPingBack = false; + client.sendMsgToServer(Protocol.pingFromClient); + try { Thread.sleep(4000); - if (gotPingBack) { - if (!isConnected) { //if !isConnected, then the connection had been lost before. - isConnected = true; - System.out.println("Connection regained!"); - } - } else { - if (isConnected) { - isConnected = false; - System.out.println("Lost connection. Waiting to reconnect..."); - } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + if (gotPingBack) { + if (!isConnected) { //if !isConnected, then the connection had been lost before. + isConnected = true; + System.out.println("Connection regained!"); + } + } else { + if (isConnected) { + isConnected = false; + System.out.println("Lost connection. Waiting to reconnect..."); } } - isConnected = false; - } catch (InterruptedException e) { - e.printStackTrace(); } + isConnected = false; } public void setGotPingBack(boolean gotPingBack) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java index 34da9e0..dfc34e5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java @@ -37,6 +37,7 @@ public class ServerPinger implements Runnable { @Override public void run() { + Thread.currentThread().setPriority(10); try { Thread.sleep(2000); while (socket.isConnected() && !socket.isClosed()) { From d45d64a9c759f3afebcc03dfe2c8a4dc2669446c Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 11:52:20 +0200 Subject: [PATCH 12/26] Removed interruption from pinger --- .../multiplayer/helpers/ClientPinger.java | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java index 52d0b11..d73b209 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ClientPinger.java @@ -38,30 +38,26 @@ public class ClientPinger implements Runnable { Thread.currentThread().setPriority(10); try { Thread.sleep(20000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - while (socket.isConnected() && !socket.isClosed()) { - gotPingBack = false; - client.sendMsgToServer(Protocol.pingFromClient); - try { + while (socket.isConnected() && !socket.isClosed()) { + gotPingBack = false; + client.sendMsgToServer(Protocol.pingFromClient); Thread.sleep(4000); - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - if (gotPingBack) { - if (!isConnected) { //if !isConnected, then the connection had been lost before. - isConnected = true; - System.out.println("Connection regained!"); - } - } else { - if (isConnected) { - isConnected = false; - System.out.println("Lost connection. Waiting to reconnect..."); + if (gotPingBack) { + if (!isConnected) { //if !isConnected, then the connection had been lost before. + isConnected = true; + System.out.println("Connection regained!"); + } + } else { + if (isConnected) { + isConnected = false; + System.out.println("Lost connection. Waiting to reconnect..."); + } } } + isConnected = false; + } catch (InterruptedException e) { + e.printStackTrace(); } - isConnected = false; } public void setGotPingBack(boolean gotPingBack) { From 46f75d3292845d5d482660d7faad021559e8aaca Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 11:53:43 +0200 Subject: [PATCH 13/26] Made the whole thing a bit more orderly, added several loggers --- .../ch/unibas/dmi/dbis/cs108/gamelogic/Game.java | 2 ++ .../unibas/dmi/dbis/cs108/gamelogic/GameState.java | 2 +- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 14 ++++++++------ .../cs108/gamelogic/klassenstruktur/Passenger.java | 3 +++ 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 380f4da..5339c9e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -103,9 +103,11 @@ public class Game implements Runnable { i = 0; while (true) { //ToDo: was ist die Abbruchbedingung? VoteHandler muss das schicken. if (!isDay) { + LOGGER.info("NIGHT"); voteHandler.ghostVote(gameState.getPassengerTrain(), this); setDay(true); } else { + LOGGER.info("DAY"); gameOverCheck = voteHandler.humanVote(gameState.getPassengerTrain(), this); } if (gameOverCheck.equals("Game over: ghosts win!") || gameOverCheck.equals( diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index 495cfb0..c6eb67e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -110,7 +110,7 @@ public class GameState { StringBuilder stringBuilder = new StringBuilder(); String[] print = new String[6]; for (int i = 0; i < array.length; i++) { - print[i] = "| " + array[i].getName() + ": " + array[i].getPosition() + "|"; + print[i] = "| " + array[i].getName() + ": " + array[i].getPosition() + "|"; } for (int i = 0; i < array.length; i++) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 9dedf84..41362bc 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -40,14 +40,13 @@ public class VoteHandler { int[] votesForPlayers = new int[6]; // Walk through entire train, ask ghosts to ghostify and humans to wait - // TODO(Seraina): Messages in for-loop should probably be handled by ServerGameInfoHandler for (Passenger passenger : passengers) { if (passenger.getIsGhost()) { passenger.send("Vote on who to ghostify!", game); } else { passenger.send( - "Please wait, ghosts are active", game); // TODO(Seraina): make sure whatever clients send in + "Please wait, ghosts are active", game); // this time, except chat is ignored } @@ -56,14 +55,16 @@ public class VoteHandler { try { // waits 20 seconds before votes get collected Thread.sleep(30*1000); } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); } + for (Passenger passenger : passengers) { // collecting the votes - distribute them among the vote counters for all players // Note: Each voting collects votes for all players even though some might not be concerned // (i.e. ghosts during ghost vote). Those players will then get 0 votes so it doesn't matter. // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler + passenger.getVoteFromClientHandler(); if (passenger.getHasVoted()) { for (int i = 0; i < votesForPlayers.length; i++) { if (passenger.getVote() == i) { @@ -135,7 +136,7 @@ public class VoteHandler { try { // waits 20 seconds before votes get collected Thread.sleep(30*1000); } catch (InterruptedException e) { - Thread.currentThread().interrupt(); + LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); } for (Passenger passenger : passengers) { @@ -143,8 +144,10 @@ public class VoteHandler { // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler if (passenger.getHasVoted()) { for (int i = 0; i < votesForPlayers.length; i++) { + LOGGER.info("Passenger: " + passenger.getPosition() + " voted for: " + passenger.getVote() ); if (passenger.getVote() == i) { votesForPlayers[i]++; + } } } @@ -156,7 +159,6 @@ public class VoteHandler { for (int votesForPlayer : votesForPlayers) { if (votesForPlayer > currentMax) { currentMax = votesForPlayer; - LOGGER.info("Max amount of votes: " + currentMax); } } // deal with voting results @@ -164,9 +166,9 @@ public class VoteHandler { for (int i = 0; i < votesForPlayers.length; i++) { if (votesForPlayers[i] == currentMax) { // if player has most votes voteIndex = i; - LOGGER.info("Player " + voteIndex + " has the most votes"); } } + LOGGER.info("Player " + voteIndex + " has the most votes"); if (!passengers[voteIndex] .getIsGhost()) { // if player with most votes is human, notify everyone about it for (Passenger passenger : passengers) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index 12167e9..333ce24 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -109,6 +109,9 @@ public class Passenger { return clientHandler; } + /** + * When called by NPC nothing should happen, because clientHandler = null + */ public void getVoteFromClientHandler() { } From 45597eee3cf4b3d06030334c726eb76cb88bf382 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 16:11:30 +0200 Subject: [PATCH 14/26] Had to change ClientHandler fields vote and hasVoted to arrays and had to make sure, the position of the Passenger is always sent along in protocol ($position$msg) --- Meilenstein II/Protocol.txt | 6 ++--- .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 4 ++-- .../dbis/cs108/gamelogic/GhostifyHandler.java | 21 +++++++++++++---- .../gamelogic/ServerGameInfoHandler.java | 8 +++---- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 10 ++++---- .../gamelogic/klassenstruktur/GhostNPC.java | 2 +- .../klassenstruktur/GhostPlayer.java | 11 +++++---- .../gamelogic/klassenstruktur/HumanNPC.java | 9 +++++--- .../klassenstruktur/HumanPlayer.java | 12 ++++++---- .../gamelogic/klassenstruktur/Passenger.java | 3 ++- .../dbis/cs108/multiplayer/client/Client.java | 9 +++++--- .../client/JClientProtocolParser.java | 4 +++- .../multiplayer/helpers/ServerPinger.java | 5 ++-- .../multiplayer/server/ClientHandler.java | 23 +++++++++++-------- .../server/JServerProtocolParser.java | 20 +++++++++++----- 15 files changed, 92 insertions(+), 55 deletions(-) diff --git a/Meilenstein II/Protocol.txt b/Meilenstein II/Protocol.txt index d53d36c..283c592 100644 --- a/Meilenstein II/Protocol.txt +++ b/Meilenstein II/Protocol.txt @@ -7,7 +7,7 @@ Implemented: * PINGB Pingback from client to server. * NAMEC$name Change name to whatever is specified * STGAM start the Game - * CVOTE$position Client has voted for position + * CVOTE$position$vote Client at position has voted for position Future / planned: * CRTGM Create a new game @@ -24,8 +24,8 @@ Server Commands: Implemented: * SPING Ping from server to client * PINGB Pingback from client to server. - * GVOTR Ghosts: Please vote now - * HVOTR Humans: Please vote now + * GVOTR$position$msg Ghosts: Please vote now + * HVOTR$position$msg Humans: Please vote now Future / planned: * MSGRS "Message received": Paramaters: a string detailing to the client that and what the server received as command. diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 5339c9e..1d45b50 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -89,11 +89,11 @@ public class Game implements Runnable { while (i < order.length) { int index = order[i]; if (passengerTrain[index].getIsGhost()) { //if they are a ghost - GhostNPC ghostNPC = new GhostNPC(passengerTrain[index].getPosition(), "NPC" + passengerTrain[index].getPosition(),passengerTrain[index].getIsOG() ,this); + GhostNPC ghostNPC = new GhostNPC(passengerTrain[index].getPosition(), "NPC" + passengerTrain[index].getPosition(),passengerTrain[index].getIsOG()); gameState.getPassengerTrain()[index] = ghostNPC; } else { //ToDo: give NPC nice usernames - HumanNPC humanNPC = new HumanNPC(passengerTrain[index].getPosition(), "NPC" + passengerTrain[index].getPosition(),this); + HumanNPC humanNPC = new HumanNPC(passengerTrain[index].getPosition(), "NPC" + passengerTrain[index].getPosition()); gameState.getPassengerTrain()[index] = humanNPC; } i++; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java index ff2a088..b2fb8c0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java @@ -2,6 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Ghost; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.GhostNPC; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.GhostPlayer; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import org.apache.logging.log4j.LogManager; @@ -19,11 +20,23 @@ public class GhostifyHandler { public Ghost ghost(Passenger p, Game game) { //TODO: Adjust for not only players but also npcs LOGGER.debug("Passenger Position " + p.getPosition()); - p.setGhost(); Ghost g; - g = new Ghost(); - g.setGhost(); - g.setPosition(p.getPosition()); + if (p.getIsPlayer()) { + p.setGhost(); + GhostPlayer ghostPlayer; + ghostPlayer = new GhostPlayer(p.getPosition(), p.getName(), p.getClientHandler(),p.getIsOG()); + ghostPlayer.setGhost(); + ghostPlayer.setPosition(p.getPosition()); + g = ghostPlayer; + } else { + p.setGhost(); + GhostNPC ghostNPC; + ghostNPC = new GhostNPC(p.getPosition(), p.getName(),p.getIsOG()); + ghostNPC.setGhost(); + ghostNPC.setPosition(p.getPosition()); + g = ghostNPC; + + } game.gameState.addNewPassenger(g, g.getPosition()); LOGGER.info("Passenger at position " + p.getPosition() + "has been ghostified"); return g; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index 68576d9..2fd184d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -25,16 +25,16 @@ public class ServerGameInfoHandler { * @param msg the message to be formatted * @return a message in a protocol format */ - public static String format(String msg, Game game) { + public static String format(String msg, Passenger p, Game game) { switch (msg) { case "Vote on who to ghostify!": - msg = Protocol.serverRequestsGhostVote + "$" + game.gameState.toString(); + msg = Protocol.serverRequestsGhostVote + "$" + p.getPosition() +"$" + game.gameState.toString(); break; case "Vote for a ghost to kick off!": - msg = Protocol.serverRequestsHumanVote + "$" + game.gameState.humanToString(); + msg = Protocol.serverRequestsHumanVote + "$" + p.getPosition() +"$"+ game.gameState.humanToString(); break; default: - msg = Protocol.printToClientConsole + "$" + msg; + msg = Protocol.printToClientConsole + "$" + p.getPosition() +"$"+ msg; } LOGGER.info(msg); return msg; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 41362bc..ab81971 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -33,6 +33,7 @@ public class VoteHandler { */ public void ghostVote(Passenger[] passengers, Game game) { LOGGER.debug("ghostVote has been called"); + LOGGER.info(game.getGameState().toString()); // array to collect votes for all players during voting, i.e. votes for player 1 (passengers[0]) // are saved in @@ -101,6 +102,7 @@ public class VoteHandler { passengers[ghostPosition].send( "You are now a ghost!", game); // TODO: ServerGameInfoHandler might deal with this one + LOGGER.info(game.getGameState().toString()); // set hasVoted to false for all passengers for future votings for (Passenger passenger : passengers) { passenger.setHasVoted(false); @@ -117,7 +119,7 @@ public class VoteHandler { * @param passengers: train passengers */ public String humanVote(Passenger[] passengers, Game game) { - + LOGGER.info(game.getGameState().toString()); // array to collect votes for all players during voting, i.e. votes for player 1 are saved in // votesForPlayers[0] @@ -134,20 +136,19 @@ public class VoteHandler { } try { // waits 20 seconds before votes get collected - Thread.sleep(30*1000); + Thread.sleep(20*1000); } catch (InterruptedException e) { LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); } for (Passenger passenger : passengers) { + passenger.getVoteFromClientHandler(); // collecting the votes - distribute them among the vote counters for all players // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler if (passenger.getHasVoted()) { for (int i = 0; i < votesForPlayers.length; i++) { - LOGGER.info("Passenger: " + passenger.getPosition() + " voted for: " + passenger.getVote() ); if (passenger.getVote() == i) { votesForPlayers[i]++; - } } } @@ -202,6 +203,7 @@ public class VoteHandler { } } } + LOGGER.info(game.getGameState().toString()); // set hasVoted to false for all passengers for future voting for (Passenger passenger : passengers) { passenger.setHasVoted(false); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index 78e2cd8..80ee9d4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -19,7 +19,7 @@ public class GhostNPC extends Ghost { * @param name player name. if null, then a default name is used. * @param isOG true if the ghost is the original ghost. */ - public GhostNPC(int position, String name, boolean isOG, Game game) { + public GhostNPC(int position, String name, boolean isOG) { this.isOG = isOG; this.position = position; this.clientHandler = null; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index c89bce0..c964b67 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -35,7 +35,7 @@ public class GhostPlayer extends Ghost { @Override public void send(String msg, Game game) { - String formattedMsg = ServerGameInfoHandler.format(msg, game); + String formattedMsg = ServerGameInfoHandler.format(msg, this, game); clientHandler.sendMsgToClient(formattedMsg); } @@ -45,10 +45,11 @@ public class GhostPlayer extends Ghost { */ @Override public void getVoteFromClientHandler() { - vote = clientHandler.getVote(); - hasVoted = clientHandler.getHasVoted(); - clientHandler.setVote(Integer.MAX_VALUE); - clientHandler.setHasVoted(false); + vote = clientHandler.getVote()[position]; + hasVoted = clientHandler.getHasVoted()[position]; + clientHandler.setVote(position,Integer.MAX_VALUE); + clientHandler.setHasVoted(position,false); + LOGGER.info("Ghost at Pos: " + position + " has voted for: " + vote); /* * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java index 4c24749..fd32f17 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java @@ -16,7 +16,7 @@ public class HumanNPC extends Human { * @param position position on the train * @param name player name. if null, then a default name is used. */ - public HumanNPC(int position, String name, Game game) { + public HumanNPC(int position, String name) { this.position = position; this.clientHandler = null; isGhost = false; @@ -38,8 +38,11 @@ public class HumanNPC extends Human { * Currently returns a random integer for voting * @return integer between 0 and 5 */ - public int vote(){ - return (int) (Math.random()*6); + public void vote(){ + int randomNr = (int) (Math.random()*6); + vote = randomNr; + hasVoted = true; + LOGGER.info("HumanNPC at Position: " + this.getPosition() + " has voted for: " + vote); } public void noise() { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index 07469ac..bdb05c5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -32,7 +32,7 @@ public class HumanPlayer extends Human { @Override public void send(String msg, Game game) { - String formattedMsg = ServerGameInfoHandler.format(msg, game); + String formattedMsg = ServerGameInfoHandler.format(msg,this, game); clientHandler.sendMsgToClient(formattedMsg); } @@ -42,10 +42,12 @@ public class HumanPlayer extends Human { */ @Override public void getVoteFromClientHandler() { - vote = clientHandler.getVote(); - hasVoted = clientHandler.getHasVoted(); - clientHandler.setVote(Integer.MAX_VALUE); - clientHandler.setHasVoted(false); + LOGGER.info("method was called by: " + position); + vote = clientHandler.getVote()[position]; + LOGGER.info("Human at Pos: " + position + " has voted for: " + vote); + hasVoted = clientHandler.getHasVoted()[position]; + clientHandler.setVote(position,Integer.MAX_VALUE); + clientHandler.setHasVoted(position,false); /* * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index 333ce24..7151294 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -28,7 +28,7 @@ public class Passenger { **/ public void send(String msg, Game game) { if (isPlayer) { - String formattedMsg = ServerGameInfoHandler.format(msg,game); + String formattedMsg = ServerGameInfoHandler.format(msg,this,game); clientHandler.sendMsgToClient(formattedMsg); } LOGGER.warn("This object should not just be a passenger. Position:" + position); @@ -113,6 +113,7 @@ public class Passenger { * When called by NPC nothing should happen, because clientHandler = null */ public void getVoteFromClientHandler() { + LOGGER.debug("a NPC called this method hopefully: " + position); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index 9771c76..f63b2aa 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -5,6 +5,7 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ClientPinger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; +import ch.unibas.dmi.dbis.cs108.multiplayer.server.JServerProtocolParser; import java.net.Socket; import java.io.*; import java.net.UnknownHostException; @@ -77,6 +78,9 @@ public class Client { */ public void voteGetter(String msg) { + int msgIndex = msg.indexOf('$'); + String position = msg.substring(0, msgIndex);; + msg = msg.substring(msgIndex + 1); Scanner userInput = new Scanner(System.in); //TODO(Seraina): implement System.out.println(msg); @@ -91,10 +95,9 @@ public class Client { LOGGER.warn(e.getMessage()); System.out.println("Invalid vote"); input = String.valueOf(Integer.MAX_VALUE); - } finally { - sendMsgToServer(Protocol.votedFor + "$" + input); } - + sendMsgToServer(Protocol.votedFor + "$" + position + "$" + input); + LOGGER.info("msg to server is: " + Protocol.votedFor + "$" + position + "$" + input); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java index bb3a7ab..a3e1462 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java @@ -44,10 +44,12 @@ public class JClientProtocolParser { break; case Protocol.serverRequestsGhostVote: System.out.println("Ghost received Vote request"); + c.voteGetter(msg.substring(6)); //TODO(Seraina): How can be enforced, that clients won't vote otherwise? Trigger a methode here that listens to input break; case Protocol.serverRequestsHumanVote: - System.out.println("Human received Vote request"); + LOGGER.info("Human received Vote request"); + c.voteGetter(msg.substring(6)); //TODO(Seraina): How can be enforced, that clients won't vote otherwise? Trigger a methode here that listens to input break; default: diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java index dfc34e5..6400ad4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java @@ -56,9 +56,8 @@ public class ServerPinger implements Runnable { System.out.println( "Lost connection to user " + c.getClientUserName() + ". Waiting to reconnect..."); } else { - c.disconnectClient(); - LOGGER.debug( - "gotPingBack has not been set to true and isConnected has been set to false before"); + //c.disconnectClient(); + //LOGGER.debug("gotPingBack has not been set to true and isConnected has been set to false before"); } } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index 1a70a38..2ed5c99 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -6,6 +6,7 @@ import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ServerPinger; import java.io.*; import java.net.InetAddress; import java.net.Socket; +import java.util.Arrays; import java.util.HashSet; import java.util.Scanner; import org.apache.logging.log4j.LogManager; @@ -35,8 +36,8 @@ public class ClientHandler implements Runnable { public static HashSet disconnectedClients = new HashSet<>(); //todo: implement re-connection public static HashSet lobby = new HashSet<>(); public static HashSet ghostClients = new HashSet<>(); - private int vote; //saves vote of clientHandler for later transmission to passenger, by default MAX_VALUE - private boolean hasVoted; //saves hasVoted status of clientHandler for later transmission to passenger, by default false + private int[] vote; //saves vote of clientHandler for later transmission to passenger, by default MAX_VALUE, index corresponds to Passenger position + private boolean[] hasVoted; //saves hasVoted status of clientHandler for later transmission to passenger, by default false, index corresponds to Passenger position /** * Implements the login logic in client-server architecture. @@ -51,8 +52,10 @@ public class ClientHandler implements Runnable { this.in = new BufferedReader(new InputStreamReader((socket.getInputStream()))); this.loggedIn = false; this.clientUserName = nameDuplicateChecker.checkName("U.N. Owen"); - this.vote = Integer.MAX_VALUE; - this.hasVoted = false; + int[] h = new int[1000]; + Arrays.fill(h,Integer.MAX_VALUE); + this.vote = h; + this.hasVoted = new boolean[1000]; connectedClients.add(this); serverPinger = new ServerPinger(socket, this); Thread sP = new Thread(serverPinger); @@ -91,11 +94,11 @@ public class ClientHandler implements Runnable { return loggedIn; } - public int getVote() { + public int[] getVote() { return vote; } - public boolean getHasVoted() { + public boolean[] getHasVoted() { return hasVoted; } @@ -108,12 +111,12 @@ public class ClientHandler implements Runnable { this.loggedIn = loggedIn; } - public void setVote(int vote) { - this.vote = vote; + public void setVote(int position, int vote) { + this.vote[position] = vote; } - public void setHasVoted(boolean hasVoted) { - this.hasVoted = hasVoted; + public void setHasVoted(int position, boolean hasVoted) { + this.hasVoted[position] = hasVoted; } @Override diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index eddceed..a7a8c70 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -32,6 +32,9 @@ public class JServerProtocolParser { String header = ""; //"header" is the first 5 characters, i.e. the protocol part try { header = msg.substring(0, 5); + if(!header.equals(Protocol.pingBack) &&!header.equals(Protocol.pingFromClient)) { //for debuging without constant pings + LOGGER.debug("got message: " + msg + "."); + } } catch (IndexOutOfBoundsException e) { System.out.println("Received unknown command"); } @@ -70,16 +73,21 @@ public class JServerProtocolParser { LOGGER.debug(Protocol.listLobbies + " command received from: " + h.getClientUserName()); break; case Protocol.votedFor: + msg = msg.substring(6); + int msgIndex = msg.indexOf('$'); int vote = Integer.MAX_VALUE; + int position = 0; + LOGGER.debug("Message is " + msg.substring(6)); try { - vote = Integer.parseInt(msg.substring(6)); + position = Integer.parseInt(msg.substring(0,msgIndex)); + vote = Integer.parseInt(msg.substring(msgIndex + 1)); } catch (Exception e) { LOGGER.warn("Invalid vote " + e.getMessage()); - } finally { - if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid - h.setVote(vote); - h.setHasVoted(true); - } + } + if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid + h.setVote(position,vote); + LOGGER.debug("Player vote: " + vote); + h.setHasVoted(position,true); } break; case Protocol.startANewGame: From 1de2e739dec617a65d09f6281c87eb23d590e35e Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 16:56:42 +0200 Subject: [PATCH 15/26] Moved all the fields in added in client handler into a separate class ClientVoteData cuz it didn't make sense there --- .../dbis/cs108/gamelogic/ClientVoteData.java | 32 +++++++++++++++++++ .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 1 + .../dmi/dbis/cs108/gamelogic/GameState.java | 4 +++ .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 15 ++++++--- .../klassenstruktur/GhostPlayer.java | 11 ++++--- .../klassenstruktur/HumanPlayer.java | 13 +++++--- .../gamelogic/klassenstruktur/Passenger.java | 4 +-- .../multiplayer/server/ClientHandler.java | 21 ------------ .../server/JServerProtocolParser.java | 9 ++++-- 9 files changed, 71 insertions(+), 39 deletions(-) create mode 100644 src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java new file mode 100644 index 0000000..d9c405f --- /dev/null +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java @@ -0,0 +1,32 @@ +package ch.unibas.dmi.dbis.cs108.gamelogic; + +import java.util.Arrays; + +public class ClientVoteData { + + private int[] vote; //saves vote of clientHandler for later transmission to passenger, by default MAX_VALUE, index corresponds to Passenger position + private boolean[] hasVoted; //saves hasVoted status of clientHandler for later transmission to passenger, by default false, index corresponds to Passenger position + + public ClientVoteData() { + int[] h = new int[6]; + Arrays.fill(h,Integer.MAX_VALUE); + this.vote = h; + this.hasVoted = new boolean[6]; + } + + public int[] getVote() { + return vote; + } + + public boolean[] getHasVoted() { + return hasVoted; + } + + public void setVote(int position, int vote) { + this.vote[position] = vote; + } + + public void setHasVoted(int position, boolean hasVoted) { + this.hasVoted[position] = hasVoted; + } +} diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 1d45b50..ba640a2 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -109,6 +109,7 @@ public class Game implements Runnable { } else { LOGGER.info("DAY"); gameOverCheck = voteHandler.humanVote(gameState.getPassengerTrain(), this); + setDay(false); } if (gameOverCheck.equals("Game over: ghosts win!") || gameOverCheck.equals( "Game over: humans win!")) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index c6eb67e..712b246 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -4,6 +4,7 @@ import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Ghost; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Human; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; +import java.util.Arrays; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -24,6 +25,7 @@ public class GameState { private Passenger[] passengerTrain; + /** * Constructs a GameState instance where nrOfPlayers >= nrOfUsers. Fills passengerTrain with * only humans @@ -65,6 +67,8 @@ public class GameState { return train; } + + /** * Takes a given Passenger and puts it into the passengerTrain at a certain position * @param passenger the new passenger being put into the train diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index ab81971..78b3323 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -2,9 +2,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Ghost; -import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.GhostPlayer; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; -import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -23,6 +21,15 @@ public class VoteHandler { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); + private ClientVoteData clientVoteData; + + public ClientVoteData getClientVoteData() { + return clientVoteData; + } + + public static void setClientVoteData(ClientVoteData clientVoteData) { + clientVoteData = clientVoteData; + } /** * Handles the ghost vote during nighttime: passengers who are ghosts are being asked on who to @@ -65,7 +72,7 @@ public class VoteHandler { // Note: Each voting collects votes for all players even though some might not be concerned // (i.e. ghosts during ghost vote). Those players will then get 0 votes so it doesn't matter. // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler - passenger.getVoteFromClientHandler(); + passenger.getVoteFromGameState(clientVoteData); if (passenger.getHasVoted()) { for (int i = 0; i < votesForPlayers.length; i++) { if (passenger.getVote() == i) { @@ -142,7 +149,7 @@ public class VoteHandler { } for (Passenger passenger : passengers) { - passenger.getVoteFromClientHandler(); + passenger.getVoteFromGameState(clientVoteData); // collecting the votes - distribute them among the vote counters for all players // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler if (passenger.getHasVoted()) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index c964b67..363bf0a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -1,6 +1,7 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.ClientVoteData; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; @@ -44,11 +45,11 @@ public class GhostPlayer extends Ghost { * Sets clientHandler fields to default: vote = Integer.MAX_VALUE , hasVoted = false */ @Override - public void getVoteFromClientHandler() { - vote = clientHandler.getVote()[position]; - hasVoted = clientHandler.getHasVoted()[position]; - clientHandler.setVote(position,Integer.MAX_VALUE); - clientHandler.setHasVoted(position,false); + public void getVoteFromGameState(ClientVoteData clientVoteData) { + vote = clientVoteData.getVote()[position]; + hasVoted = clientVoteData.getHasVoted()[position]; + clientVoteData.setVote(position,Integer.MAX_VALUE); + clientVoteData.setHasVoted(position,false); LOGGER.info("Ghost at Pos: " + position + " has voted for: " + vote); /* * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index bdb05c5..0084d8b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -1,9 +1,11 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.ClientVoteData; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; +import java.util.Arrays; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -41,13 +43,14 @@ public class HumanPlayer extends Human { * Sets clientHandler fields to default: vote = Integer.MAX_VALUE , hasVoted = false */ @Override - public void getVoteFromClientHandler() { + public void getVoteFromGameState(ClientVoteData clientVoteData) { + LOGGER.debug(Arrays.toString(clientVoteData.getVote())); LOGGER.info("method was called by: " + position); - vote = clientHandler.getVote()[position]; + vote = clientVoteData.getVote()[position]; LOGGER.info("Human at Pos: " + position + " has voted for: " + vote); - hasVoted = clientHandler.getHasVoted()[position]; - clientHandler.setVote(position,Integer.MAX_VALUE); - clientHandler.setHasVoted(position,false); + hasVoted = clientVoteData.getHasVoted()[position]; + clientVoteData.setVote(position,Integer.MAX_VALUE); + clientVoteData.setHasVoted(position,false); /* * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index 7151294..efe4446 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -1,9 +1,9 @@ package ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.ClientVoteData; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; import ch.unibas.dmi.dbis.cs108.gamelogic.ServerGameInfoHandler; -import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -112,7 +112,7 @@ public class Passenger { /** * When called by NPC nothing should happen, because clientHandler = null */ - public void getVoteFromClientHandler() { + public void getVoteFromGameState(ClientVoteData clientVoteData) { LOGGER.debug("a NPC called this method hopefully: " + position); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index 2ed5c99..d9ed5fa 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -36,8 +36,6 @@ public class ClientHandler implements Runnable { public static HashSet disconnectedClients = new HashSet<>(); //todo: implement re-connection public static HashSet lobby = new HashSet<>(); public static HashSet ghostClients = new HashSet<>(); - private int[] vote; //saves vote of clientHandler for later transmission to passenger, by default MAX_VALUE, index corresponds to Passenger position - private boolean[] hasVoted; //saves hasVoted status of clientHandler for later transmission to passenger, by default false, index corresponds to Passenger position /** * Implements the login logic in client-server architecture. @@ -52,10 +50,6 @@ public class ClientHandler implements Runnable { this.in = new BufferedReader(new InputStreamReader((socket.getInputStream()))); this.loggedIn = false; this.clientUserName = nameDuplicateChecker.checkName("U.N. Owen"); - int[] h = new int[1000]; - Arrays.fill(h,Integer.MAX_VALUE); - this.vote = h; - this.hasVoted = new boolean[1000]; connectedClients.add(this); serverPinger = new ServerPinger(socket, this); Thread sP = new Thread(serverPinger); @@ -94,14 +88,6 @@ public class ClientHandler implements Runnable { return loggedIn; } - public int[] getVote() { - return vote; - } - - public boolean[] getHasVoted() { - return hasVoted; - } - public String getClientUserName() { return clientUserName; } @@ -111,13 +97,6 @@ public class ClientHandler implements Runnable { this.loggedIn = loggedIn; } - public void setVote(int position, int vote) { - this.vote[position] = vote; - } - - public void setHasVoted(int position, boolean hasVoted) { - this.hasVoted[position] = hasVoted; - } @Override public void run() { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index a7a8c70..a213128 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -2,8 +2,11 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.server; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +import ch.unibas.dmi.dbis.cs108.gamelogic.ClientVoteData; import ch.unibas.dmi.dbis.cs108.gamelogic.Game; +import ch.unibas.dmi.dbis.cs108.gamelogic.GameState; import ch.unibas.dmi.dbis.cs108.gamelogic.TrainOverflow; +import ch.unibas.dmi.dbis.cs108.gamelogic.VoteHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; @@ -77,6 +80,7 @@ public class JServerProtocolParser { int msgIndex = msg.indexOf('$'); int vote = Integer.MAX_VALUE; int position = 0; + ClientVoteData clientVoteData = new ClientVoteData(); LOGGER.debug("Message is " + msg.substring(6)); try { position = Integer.parseInt(msg.substring(0,msgIndex)); @@ -85,10 +89,11 @@ public class JServerProtocolParser { LOGGER.warn("Invalid vote " + e.getMessage()); } if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid - h.setVote(position,vote); + clientVoteData.setVote(position,vote); LOGGER.debug("Player vote: " + vote); - h.setHasVoted(position,true); + clientVoteData.setHasVoted(position,true); } + VoteHandler.setClientVoteData(clientVoteData); break; case Protocol.startANewGame: try { From d3a0c00deafb6dbaf4c28290e1233cffa7ad84ab Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 17:55:27 +0200 Subject: [PATCH 16/26] Found the annoying issue, had to change run() to start() now it kinda works --- .../ch/unibas/dmi/dbis/cs108/BudaLogConfig.java | 2 +- .../dmi/dbis/cs108/gamelogic/ClientVoteData.java | 2 +- .../unibas/dmi/dbis/cs108/gamelogic/GameState.java | 2 ++ .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 9 +++++++-- .../gamelogic/klassenstruktur/HumanPlayer.java | 5 +++-- .../cs108/gamelogic/klassenstruktur/Passenger.java | 2 +- .../multiplayer/server/JServerProtocolParser.java | 13 +++++++------ 7 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/BudaLogConfig.java b/src/main/java/ch/unibas/dmi/dbis/cs108/BudaLogConfig.java index 89f880f..0d809eb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/BudaLogConfig.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/BudaLogConfig.java @@ -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.DEBUG); // change level here + loggerConfig.setLevel(Level.INFO); // change level here ctx.updateLoggers(); // This causes all Loggers to refetch information from their LoggerConfig. } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java index d9c405f..26d8bf3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java @@ -9,7 +9,7 @@ public class ClientVoteData { public ClientVoteData() { int[] h = new int[6]; - Arrays.fill(h,Integer.MAX_VALUE); + Arrays.fill(h,0); this.vote = h; this.hasVoted = new boolean[6]; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index 712b246..965c69f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -23,6 +23,7 @@ public class GameState { * contains all Passengers on train, needs to be updated */ private Passenger[] passengerTrain; + private ClientVoteData clientVoteData; @@ -41,6 +42,7 @@ public class GameState { this.nrOfGhosts = nrOfGhosts; this.nrOfUsers = nrOfUsers; this.train = new Train(nrOfPlayers, nrOfUsers); + clientVoteData = new ClientVoteData(); Passenger[] passengerTrain = new Passenger[nrOfPlayers]; //Creates an array with Passengers with correlation positions (Train) for (int i = 0; i < nrOfPlayers; i++) { if (i == 3) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 78b3323..5ff7192 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -21,16 +21,21 @@ public class VoteHandler { public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); - private ClientVoteData clientVoteData; + private static ClientVoteData clientVoteData = new ClientVoteData(); - public ClientVoteData getClientVoteData() { + public static ClientVoteData getClientVoteData() { return clientVoteData; } + + public static void setClientVoteData(ClientVoteData clientVoteData) { clientVoteData = clientVoteData; } + + + /** * Handles the ghost vote during nighttime: passengers who are ghosts are being asked on who to * ghostify, others are waiting. Results are being collected and the player with most votes is diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index 0084d8b..ac512f3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -49,8 +49,9 @@ public class HumanPlayer extends Human { vote = clientVoteData.getVote()[position]; LOGGER.info("Human at Pos: " + position + " has voted for: " + vote); hasVoted = clientVoteData.getHasVoted()[position]; - clientVoteData.setVote(position,Integer.MAX_VALUE); - clientVoteData.setHasVoted(position,false); + LOGGER.debug(Arrays.toString(clientVoteData.getVote())); + //clientVoteData.setVote(position,Integer.MAX_VALUE); + //clientVoteData.setHasVoted(position,false); /* * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry */ diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index efe4446..449c53b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -113,7 +113,7 @@ public class Passenger { * When called by NPC nothing should happen, because clientHandler = null */ public void getVoteFromGameState(ClientVoteData clientVoteData) { - LOGGER.debug("a NPC called this method hopefully: " + position); + //LOGGER.debug("a NPC called this method hopefully: " + position); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index a213128..de6ad69 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -76,31 +76,32 @@ public class JServerProtocolParser { LOGGER.debug(Protocol.listLobbies + " command received from: " + h.getClientUserName()); break; case Protocol.votedFor: + LOGGER.debug("Made it here"); msg = msg.substring(6); int msgIndex = msg.indexOf('$'); int vote = Integer.MAX_VALUE; int position = 0; - ClientVoteData clientVoteData = new ClientVoteData(); - LOGGER.debug("Message is " + msg.substring(6)); + LOGGER.debug("Message is " + msg); try { position = Integer.parseInt(msg.substring(0,msgIndex)); vote = Integer.parseInt(msg.substring(msgIndex + 1)); + LOGGER.debug("Vote is:" + vote); } catch (Exception e) { LOGGER.warn("Invalid vote " + e.getMessage()); } + LOGGER.debug("Vote is:" + vote); if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid - clientVoteData.setVote(position,vote); + VoteHandler.getClientVoteData().setVote(position,vote); LOGGER.debug("Player vote: " + vote); - clientVoteData.setHasVoted(position,true); + VoteHandler.getClientVoteData().setHasVoted(position,true); } - VoteHandler.setClientVoteData(clientVoteData); break; case Protocol.startANewGame: try { Game game = new Game(h,6,1, ClientHandler.getConnectedClients().size()); Thread t = new Thread(game); - game.run(); + t.start(); } catch (TrainOverflow e) { LOGGER.warn(e.getMessage()); } From ac80a88b9842d0172191ebfaa6753c0f34f88927 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 18:35:13 +0200 Subject: [PATCH 17/26] Did some cleanup with the loggers, only set vital information at info level --- .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 2 ++ .../dmi/dbis/cs108/gamelogic/GameState.java | 11 +++++++ .../gamelogic/ServerGameInfoHandler.java | 4 +-- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 13 ++++---- .../klassenstruktur/GhostPlayer.java | 2 +- .../klassenstruktur/HumanPlayer.java | 30 ++++++++++--------- .../gamelogic/klassenstruktur/Passenger.java | 4 +-- .../dbis/cs108/multiplayer/client/Client.java | 2 +- .../client/JClientProtocolParser.java | 6 ++-- 9 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index ba640a2..243ac36 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -58,6 +58,8 @@ public class Game implements Runnable { return nrOfUsers; } + public boolean getIsDay() {return isDay;} + public void setDay(boolean day) { isDay = day; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index 965c69f..c11cd80 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -81,6 +81,11 @@ public class GameState { } + /** + * Converts the data in this passengerTrain into a human-readable string, + * where one can see who is a ghost and who is a human, who is a player and who an NPC + * @return a String that displays passengerTrain + */ public String toString() { Passenger[] array = passengerTrain; StringBuilder stringBuilder = new StringBuilder(); @@ -111,6 +116,12 @@ public class GameState { return stringBuilder.toString(); } + /** + * Converts the data in this passengerTrain into a human-readable string, but it is anonymised for + * human players, so it is not obvious who is a human and who a ghost, only names and positions + * are displayed + * @return the String displaying an anonymised passengerTrain + */ public String humanToString() { Passenger[] array = passengerTrain; StringBuilder stringBuilder = new StringBuilder(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index 2fd184d..e43d7cc 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -34,9 +34,9 @@ public class ServerGameInfoHandler { msg = Protocol.serverRequestsHumanVote + "$" + p.getPosition() +"$"+ game.gameState.humanToString(); break; default: - msg = Protocol.printToClientConsole + "$" + p.getPosition() +"$"+ msg; + msg = Protocol.printToClientConsole + "$"+ msg; } - LOGGER.info(msg); + LOGGER.debug(msg); return msg; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 5ff7192..2c56d43 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -72,17 +72,16 @@ public class VoteHandler { } - for (Passenger passenger : passengers) { + for (Passenger passenger : passengers) { //TODO: could be outsourced to a method to increase readability // collecting the votes - distribute them among the vote counters for all players // Note: Each voting collects votes for all players even though some might not be concerned // (i.e. ghosts during ghost vote). Those players will then get 0 votes so it doesn't matter. // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler - passenger.getVoteFromGameState(clientVoteData); + passenger.getVoteFromGameState(clientVoteData, game); if (passenger.getHasVoted()) { for (int i = 0; i < votesForPlayers.length; i++) { if (passenger.getVote() == i) { votesForPlayers[i]++; - LOGGER.info(passengers[i] + " has received a vote"); } } } @@ -96,18 +95,18 @@ public class VoteHandler { currentMax = votesForPlayer; } } - LOGGER.info("Most votes: " + currentMax + " vote"); + LOGGER.debug("Most votes: " + currentMax + " vote"); // ghostify the player with most votes int ghostPosition = 0; for (int i = 0; i < votesForPlayers.length; i++) { if (votesForPlayers[i] == currentMax) { // if player at position i has most votes ghostPosition = i; - LOGGER.info("Most votes for Passenger " + i); + LOGGER.debug("Most votes for Passenger " + i); } } - LOGGER.debug("ghostPosition: " + ghostPosition); + LOGGER.info("Most votes for: " + ghostPosition); GhostifyHandler gh = new GhostifyHandler(); Ghost g = gh.ghost(passengers[ghostPosition], game); passengers[ghostPosition] = g; @@ -154,7 +153,7 @@ public class VoteHandler { } for (Passenger passenger : passengers) { - passenger.getVoteFromGameState(clientVoteData); + passenger.getVoteFromGameState(clientVoteData, game); // collecting the votes - distribute them among the vote counters for all players // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler if (passenger.getHasVoted()) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index 363bf0a..72f865d 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -45,7 +45,7 @@ public class GhostPlayer extends Ghost { * Sets clientHandler fields to default: vote = Integer.MAX_VALUE , hasVoted = false */ @Override - public void getVoteFromGameState(ClientVoteData clientVoteData) { + public void getVoteFromGameState(ClientVoteData clientVoteData, Game game) { vote = clientVoteData.getVote()[position]; hasVoted = clientVoteData.getHasVoted()[position]; clientVoteData.setVote(position,Integer.MAX_VALUE); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index ac512f3..b7e714f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -43,20 +43,22 @@ public class HumanPlayer extends Human { * Sets clientHandler fields to default: vote = Integer.MAX_VALUE , hasVoted = false */ @Override - public void getVoteFromGameState(ClientVoteData clientVoteData) { - LOGGER.debug(Arrays.toString(clientVoteData.getVote())); - LOGGER.info("method was called by: " + position); - vote = clientVoteData.getVote()[position]; - LOGGER.info("Human at Pos: " + position + " has voted for: " + vote); - hasVoted = clientVoteData.getHasVoted()[position]; - LOGGER.debug(Arrays.toString(clientVoteData.getVote())); - //clientVoteData.setVote(position,Integer.MAX_VALUE); - //clientVoteData.setHasVoted(position,false); - /* - * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry - */ - if(vote == Integer.MAX_VALUE) { - hasVoted = false; + public void getVoteFromGameState(ClientVoteData clientVoteData, Game game) { + if(game.getIsDay()) { + LOGGER.debug(Arrays.toString(clientVoteData.getVote())); + LOGGER.debug("method was called by: " + position); + vote = clientVoteData.getVote()[position]; + LOGGER.info("Human at Pos: " + position + " has voted for: " + vote); + hasVoted = clientVoteData.getHasVoted()[position]; + LOGGER.debug(Arrays.toString(clientVoteData.getVote())); + clientVoteData.setVote(position, Integer.MAX_VALUE); + clientVoteData.setHasVoted(position, false); + /* + * if vote wasn't valid, make sure, the passenger field hasVoted == false, probably redundant but better be safe than sorry + */ + if (vote == Integer.MAX_VALUE) { + hasVoted = false; + } } } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index 449c53b..a595bac 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -112,8 +112,8 @@ public class Passenger { /** * When called by NPC nothing should happen, because clientHandler = null */ - public void getVoteFromGameState(ClientVoteData clientVoteData) { - //LOGGER.debug("a NPC called this method hopefully: " + position); + public void getVoteFromGameState(ClientVoteData clientVoteData,Game game) { + LOGGER.debug("a NPC called this method hopefully: " + position); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index f63b2aa..db6c3eb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -97,7 +97,7 @@ public class Client { input = String.valueOf(Integer.MAX_VALUE); } sendMsgToServer(Protocol.votedFor + "$" + position + "$" + input); - LOGGER.info("msg to server is: " + Protocol.votedFor + "$" + position + "$" + input); + LOGGER.debug("msg to server is: " + Protocol.votedFor + "$" + position + "$" + input); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java index a3e1462..0789616 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java @@ -43,12 +43,14 @@ public class JClientProtocolParser { c.disconnectFromServer(); break; case Protocol.serverRequestsGhostVote: - System.out.println("Ghost received Vote request"); + LOGGER.debug("Ghost received Vote request"); + System.out.println("Ghost Vote:"); c.voteGetter(msg.substring(6)); //TODO(Seraina): How can be enforced, that clients won't vote otherwise? Trigger a methode here that listens to input break; case Protocol.serverRequestsHumanVote: - LOGGER.info("Human received Vote request"); + LOGGER.debug("Human received Vote request"); + System.out.println("Human Vote:"); c.voteGetter(msg.substring(6)); //TODO(Seraina): How can be enforced, that clients won't vote otherwise? Trigger a methode here that listens to input break; From fcd93c4d58c1e753acf1e698218eaf967d76ab15 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 19:03:47 +0200 Subject: [PATCH 18/26] Outsourced all messages sent by votehandler and noisehandler to ClientGameInfoHandler --- .../gamelogic/ClientGameInfoHandler.java | 18 ++++++ .../gamelogic/ServerGameInfoHandler.java | 13 +++-- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 56 ++++--------------- 3 files changed, 36 insertions(+), 51 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java index 3fafbdd..820307b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java @@ -10,6 +10,24 @@ import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; public class ClientGameInfoHandler { + /** + * All messages that are used in VoteHandler + */ + //relevant: + 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 = "noise"; + public static final String gameOverHumansWin = "Game over: humans win!"; + public static final String gameOverGhostsWin = "Game over: ghosts win!"; + + //just messages + public static final String itsNightTime = "Please wait, ghosts are active"; + public static final String youGotGhostyfied = "You are now a ghost!"; + public static final String itsDayTime = "Please wait, humans are active"; + public static final String humansVotedFor = "Humans voted for:"; + public static final String isAHuman = "but they're a human!"; + public static final String gotKickedOff = "is a Ghost and got kicked off"; + /** * sends a msg "" to Server stating who voted for who, this being the Client that votes * @param position the position of the passenger that is voted for diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index e43d7cc..a97458a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -27,10 +27,10 @@ public class ServerGameInfoHandler { */ public static String format(String msg, Passenger p, Game game) { switch (msg) { - case "Vote on who to ghostify!": + case ClientGameInfoHandler.ghostVoteRequest: msg = Protocol.serverRequestsGhostVote + "$" + p.getPosition() +"$" + game.gameState.toString(); break; - case "Vote for a ghost to kick off!": + case ClientGameInfoHandler.humanVoteRequest: msg = Protocol.serverRequestsHumanVote + "$" + p.getPosition() +"$"+ game.gameState.humanToString(); break; default: @@ -42,10 +42,11 @@ public class ServerGameInfoHandler { public static void ghostNpcParser(GhostNPC npc, String msg, Game game) { switch (msg) { - case "noise": + case ClientGameInfoHandler.noiseNotification: + //TODO(Seraina & Alex): noise handling npc.noise(); break; - case "Vote on who to ghostify!": + case ClientGameInfoHandler.ghostVoteRequest: npc.vote(game); } @@ -54,10 +55,10 @@ public class ServerGameInfoHandler { public static void humanNpcParser(HumanNPC npc, String msg, Game game) { switch (msg) { - case "noise": + case ClientGameInfoHandler.noiseNotification: npc.noise(); break; - case "Vote for a ghost to kick off!": + case ClientGameInfoHandler.humanVoteRequest: npc.vote(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 2c56d43..665b2f4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -56,10 +56,10 @@ public class VoteHandler { for (Passenger passenger : passengers) { if (passenger.getIsGhost()) { - passenger.send("Vote on who to ghostify!", game); + passenger.send(ClientGameInfoHandler.ghostVoteRequest, game); } else { passenger.send( - "Please wait, ghosts are active", game); + ClientGameInfoHandler.itsNightTime, game); // this time, except chat is ignored } @@ -111,7 +111,7 @@ public class VoteHandler { Ghost g = gh.ghost(passengers[ghostPosition], game); passengers[ghostPosition] = g; passengers[ghostPosition].send( - "You are now a ghost!", game); // TODO: ServerGameInfoHandler might deal with this one + ClientGameInfoHandler.youGotGhostyfied, game); // TODO: ServerGameInfoHandler might deal with this one LOGGER.info(game.getGameState().toString()); // set hasVoted to false for all passengers for future votings @@ -140,9 +140,9 @@ public class VoteHandler { // TODO: Messages in for-loop should probably be handled by ServerGameInfoHandler for (Passenger passenger : passengers) { if (passenger.getIsGhost()) { - passenger.send("Please wait, humans are active", game); + passenger.send(ClientGameInfoHandler.itsDayTime, game); } else { - passenger.send("Vote for a ghost to kick off!", game); + passenger.send(ClientGameInfoHandler.humanVoteRequest , game); } } @@ -185,13 +185,13 @@ public class VoteHandler { .getIsGhost()) { // if player with most votes is human, notify everyone about it for (Passenger passenger : passengers) { passenger.send( - "You voted for a human!", game); // TODO: ServerGameInfoHandler might be better to use here + ClientGameInfoHandler.humansVotedFor + voteIndex + ClientGameInfoHandler.isAHuman, game); // TODO: ServerGameInfoHandler might be better to use here } } if (passengers[voteIndex].getIsGhost()) { // if player is a ghost if (passengers[voteIndex].getIsOG()) { // if ghost is OG --> end game, humans win - System.out.println("Game over: humans win!"); // TODO: correctly handle end of game - return "Game over: humans win!"; + System.out.println(ClientGameInfoHandler.gameOverHumansWin); // TODO: correctly handle end of game + return ClientGameInfoHandler.gameOverHumansWin; } else { /* Special case: if ghost is not OG and if only one human is left (--> last human didn't vote for OG ghost), ghosts win. @@ -203,14 +203,14 @@ public class VoteHandler { } } if (humans == 1) { - System.out.println("Game over: ghosts win!"); - return "Game over: ghosts win!"; + System.out.println(ClientGameInfoHandler.gameOverGhostsWin); + return ClientGameInfoHandler.gameOverGhostsWin; } // Usual case: there is more than one human left and a normal ghost has been voted for --> // kick this ghost off passengers[voteIndex].setKickedOff(true); for (Passenger passenger : passengers) { - passenger.send("Player " + voteIndex + " has been kicked off!", game); + passenger.send("Player " + voteIndex + ClientGameInfoHandler.gotKickedOff, game); } } } @@ -248,38 +248,4 @@ public class VoteHandler { } - /*public static void main(String[] args) { - try { - Game game = new Game(6,1, 6); - VoteHandler voteHandler = new VoteHandler(); - - Passenger[] testArray = game.gameState.getPassengerTrain(); - Passenger ghost = new Ghost(); - testArray[3] = ghost; - testArray[3].setGhost(); - testArray[3].setIsOg(); - testArray[3].setPosition(3); - print(testArray); - LOGGER.info("NIGHT"); - voteHandler.ghostVote(testArray,game); - print(testArray); - - LOGGER.info("Day"); - voteHandler.humanVote(testArray, game); - print(testArray); - - LOGGER.info("NIGHT"); - voteHandler.ghostVote(testArray,game); - print(testArray); - - LOGGER.info("Day"); - voteHandler.humanVote(testArray, game); - print(testArray); - } catch (TrainOverflow e) { - LOGGER.warn(e.getMessage()); - } - - - - }*/ } From 159310c7caa2d1a845157d2e96034939d92771f5 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 22:04:00 +0200 Subject: [PATCH 19/26] Created new methods in ClientHandler for the start of a game and for incoming Vote --- .../multiplayer/server/ClientHandler.java | 41 +++++++++++++++++++ .../server/JServerProtocolParser.java | 29 ++----------- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index d9ed5fa..7083c84 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -1,6 +1,9 @@ package ch.unibas.dmi.dbis.cs108.multiplayer.server; import ch.unibas.dmi.dbis.cs108.BudaLogConfig; +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.multiplayer.helpers.Protocol; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.ServerPinger; import java.io.*; @@ -182,6 +185,44 @@ public class ClientHandler implements Runnable { } } + /** + * Takes a msg of the form position$vote and extracts vote and position from it and saves it + * in VoteHandler.getClientVoteData + * @param msg the messaged to decode + */ + public void decodeVote(String msg){ + int msgIndex = msg.indexOf('$'); + int vote = Integer.MAX_VALUE; + int position = 0; + LOGGER.debug("Message is " + msg); + try { + position = Integer.parseInt(msg.substring(0,msgIndex)); + vote = Integer.parseInt(msg.substring(msgIndex + 1)); + LOGGER.debug("Vote is:" + vote); + } catch (Exception e) { + LOGGER.warn("Invalid vote " + e.getMessage()); + } + LOGGER.debug("Vote is:" + vote); + if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid + VoteHandler.getClientVoteData().setVote(position,vote); + LOGGER.debug("Player vote: " + vote); + VoteHandler.getClientVoteData().setHasVoted(position,true); + } + } + + /** + * Initializes a new Game instance and starts its run method in a new thread + */ + public void startNewGame() { + try { + Game game = new Game(this,6,1, ClientHandler.getConnectedClients().size()); + Thread t = new Thread(game); + t.start(); + } catch (TrainOverflow e) { + LOGGER.warn(e.getMessage()); + } + } + /** * Removes & disconnects the client. To be used if a severe connection loss is detected (i.e. if trying to * send / receive a message throws an exception, not just if ping-pong detects a connection loss). diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java index de6ad69..df365a4 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/JServerProtocolParser.java @@ -78,34 +78,11 @@ public class JServerProtocolParser { case Protocol.votedFor: LOGGER.debug("Made it here"); msg = msg.substring(6); - int msgIndex = msg.indexOf('$'); - int vote = Integer.MAX_VALUE; - int position = 0; - LOGGER.debug("Message is " + msg); - try { - position = Integer.parseInt(msg.substring(0,msgIndex)); - vote = Integer.parseInt(msg.substring(msgIndex + 1)); - LOGGER.debug("Vote is:" + vote); - } catch (Exception e) { - LOGGER.warn("Invalid vote " + e.getMessage()); - } - LOGGER.debug("Vote is:" + vote); - if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid - VoteHandler.getClientVoteData().setVote(position,vote); - LOGGER.debug("Player vote: " + vote); - VoteHandler.getClientVoteData().setHasVoted(position,true); - } + h.decodeVote(msg); break; case Protocol.startANewGame: - try { - - Game game = new Game(h,6,1, ClientHandler.getConnectedClients().size()); - Thread t = new Thread(game); - t.start(); - } catch (TrainOverflow e) { - LOGGER.warn(e.getMessage()); - } - + h.startNewGame(); + break; default: System.out.println("Received unknown command"); } From 362b96574229246aaa7f7b89156963380d7ac886 Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 23:10:11 +0200 Subject: [PATCH 20/26] Added a thread to voteGetter so it would interfere with Pinger. Added to do for jonas --- .../dbis/cs108/multiplayer/client/Client.java | 62 ++++++++++++------- .../cs108/multiplayer/helpers/Protocol.java | 2 +- 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index db6c3eb..27e8a7a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -77,30 +77,50 @@ public class Client { * Tells user to enter a position to vote for passenger at that position */ - public void voteGetter(String msg) { - int msgIndex = msg.indexOf('$'); - String position = msg.substring(0, msgIndex);; - msg = msg.substring(msgIndex + 1); - Scanner userInput = new Scanner(System.in); - //TODO(Seraina): implement - System.out.println(msg); - System.out.println("Please enter your vote"); - int vote; - String input = ""; - try { - input = userInput.nextLine(); - vote = Integer.parseInt(input); - LOGGER.info("input is: " + vote); - } catch (Exception e) { - LOGGER.warn(e.getMessage()); - System.out.println("Invalid vote"); - input = String.valueOf(Integer.MAX_VALUE); - } - sendMsgToServer(Protocol.votedFor + "$" + position + "$" + input); - LOGGER.debug("msg to server is: " + Protocol.votedFor + "$" + position + "$" + input); + public void voteGetter(final String msg) { + /*TODO(Jonas): find a way to integrate this with userInput listener, so we can still send the + * position to the server. This way doesnt work, after a game is finished it thinks you still + * want to vote when entering /c msg + */ + new Thread(new Runnable() { + @Override + public void run() { + int msgIndex = msg.indexOf('$'); + String position = msg.substring(0, msgIndex); + String justMsg = msg.substring(msgIndex + 1); + BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in)); + while (socket.isConnected() && !socket.isClosed()) { + try { + if (bfr.ready()) { + System.out.println(justMsg); + System.out.println("Please enter your vote"); + String msgInput = bfr.readLine(); + int vote; + try { + vote = Integer.parseInt(msgInput); + LOGGER.info("input is: " + vote); + } catch (Exception e) { + LOGGER.warn(e.getMessage()); + System.out.println("Invalid vote"); + msgInput = String.valueOf(Integer.MAX_VALUE); + } + sendMsgToServer(Protocol.votedFor + "$" + position + "$" + msgInput); + LOGGER.debug( + "msg to server is: " + Protocol.votedFor + "$" + position + "$" + msgInput); + + Thread.sleep(5); + } + //LOGGER.debug("just checked next line"); + } catch (IOException | InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); } + /** * Starts a thread which listens for incoming chat messages / other messages that the user * has to see diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java index c19a11a..e40e3ff 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/Protocol.java @@ -98,7 +98,7 @@ public class Protocol { public static final String startANewGame = "STGAM"; /** - * Client informs server that they have voted and delivers this vote in the form of "CVOTE$position" + * Client informs server that they have voted and delivers this vote in the form of "CVOTE$position$vote" */ public static final String votedFor = "CVOTE"; From 52a7d2c788a5f6c0960d7bd9267ed123319e10ed Mon Sep 17 00:00:00 2001 From: Alexander Sazonov Date: Sat, 9 Apr 2022 23:35:16 +0200 Subject: [PATCH 21/26] Completed NoiseHandler and connected it to VoteHandler --- .../dbis/cs108/gamelogic/GhostifyHandler.java | 2 +- .../dbis/cs108/gamelogic/NoiseHandler.java | 31 +++++++++++++++++-- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 11 +++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java index b2fb8c0..902e08c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GhostifyHandler.java @@ -38,7 +38,7 @@ public class GhostifyHandler { } game.gameState.addNewPassenger(g, g.getPosition()); - LOGGER.info("Passenger at position " + p.getPosition() + "has been ghostified"); + LOGGER.info("Passenger at position " + p.getPosition() + " has been ghostified"); return g; } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java index 0b3fc50..d5c7bc0 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/NoiseHandler.java @@ -1,10 +1,37 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Ghost; +import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; + /** * Determines who heard something (via Passenger Array currently in GameFunctions 'passengerTrain') * and broadcasts noise message to them (via ServerGameInfoHandler) */ - public class NoiseHandler { - + /** + * Notifies passengers in the train about a ghost walking by them. Differentiates between two + * cases: if the active ghost (predator) is to the right of his victim, the Passenger array is + * being walked through from right to left (from the predator's position back to the victim's + * position), otherwise the other way around. One call of noiseNotifier only deals with one + * predator infecting a victim, so if there are already multiple ghosts in the game, the method + * should be called for each of them individually. + * + * @param passengers passengers of the train the game is played in + * @param predator ghost that has infected a human player during this night (called upon as + * passenger for convenience reasons) + * @param victim human player who has been turned into a ghost this night + * @param game current game instance + */ + public void noiseNotifier(Passenger[] passengers, Passenger predator, Ghost victim, Game game) { + if (predator.getPosition() - victim.getPosition() + > 0) { // if predator is to the right of victim + for (int i = predator.getPosition() - 1; i > victim.getPosition(); i--) { + passengers[i].send(ClientGameInfoHandler.noiseNotification, game); + } + } else { // if predator is to the left of victim + for (int i = predator.getPosition() + 1; i < victim.getPosition(); i++) { + passengers[i].send(ClientGameInfoHandler.noiseNotification, game); + } + } + } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 665b2f4..64ca673 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -43,6 +43,7 @@ public class VoteHandler { * * @param passengers: passengers on the train */ + public void ghostVote(Passenger[] passengers, Game game) { LOGGER.debug("ghostVote has been called"); LOGGER.info(game.getGameState().toString()); @@ -113,6 +114,16 @@ public class VoteHandler { passengers[ghostPosition].send( ClientGameInfoHandler.youGotGhostyfied, game); // TODO: ServerGameInfoHandler might deal with this one + /* notify passengers the ghosts passed by - for each ghost that ghostified a player, an instance of NoiseHandler + is being created and the passengers this ghost passed by are being notified. The player who's just been ghostified + is ignored since he didn't participate in this night's ghostification. */ + for (int i = 0; i < passengers.length; i++) { + if (passengers[i].getIsGhost() && i != ghostPosition) { + NoiseHandler n = new NoiseHandler(); + n.noiseNotifier(passengers, passengers[i], g, game); + } + } + LOGGER.info(game.getGameState().toString()); // set hasVoted to false for all passengers for future votings for (Passenger passenger : passengers) { From 0710703f77786021a87066193575da7802396d6f Mon Sep 17 00:00:00 2001 From: Seraina Date: Sat, 9 Apr 2022 23:39:38 +0200 Subject: [PATCH 22/26] Extended Doc in all classes I did smt in to hopefully make it understandable --- .../gamelogic/ClientGameInfoHandler.java | 7 +----- .../dbis/cs108/gamelogic/ClientVoteData.java | 17 +++++++++++++- .../unibas/dmi/dbis/cs108/gamelogic/Game.java | 11 +++++++-- .../dmi/dbis/cs108/gamelogic/GameState.java | 3 +++ .../gamelogic/ServerGameInfoHandler.java | 12 ++++++++++ .../dmi/dbis/cs108/gamelogic/Train.java | 10 +------- .../dbis/cs108/gamelogic/TrainOverflow.java | 3 +++ .../gamelogic/klassenstruktur/GhostNPC.java | 17 ++++---------- .../klassenstruktur/GhostPlayer.java | 7 +++++- .../gamelogic/klassenstruktur/HumanNPC.java | 5 ++++ .../klassenstruktur/HumanPlayer.java | 6 +++++ .../gamelogic/klassenstruktur/Passenger.java | 23 ++++++++++--------- .../multiplayer/helpers/ServerPinger.java | 2 +- .../multiplayer/server/ClientHandler.java | 4 ++++ 14 files changed, 84 insertions(+), 43 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java index 820307b..ed957e8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java @@ -12,6 +12,7 @@ public class ClientGameInfoHandler { /** * All messages that are used in VoteHandler + * TODO(Seraina&Alex): Adjust strings to be more meaningful */ //relevant: public static final String ghostVoteRequest = "Vote on who to ghostify!"; @@ -28,11 +29,5 @@ public class ClientGameInfoHandler { public static final String isAHuman = "but they're a human!"; public static final String gotKickedOff = "is a Ghost and got kicked off"; - /** - * sends a msg "" to Server stating who voted for who, this being the Client that votes - * @param position the position of the passenger that is voted for - */ - public void vote(int position) { - } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java index 26d8bf3..bcf72a9 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientVoteData.java @@ -2,6 +2,11 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; import java.util.Arrays; +/** + * Data structure that is used to store clientVotes in an array, where the index correponds to the + * position in the train of the client. + */ + public class ClientVoteData { private int[] vote; //saves vote of clientHandler for later transmission to passenger, by default MAX_VALUE, index corresponds to Passenger position @@ -9,7 +14,7 @@ public class ClientVoteData { public ClientVoteData() { int[] h = new int[6]; - Arrays.fill(h,0); + Arrays.fill(h,Integer.MAX_VALUE); this.vote = h; this.hasVoted = new boolean[6]; } @@ -22,10 +27,20 @@ public class ClientVoteData { return hasVoted; } + /** + * Sets a vote value at the right position in the vote array + * @param position the index of the array + * @param vote the vote value + */ public void setVote(int position, int vote) { this.vote[position] = vote; } + /** + * Sets true or false at the right position in the hasVoted array + * @param position the index of the array + * @param hasVoted the vote state value + */ public void setHasVoted(int position, boolean hasVoted) { this.hasVoted[position] = hasVoted; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index 243ac36..fb7f007 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -64,6 +64,13 @@ public class Game implements Runnable { isDay = day; } + /** + * Starts a new game, creates a passenger array and saves it in gameState, sets the OG + * currently at gameState.train[3] fills the passengerTrain moving from left to rigth in the + * gameState.train array it connects clientHandlers witch the passengers in those positions + * (Players) and fills the rest with NPC's + * TODO: set ghost in a random position(i), gameState.train[i] so that a lone player can also start as a Ghost maybe use Train class + */ @Override public void run() { LOGGER.info("the run-method has been called"); @@ -113,8 +120,8 @@ public class Game implements Runnable { gameOverCheck = voteHandler.humanVote(gameState.getPassengerTrain(), this); setDay(false); } - if (gameOverCheck.equals("Game over: ghosts win!") || gameOverCheck.equals( - "Game over: humans win!")) { + if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) || gameOverCheck.equals( + ClientGameInfoHandler.gameOverHumansWin)) { clientHandler.broadcastAnnouncement(gameOverCheck); return; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index c11cd80..6aeef13 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -23,6 +23,9 @@ public class GameState { * contains all Passengers on train, needs to be updated */ private Passenger[] passengerTrain; + /** + * Saves ClientVoteData, might not be used + */ private ClientVoteData clientVoteData; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index a97458a..c15e7cc 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -40,6 +40,12 @@ public class ServerGameInfoHandler { return msg; } + /** + * decides which action an GhostNpc needs to take, based on a message + * @param npc the GhostNpc needing to do smt + * @param msg the msg containing the information on what to do + * @param game the game the GhostNpc lives in (in gameState.passengerTrain) + */ public static void ghostNpcParser(GhostNPC npc, String msg, Game game) { switch (msg) { case ClientGameInfoHandler.noiseNotification: @@ -53,6 +59,12 @@ public class ServerGameInfoHandler { } + /** + * decides which action an HumanNpc needs to take, based on a message + * @param npc the HumanNpc needing to do smt + * @param msg the msg containing the information on what to do + * @param game the game the HumanNpc lives in (in gameState.passengerTrain) + */ public static void humanNpcParser(HumanNPC npc, String msg, Game game) { switch (msg) { case ClientGameInfoHandler.noiseNotification: diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java index 7449484..ee76cc8 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java @@ -9,7 +9,7 @@ public class Train { public static final BudaLogConfig l = new BudaLogConfig(LOGGER); int[] orderOfTrain; //gives the random order in which the passengers enter the train - int positionOfGhost; + int positionOfGhost; // useful for randomization of og ghost position /** * Constructs a Train with orderOfTrain of the size nrOfPlayers, filled with a Random order of the @@ -67,12 +67,4 @@ public class Train { return false; } - public static void main(String[] args) { - try { - Train t = new Train(6, 1); - } catch (TrainOverflow e) { - LOGGER.error(e.getMessage()); - } - - } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/TrainOverflow.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/TrainOverflow.java index 0eaaab1..a44cb91 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/TrainOverflow.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/TrainOverflow.java @@ -1,5 +1,8 @@ package ch.unibas.dmi.dbis.cs108.gamelogic; +/** + * An exception that is thrown, if for some reason to many clients want to start a game + */ public class TrainOverflow extends Exception { private static final String message = "Too many users are logged on"; diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index 80ee9d4..9125099 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -41,6 +41,7 @@ public class GhostNPC extends Ghost { /** * Sets vote of this Ghost position on a number between 0 and 5, * but only for positions where there aren't any ghosts and sets hasVoted to true + * TODO: Make NPC smarter */ public void vote(Game game){ int ghostCounter = 0; @@ -64,21 +65,13 @@ public class GhostNPC extends Ghost { LOGGER.info("GhostNPC at Position: " + this.getPosition() + " has voted for: " + vote); } + /** + * Decides what to do when a noise ist heard, currently just always broadcasts it + * TODO: Make NPC smarter + */ public void noise() { clientHandler.broadcastChatMessage("I heard some noise tonight"); } - /*public static void main(String[] args) { - try { - Game game = new Game(6,1,1); - Passenger p = new Passenger(); - GhostNPC ghostNPC = new GhostNPC(2,"peter", false, game); - p = ghostNPC; - ghostNPC.vote(game); - } catch (TrainOverflow e) { - LOGGER.warn(e.getMessage()); - } - - }*/ } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java index 72f865d..1d7133e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostPlayer.java @@ -33,7 +33,12 @@ public class GhostPlayer extends Ghost { } } - + /** + * Sends a message to the client handled bye this client handler + * TODO: does this also work with 2 clients? + * @param msg the message that is sent to this player. + * @param game the game the GhostPlayer lives on (in game.gameState.passengerTrain) + */ @Override public void send(String msg, Game game) { String formattedMsg = ServerGameInfoHandler.format(msg, this, game); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java index fd32f17..3b3a3c3 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java @@ -29,6 +29,11 @@ public class HumanNPC extends Human { } } + /** + * Sends a msg to the ServerGameInfoHandler.humanNpcParser to decide what has to happen now + * @param msg the message that is sent to this player. + * @param game the game the HumanNPC lives on (in game.gameState.passengerTrain) + */ @Override public void send(String msg, Game game) { ServerGameInfoHandler.humanNpcParser(this, msg, game); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java index b7e714f..2f257cb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanPlayer.java @@ -32,6 +32,12 @@ public class HumanPlayer extends Human { } } + /** + * Sends a message to the client handled bye this client handler + * TODO: does this also work with 2 clients? + * @param msg the message that is sent to this player. + * @param game the game the HumanPlayer lives on (in game.gameState.passengerTrain) + */ @Override public void send(String msg, Game game) { String formattedMsg = ServerGameInfoHandler.format(msg,this, game); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java index a595bac..c3d3462 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/Passenger.java @@ -22,17 +22,6 @@ public class Passenger { protected boolean hasVoted; //true if the player gave his vote during voting time protected int vote; //saves the number of the player this passenger voted for during voting (0-5) - /** - * Sends a protocol message to the respective player or NPC. - * @param msg the message that is sent to this player. - **/ - public void send(String msg, Game game) { - if (isPlayer) { - String formattedMsg = ServerGameInfoHandler.format(msg,this,game); - clientHandler.sendMsgToClient(formattedMsg); - } - LOGGER.warn("This object should not just be a passenger. Position:" + position); - } /** * sets the Position of this passenger @@ -116,4 +105,16 @@ public class Passenger { LOGGER.debug("a NPC called this method hopefully: " + position); } + /** + * Sends a protocol message to the respective player or NPC. + * @param msg the message that is sent to this player. + **/ + public void send(String msg, Game game) { + if (isPlayer) { + String formattedMsg = ServerGameInfoHandler.format(msg,this,game); + clientHandler.sendMsgToClient(formattedMsg); + } + LOGGER.warn("This object should not just be a passenger. Position:" + position); + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java index 6400ad4..cf758c5 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/helpers/ServerPinger.java @@ -56,7 +56,7 @@ public class ServerPinger implements Runnable { System.out.println( "Lost connection to user " + c.getClientUserName() + ". Waiting to reconnect..."); } else { - //c.disconnectClient(); + //c.disconnectClient(); TODO: is that ever necessary? //LOGGER.debug("gotPingBack has not been set to true and isConnected has been set to false before"); } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index 7083c84..0c02d39 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -75,6 +75,10 @@ public class ClientHandler implements Runnable { return socket; } + /** + * Needed to fill a train with client TODO: how do lobbies fit here? + * @return the HashSet of Connected Clients + */ public static HashSet getConnectedClients() { return connectedClients; } From 087250b9f59b07eb81991e19fb934b675c4685b3 Mon Sep 17 00:00:00 2001 From: Alexander Sazonov Date: Mon, 11 Apr 2022 13:56:15 +0200 Subject: [PATCH 23/26] Packed duplicated code fragments into a method (in VoteHandler) --- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 79 ++++++++----------- 1 file changed, 34 insertions(+), 45 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 64ca673..8a7347c 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -72,30 +72,8 @@ public class VoteHandler { LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); } + int currentMax = voteEvaluation(passengers, votesForPlayers, clientVoteData, game); - for (Passenger passenger : passengers) { //TODO: could be outsourced to a method to increase readability - // collecting the votes - distribute them among the vote counters for all players - // Note: Each voting collects votes for all players even though some might not be concerned - // (i.e. ghosts during ghost vote). Those players will then get 0 votes so it doesn't matter. - // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler - passenger.getVoteFromGameState(clientVoteData, game); - if (passenger.getHasVoted()) { - for (int i = 0; i < votesForPlayers.length; i++) { - if (passenger.getVote() == i) { - votesForPlayers[i]++; - } - } - } - } - - // count the votes - determine which player has the most votes by going through the - // votesForPlayers array - int currentMax = 0; - for (int votesForPlayer : votesForPlayers) { - if (votesForPlayer > currentMax) { - currentMax = votesForPlayer; - } - } LOGGER.debug("Most votes: " + currentMax + " vote"); // ghostify the player with most votes @@ -138,7 +116,7 @@ public class VoteHandler { * normal ghost, kick him off; if it's the OG ghost, end game, humans win. * @return Returns an empty String by default, returns a complex string when game is over: * "Game over: ghosts win!" or "Game over: humans win!" - * @param passengers: train passengers + * @param passengers train passengers */ public String humanVote(Passenger[] passengers, Game game) { LOGGER.info(game.getGameState().toString()); @@ -153,7 +131,7 @@ public class VoteHandler { if (passenger.getIsGhost()) { passenger.send(ClientGameInfoHandler.itsDayTime, game); } else { - passenger.send(ClientGameInfoHandler.humanVoteRequest , game); + passenger.send(ClientGameInfoHandler.humanVoteRequest, game); } } @@ -163,27 +141,8 @@ public class VoteHandler { LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); } - for (Passenger passenger : passengers) { - passenger.getVoteFromGameState(clientVoteData, game); - // collecting the votes - distribute them among the vote counters for all players - // TODO: Perhaps the vote results should be handled by ClientGameInfoHandler - if (passenger.getHasVoted()) { - for (int i = 0; i < votesForPlayers.length; i++) { - if (passenger.getVote() == i) { - votesForPlayers[i]++; - } - } - } - } + int currentMax = voteEvaluation(passengers, votesForPlayers, clientVoteData, game); - // count the votes - determine which player has the most votes by going through the - // votesForPlayers array - int currentMax = 0; - for (int votesForPlayer : votesForPlayers) { - if (votesForPlayer > currentMax) { - currentMax = votesForPlayer; - } - } // deal with voting results int voteIndex = 0; for (int i = 0; i < votesForPlayers.length; i++) { @@ -259,4 +218,34 @@ public class VoteHandler { } + /** + * Collecting the votes - distribute them among the vote counters for all players. Note: each voting collects + * votes for all players even though some might not be concerned (i.e. ghosts during ghost vote). Those players + * will then get 0 votes so it dosen't matter. Returns the max amount of votes a player received. + * @param passengers train passengers + * @param votesForPlayers array collecting the votes each player received during a voting + * @param data deals with Client votes + * @param game current game instance + */ + int voteEvaluation(Passenger[] passengers, int[] votesForPlayers, ClientVoteData data, Game game) { + for (Passenger passenger : passengers) { + passenger.getVoteFromGameState(data, game); + if (passenger.getHasVoted()) { + for (int i = 0; i < votesForPlayers.length; i++) { + if (passenger.getVote() == i) { + votesForPlayers[i]++; + } + } + } + } + /* count the votes - determine which player has the most votes by going through the + votesForPlayers array */ + int currentMax = 0; + for (int votesForPlayer : votesForPlayers) { + if (votesForPlayer > currentMax) { + currentMax = votesForPlayer; + } + } + return currentMax; + } } From 850e09e0affcd5367d5c327bed39595024c1b8d8 Mon Sep 17 00:00:00 2001 From: Seraina Date: Wed, 13 Apr 2022 11:43:35 +0200 Subject: [PATCH 24/26] Integrated noise handling so it would run, some bugs still to work out --- .../ch/unibas/dmi/dbis/cs108/gamelogic/Game.java | 4 ++++ .../unibas/dmi/dbis/cs108/gamelogic/GameState.java | 2 +- .../dbis/cs108/gamelogic/ServerGameInfoHandler.java | 5 +++-- .../dmi/dbis/cs108/gamelogic/VoteHandler.java | 5 +++++ .../cs108/gamelogic/klassenstruktur/GhostNPC.java | 3 --- .../cs108/gamelogic/klassenstruktur/HumanNPC.java | 13 ++++++------- .../cs108/multiplayer/server/ClientHandler.java | 2 +- 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java index fb7f007..460af73 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Game.java @@ -58,6 +58,10 @@ public class Game implements Runnable { return nrOfUsers; } + public ClientHandler getClientHandler() { + return clientHandler; + } + public boolean getIsDay() {return isDay;} public void setDay(boolean day) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index 6aeef13..c28d553 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -48,7 +48,7 @@ public class GameState { clientVoteData = new ClientVoteData(); Passenger[] passengerTrain = new Passenger[nrOfPlayers]; //Creates an array with Passengers with correlation positions (Train) for (int i = 0; i < nrOfPlayers; i++) { - if (i == 3) { + if (i == 3) { //TODO: randomize via Train.ghostposition Ghost g = new Ghost(); g.setPosition(train.orderOfTrain[i]); g.setGhost(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index c15e7cc..ce8d57a 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -6,6 +6,7 @@ import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.GhostNPC; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.HumanNPC; import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger; import ch.unibas.dmi.dbis.cs108.multiplayer.helpers.Protocol; +import ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -50,7 +51,7 @@ public class ServerGameInfoHandler { switch (msg) { case ClientGameInfoHandler.noiseNotification: //TODO(Seraina & Alex): noise handling - npc.noise(); + game.getClientHandler().broadcastChatMessage(ClientGameInfoHandler.noiseNotification); break; case ClientGameInfoHandler.ghostVoteRequest: npc.vote(game); @@ -68,7 +69,7 @@ public class ServerGameInfoHandler { public static void humanNpcParser(HumanNPC npc, String msg, Game game) { switch (msg) { case ClientGameInfoHandler.noiseNotification: - npc.noise(); + game.getClientHandler().broadcastChatMessage(ClientGameInfoHandler.noiseNotification); break; case ClientGameInfoHandler.humanVoteRequest: npc.vote(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java index 64ca673..3588b1e 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/VoteHandler.java @@ -113,6 +113,11 @@ public class VoteHandler { passengers[ghostPosition] = g; passengers[ghostPosition].send( ClientGameInfoHandler.youGotGhostyfied, game); // TODO: ServerGameInfoHandler might deal with this one + try { // waits 20 seconds before votes get collected + Thread.sleep(10); + } catch (InterruptedException e) { + LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted"); + } /* notify passengers the ghosts passed by - for each ghost that ghostified a player, an instance of NoiseHandler is being created and the passengers this ghost passed by are being notified. The player who's just been ghostified diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java index 9125099..d4918d7 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/GhostNPC.java @@ -69,9 +69,6 @@ public class GhostNPC extends Ghost { * Decides what to do when a noise ist heard, currently just always broadcasts it * TODO: Make NPC smarter */ - public void noise() { - clientHandler.broadcastChatMessage("I heard some noise tonight"); - } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java index 3b3a3c3..04d2674 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/klassenstruktur/HumanNPC.java @@ -7,6 +7,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class HumanNPC extends Human { + public static final Logger LOGGER = LogManager.getLogger(); public static final BudaLogConfig l = new BudaLogConfig(LOGGER); @@ -31,7 +32,8 @@ public class HumanNPC extends Human { /** * Sends a msg to the ServerGameInfoHandler.humanNpcParser to decide what has to happen now - * @param msg the message that is sent to this player. + * + * @param msg the message that is sent to this player. * @param game the game the HumanNPC lives on (in game.gameState.passengerTrain) */ @Override @@ -41,16 +43,13 @@ public class HumanNPC extends Human { /** * Currently returns a random integer for voting + * * @return integer between 0 and 5 */ - public void vote(){ - int randomNr = (int) (Math.random()*6); + public void vote() { + int randomNr = (int) (Math.random() * 6); vote = randomNr; hasVoted = true; LOGGER.info("HumanNPC at Position: " + this.getPosition() + " has voted for: " + vote); } - - public void noise() { - clientHandler.broadcastChatMessage("I heard some noise tonight"); - } } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index 0c02d39..30da240 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -210,7 +210,7 @@ public class ClientHandler implements Runnable { if(vote != Integer.MAX_VALUE) { //gets MAX_VALUE when the vote wasn't valid VoteHandler.getClientVoteData().setVote(position,vote); LOGGER.debug("Player vote: " + vote); - VoteHandler.getClientVoteData().setHasVoted(position,true); + VoteHandler.getClientVoteData().setHasVoted(position,true); //TODO: move clientVoteData to gamestate } } From bc136d7b68ca1f7f361a4938c746028dc52d1d42 Mon Sep 17 00:00:00 2001 From: Seraina Date: Wed, 13 Apr 2022 12:57:49 +0200 Subject: [PATCH 25/26] Fixed some bugs with the noise handeling, seems not work now Still need to handle connection loss and name-change in gamelogic --- .../gamelogic/ClientGameInfoHandler.java | 8 ++--- .../dmi/dbis/cs108/gamelogic/GameState.java | 12 +++---- .../gamelogic/ServerGameInfoHandler.java | 34 ++++++++++++++++--- .../dmi/dbis/cs108/gamelogic/Train.java | 4 +++ .../dbis/cs108/multiplayer/client/Client.java | 18 ++++------ .../multiplayer/server/ClientHandler.java | 11 ++++++ 6 files changed, 60 insertions(+), 27 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java index ed957e8..27d09fb 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ClientGameInfoHandler.java @@ -17,7 +17,7 @@ public class ClientGameInfoHandler { //relevant: 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 = "noise"; + public static final String noiseNotification = "You heard some noise"; public static final String gameOverHumansWin = "Game over: humans win!"; public static final String gameOverGhostsWin = "Game over: ghosts win!"; @@ -25,9 +25,9 @@ public class ClientGameInfoHandler { public static final String itsNightTime = "Please wait, ghosts are active"; public static final String youGotGhostyfied = "You are now a ghost!"; public static final String itsDayTime = "Please wait, humans are active"; - public static final String humansVotedFor = "Humans voted for:"; - public static final String isAHuman = "but they're a human!"; - public static final String gotKickedOff = "is a Ghost and got kicked off"; + public static final String humansVotedFor = "Humans voted for: "; + public static final String isAHuman = " but they're a human!"; + public static final String gotKickedOff = " is a Ghost and got kicked off"; } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java index c28d553..7ea236b 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java @@ -95,19 +95,19 @@ public class GameState { String[] print = new String[6]; for (int i = 0; i < array.length; i++) { if (array[i].getKickedOff()) { - print[i] = "| kicked off: " + array[i].getPosition() + "|"; + print[i] = "-| kicked off: " + array[i].getPosition() + "|-"; } else { if (array[i].getIsPlayer()) { if (array[i].getIsGhost()) { - print[i] = "| ghostPlayer: " + array[i].getPosition() + "|"; + print[i] = "-| ghostPlayer: " + array[i].getPosition() + "|-"; } else { - print[i] = "| humanPlayer: " + array[i].getPosition() + "|"; + print[i] = "-| humanPlayer: " + array[i].getPosition() + "|"; } } else { if (array[i].getIsGhost()) { - print[i] = "| ghostNPC: " + array[i].getPosition() + "|"; + print[i] = "-| ghostNPC: " + array[i].getPosition() + "|-"; } else { - print[i] = "| humanNPC: " + array[i].getPosition() + "|"; + print[i] = "-| humanNPC: " + array[i].getPosition() + "|-"; } } } @@ -130,7 +130,7 @@ public class GameState { StringBuilder stringBuilder = new StringBuilder(); String[] print = new String[6]; for (int i = 0; i < array.length; i++) { - print[i] = "| " + array[i].getName() + ": " + array[i].getPosition() + "|"; + print[i] = "-| " + array[i].getName() + ": " + array[i].getPosition() + "|-"; } for (int i = 0; i < array.length; i++) { diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java index ce8d57a..1279b73 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/ServerGameInfoHandler.java @@ -41,6 +41,31 @@ public class ServerGameInfoHandler { return msg; } + /** + * Chooses for an NPC what they want to say, so they don't sound the same all the time + * @return a String saying that sm heard sm noise + */ + public static String noiseRandomizer() { + String a = "I heard some noise tonight"; + String b = "noise"; + String c = "I heard smt strange tonight"; + String d = "Me, noise!"; + String e = "Uuuuh, spoky noises"; + int number = (int)(Math.random()*4); + switch (number) { + case 0: + return a; + case 1: + return d; + case 2: + return c; + case 3: + return e; + default: + return b; + } + } + /** * decides which action an GhostNpc needs to take, based on a message * @param npc the GhostNpc needing to do smt @@ -50,14 +75,12 @@ public class ServerGameInfoHandler { public static void ghostNpcParser(GhostNPC npc, String msg, Game game) { switch (msg) { case ClientGameInfoHandler.noiseNotification: - //TODO(Seraina & Alex): noise handling - game.getClientHandler().broadcastChatMessage(ClientGameInfoHandler.noiseNotification); + String outMsg = npc.getName() + ": " + noiseRandomizer(); + game.getClientHandler().broadcastNpcChatMessage(outMsg); break; case ClientGameInfoHandler.ghostVoteRequest: npc.vote(game); } - - } /** @@ -69,7 +92,8 @@ public class ServerGameInfoHandler { public static void humanNpcParser(HumanNPC npc, String msg, Game game) { switch (msg) { case ClientGameInfoHandler.noiseNotification: - game.getClientHandler().broadcastChatMessage(ClientGameInfoHandler.noiseNotification); + String outMsg = npc.getName() + ": " + noiseRandomizer();; + game.getClientHandler().broadcastNpcChatMessage(outMsg); break; case ClientGameInfoHandler.humanVoteRequest: npc.vote(); diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java index ee76cc8..852d748 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/Train.java @@ -67,4 +67,8 @@ public class Train { return false; } + public static void main(String[] args) { + System.out.println("Hallo"); + } + } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index 27e8a7a..539b206 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -78,23 +78,18 @@ public class Client { */ public void voteGetter(final String msg) { - /*TODO(Jonas): find a way to integrate this with userInput listener, so we can still send the - * position to the server. This way doesnt work, after a game is finished it thinks you still - * want to vote when entering /c msg - */ + /*TODO(Seraina): Find out what happens if there is no input*/ new Thread(new Runnable() { @Override public void run() { int msgIndex = msg.indexOf('$'); String position = msg.substring(0, msgIndex); String justMsg = msg.substring(msgIndex + 1); - BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in)); - while (socket.isConnected() && !socket.isClosed()) { + Scanner input = new Scanner(System.in); + System.out.println(justMsg); try { - if (bfr.ready()) { - System.out.println(justMsg); System.out.println("Please enter your vote"); - String msgInput = bfr.readLine(); + String msgInput = input.nextLine(); int vote; try { vote = Integer.parseInt(msgInput); @@ -109,12 +104,11 @@ public class Client { "msg to server is: " + Protocol.votedFor + "$" + position + "$" + msgInput); Thread.sleep(5); - } + //LOGGER.debug("just checked next line"); - } catch (IOException | InterruptedException e) { + } catch (InterruptedException e) { e.printStackTrace(); } - } } }).start(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java index 30da240..e6473ee 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/server/ClientHandler.java @@ -158,6 +158,17 @@ public class ClientHandler implements Runnable { } } + /** + * Broadcasts a pseudo chat Message from a NPC to all active clients + * + * @param msg the Message to be broadcast + */ + public void broadcastNpcChatMessage(String msg) { + for (ClientHandler client : connectedClients) { + client.sendMsgToClient(Protocol.printToClientConsole + "$" + msg); + } + } + /** * Broadcasts a non-chat Message to all active clients. This can be used for server * messages / announcements rather than chat messages. The message will be printed to the user From 9299027bcd3c3ddeea939718a9d0d82860559341 Mon Sep 17 00:00:00 2001 From: Seraina Date: Wed, 13 Apr 2022 18:56:48 +0200 Subject: [PATCH 26/26] Had to redo the voteGetter: now it is handled via userInputListener and messageFormatter --- .../dbis/cs108/multiplayer/client/Client.java | 52 ++++++++----------- .../client/JClientProtocolParser.java | 4 +- .../multiplayer/client/MessageFormatter.java | 12 ++++- 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java index 539b206..85a783f 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/Client.java @@ -11,6 +11,8 @@ import java.io.*; import java.net.UnknownHostException; import java.util.Objects; import java.util.Scanner; +import java.util.Timer; +import java.util.TimerTask; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -24,6 +26,11 @@ public class Client { private BufferedWriter out; public ClientPinger clientPinger; + /** + * Saves the position of the client, gets refreshed everytime the client gets a vote request. + */ + int position = Integer.MAX_VALUE; + public Client(Socket socket) { try { this.socket = socket; @@ -59,7 +66,7 @@ public class Client { try { if (bfr.ready()) { String msg = bfr.readLine(); - String formattedMSG = MessageFormatter.formatMsg(msg); + String formattedMSG = MessageFormatter.formatMsg(msg, position); sendMsgToServer(formattedMSG); } Thread.sleep(5); @@ -73,44 +80,27 @@ public class Client { }).start(); } + /** * Tells user to enter a position to vote for passenger at that position */ + public void positionSetter(String msg) { - public void voteGetter(final String msg) { - /*TODO(Seraina): Find out what happens if there is no input*/ - new Thread(new Runnable() { - @Override - public void run() { + LOGGER.info("Im in thread:" + Thread.currentThread()); int msgIndex = msg.indexOf('$'); - String position = msg.substring(0, msgIndex); + String pos = msg.substring(0, msgIndex); + try { + position = Integer.parseInt(pos); + } catch (NumberFormatException e) { + LOGGER.warn("Position got scrabbled on the way here"); + } String justMsg = msg.substring(msgIndex + 1); - Scanner input = new Scanner(System.in); + System.out.println(justMsg); - try { - System.out.println("Please enter your vote"); - String msgInput = input.nextLine(); - int vote; - try { - vote = Integer.parseInt(msgInput); - LOGGER.info("input is: " + vote); - } catch (Exception e) { - LOGGER.warn(e.getMessage()); - System.out.println("Invalid vote"); - msgInput = String.valueOf(Integer.MAX_VALUE); - } - sendMsgToServer(Protocol.votedFor + "$" + position + "$" + msgInput); - LOGGER.debug( - "msg to server is: " + Protocol.votedFor + "$" + position + "$" + msgInput); + System.out.println("Please enter your vote"); - Thread.sleep(5); - //LOGGER.debug("just checked next line"); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - }).start(); + //LOGGER.debug("just checked next line"); } @@ -134,7 +124,7 @@ public class Client { } else { System.out.println("chatMsg is null"); throw new IOException();} } catch (IOException e) { //e.printStackTrace(); - LOGGER.debug("Exception while trying to read message: " + e.getMessage()); + LOGGER.warn("Exception while trying to read message: " + e.getMessage()); disconnectFromServer(); } diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java index 0789616..3af6d14 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/JClientProtocolParser.java @@ -45,13 +45,13 @@ public class JClientProtocolParser { case Protocol.serverRequestsGhostVote: LOGGER.debug("Ghost received Vote request"); System.out.println("Ghost Vote:"); - c.voteGetter(msg.substring(6)); + c.positionSetter(msg.substring(6)); //TODO(Seraina): How can be enforced, that clients won't vote otherwise? Trigger a methode here that listens to input break; case Protocol.serverRequestsHumanVote: LOGGER.debug("Human received Vote request"); System.out.println("Human Vote:"); - c.voteGetter(msg.substring(6)); + c.positionSetter(msg.substring(6)); //TODO(Seraina): How can be enforced, that clients won't vote otherwise? Trigger a methode here that listens to input break; default: diff --git a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java index 5758e17..7679536 100644 --- a/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java +++ b/src/main/java/ch/unibas/dmi/dbis/cs108/multiplayer/client/MessageFormatter.java @@ -18,7 +18,7 @@ public class MessageFormatter { * @return the reformatted message in the form HEADR$msg */ - public static String formatMsg(String msg) { + public static String formatMsg(String msg, int position) { String header = ""; //header is first two characters StringBuilder stringBuilder = new StringBuilder(); String s = ""; // just a friendly helper to save message in @@ -59,10 +59,20 @@ public class MessageFormatter { stringBuilder.append(Protocol.listLobbies + "$"); s = ""; //Command has no parameters break; + case "/v": + try { + s = msg.substring(3); + LOGGER.debug("substring: " + s); + } catch (Exception e) { + System.out.println("invalid vote"); + } + stringBuilder.append(Protocol.votedFor + "$" + position + "$"); + break; default: s = msg; } stringBuilder.append(s); + LOGGER.debug(stringBuilder.toString()); return stringBuilder.toString(); }