Feat/ms 4 integration #282
@@ -63,13 +63,17 @@ public class ChatController {
|
||||
localUserList = new ArrayList<>();
|
||||
this.chatBoxController = new ChatBoxController(username, this);
|
||||
this.logger = LogManager.getLogger(ChatController.class);
|
||||
this.timer = new Timer();
|
||||
this.timer = new Timer(true);
|
||||
timer.schedule(
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
receiveMessage();
|
||||
checkWhisperUsers();
|
||||
try {
|
||||
receiveMessage();
|
||||
checkWhisperUsers();
|
||||
} catch (RuntimeException e) {
|
||||
logger.warn("Chat refresh failed: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
},
|
||||
0,
|
||||
@@ -84,8 +88,12 @@ public class ChatController {
|
||||
*/
|
||||
public void setLobbyChat(int lobbyId) {
|
||||
this.lobbyId = lobbyId;
|
||||
ChatKey key = new ChatKey(ChatType.LOBBY);
|
||||
if (chatModelMap.containsKey(key)) {
|
||||
return;
|
||||
}
|
||||
ChatModel lobbyChatModel = new ChatModel(ChatType.LOBBY, username, lobbyId, null);
|
||||
chatModelMap.put(new ChatKey(ChatType.LOBBY), lobbyChatModel);
|
||||
chatModelMap.put(key, lobbyChatModel);
|
||||
this.chatBoxController.addChatTab("Lobby", lobbyChatModel);
|
||||
}
|
||||
|
||||
@@ -162,15 +170,32 @@ public class ChatController {
|
||||
for (String user : users) {
|
||||
String value = user.split("\\=")[1];
|
||||
logger.info(value);
|
||||
if (!(localUserList.contains(value) || value.equals(username))) {
|
||||
localUserList.add(value);
|
||||
logger.info("adding new whisper user");
|
||||
chatBoxController.addWhisperUser(value);
|
||||
}
|
||||
addWhisperUser(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a whisper target locally and updates the UI if it is a new user.
|
||||
*
|
||||
* @param user target username
|
||||
*/
|
||||
public synchronized void addWhisperUser(String user) {
|
||||
if (user == null || user.isBlank()) {
|
||||
return;
|
||||
}
|
||||
if (!(localUserList.contains(user) || user.equals(username))) {
|
||||
localUserList.add(user);
|
||||
logger.info("adding new whisper user");
|
||||
chatBoxController.addWhisperUser(user);
|
||||
}
|
||||
}
|
||||
|
||||
/** Stops polling background tasks for this chat controller instance. */
|
||||
public void shutdown() {
|
||||
timer.cancel();
|
||||
}
|
||||
|
||||
/**
|
||||
* method to send a message to the server
|
||||
*
|
||||
|
||||
+67
@@ -1,19 +1,27 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatController;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Card;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.GameService;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.GameState;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.Player;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.game.PlayerId;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.gameuicomponents.PlayerStatusController;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.gameuicomponents.TaskbarController;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.logging.Logger;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
@@ -44,6 +52,7 @@ public class CasinoGameController {
|
||||
@FXML private VBox player2;
|
||||
@FXML private VBox player3;
|
||||
@FXML private ImageView myDealerIcon;
|
||||
@FXML private AnchorPane chatContainer;
|
||||
|
||||
private GameService gameService;
|
||||
private PlayerId myPlayerId;
|
||||
@@ -125,6 +134,12 @@ public class CasinoGameController {
|
||||
private static final long CHIP_DROP_DURATION_MS = 250;
|
||||
private static final long CHIP_STAGGER_DELAY_MULTIPLIER = 35L;
|
||||
|
||||
private ChatController chatController;
|
||||
private String chatUsername;
|
||||
private ClientService chatClientService;
|
||||
private int chatLobbyId = -1;
|
||||
private boolean chatInitialized;
|
||||
|
||||
/** Standard constructor. Used by FXML. */
|
||||
public CasinoGameController() {
|
||||
// default constructor for FXML
|
||||
@@ -203,6 +218,38 @@ public class CasinoGameController {
|
||||
// empty display only (optional)
|
||||
renderCommunityCards(List.of());
|
||||
renderPlayerCards(List.of());
|
||||
initializeChatIfPossible();
|
||||
}
|
||||
|
||||
public void setChatContext(String username, ClientService clientService, int lobbyId) {
|
||||
this.chatUsername = username;
|
||||
this.chatClientService = clientService;
|
||||
this.chatLobbyId = lobbyId;
|
||||
initializeChatIfPossible();
|
||||
}
|
||||
|
||||
private void initializeChatIfPossible() {
|
||||
if (chatInitialized || chatContainer == null || chatClientService == null || chatUsername == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
chatController = new ChatController(chatUsername, chatClientService);
|
||||
URL resource = getClass().getResource("/ui-structure/components/chatui/chatbox.fxml");
|
||||
FXMLLoader loader = new FXMLLoader(resource);
|
||||
loader.setController(chatController.getChatBoxController());
|
||||
javafx.scene.Node chatNode = loader.load();
|
||||
chatContainer.getChildren().setAll(chatNode);
|
||||
AnchorPane.setTopAnchor(chatNode, 0.0);
|
||||
AnchorPane.setBottomAnchor(chatNode, 0.0);
|
||||
AnchorPane.setLeftAnchor(chatNode, 0.0);
|
||||
AnchorPane.setRightAnchor(chatNode, 0.0);
|
||||
if (chatLobbyId >= 0) {
|
||||
chatController.setLobbyChat(chatLobbyId);
|
||||
}
|
||||
chatInitialized = true;
|
||||
} catch (IOException e) {
|
||||
LOGGER.warning("Could not initialize game chat UI: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Test method to demonstrate the UI functionality with sample data.
|
||||
@@ -329,6 +376,9 @@ public class CasinoGameController {
|
||||
if (timeline != null) {
|
||||
timeline.stop();
|
||||
}
|
||||
if (chatController != null) {
|
||||
chatController.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,6 +455,7 @@ public class CasinoGameController {
|
||||
}
|
||||
|
||||
updatePlayers(players);
|
||||
syncWhisperTargetsFromPlayers(players);
|
||||
updateGameInfo(s);
|
||||
highlightDealer(s);
|
||||
updateTaskbar(s);
|
||||
@@ -419,6 +470,22 @@ public class CasinoGameController {
|
||||
}
|
||||
}
|
||||
|
||||
private void syncWhisperTargetsFromPlayers(List<Player> players) {
|
||||
if (chatController == null || players == null || players.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Set<String> seen = new HashSet<>();
|
||||
for (Player player : players) {
|
||||
if (player == null) {
|
||||
continue;
|
||||
}
|
||||
String name = player.getName();
|
||||
if (name != null && !name.isBlank() && seen.add(name)) {
|
||||
chatController.addWhisperUser(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private List<Card> getMyCards(List<Player> players) {
|
||||
|
||||
if (myPlayerId == null || players == null) {
|
||||
|
||||
@@ -26,6 +26,7 @@ public class CasinoGameUI extends Application {
|
||||
private static ClientService clientService;
|
||||
|
||||
private static String username;
|
||||
private static int lobbyId = -1;
|
||||
|
||||
private static final int DEFAULT_WIDTH = 1200;
|
||||
private static final int DEFAULT_HEIGHT = 800;
|
||||
@@ -42,6 +43,10 @@ public class CasinoGameUI extends Application {
|
||||
CasinoGameUI.username = username;
|
||||
}
|
||||
|
||||
public static void setLobbyId(int lobbyId) {
|
||||
CasinoGameUI.lobbyId = lobbyId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage stage) throws IOException {
|
||||
|
||||
@@ -81,6 +86,7 @@ public class CasinoGameUI extends Application {
|
||||
controller.setGameService(gameService);
|
||||
|
||||
controller.setMyPlayerId(PlayerId.of(effectiveUsername));
|
||||
controller.setChatContext(effectiveUsername, clientService, lobbyId);
|
||||
|
||||
Scene scene = new Scene(root, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
||||
stage.setTitle("Casono");
|
||||
@@ -90,6 +96,7 @@ public class CasinoGameUI extends Application {
|
||||
|
||||
stage.setScene(scene);
|
||||
stage.setFullScreen(true);
|
||||
stage.setOnHidden(e -> controller.stop());
|
||||
stage.show();
|
||||
|
||||
controller.start();
|
||||
|
||||
+44
@@ -1,10 +1,14 @@
|
||||
package ch.unibas.dmi.dbis.cs108.casono.client.ui.lobbyui;
|
||||
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.ClientApp;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.chat.ChatController;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.ClientService;
|
||||
import ch.unibas.dmi.dbis.cs108.casono.client.network.LobbyClient;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import javafx.application.Platform;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Alert.AlertType;
|
||||
import javafx.scene.control.Button;
|
||||
@@ -13,6 +17,7 @@ import javafx.scene.control.TextField;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.AnchorPane;
|
||||
import javafx.scene.Node;
|
||||
import javafx.scene.layout.VBox;
|
||||
import javafx.scene.shape.Rectangle;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@@ -31,11 +36,13 @@ public class CasinomainuiController {
|
||||
@FXML private VBox casinoTable;
|
||||
@FXML private TextField usernameField;
|
||||
@FXML private Button loginButton;
|
||||
@FXML private AnchorPane chatContainer;
|
||||
|
||||
private LobbyButtonTranslationManager translationManager;
|
||||
private LobbyButtonGridManager gridManager;
|
||||
private int nextButtonId = 1;
|
||||
private LobbyClient lobbyClient;
|
||||
private ChatController chatController;
|
||||
|
||||
/** Default constructor used by FXMLLoader. */
|
||||
public CasinomainuiController() {
|
||||
@@ -96,6 +103,40 @@ public class CasinomainuiController {
|
||||
casinoTable.getChildren().clear();
|
||||
casinoTable.getChildren().add(gridManager.getGridPane());
|
||||
gridManager.renderLobbyButtons();
|
||||
|
||||
initializeChat(clientService);
|
||||
}
|
||||
|
||||
private void initializeChat(ClientService clientService) {
|
||||
if (clientService == null || clientService.isOffline() || chatContainer == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
String username = resolveChatUsername();
|
||||
chatController = new ChatController(username, clientService);
|
||||
URL resource = getClass().getResource("/ui-structure/components/chatui/chatbox.fxml");
|
||||
FXMLLoader loader = new FXMLLoader(resource);
|
||||
loader.setController(chatController.getChatBoxController());
|
||||
Node chatNode = loader.load();
|
||||
chatContainer.getChildren().setAll(chatNode);
|
||||
AnchorPane.setTopAnchor(chatNode, 0.0);
|
||||
AnchorPane.setBottomAnchor(chatNode, 0.0);
|
||||
AnchorPane.setLeftAnchor(chatNode, 0.0);
|
||||
AnchorPane.setRightAnchor(chatNode, 0.0);
|
||||
} catch (IOException e) {
|
||||
LOGGER.warn("Could not initialize lobby chat UI: {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveChatUsername() {
|
||||
String shared = ClientApp.getSharedUsername();
|
||||
if (shared != null && !shared.isBlank()) {
|
||||
return shared.trim();
|
||||
}
|
||||
if (usernameField != null && usernameField.getText() != null && !usernameField.getText().isBlank()) {
|
||||
return usernameField.getText().trim();
|
||||
}
|
||||
return "Guest";
|
||||
}
|
||||
|
||||
/** Handles the login button action. Validates input and calls LobbyClient.login(). */
|
||||
@@ -139,6 +180,9 @@ public class CasinomainuiController {
|
||||
/** Handles the exit button action to close the application. */
|
||||
@FXML
|
||||
public void handleexitbutton() {
|
||||
if (chatController != null) {
|
||||
chatController.shutdown();
|
||||
}
|
||||
Platform.exit();
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -554,6 +554,7 @@ public class LobbyButtonGridManager {
|
||||
var cs = lobbyClient.getClientService();
|
||||
|
||||
ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.CasinoGameUI.setClientService(cs);
|
||||
ch.unibas.dmi.dbis.cs108.casono.client.ui.gameui.CasinoGameUI.setLobbyId(lobbyId);
|
||||
|
||||
String username = ch.unibas.dmi.dbis.cs108.casono.client.ClientApp.getSharedUsername();
|
||||
if (username == null || username.isBlank()) {
|
||||
|
||||
Reference in New Issue
Block a user