Compare commits
7 Commits
dfdaae163b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d62e0b7188 | |||
| ef7bbc8492 | |||
|
|
eee63cc5c6 | ||
|
|
a4c5d3f67b | ||
|
|
709a92aa4c | ||
|
|
67124f4731 | ||
|
|
631cd25a9d |
@@ -1,5 +1,7 @@
|
|||||||
package client;
|
package client;
|
||||||
|
|
||||||
|
import javafx.animation.KeyFrame;
|
||||||
|
import javafx.animation.Timeline;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
@@ -7,6 +9,7 @@ import javafx.scene.layout.*;
|
|||||||
import javafx.scene.text.Text;
|
import javafx.scene.text.Text;
|
||||||
import javafx.scene.text.TextFlow;
|
import javafx.scene.text.TextFlow;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import javafx.util.Duration;
|
||||||
import network.protocol.packets.ServerResponsePacket;
|
import network.protocol.packets.ServerResponsePacket;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
@@ -41,13 +44,16 @@ public class ClientGuiController implements ClientListener {
|
|||||||
@FXML
|
@FXML
|
||||||
private ScrollPane chatPane;
|
private ScrollPane chatPane;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private Label roomName;
|
||||||
|
|
||||||
public void setClient(Client client) {
|
public void setClient(Client client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
}
|
}
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
public void initialize() throws SocketException {
|
public void initialize() throws SocketException {
|
||||||
client = new Client(new InetSocketAddress("localhost", 6665), this, UsernameSingleton.getInstance().getUsername());
|
client = new Client(new InetSocketAddress("192.168.163.131", 6665), this, UsernameSingleton.getInstance().getUsername());
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
Stage stage = (Stage) vueContainer.getScene().getWindow();
|
Stage stage = (Stage) vueContainer.getScene().getWindow();
|
||||||
stage.setResizable(true); // Fixed a bug that made the close button disappear under my Wayland setup (don't know if it's the same for x11)
|
stage.setResizable(true); // Fixed a bug that made the close button disappear under my Wayland setup (don't know if it's the same for x11)
|
||||||
@@ -57,6 +63,17 @@ public class ClientGuiController implements ClientListener {
|
|||||||
});
|
});
|
||||||
chatList.heightProperty().addListener((obs, oldVal, newVal) -> chatPane.setVvalue(1.0));
|
chatList.heightProperty().addListener((obs, oldVal, newVal) -> chatPane.setVvalue(1.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
requestRoomsRegularly();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the list of rooms from the server every second.
|
||||||
|
*/
|
||||||
|
private void requestRoomsRegularly() {
|
||||||
|
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(10), event -> client.RequestRoomList()));
|
||||||
|
timeline.setCycleCount(Timeline.INDEFINITE);
|
||||||
|
timeline.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -111,7 +128,7 @@ public class ClientGuiController implements ClientListener {
|
|||||||
String timeString = formatter.format(time);
|
String timeString = formatter.format(time);
|
||||||
Text chatterText = new Text(chatter + ": ");
|
Text chatterText = new Text(chatter + ": ");
|
||||||
chatterText.setStyle("-fx-fill: black; -fx-font-weight: bold;");
|
chatterText.setStyle("-fx-fill: black; -fx-font-weight: bold;");
|
||||||
TextFlow messageText = formatMessage(chatter, untagged);
|
TextFlow messageText = formatMessage(untagged);
|
||||||
TextFlow wholeMessage = new TextFlow(chatterText, messageText);
|
TextFlow wholeMessage = new TextFlow(chatterText, messageText);
|
||||||
Text timeText = new Text(" " + timeString);
|
Text timeText = new Text(" " + timeString);
|
||||||
timeText.setStyle("-fx-fill: gray; -fx-font-size: 10px;");
|
timeText.setStyle("-fx-fill: gray; -fx-font-size: 10px;");
|
||||||
@@ -132,7 +149,7 @@ public class ClientGuiController implements ClientListener {
|
|||||||
Pattern pattern = Pattern.compile("\u001B\\[44;30m(.*?)\u001B\\[49;39m");
|
Pattern pattern = Pattern.compile("\u001B\\[44;30m(.*?)\u001B\\[49;39m");
|
||||||
Matcher matcher = pattern.matcher(message);
|
Matcher matcher = pattern.matcher(message);
|
||||||
|
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuilder result = new StringBuilder();
|
||||||
while (matcher.find()) {
|
while (matcher.find()) {
|
||||||
String taggedName = matcher.group(1);
|
String taggedName = matcher.group(1);
|
||||||
matcher.appendReplacement(result, taggedName);
|
matcher.appendReplacement(result, taggedName);
|
||||||
@@ -167,11 +184,13 @@ public class ClientGuiController implements ClientListener {
|
|||||||
*/
|
*/
|
||||||
private void createChatEnv(String roomName) {
|
private void createChatEnv(String roomName) {
|
||||||
Platform.runLater(() -> {
|
Platform.runLater(() -> {
|
||||||
|
this.roomName.setText("Room: " + roomName);
|
||||||
chatList.getChildren().clear();
|
chatList.getChildren().clear();
|
||||||
chatInput.getChildren().clear();
|
chatInput.getChildren().clear();
|
||||||
Button leaveButton = new Button("Leave room");
|
Button leaveButton = new Button("Leave room");
|
||||||
leaveButton.setOnAction(event -> {
|
leaveButton.setOnAction(event -> {
|
||||||
client.SendLeaveRoom();
|
client.SendLeaveRoom();
|
||||||
|
this.roomName.setText("");
|
||||||
chatList.getChildren().clear();
|
chatList.getChildren().clear();
|
||||||
chatInput.getChildren().clear();
|
chatInput.getChildren().clear();
|
||||||
});
|
});
|
||||||
@@ -199,11 +218,10 @@ public class ClientGuiController implements ClientListener {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Colorize the message according to the color codes.
|
* Colorize the message according to the color codes.
|
||||||
* @param chatter the name of the person who sent the message
|
|
||||||
* @param content the content of the message
|
* @param content the content of the message
|
||||||
* @return the formatted message
|
* @return the formatted message
|
||||||
*/
|
*/
|
||||||
private TextFlow formatMessage(String chatter, String content) {
|
private TextFlow formatMessage(String content) {
|
||||||
TextFlow textFlow = new TextFlow();
|
TextFlow textFlow = new TextFlow();
|
||||||
// Evil regex : match every sequence starting with a color code ending with the next color code
|
// Evil regex : match every sequence starting with a color code ending with the next color code
|
||||||
Pattern pattern = Pattern.compile("&([rbgyn])([^&]*)");
|
Pattern pattern = Pattern.compile("&([rbgyn])([^&]*)");
|
||||||
@@ -250,4 +268,16 @@ public class ClientGuiController implements ClientListener {
|
|||||||
public void handleActualRoom(String roomName) {
|
public void handleActualRoom(String roomName) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void createRoom() {
|
||||||
|
TextInputDialog dialog = new TextInputDialog();
|
||||||
|
dialog.setTitle("Create a room");
|
||||||
|
dialog.setHeaderText("Enter the name of the room");
|
||||||
|
dialog.setContentText("Room name:");
|
||||||
|
Optional<String> result = dialog.showAndWait();
|
||||||
|
result.ifPresent(name -> {
|
||||||
|
client.SendCreateRoom(name);
|
||||||
|
createChatEnv(name);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
private static int MAX_SEND_TRY = 50;
|
private static int MAX_SEND_TRY = 50;
|
||||||
private static long SEND_DELAY = 10;
|
private static long SEND_DELAY = 10;
|
||||||
private static long RETRY_INTERVAL = SEND_DELAY * 2;
|
private static long RETRY_INTERVAL = 100;
|
||||||
private static float PACKET_LOSS_PROBABILITY = 0.1f;
|
private static float PACKET_LOSS_PROBABILITY = 0.1f;
|
||||||
|
|
||||||
private static record ReliablePacketAddress(ReliablePacket packet, InetSocketAddress address) {
|
private static record ReliablePacketAddress(ReliablePacket packet, InetSocketAddress address) {
|
||||||
@@ -71,6 +71,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the recieve sequence number
|
* Set the recieve sequence number
|
||||||
|
*
|
||||||
* @param address
|
* @param address
|
||||||
* @param newValue
|
* @param newValue
|
||||||
*/
|
*/
|
||||||
@@ -80,6 +81,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to add the address into memory
|
* Try to add the address into memory
|
||||||
|
*
|
||||||
* @param address
|
* @param address
|
||||||
*/
|
*/
|
||||||
private void tryAddContext(InetSocketAddress address) {
|
private void tryAddContext(InetSocketAddress address) {
|
||||||
@@ -88,6 +90,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a PacketPool
|
* Construct a PacketPool
|
||||||
|
*
|
||||||
* @param socket
|
* @param socket
|
||||||
*/
|
*/
|
||||||
public PacketPool(Socket socket) {
|
public PacketPool(Socket socket) {
|
||||||
@@ -114,6 +117,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet to the socket
|
* Send a packet to the socket
|
||||||
|
*
|
||||||
* @param packet
|
* @param packet
|
||||||
* @param address
|
* @param address
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@@ -122,13 +126,17 @@ public class PacketPool {
|
|||||||
var packetsSentTries = this.addressContexts.get(address).packetsSentTries;
|
var packetsSentTries = this.addressContexts.get(address).packetsSentTries;
|
||||||
|
|
||||||
new Thread(() -> {
|
new Thread(() -> {
|
||||||
|
// try {
|
||||||
|
// Thread.sleep(SEND_DELAY);
|
||||||
|
// if (Math.random() > PACKET_LOSS_PROBABILITY)
|
||||||
try {
|
try {
|
||||||
Thread.sleep(SEND_DELAY);
|
|
||||||
if (Math.random() > PACKET_LOSS_PROBABILITY)
|
|
||||||
this.socket.sendPacket(packet, address);
|
this.socket.sendPacket(packet, address);
|
||||||
} catch (InterruptedException | IOException e) {
|
} catch (IOException e) {
|
||||||
// e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
// } catch (InterruptedException | IOException e) {
|
||||||
|
// // e.printStackTrace();
|
||||||
|
// }
|
||||||
}).start();
|
}).start();
|
||||||
|
|
||||||
if (packet.getPacket() instanceof AcknowlegdementPacket)
|
if (packet.getPacket() instanceof AcknowlegdementPacket)
|
||||||
@@ -143,7 +151,9 @@ public class PacketPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet to socket and try to resend if an acknowlegment was not recieved
|
* Send a packet to socket and try to resend if an acknowlegment was not
|
||||||
|
* recieved
|
||||||
|
*
|
||||||
* @param packet
|
* @param packet
|
||||||
* @param address
|
* @param address
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@@ -163,6 +173,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a packet (and encapsulate it)
|
* Send a packet (and encapsulate it)
|
||||||
|
*
|
||||||
* @param packet
|
* @param packet
|
||||||
* @param address
|
* @param address
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@@ -175,6 +186,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to resend a packet
|
* Try to resend a packet
|
||||||
|
*
|
||||||
* @param reliablePacketAddress
|
* @param reliablePacketAddress
|
||||||
*/
|
*/
|
||||||
private void tryResend(ReliablePacketAddress reliablePacketAddress) {
|
private void tryResend(ReliablePacketAddress reliablePacketAddress) {
|
||||||
@@ -212,7 +224,6 @@ public class PacketPool {
|
|||||||
ctx.sendThreads.remove(Thread.currentThread());
|
ctx.sendThreads.remove(Thread.currentThread());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param address
|
* @param address
|
||||||
* @return The smallest sequence number recieved
|
* @return The smallest sequence number recieved
|
||||||
@@ -227,7 +238,9 @@ public class PacketPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move packets in buffer to the packet recieved queue to be processed by the app
|
* Move packets in buffer to the packet recieved queue to be processed by the
|
||||||
|
* app
|
||||||
|
*
|
||||||
* @param address
|
* @param address
|
||||||
* @return the sequence number of the last packet that was added to the queue
|
* @return the sequence number of the last packet that was added to the queue
|
||||||
*/
|
*/
|
||||||
@@ -251,6 +264,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Process packet when recieved
|
* Process packet when recieved
|
||||||
|
*
|
||||||
* @param packet
|
* @param packet
|
||||||
* @param address
|
* @param address
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
@@ -311,6 +325,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the connexion
|
* Closes the connexion
|
||||||
|
*
|
||||||
* @param adress
|
* @param adress
|
||||||
*/
|
*/
|
||||||
private void close(InetSocketAddress adress) {
|
private void close(InetSocketAddress adress) {
|
||||||
@@ -321,6 +336,7 @@ public class PacketPool {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop the threads of the connexion
|
* Stop the threads of the connexion
|
||||||
|
*
|
||||||
* @param adressContext
|
* @param adressContext
|
||||||
*/
|
*/
|
||||||
private void close(AdressContext adressContext) {
|
private void close(AdressContext adressContext) {
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
<BorderPane xmlns="http://javafx.com/javafx"
|
<BorderPane xmlns="http://javafx.com/javafx"
|
||||||
xmlns:fx="http://javafx.com/fxml"
|
xmlns:fx="http://javafx.com/fxml"
|
||||||
fx:controller="client.ClientGuiController"
|
fx:controller="client.ClientGuiController"
|
||||||
prefHeight="400.0" prefWidth="600.0" styleClass="vue-container" fx:id="vueContainer">
|
prefHeight="400.0" prefWidth="600.0" fx:id="vueContainer">
|
||||||
<top>
|
<top>
|
||||||
<HBox alignment="CENTER" styleClass="logo-box">
|
<HBox alignment="CENTER" styleClass="logo-box">
|
||||||
<padding>
|
<padding>
|
||||||
@@ -25,24 +25,39 @@
|
|||||||
</HBox>
|
</HBox>
|
||||||
</top>
|
</top>
|
||||||
<left>
|
<left>
|
||||||
<ScrollPane prefWidth="200.0" styleClass="rooms-pane" fx:id="roomsPane" fitToWidth="true">
|
<ScrollPane prefWidth="200.0" fitToWidth="true">
|
||||||
<VBox fx:id="rooms" spacing="10.0" alignment="CENTER" VBox.vgrow="ALWAYS">
|
<BorderPane>
|
||||||
|
<center>
|
||||||
|
<VBox spacing="10.0" alignment="CENTER" VBox.vgrow="ALWAYS">
|
||||||
<Label text="Rooms" styleClass="rooms-label"/>
|
<Label text="Rooms" styleClass="rooms-label"/>
|
||||||
<VBox fx:id="roomList" styleClass="rooms-list" spacing="5.0" VBox.vgrow="ALWAYS" alignment="CENTER"/>
|
<VBox fx:id="roomList" styleClass="rooms-list" spacing="5.0" VBox.vgrow="ALWAYS" alignment="CENTER"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
|
</center>
|
||||||
|
<bottom>
|
||||||
|
<Button text="Create room" onAction="#createRoom" />
|
||||||
|
</bottom>
|
||||||
|
</BorderPane>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
</left>
|
</left>
|
||||||
<center>
|
<center>
|
||||||
<BorderPane>
|
<BorderPane>
|
||||||
|
<top>
|
||||||
|
<HBox alignment="CENTER">
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/>
|
||||||
|
</padding>
|
||||||
|
<Label fx:id="roomName" style="-fx-font-size: 18px; -fx-font-weight: bold;"/>
|
||||||
|
</HBox>
|
||||||
|
</top>
|
||||||
<center>
|
<center>
|
||||||
<ScrollPane styleClass="chat-pane" fx:id="chatPane" fitToWidth="true">
|
<ScrollPane fx:id="chatPane" fitToWidth="true">
|
||||||
<VBox fx:id="chat" spacing="10.0">
|
<VBox spacing="10.0">
|
||||||
<VBox fx:id="chatList" styleClass="chat-list" spacing="5.0" VBox.vgrow="ALWAYS"/>
|
<VBox fx:id="chatList" styleClass="chat-list" spacing="5.0" VBox.vgrow="ALWAYS"/>
|
||||||
</VBox>
|
</VBox>
|
||||||
</ScrollPane>
|
</ScrollPane>
|
||||||
</center>
|
</center>
|
||||||
<bottom>
|
<bottom>
|
||||||
<HBox fx:id="chatInput" styleClass="chat-input" spacing="5.0" style="-fx-padding: 10;" />
|
<HBox fx:id="chatInput" spacing="5.0" style="-fx-padding: 10;" />
|
||||||
</bottom>
|
</bottom>
|
||||||
</BorderPane>
|
</BorderPane>
|
||||||
</center>
|
</center>
|
||||||
|
|||||||
Reference in New Issue
Block a user