Fix: Resolving Git Merge Conflicts #253
@@ -0,0 +1,9 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.game;
|
||||
|
||||
/**
|
||||
* Represents a playing card with a value and suit.
|
||||
*/
|
||||
public class Card {
|
||||
public String value;
|
||||
public String suit;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.game;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Card;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents the current state of the poker game, including the phase, pot
|
||||
* size, current bet, dealer position,
|
||||
* active player, community cards, and player information.
|
||||
*/
|
||||
public class GameState {
|
||||
public String phase;
|
||||
public int pot;
|
||||
public int currentBet;
|
||||
public int dealer;
|
||||
public int activePlayer;
|
||||
|
||||
public List<Card> communityCards = new ArrayList<>();
|
||||
public List<Player> players = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.game;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a player in the poker game, including their name, chip count,
|
||||
* current bet, state (e.g., "active", "folded"), and their hole cards.
|
||||
*/
|
||||
public class Player {
|
||||
public String name;
|
||||
public int chips;
|
||||
public int bet;
|
||||
public String state;
|
||||
|
||||
public List<Card> cards = new ArrayList<>();
|
||||
}
|
||||
@@ -5,29 +5,45 @@ import ch.unibas.dmi.dbis.cs108.casono.client.chat.Message;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The ChatClient class is responsible for sending messages to the server and
|
||||
* retrieving messages from the server. It uses the ClientService to send
|
||||
* commands and receive responses from the server.
|
||||
*/
|
||||
public class ChatClient {
|
||||
|
||||
private ClientService clientService;
|
||||
|
||||
/**
|
||||
* Constructs a ChatClient with the given ClientService for communication.
|
||||
*
|
||||
* @param clientService The ClientService instance used to send commands and
|
||||
* receive responses from the server.
|
||||
*/
|
||||
public ChatClient(ClientService clientService) {
|
||||
this.clientService = clientService;
|
||||
}
|
||||
|
||||
/**
|
||||
* sends a message to the server
|
||||
* @param message
|
||||
* Send a Message to the server by converting it to a string format and
|
||||
* sending a "SEND_MESSAGE" command with the message content as arguments.
|
||||
*
|
||||
* @param message The Message object to be sent to the server.
|
||||
*/
|
||||
|
||||
public void sendMessage(Message message) {
|
||||
String request = "SEND_MESSAGE " + message.toArgsString();
|
||||
clientService.processCommand(request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a Request to get the number of Messages currently in the Queue for the client.
|
||||
* Then proceeds, if needed, to get the messages by sending
|
||||
* Retrieve messages from the server by first sending a "GET_MESSAGE_COUNT"
|
||||
* command to determine how many messages are available and then sending
|
||||
* "GET_NEXT_MESSAGE" commands in a loop to retrieve each message. The
|
||||
* retrieved messages are parsed into Message objects and returned as a list.
|
||||
*
|
||||
* @return A list of Message objects representing the messages retrieved from
|
||||
* the server.
|
||||
*/
|
||||
|
||||
public List<Message> getMessages() {
|
||||
String countStr = clientService.processCommand("GET_MESSAGE_COUNT");
|
||||
int count = Integer.parseInt(countStr);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
||||
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.RawPacket;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.server.network.transport.TcpTransport;
|
||||
import java.net.Socket;
|
||||
@@ -14,11 +13,13 @@ import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
||||
/**
|
||||
* Responsible for the transferring of the data from the Client to the Server and the other way around
|
||||
* The ClientService class is responsible for managing the connection to the
|
||||
* server,
|
||||
* sending commands, and receiving responses. It uses a TcpTransport to
|
||||
* communicate
|
||||
* with the server and an ExecutorService to handle asynchronous requests.
|
||||
*/
|
||||
|
||||
public class ClientService {
|
||||
|
||||
private final TcpTransport clienttcptransport;
|
||||
@@ -30,11 +31,13 @@ public class ClientService {
|
||||
private final AtomicInteger idGenerator;
|
||||
|
||||
/**
|
||||
* Creates a new ClientSession with a Socket, a Reader and Writer of the Input- and the Outputstream and a pool of threads to send requests and receive responses.
|
||||
* @param ip : ip-adress of the server
|
||||
* @param port : port of the server
|
||||
* Constructs a ClientService with the given server IP and port. It establishes
|
||||
* a socket connection to the server and initializes the TcpTransport and
|
||||
* ExecutorService for communication.
|
||||
*
|
||||
* @param ip The IP address of the server to connect to.
|
||||
* @param port The port number of the server to connect to.
|
||||
*/
|
||||
|
||||
public ClientService(String ip, int port) {
|
||||
|
||||
this.idGenerator = new AtomicInteger(0);
|
||||
@@ -42,30 +45,28 @@ public class ClientService {
|
||||
try {
|
||||
socket = new Socket(ip, port);
|
||||
clienttcptransport = new TcpTransport(socket);
|
||||
}
|
||||
catch (IOException i) {
|
||||
} catch (IOException i) {
|
||||
throw new RuntimeException(i);
|
||||
}
|
||||
|
||||
executor = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sends the Requests to the server and waits for the response
|
||||
* If the response is "+OK" it proceeds normal
|
||||
* If the response "-ERROR" it throws a runtime exception
|
||||
* @param message
|
||||
* @return - The response as a string, if it has to be returned
|
||||
* (+OK will not be returned)
|
||||
* Sends a command to the server and waits for the response. The command is
|
||||
* sent using the TcpTransport, and the response is read in a loop until a
|
||||
* valid response is received. The method handles "+OK" and "-ERROR" responses
|
||||
* from the server and returns the actual response content.
|
||||
*
|
||||
* @param message The command message to be sent to the server.
|
||||
* @return The response from the server as a string.
|
||||
*/
|
||||
|
||||
protected String processCommand(String message) {
|
||||
AtomicReference<String> response = new AtomicReference<>();
|
||||
sendRequest(() -> {
|
||||
try {
|
||||
writeToTransport(message);
|
||||
String responseLine=null;
|
||||
String responseLine = null;
|
||||
do {
|
||||
responseLine = clienttcptransport.read().payload();
|
||||
System.out.println("Raw message '" + responseLine + "'");
|
||||
@@ -75,7 +76,7 @@ public class ClientService {
|
||||
throw new RuntimeException(responseLine);
|
||||
}
|
||||
response.set(responseLine);
|
||||
} while(true);
|
||||
} while (true);
|
||||
} catch (Exception e) {
|
||||
throw getRuntimeException(e);
|
||||
}
|
||||
@@ -84,10 +85,14 @@ public class ClientService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to send a request to the server using the ExecutorService. It
|
||||
* submits the request as a Runnable task and waits for its completion. If
|
||||
* the task is interrupted or encounters an execution exception, it throws a
|
||||
* RuntimeException with the appropriate cause.
|
||||
*
|
||||
* @param request
|
||||
* @param request The Runnable task representing the request to be sent to the
|
||||
* server.
|
||||
*/
|
||||
|
||||
private void sendRequest(Runnable request) {
|
||||
Future<?> future = executor.submit(request);
|
||||
try {
|
||||
@@ -100,11 +105,15 @@ public class ClientService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Runtime Exceptions thrown by the sendRequest method
|
||||
* @param e - an Exception
|
||||
* @return - a Runtime Exception
|
||||
* Helper method to extract the cause of an exception and return it as a
|
||||
* RuntimeException. If the cause is null, it returns the original exception as
|
||||
* a RuntimeException. If the cause is already a RuntimeException, it returns
|
||||
* it directly. Otherwise, it wraps the cause in a new RuntimeException and
|
||||
* returns it.
|
||||
*
|
||||
* @param e The exception from which to extract the cause.
|
||||
* @return A RuntimeException representing the cause of the original exception.
|
||||
*/
|
||||
|
||||
private static RuntimeException getRuntimeException(Exception e) {
|
||||
Throwable reason = e.getCause();
|
||||
RuntimeException re;
|
||||
@@ -118,9 +127,11 @@ public class ClientService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the Socket and shuts down the Threadpool associated with that Socket-Connection.
|
||||
* Closes the socket connection to the server and shuts down the
|
||||
* ExecutorService.
|
||||
* It also closes the TcpTransport used for communication. If any IOException
|
||||
* occurs during this process, it prints the exception to the console.
|
||||
*/
|
||||
|
||||
public void closeSocket() {
|
||||
try {
|
||||
executor.shutdown();
|
||||
@@ -133,11 +144,14 @@ public class ClientService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to write with the tcp transport to the server
|
||||
* @param s - Message to be sent
|
||||
* @throws IOException
|
||||
* Helper method to write a command string to the TcpTransport. It generates a
|
||||
* unique ID for the command using the idGenerator and sends a RawPacket
|
||||
* containing the ID and the command string to the server. If an IOException
|
||||
* occurs during this process, it throws a RuntimeException with the cause.
|
||||
*
|
||||
* @param s The command string to be sent to the server.
|
||||
* @throws IOException If an I/O error occurs while writing to the transport.
|
||||
*/
|
||||
|
||||
private void writeToTransport(String s) throws IOException {
|
||||
int id = this.idGenerator.incrementAndGet();
|
||||
this.clienttcptransport.write(new RawPacket(id, s));
|
||||
|
||||
@@ -1,16 +1,38 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
||||
|
||||
/**
|
||||
* The CoreClient class provides basic functionalities for communicating with
|
||||
* the
|
||||
* server, such as sending a ping command to check connectivity and logging in
|
||||
* with a username. It uses the ClientService to send commands and receive
|
||||
* responses from the server.
|
||||
*/
|
||||
public class CoreClient {
|
||||
private final ClientService clientService;
|
||||
|
||||
/**
|
||||
* Constructs a CoreClient with the given ClientService for communication.
|
||||
*
|
||||
* @param clientservice The ClientService instance used to send commands and
|
||||
* receive responses from the server.
|
||||
*/
|
||||
public CoreClient(ClientService clientservice) {
|
||||
this.clientService = clientservice;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a "PING" command to the server to check connectivity. The server
|
||||
* should respond with a "PONG" message if the connection is successful.
|
||||
*/
|
||||
public void ping() {
|
||||
clientService.processCommand("PING");
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs in to the server with the given username by sending a "LOGIN" command.
|
||||
*
|
||||
* @param user The username to log in with.
|
||||
*/
|
||||
public void login(String user) {
|
||||
clientService.processCommand("LOGIN USERNAME=" + user);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Card;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.GameState;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The GameClient class is responsible for communicating with the server to
|
||||
* retrieve the current game state. It sends a command to the server and
|
||||
* parses the response into a structured GameState object.
|
||||
*/
|
||||
public class GameClient {
|
||||
|
||||
private final ClientService client;
|
||||
|
||||
/**
|
||||
* Constructs a GameClient with the given ClientService for communication.
|
||||
*
|
||||
* @param client The ClientService instance used to send commands and receive
|
||||
* responses from the server.
|
||||
*/
|
||||
public GameClient(ClientService client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current game state from the server by sending a command and
|
||||
* parsing the response.
|
||||
*
|
||||
* @return A GameState object representing the current state of the game.
|
||||
*/
|
||||
public GameState getGameState() {
|
||||
String response = client.processCommand("GET_GAME_STATE");
|
||||
return parseGameState(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the raw response from the server into a structured GameState object.
|
||||
*
|
||||
* @param input The raw response string from the server.
|
||||
* @return A GameState object representing the current state of the game.
|
||||
*/
|
||||
private GameState parseGameState(String input) {
|
||||
|
||||
GameState state = new GameState();
|
||||
|
||||
String[] lines = input.split("\n");
|
||||
|
||||
Player currentPlayer = null;
|
||||
Card currentCard = null;
|
||||
|
||||
for (String rawLine : lines) {
|
||||
|
||||
String line = rawLine.trim();
|
||||
|
||||
if (line.startsWith("+OK") || line.equals("END")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line.startsWith("PHASE=")) {
|
||||
state.phase = line.split("=")[1];
|
||||
}
|
||||
|
||||
else if (line.startsWith("POT=")) {
|
||||
state.pot = Integer.parseInt(line.split("=")[1]);
|
||||
}
|
||||
|
||||
else if (line.startsWith("CURRENT_BET=")) {
|
||||
state.currentBet = Integer.parseInt(line.split("=")[1]);
|
||||
}
|
||||
|
||||
else if (line.startsWith("DEALER=")) {
|
||||
state.dealer = Integer.parseInt(line.split("=")[1]);
|
||||
}
|
||||
|
||||
else if (line.startsWith("ACTIVE_PLAYER=")) {
|
||||
state.activePlayer = Integer.parseInt(line.split("=")[1]);
|
||||
}
|
||||
|
||||
else if (line.startsWith("PLAYER")) {
|
||||
currentPlayer = new Player();
|
||||
state.players.add(currentPlayer);
|
||||
}
|
||||
|
||||
else if (line.startsWith("NAME=") && currentPlayer != null) {
|
||||
currentPlayer.name = line.split("=")[1];
|
||||
}
|
||||
|
||||
else if (line.startsWith("CHIPS=") && currentPlayer != null) {
|
||||
currentPlayer.chips = Integer.parseInt(line.split("=")[1]);
|
||||
}
|
||||
|
||||
else if (line.startsWith("BET=") && currentPlayer != null) {
|
||||
currentPlayer.bet = Integer.parseInt(line.split("=")[1]);
|
||||
}
|
||||
|
||||
else if (line.startsWith("STATE=") && currentPlayer != null) {
|
||||
currentPlayer.state = line.split("=")[1];
|
||||
}
|
||||
|
||||
else if (line.startsWith("CARD")) {
|
||||
currentCard = new Card();
|
||||
|
||||
if (currentPlayer != null) {
|
||||
currentPlayer.cards.add(currentCard);
|
||||
} else {
|
||||
state.communityCards.add(currentCard);
|
||||
}
|
||||
}
|
||||
|
||||
else if (line.startsWith("VALUE=") && currentCard != null) {
|
||||
currentCard.value = line.split("=")[1];
|
||||
}
|
||||
|
||||
else if (line.startsWith("SUIT=") && currentCard != null) {
|
||||
currentCard.suit = line.split("=")[1];
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.network;
|
||||
|
||||
/**
|
||||
* The LobbyClient class is responsible for communicating with the server to
|
||||
* manage game lobbies. It provides methods to create a lobby, join a lobby,
|
||||
* and fetch the current status of a lobby by sending appropriate commands to
|
||||
* the server and processing the responses.
|
||||
*/
|
||||
public class LobbyClient {
|
||||
private final ClientService client;
|
||||
|
||||
/**
|
||||
* Constructs a LobbyClient with the given ClientService for communication.
|
||||
*
|
||||
* @param client The ClientService instance used to send commands and receive
|
||||
* responses from the server.
|
||||
*/
|
||||
public LobbyClient(ClientService client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the current status of the lobby with the given id from the server.
|
||||
*
|
||||
* @param lobbyId The id of the lobby to fetch the status for.
|
||||
* @return A string representing the current status of the lobby, as returned
|
||||
* by the server.
|
||||
*/
|
||||
public String fetchLobbyStatusString(int lobbyId) {
|
||||
return client.processCommand("GET_LOBBY_STATUS ID=" + lobbyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the server to create a new lobby and return the id of the newly
|
||||
* created lobby.
|
||||
*
|
||||
* @return The id of the newly created lobby, as returned by the server.
|
||||
*/
|
||||
public int createLobby() {
|
||||
String response = client.processCommand("CREATE_LOBBY");
|
||||
return Integer.parseInt(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the server to return the id of the lobby that the client is
|
||||
* currently in.
|
||||
*
|
||||
* @return The id of the lobby that the client is currently in, as returned by
|
||||
* the server.
|
||||
*/
|
||||
public int getLobbyId() {
|
||||
String response = client.processCommand("GET_LOBBY_ID");
|
||||
return Integer.parseInt(response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the server to join the lobby with the given id.
|
||||
*
|
||||
* @param lobbyId The id of the lobby to join.
|
||||
*/
|
||||
public void joinLobby(int lobbyId) {
|
||||
client.processCommand("JOIN_LOBBY ID=" + lobbyId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user