Merge branch 'SerainaSpiellogik'
This commit is contained in:
commit
b8c970801c
@ -6,6 +6,8 @@ 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
|
||||
* CVOTE$position$vote Client at position has voted for position
|
||||
|
||||
Future / planned:
|
||||
* CRTGM Create a new game
|
||||
@ -22,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.
|
||||
|
||||
@ -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.
|
||||
}
|
||||
|
||||
|
||||
@ -11,10 +11,23 @@ import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Passenger;
|
||||
public class ClientGameInfoHandler {
|
||||
|
||||
/**
|
||||
* 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
|
||||
* All messages that are used in VoteHandler
|
||||
* TODO(Seraina&Alex): Adjust strings to be more meaningful
|
||||
*/
|
||||
public void vote(int position) {
|
||||
//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 = "You heard some 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";
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,47 @@
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@ -2,19 +2,29 @@ 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 {
|
||||
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 GameFunctions gameFunctions;
|
||||
protected GameState gameState;
|
||||
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:
|
||||
@ -23,26 +33,107 @@ 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(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.gameFunctions = new GameFunctions(nrOfPlayers, nrOfGhosts, nrOfUsers);
|
||||
this.gameState = new GameState(nrOfPlayers, nrOfGhosts, nrOfUsers);
|
||||
this.clientHandler = clientHandler;
|
||||
}
|
||||
|
||||
public GameState getGameState() {
|
||||
return gameState;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
public int getNrOfGhosts() {
|
||||
return nrOfGhosts;
|
||||
}
|
||||
|
||||
try {
|
||||
public int getNrOfPlayers() {
|
||||
return nrOfPlayers;
|
||||
}
|
||||
|
||||
Game game1 = new Game(6, 1, 1);
|
||||
public int getNrOfUsers() {
|
||||
return nrOfUsers;
|
||||
}
|
||||
|
||||
} catch (TrainOverflow e) {
|
||||
System.out.println(e.getMessage());
|
||||
public ClientHandler getClientHandler() {
|
||||
return clientHandler;
|
||||
}
|
||||
|
||||
public boolean getIsDay() {return isDay;}
|
||||
|
||||
public void setDay(boolean day) {
|
||||
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");
|
||||
int i = 0;
|
||||
HashSet<ClientHandler> clients = ClientHandler.getConnectedClients();
|
||||
String gameOverCheck = "";
|
||||
int[] order = gameState.getTrain().orderOfTrain;
|
||||
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
|
||||
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 they are a ghost
|
||||
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());
|
||||
gameState.getPassengerTrain()[index] = humanNPC;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
LOGGER.info(gameState.toString());
|
||||
|
||||
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);
|
||||
setDay(false);
|
||||
}
|
||||
if (gameOverCheck.equals(ClientGameInfoHandler.gameOverGhostsWin) || gameOverCheck.equals(
|
||||
ClientGameInfoHandler.gameOverHumansWin)) {
|
||||
clientHandler.broadcastAnnouncement(gameOverCheck);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1,60 +0,0 @@
|
||||
package ch.unibas.dmi.dbis.cs108.gamelogic;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.BudaLogConfig;
|
||||
import ch.unibas.dmi.dbis.cs108.gamelogic.klassenstruktur.Human;
|
||||
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 static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Constructs a GameFunctions instance where nrOfPlayers >= nrOfUsers. Fills passengerTrain with
|
||||
* only humans
|
||||
*
|
||||
* @param nrOfPlayers is the length of the Train
|
||||
* @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)
|
||||
* @throws TrainOverflow if nrOfPlayers < nrOfUsers
|
||||
*/
|
||||
GameFunctions(int nrOfPlayers, int nrOfGhosts, int nrOfUsers)
|
||||
throws TrainOverflow { //ToDo: where will Exception be handled?
|
||||
this.nrOfPlayers = nrOfPlayers;
|
||||
this.nrOfGhosts = nrOfGhosts;
|
||||
this.nrOfUsers = nrOfUsers;
|
||||
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();
|
||||
h.setPosition(train.orderOfTrain[i]);
|
||||
passengerTrain[train.orderOfTrain[i]] = h;
|
||||
}
|
||||
this.passengerTrain = passengerTrain;
|
||||
}
|
||||
|
||||
public int getNrOfGhosts() {
|
||||
return nrOfGhosts;
|
||||
}
|
||||
|
||||
public int getNrOfPlayers() {
|
||||
return nrOfPlayers;
|
||||
}
|
||||
|
||||
public int getNrOfUsers() {
|
||||
return nrOfUsers;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
142
src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java
Normal file
142
src/main/java/ch/unibas/dmi/dbis/cs108/gamelogic/GameState.java
Normal file
@ -0,0 +1,142 @@
|
||||
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 java.util.Arrays;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
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
|
||||
**/
|
||||
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;
|
||||
/**
|
||||
* Saves ClientVoteData, might not be used
|
||||
*/
|
||||
private ClientVoteData clientVoteData;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a GameState instance where nrOfPlayers >= nrOfUsers. Fills passengerTrain with
|
||||
* only humans
|
||||
*
|
||||
* @param nrOfPlayers is the length of the Train
|
||||
* @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)
|
||||
* @throws TrainOverflow if nrOfPlayers < nrOfUsers
|
||||
*/
|
||||
GameState(int nrOfPlayers, int nrOfGhosts, int nrOfUsers)
|
||||
throws TrainOverflow { //ToDo: where will Exception be handled?
|
||||
this.nrOfPlayers = nrOfPlayers;
|
||||
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) { //TODO: randomize via Train.ghostposition
|
||||
Ghost g = new Ghost();
|
||||
g.setPosition(train.orderOfTrain[i]);
|
||||
g.setGhost();
|
||||
g.setIsOG(true);
|
||||
passengerTrain[train.orderOfTrain[i]] = g;
|
||||
} else {
|
||||
Human h = new Human();
|
||||
h.setPosition(train.orderOfTrain[i]);
|
||||
passengerTrain[train.orderOfTrain[i]] = h;
|
||||
}
|
||||
}
|
||||
|
||||
this.passengerTrain = passengerTrain;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
@ -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,13 +20,25 @@ 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());
|
||||
game.gameFunctions.passengerTrain[g.getPosition()] = g;
|
||||
LOGGER.info("Passenger at position " + p.getPosition() + "has been ghostified");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,14 @@
|
||||
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 ch.unibas.dmi.dbis.cs108.multiplayer.server.ClientHandler;
|
||||
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,26 +18,89 @@ 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 void sendVoteRequestGhosts(Passenger passenger){
|
||||
passenger.getClientHandler().sendMsgToClient("GVOTR");
|
||||
public static String format(String msg, Passenger p, Game game) {
|
||||
switch (msg) {
|
||||
case ClientGameInfoHandler.ghostVoteRequest:
|
||||
msg = Protocol.serverRequestsGhostVote + "$" + p.getPosition() +"$" + game.gameState.toString();
|
||||
break;
|
||||
case ClientGameInfoHandler.humanVoteRequest:
|
||||
msg = Protocol.serverRequestsHumanVote + "$" + p.getPosition() +"$"+ game.gameState.humanToString();
|
||||
break;
|
||||
default:
|
||||
msg = Protocol.printToClientConsole + "$"+ msg;
|
||||
}
|
||||
LOGGER.debug(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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 void sendVoteRequestHumans(Passenger passenger){
|
||||
passenger.getClientHandler().sendMsgToClient("HVOTR");
|
||||
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
|
||||
* @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:
|
||||
String outMsg = npc.getName() + ": " + noiseRandomizer();
|
||||
game.getClientHandler().broadcastNpcChatMessage(outMsg);
|
||||
break;
|
||||
case ClientGameInfoHandler.ghostVoteRequest:
|
||||
npc.vote(game);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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:
|
||||
String outMsg = npc.getName() + ": " + noiseRandomizer();;
|
||||
game.getClientHandler().broadcastNpcChatMessage(outMsg);
|
||||
break;
|
||||
case ClientGameInfoHandler.humanVoteRequest:
|
||||
npc.vote();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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
|
||||
@ -68,11 +68,7 @@ public class Train {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Train t = new Train(6, 1);
|
||||
} catch (TrainOverflow e) {
|
||||
LOGGER.error(e.getMessage());
|
||||
}
|
||||
|
||||
System.out.println("Hallo");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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";
|
||||
|
||||
@ -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,20 @@ public class VoteHandler {
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
|
||||
|
||||
private static ClientVoteData clientVoteData = new ClientVoteData();
|
||||
|
||||
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
|
||||
@ -31,7 +43,10 @@ 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());
|
||||
|
||||
// array to collect votes for all players during voting, i.e. votes for player 1 (passengers[0])
|
||||
// are saved in
|
||||
@ -39,60 +54,60 @@ 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!");
|
||||
passenger.send(ClientGameInfoHandler.ghostVoteRequest, game);
|
||||
} else {
|
||||
passenger.send(
|
||||
"Please wait, ghosts are active"); // TODO(Seraina): make sure whatever clients send in
|
||||
ClientGameInfoHandler.itsNightTime, game);
|
||||
// this time, except chat is ignored
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if (passenger.getHasVoted()) {
|
||||
for (int i = 0; i < votesForPlayers.length; i++) {
|
||||
if (passenger.getVote() == i) {
|
||||
votesForPlayers[i]++;
|
||||
LOGGER.info(passengers[i] + " has received the most votes");
|
||||
}
|
||||
}
|
||||
}
|
||||
try { // waits 20 seconds before votes get collected
|
||||
Thread.sleep(30*1000);
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted");
|
||||
}
|
||||
|
||||
// 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.info("Most votes: " + currentMax + " vote");
|
||||
int currentMax = voteEvaluation(passengers, votesForPlayers, clientVoteData, game);
|
||||
|
||||
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;
|
||||
passengers[ghostPosition].send(
|
||||
"You are now a ghost!"); // TODO: ServerGameInfoHandler might deal with this one
|
||||
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
|
||||
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) {
|
||||
passenger.setHasVoted(false);
|
||||
@ -104,11 +119,12 @@ 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.
|
||||
*
|
||||
* @param passengers: train passengers
|
||||
* @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) {
|
||||
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]
|
||||
@ -118,51 +134,39 @@ 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(ClientGameInfoHandler.itsDayTime, game);
|
||||
} else {
|
||||
passenger.send("Vote for a ghost to kick off!");
|
||||
passenger.send(ClientGameInfoHandler.humanVoteRequest, game);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
if (passenger.getHasVoted()) {
|
||||
for (int i = 0; i < votesForPlayers.length; i++) {
|
||||
if (passenger.getVote() == i) {
|
||||
votesForPlayers[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
try { // waits 20 seconds before votes get collected
|
||||
Thread.sleep(20*1000);
|
||||
} catch (InterruptedException e) {
|
||||
LOGGER.warn("Thread " + Thread.currentThread() + " was interrupted");
|
||||
}
|
||||
|
||||
// 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.info("Max amount of votes: " + currentMax);
|
||||
}
|
||||
}
|
||||
int currentMax = voteEvaluation(passengers, votesForPlayers, clientVoteData, game);
|
||||
|
||||
// deal with voting results
|
||||
int voteIndex = 0;
|
||||
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) {
|
||||
passenger.send(
|
||||
"You voted for a human!"); // 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
|
||||
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.
|
||||
@ -174,20 +178,23 @@ public class VoteHandler {
|
||||
}
|
||||
}
|
||||
if (humans == 1) {
|
||||
System.out.println("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!");
|
||||
passenger.send("Player " + voteIndex + ClientGameInfoHandler.gotKickedOff, game);
|
||||
}
|
||||
}
|
||||
}
|
||||
LOGGER.info(game.getGameState().toString());
|
||||
// set hasVoted to false for all passengers for future voting
|
||||
for (Passenger passenger : passengers) {
|
||||
passenger.setHasVoted(false);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
@ -216,38 +223,34 @@ public class VoteHandler {
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Game game = new Game(6,1, 6);
|
||||
VoteHandler voteHandler = new VoteHandler();
|
||||
|
||||
Passenger[] testArray = game.gameFunctions.passengerTrain;
|
||||
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());
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,8 @@ public class Ghost extends Passenger {
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
|
||||
|
||||
|
||||
|
||||
public boolean getIsOG() {
|
||||
return isOG;
|
||||
}
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
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;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@ -28,4 +32,43 @@ public class GhostNPC extends Ghost {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(String msg, Game game) {
|
||||
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
|
||||
* TODO: Make NPC smarter
|
||||
*/
|
||||
public void vote(Game game){
|
||||
int ghostCounter = 0;
|
||||
Passenger[] train = game.getGameState().getPassengerTrain();
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides what to do when a noise ist heard, currently just always broadcasts it
|
||||
* TODO: Make NPC smarter
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,6 +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.server.ClientHandler;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@ -12,8 +15,7 @@ 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.
|
||||
*/
|
||||
@ -31,8 +33,36 @@ public class GhostPlayer extends Ghost {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void send(String msg) {
|
||||
//todo(Jonas): pass message along to client.
|
||||
/**
|
||||
* 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);
|
||||
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 getVoteFromGameState(ClientVoteData clientVoteData, Game game) {
|
||||
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
|
||||
*/
|
||||
if(vote == Integer.MAX_VALUE) {
|
||||
hasVoted = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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,5 @@ public class Human extends Passenger {
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
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;
|
||||
|
||||
public class HumanNPC extends Human {
|
||||
|
||||
public static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final BudaLogConfig l = new BudaLogConfig(LOGGER);
|
||||
|
||||
@ -26,4 +29,27 @@ public class HumanNPC extends Human {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently returns a random integer for voting
|
||||
*
|
||||
* @return integer between 0 and 5
|
||||
*/
|
||||
public void vote() {
|
||||
int randomNr = (int) (Math.random() * 6);
|
||||
vote = randomNr;
|
||||
hasVoted = true;
|
||||
LOGGER.info("HumanNPC at Position: " + this.getPosition() + " has voted for: " + vote);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +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;
|
||||
|
||||
@ -12,8 +16,7 @@ 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) {
|
||||
@ -29,5 +32,39 @@ 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);
|
||||
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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.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 org.apache.logging.log4j.LogManager;
|
||||
@ -19,32 +21,7 @@ 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;
|
||||
/**
|
||||
* 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++;
|
||||
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) {
|
||||
//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
|
||||
}*/
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the Position of this passenger
|
||||
@ -82,6 +59,10 @@ public class Passenger {
|
||||
hasVoted = voted;
|
||||
}
|
||||
|
||||
public void setVote(int vote) {
|
||||
this.vote = vote;
|
||||
}
|
||||
|
||||
public void setIsOg() {
|
||||
isOG = true;
|
||||
}
|
||||
@ -116,4 +97,24 @@ public class Passenger {
|
||||
public ClientHandler getClientHandler() {
|
||||
return clientHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* When called by NPC nothing should happen, because clientHandler = null
|
||||
*/
|
||||
public void getVoteFromGameState(ClientVoteData clientVoteData,Game game) {
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,11 +5,14 @@ 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;
|
||||
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;
|
||||
|
||||
@ -23,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;
|
||||
@ -58,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,6 +81,30 @@ public class Client {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells user to enter a position to vote for passenger at that position
|
||||
*/
|
||||
public void positionSetter(String msg) {
|
||||
|
||||
LOGGER.info("Im in thread:" + Thread.currentThread());
|
||||
int msgIndex = msg.indexOf('$');
|
||||
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);
|
||||
|
||||
System.out.println(justMsg);
|
||||
System.out.println("Please enter your vote");
|
||||
|
||||
|
||||
//LOGGER.debug("just checked next line");
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Starts a thread which listens for incoming chat messages / other messages that the user
|
||||
* has to see
|
||||
@ -92,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();
|
||||
}
|
||||
|
||||
|
||||
@ -43,11 +43,15 @@ 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.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:
|
||||
System.out.println("Human received Vote request");
|
||||
LOGGER.debug("Human received Vote request");
|
||||
System.out.println("Human Vote:");
|
||||
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:
|
||||
|
||||
@ -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();
|
||||
|
||||
}
|
||||
|
||||
@ -35,6 +35,7 @@ public class ClientPinger implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setPriority(10);
|
||||
try {
|
||||
Thread.sleep(20000);
|
||||
while (socket.isConnected() && !socket.isClosed()) {
|
||||
|
||||
@ -92,6 +92,16 @@ public class Protocol {
|
||||
*/
|
||||
public static final String listLobbies = "LISTL";
|
||||
|
||||
/**
|
||||
* 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$vote"
|
||||
*/
|
||||
public static final String votedFor = "CVOTE";
|
||||
|
||||
|
||||
//SERVER TO CLIENT COMMANDS
|
||||
|
||||
@ -117,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";
|
||||
|
||||
@ -128,4 +139,6 @@ public class Protocol {
|
||||
public static final String serverRequestsHumanVote = "HVOTR";
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -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:
|
||||
|
||||
|
||||
@ -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()) {
|
||||
@ -55,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(); TODO: is that ever necessary?
|
||||
//LOGGER.debug("gotPingBack has not been set to true and isConnected has been set to false before");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,15 @@
|
||||
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.*;
|
||||
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;
|
||||
@ -21,6 +25,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
|
||||
@ -70,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<ClientHandler> getConnectedClients() {
|
||||
return connectedClients;
|
||||
}
|
||||
@ -86,14 +95,14 @@ public class ClientHandler implements Runnable {
|
||||
return loggedIn;
|
||||
}
|
||||
|
||||
public void setLoggedIn(boolean loggedIn) {
|
||||
this.loggedIn = loggedIn;
|
||||
}
|
||||
|
||||
//Setters:
|
||||
public String getClientUserName() {
|
||||
return clientUserName;
|
||||
}
|
||||
//Setters:
|
||||
|
||||
public void setLoggedIn(boolean loggedIn) {
|
||||
this.loggedIn = loggedIn;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@ -149,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
|
||||
@ -180,6 +200,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); //TODO: move clientVoteData to gamestate
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).
|
||||
|
||||
@ -2,6 +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;
|
||||
@ -30,6 +35,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");
|
||||
}
|
||||
@ -65,7 +73,15 @@ 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:
|
||||
LOGGER.debug("Made it here");
|
||||
msg = msg.substring(6);
|
||||
h.decodeVote(msg);
|
||||
break;
|
||||
case Protocol.startANewGame:
|
||||
h.startNewGame();
|
||||
break;
|
||||
default:
|
||||
System.out.println("Received unknown command");
|
||||
|
||||
Reference in New Issue
Block a user