Compare commits
10 Commits
623f5e168e
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
b35ab6e691
|
|||
|
f88cfe81dc
|
|||
|
ef4fdc1c9c
|
|||
|
a425be712e
|
|||
|
1492f078f9
|
|||
|
5c3e7fcdf5
|
|||
|
77df0f8298
|
|||
|
22a11a0fa6
|
|||
|
db77793f23
|
|||
|
f5a11fc2de
|
@@ -4,8 +4,6 @@ import java.io.IOException;
|
|||||||
import java.net.DatagramPacket;
|
import java.net.DatagramPacket;
|
||||||
import java.net.DatagramSocket;
|
import java.net.DatagramSocket;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Scanner;
|
|
||||||
|
|
||||||
public class Client {
|
public class Client {
|
||||||
|
|
||||||
|
|||||||
10
src/Ex2/App.java
Normal file
10
src/Ex2/App.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package Ex2;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Server server = new Server(6666);
|
||||||
|
Client client = new Client(new InetSocketAddress("localhost", 6666));
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/Ex2/Client.java
Normal file
77
src/Ex2/Client.java
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package Ex2;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.temporal.TemporalUnit;
|
||||||
|
|
||||||
|
public class Client {
|
||||||
|
|
||||||
|
private final DatagramSocket socket;
|
||||||
|
private final InetSocketAddress address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new client
|
||||||
|
*
|
||||||
|
* @param address server adress (needed
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Client(InetSocketAddress address) throws IOException {
|
||||||
|
this.address = address;
|
||||||
|
this.socket = new DatagramSocket();
|
||||||
|
sendGreetings();
|
||||||
|
readMessage();
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendGreetings() throws IOException {
|
||||||
|
sendMessage(Instant.now().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(String message) throws IOException {
|
||||||
|
byte[] buffer = message.getBytes();
|
||||||
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, this.address.getAddress(),
|
||||||
|
this.address.getPort());
|
||||||
|
this.socket.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processMessage(DatagramPacket packet) {
|
||||||
|
String message = new String(packet.getData(), 0, packet.getLength());
|
||||||
|
long t2 = Instant.now().toEpochMilli();
|
||||||
|
System.out.println("[Client] Message recieved : " + message);
|
||||||
|
String[] times = message.split(" ");
|
||||||
|
long t1 = Instant.parse(times[0]).toEpochMilli();
|
||||||
|
long tPrime1 = Instant.parse(times[1]).toEpochMilli();
|
||||||
|
long tPrime2 = Instant.parse(times[2]).toEpochMilli();
|
||||||
|
var delta = (t2 - t1) - (tPrime2 - tPrime1);
|
||||||
|
var theta = (tPrime1 + tPrime2) / 2 - (t1 + t2) / 2;
|
||||||
|
var now = System.currentTimeMillis();
|
||||||
|
System.out.println("Delta : " + delta + "ms, Theta : " + theta + "ms");
|
||||||
|
System.out.println("Temps actuel : " + new Timestamp(now));
|
||||||
|
System.out.println("Temps corrigé: " + new Timestamp(now + theta));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean readMessage() {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
||||||
|
try {
|
||||||
|
this.socket.receive(packet);
|
||||||
|
processMessage(packet);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readMessages() {
|
||||||
|
while (true) {
|
||||||
|
if(!readMessage())
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
52
src/Ex2/Server.java
Normal file
52
src/Ex2/Server.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
package Ex2;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
|
||||||
|
private final DatagramSocket socket;
|
||||||
|
|
||||||
|
public Server(int port) throws SocketException {
|
||||||
|
this.socket = new DatagramSocket(port);
|
||||||
|
new Thread(this::readMessages).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return this.socket.getLocalPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessage(String message, InetAddress address, int port) throws IOException {
|
||||||
|
byte[] buffer = message.getBytes();
|
||||||
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, port);
|
||||||
|
this.socket.send(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processMessage(DatagramPacket packet) throws IOException {
|
||||||
|
Instant tPrime1 = Instant.now();
|
||||||
|
String message = new String(packet.getData(), 0, packet.getLength());
|
||||||
|
System.out.println("[Server] Message recieved : " + message);
|
||||||
|
Instant t1 = Instant.parse(message);
|
||||||
|
Instant tPrime2 = Instant.now();
|
||||||
|
sendMessage(t1.toString() + " " + tPrime1.toString() + " " + tPrime2.toString(), packet.getAddress(), packet.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readMessages() {
|
||||||
|
while (true) {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
||||||
|
try {
|
||||||
|
this.socket.receive(packet);
|
||||||
|
processMessage(packet);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
11
src/Ex3/App.java
Normal file
11
src/Ex3/App.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package Ex3;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Server server = new Server(6666);
|
||||||
|
Client client = new Client(new InetSocketAddress("localhost", 6666));
|
||||||
|
// Client client2 = new Client(new InetSocketAddress("localhost", 6666));
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/Ex3/Client.java
Normal file
34
src/Ex3/Client.java
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package Ex3;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Client {
|
||||||
|
|
||||||
|
private final Socket socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new client
|
||||||
|
*
|
||||||
|
* @param address server adress (needed
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Client(InetSocketAddress address) throws IOException {
|
||||||
|
this.socket = new Socket(address.getAddress(), address.getPort());
|
||||||
|
readMessage();
|
||||||
|
this.socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readMessage() {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
||||||
|
System.out.println("Heure du serveur : " + reader.readLine());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
45
src/Ex3/Server.java
Normal file
45
src/Ex3/Server.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package Ex3;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.time.Instant;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
|
||||||
|
private final ServerSocket serverSocket;
|
||||||
|
|
||||||
|
public Server(int port) throws IOException {
|
||||||
|
this.serverSocket = new ServerSocket(port);
|
||||||
|
new Thread(this::listen).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return this.serverSocket.getLocalPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processConnexion(Socket socket) throws IOException {
|
||||||
|
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
|
||||||
|
writer.println(Instant.now().toString());
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void listen() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Socket connexion = this.serverSocket.accept();
|
||||||
|
processConnexion(connexion);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
17
src/Ex4/App.java
Normal file
17
src/Ex4/App.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package Ex4;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Server server = new Server(6666);
|
||||||
|
Client client = new Client(new InetSocketAddress("localhost", 6666));
|
||||||
|
client.sendMessage("DATE");
|
||||||
|
client.sendMessage("HOUR");
|
||||||
|
client.sendMessage("FULL");
|
||||||
|
client.sendMessage("CLOSE");
|
||||||
|
|
||||||
|
// stopping server
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/Ex4/Client.java
Normal file
45
src/Ex4/Client.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package Ex4;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Client {
|
||||||
|
|
||||||
|
private final Socket socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new client
|
||||||
|
*
|
||||||
|
* @param address server adress (needed
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Client(InetSocketAddress address) throws IOException {
|
||||||
|
this.socket = new Socket(address.getAddress(), address.getPort());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
PrintWriter writer;
|
||||||
|
try {
|
||||||
|
writer = new PrintWriter(this.socket.getOutputStream(), true);
|
||||||
|
writer.println(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
readMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readMessage() {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
||||||
|
System.out.println("[Client] " + reader.readLine());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
102
src/Ex4/Server.java
Normal file
102
src/Ex4/Server.java
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package Ex4;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.DatagramPacket;
|
||||||
|
import java.net.DatagramSocket;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
|
||||||
|
private final ServerSocket serverSocket;
|
||||||
|
|
||||||
|
public Server(int port) throws IOException {
|
||||||
|
this.serverSocket = new ServerSocket(port);
|
||||||
|
new Thread(this::listen).start();
|
||||||
|
System.out.println("Server running on port " + getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
this.serverSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return this.serverSocket.getLocalPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processConnexion(Socket socket) throws IOException {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
readMessages(socket);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void listen() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
Socket connexion = this.serverSocket.accept();
|
||||||
|
processConnexion(connexion);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readMessages(Socket socket) throws IOException {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
String message = reader.readLine();
|
||||||
|
Date date = Date.from(Instant.now());
|
||||||
|
Calendar now = GregorianCalendar.getInstance();
|
||||||
|
now.setTime(date);
|
||||||
|
System.out.println("[Server] Received " + message);
|
||||||
|
switch (message) {
|
||||||
|
case "DATE":
|
||||||
|
writer.println(LocalDate.now());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "HOUR":
|
||||||
|
writer.println(now.get(Calendar.HOUR_OF_DAY) + ":" + now.get(Calendar.MINUTE));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "FULL":
|
||||||
|
writer.println(Instant.now().toString());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "CLOSE":
|
||||||
|
System.out.println("[Server] Closing socket...");
|
||||||
|
socket.close();
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
22
src/Ex5/App.java
Normal file
22
src/Ex5/App.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package Ex5;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Server server = new Server(6666);
|
||||||
|
Client client = new Client(new InetSocketAddress("localhost", 6666));
|
||||||
|
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
System.out.println("Entrez des messages :");
|
||||||
|
while (true) {
|
||||||
|
String line = scanner.nextLine();
|
||||||
|
System.out.println("[Client -> Server] " + line);
|
||||||
|
client.sendMessage(line);
|
||||||
|
|
||||||
|
String response = client.readMessage();
|
||||||
|
System.out.println("[Client <- Server] " + response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/Ex5/Client.java
Normal file
45
src/Ex5/Client.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
package Ex5;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Client {
|
||||||
|
|
||||||
|
private final Socket socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new client
|
||||||
|
*
|
||||||
|
* @param address server adress (needed
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Client(InetSocketAddress address) throws IOException {
|
||||||
|
this.socket = new Socket(address.getAddress(), address.getPort());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
PrintWriter writer;
|
||||||
|
try {
|
||||||
|
writer = new PrintWriter(this.socket.getOutputStream(), true);
|
||||||
|
writer.println(message);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String readMessage() {
|
||||||
|
try {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
|
||||||
|
return reader.readLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
65
src/Ex5/Server.java
Normal file
65
src/Ex5/Server.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
package Ex5;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class Server {
|
||||||
|
|
||||||
|
private final ServerSocket serverSocket;
|
||||||
|
|
||||||
|
public Server(int port) throws IOException {
|
||||||
|
this.serverSocket = new ServerSocket(port);
|
||||||
|
new Thread(this::listen).start();
|
||||||
|
System.out.println("Server running on port " + getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
this.serverSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPort() {
|
||||||
|
return this.serverSocket.getLocalPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processConnexion(Socket socket) throws IOException {
|
||||||
|
new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
readMessages(socket);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void listen() {
|
||||||
|
try {
|
||||||
|
while (true) {
|
||||||
|
Socket connexion = this.serverSocket.accept();
|
||||||
|
processConnexion(connexion);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readMessages(Socket socket) throws IOException {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
|
||||||
|
while (true) {
|
||||||
|
String message = reader.readLine();
|
||||||
|
writer.println(message.toUpperCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
23
src/Ex6/README.md
Normal file
23
src/Ex6/README.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Architecture
|
||||||
|
|
||||||
|
- The main package contains the logic.
|
||||||
|
- The network package contains the protocol implementation details.
|
||||||
|
|
||||||
|
# Running the program
|
||||||
|
|
||||||
|
## Launch server
|
||||||
|
|
||||||
|
Run Serveur.java
|
||||||
|
|
||||||
|
## Launch Client
|
||||||
|
|
||||||
|
Run Client.java
|
||||||
|
|
||||||
|
## Launch Server + Client
|
||||||
|
|
||||||
|
Run App.java
|
||||||
|
|
||||||
|
# CLI interface
|
||||||
|
|
||||||
|
To play a move, enter the number of the cell you want to change.
|
||||||
|
To exit, type "stop" or "close".
|
||||||
20
src/Ex6/main/App.java
Normal file
20
src/Ex6/main/App.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package Ex6.main;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
public class App {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run this to launch the server and immediatly connect to it with a CLI Client.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
final int port = 6666;
|
||||||
|
|
||||||
|
System.out.println("Launching server ...");
|
||||||
|
Serveur serveur = new Serveur(port);
|
||||||
|
|
||||||
|
System.out.println("Connecting client1 ...");
|
||||||
|
Client client1 = new Client(new Socket("localhost", port));
|
||||||
|
}
|
||||||
|
}
|
||||||
160
src/Ex6/main/Client.java
Normal file
160
src/Ex6/main/Client.java
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
package Ex6.main;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
import Ex6.main.Jeu.EtatCase;
|
||||||
|
import Ex6.network.Connexion;
|
||||||
|
import Ex6.network.packets.EndGamePacket;
|
||||||
|
import Ex6.network.packets.InvalidMovePacket;
|
||||||
|
import Ex6.network.packets.LeavePacket;
|
||||||
|
import Ex6.network.packets.NewGamePacket;
|
||||||
|
import Ex6.network.packets.PlayMovePacket;
|
||||||
|
import Ex6.network.packets.PlayerMovePacket;
|
||||||
|
|
||||||
|
public class Client extends Connexion {
|
||||||
|
|
||||||
|
private EtatCase player = EtatCase.Vide;
|
||||||
|
private EtatCase turn = EtatCase.Vide;
|
||||||
|
private EtatCase[] cases = new EtatCase[9];
|
||||||
|
|
||||||
|
// I swear I typed those by hand
|
||||||
|
private static final String[] CELL_EMOJIS = {
|
||||||
|
"0️⃣ ", "1️⃣ ", "2️⃣ ",
|
||||||
|
"3️⃣ ", "4️⃣ ", "5️⃣ ",
|
||||||
|
"6️⃣ ", "7️⃣ ", "8️⃣ ",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run this to connect to an existing server
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
new Client(new Socket("localhost", 6666));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Client(Socket socket) throws IOException {
|
||||||
|
super(socket);
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
boolean done = false;
|
||||||
|
while (!done) {
|
||||||
|
String line = scanner.nextLine();
|
||||||
|
switch (line) {
|
||||||
|
case "CLOSE":
|
||||||
|
case "close":
|
||||||
|
case "STOP":
|
||||||
|
case "stop":
|
||||||
|
sendPacket(new LeavePacket());
|
||||||
|
socket.close();
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int cellIndex = Integer.parseInt(line);
|
||||||
|
if (cellIndex > 8 || cellIndex < 0) {
|
||||||
|
System.out.println("Number not in range !");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sendPacket(new PlayMovePacket(cellIndex));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
System.out.println("Number not recognized !");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scanner.close();
|
||||||
|
System.out.println("Bye !");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPlayerTurn() {
|
||||||
|
return this.player == this.turn;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPlayerCharacter() {
|
||||||
|
return this.player == EtatCase.Rond ? "⭕" : "❌";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchTurn() {
|
||||||
|
if (this.turn == EtatCase.Croix) {
|
||||||
|
this.turn = EtatCase.Rond;
|
||||||
|
} else {
|
||||||
|
this.turn = EtatCase.Croix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String renderBoard() {
|
||||||
|
String board = "";
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
EtatCase cell = cases[i];
|
||||||
|
switch (cell) {
|
||||||
|
case Vide:
|
||||||
|
board += CELL_EMOJIS[i];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Croix:
|
||||||
|
board += "❌";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Rond:
|
||||||
|
board += "⭕";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i % 3 == 2)
|
||||||
|
board += "\n";
|
||||||
|
}
|
||||||
|
return board;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printBoard() {
|
||||||
|
System.out.println("\n\n\n\n\n\n\n\n\n");
|
||||||
|
System.out.println(renderBoard());
|
||||||
|
if (isPlayerTurn()) {
|
||||||
|
System.out.println("C'est à votre tour !");
|
||||||
|
} else {
|
||||||
|
System.out.println("En attente de l'adversaire ...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(EndGamePacket packet) {
|
||||||
|
System.out.println("Jeu terminé !");
|
||||||
|
printBoard();
|
||||||
|
System.out.println("\n\n\nVous avez " + (packet.getVainqueur() == player ? "gagné 🤩" : "perdu 💩"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(InvalidMovePacket packet) {
|
||||||
|
System.out.println("Coups non autorisé !");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(NewGamePacket packet) {
|
||||||
|
this.player = packet.isRond() ? EtatCase.Rond : EtatCase.Croix;
|
||||||
|
this.turn = EtatCase.Croix;
|
||||||
|
Arrays.fill(cases, EtatCase.Vide);
|
||||||
|
System.out.printf("Nouvelle partie !\n", this.getPlayerCharacter());
|
||||||
|
System.out.println("Vous êtes les " + getPlayerCharacter());
|
||||||
|
printBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PlayerMovePacket packet) {
|
||||||
|
cases[packet.getCellIndex()] = turn;
|
||||||
|
switchTurn();
|
||||||
|
printBoard();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LeavePacket packet) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'visit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PlayMovePacket packet) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'visit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
115
src/Ex6/main/Jeu.java
Normal file
115
src/Ex6/main/Jeu.java
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
package Ex6.main;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class Jeu {
|
||||||
|
public enum EtatCase {
|
||||||
|
Croix,
|
||||||
|
Rond,
|
||||||
|
Vide
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean gameDone;
|
||||||
|
|
||||||
|
private EtatCase turn = EtatCase.Vide;
|
||||||
|
private EtatCase[] cases = new EtatCase[9];
|
||||||
|
|
||||||
|
private final Serveur serveur;
|
||||||
|
|
||||||
|
private static final int[][] CHECK_INDICES = {
|
||||||
|
// rows
|
||||||
|
{0, 1, 2}, {3, 4, 5}, {6, 7, 8},
|
||||||
|
|
||||||
|
// columns
|
||||||
|
{0, 3, 6}, {1, 4, 7}, {2, 5, 8},
|
||||||
|
|
||||||
|
// diagonals
|
||||||
|
{0, 4, 8}, {2, 4, 6}
|
||||||
|
};
|
||||||
|
|
||||||
|
public Jeu(Serveur serveur) {
|
||||||
|
this.serveur = serveur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a new game and randomly assign symbols to players
|
||||||
|
*/
|
||||||
|
public void start() {
|
||||||
|
boolean player1Rond = new Random().nextBoolean();
|
||||||
|
|
||||||
|
this.serveur.joueur1.startGame(player1Rond);
|
||||||
|
this.serveur.joueur2.startGame(!player1Rond);
|
||||||
|
|
||||||
|
this.gameDone = false;
|
||||||
|
this.turn = EtatCase.Croix;
|
||||||
|
Arrays.fill(cases, EtatCase.Vide);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void switchTurn() {
|
||||||
|
if (this.turn == EtatCase.Croix){
|
||||||
|
this.turn = EtatCase.Rond;
|
||||||
|
} else {
|
||||||
|
this.turn = EtatCase.Croix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for winning pattern by looking at an index table.
|
||||||
|
* @return EtatCase.Vide if no one won.
|
||||||
|
*/
|
||||||
|
private EtatCase checkWin() {
|
||||||
|
for (int i = 0; i < CHECK_INDICES.length; i++) {
|
||||||
|
EtatCase previousCell = null;
|
||||||
|
boolean skip = false;
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
int cellIndex = CHECK_INDICES[i][j];
|
||||||
|
EtatCase cell = cases[cellIndex];
|
||||||
|
if (cell == EtatCase.Vide) {
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (previousCell != null) {
|
||||||
|
if (previousCell != cell) {
|
||||||
|
skip = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previousCell = cell;
|
||||||
|
}
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return previousCell;
|
||||||
|
}
|
||||||
|
return EtatCase.Vide;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply a move for the current player.
|
||||||
|
* Be aware that the move is not checked and should be done before.
|
||||||
|
* @see Ex6.main.Jeu.checkWin
|
||||||
|
* @param cellIndex index of the cell to replace.
|
||||||
|
* @return EtatCase.Vide if no one won.
|
||||||
|
*/
|
||||||
|
public EtatCase playMove(int cellIndex) {
|
||||||
|
cases[cellIndex] = this.turn;
|
||||||
|
switchTurn();
|
||||||
|
EtatCase winner = checkWin();
|
||||||
|
if (winner != EtatCase.Vide)
|
||||||
|
this.gameDone = true;
|
||||||
|
return winner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EtatCase getCell(int index) {
|
||||||
|
return cases[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public EtatCase getTurn() {
|
||||||
|
return turn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isGameDone() {
|
||||||
|
return this.gameDone;
|
||||||
|
}
|
||||||
|
}
|
||||||
90
src/Ex6/main/Joueur.java
Normal file
90
src/Ex6/main/Joueur.java
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
package Ex6.main;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import Ex6.main.Jeu.EtatCase;
|
||||||
|
import Ex6.network.Connexion;
|
||||||
|
import Ex6.network.packets.EndGamePacket;
|
||||||
|
import Ex6.network.packets.InvalidMovePacket;
|
||||||
|
import Ex6.network.packets.LeavePacket;
|
||||||
|
import Ex6.network.packets.NewGamePacket;
|
||||||
|
import Ex6.network.packets.PlayMovePacket;
|
||||||
|
import Ex6.network.packets.PlayerMovePacket;
|
||||||
|
|
||||||
|
public class Joueur extends Connexion {
|
||||||
|
|
||||||
|
private final Jeu jeu;
|
||||||
|
private final Serveur serveur;
|
||||||
|
private EtatCase player;
|
||||||
|
|
||||||
|
public Joueur(Socket socket, Jeu jeu, Serveur serveur) throws IOException {
|
||||||
|
super(socket);
|
||||||
|
this.jeu = jeu;
|
||||||
|
this.serveur = serveur;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify a new game has started to the client
|
||||||
|
* @param rond True if player is 'O'
|
||||||
|
*/
|
||||||
|
public void startGame(boolean rond) {
|
||||||
|
this.player = rond ? EtatCase.Rond : EtatCase.Croix;
|
||||||
|
sendPacket(new NewGamePacket(rond));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(LeavePacket packet) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PlayMovePacket packet) {
|
||||||
|
// player should not play
|
||||||
|
if (this.jeu.isGameDone() || this.jeu.getTurn() != this.player) {
|
||||||
|
sendPacket(new InvalidMovePacket());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check placing on empty cell
|
||||||
|
if (this.jeu.getCell(packet.getCellIndex()) != EtatCase.Vide) {
|
||||||
|
sendPacket(new InvalidMovePacket());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EtatCase winner = this.jeu.playMove(packet.getCellIndex());
|
||||||
|
this.serveur.broadcastPacket(new PlayerMovePacket(packet.getCellIndex()));
|
||||||
|
if (winner != EtatCase.Vide) {
|
||||||
|
this.serveur.broadcastPacket(new EndGamePacket(winner));
|
||||||
|
try {
|
||||||
|
Thread.sleep(10000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// automatically launch new game after 10s
|
||||||
|
this.jeu.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(EndGamePacket packet) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'visit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(InvalidMovePacket packet) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'visit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(NewGamePacket packet) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'visit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(PlayerMovePacket packet) {
|
||||||
|
throw new UnsupportedOperationException("Unimplemented method 'visit'");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
69
src/Ex6/main/Serveur.java
Normal file
69
src/Ex6/main/Serveur.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package Ex6.main;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
import Ex6.network.Packet;
|
||||||
|
|
||||||
|
public class Serveur {
|
||||||
|
|
||||||
|
private final Jeu jeu;
|
||||||
|
|
||||||
|
private final ServerSocket serverSocket;
|
||||||
|
public Joueur joueur1;
|
||||||
|
public Joueur joueur2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Run this to launch the server in headless mode
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws IOException {
|
||||||
|
new Serveur(6666);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a TicTacToe server on the specified port
|
||||||
|
* @param port the port to listen to
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Serveur(int port) throws IOException {
|
||||||
|
this.jeu = new Jeu(this);
|
||||||
|
this.serverSocket = new ServerSocket(port);
|
||||||
|
this.joueur1 = null;
|
||||||
|
this.joueur2 = null;
|
||||||
|
new Thread(this::acceptLoop).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a packet to both players
|
||||||
|
* @param packet the packet to send
|
||||||
|
*/
|
||||||
|
public void broadcastPacket(Packet packet) {
|
||||||
|
this.joueur1.sendPacket(packet);
|
||||||
|
this.joueur2.sendPacket(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Here we accept only the first two players.
|
||||||
|
* If a player leaves, the server needs to be restarted.
|
||||||
|
* It's not robust but enough for a demo.
|
||||||
|
*/
|
||||||
|
private void acceptLoop() {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
Socket socket = this.serverSocket.accept();
|
||||||
|
if (this.joueur1 == null) {
|
||||||
|
this.joueur1 = new Joueur(socket, jeu, this);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (this.joueur2 == null) {
|
||||||
|
this.joueur2 = new Joueur(socket, jeu, this);
|
||||||
|
this.jeu.start();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
src/Ex6/network/Connexion.java
Normal file
81
src/Ex6/network/Connexion.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package Ex6.network;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction of TCP connection implementing PacketVisitor
|
||||||
|
*/
|
||||||
|
public abstract class Connexion implements PacketVisitor {
|
||||||
|
|
||||||
|
private final Socket socket;
|
||||||
|
private final ObjectOutputStream out;
|
||||||
|
private ObjectInputStream in;
|
||||||
|
|
||||||
|
public Connexion(Socket socket) throws IOException {
|
||||||
|
this.socket = socket;
|
||||||
|
this.out = new ObjectOutputStream(this.socket.getOutputStream());
|
||||||
|
new Thread(this::readPackets).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a packet through network
|
||||||
|
* @param packet The packet to send
|
||||||
|
*/
|
||||||
|
public void sendPacket(Packet packet) {
|
||||||
|
try {
|
||||||
|
out.writeObject(packet);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loop to process new packets infinitely.
|
||||||
|
*/
|
||||||
|
private void readPackets() {
|
||||||
|
try {
|
||||||
|
this.in = new ObjectInputStream(this.socket.getInputStream());
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
processPacket();
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a packet.
|
||||||
|
* @return The packet read.
|
||||||
|
*/
|
||||||
|
private Packet readPacket() throws ClassNotFoundException, IOException {
|
||||||
|
Object o = in.readObject();
|
||||||
|
Packet packet = (Packet) o;
|
||||||
|
return packet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processing the packet through double-dispatch.
|
||||||
|
*/
|
||||||
|
public void processPacket() throws ClassNotFoundException, IOException {
|
||||||
|
Packet packet = readPacket();
|
||||||
|
visit(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close the connection.
|
||||||
|
*/
|
||||||
|
protected void close() {
|
||||||
|
try {
|
||||||
|
this.socket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
8
src/Ex6/network/Packet.java
Normal file
8
src/Ex6/network/Packet.java
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
package Ex6.network;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract class representing a packet (implementing the Visitor design pattern)
|
||||||
|
*/
|
||||||
|
public abstract class Packet {
|
||||||
|
public abstract void accept(PacketVisitor visitor);
|
||||||
|
}
|
||||||
29
src/Ex6/network/PacketVisitor.java
Normal file
29
src/Ex6/network/PacketVisitor.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package Ex6.network;
|
||||||
|
|
||||||
|
import Ex6.network.packets.EndGamePacket;
|
||||||
|
import Ex6.network.packets.InvalidMovePacket;
|
||||||
|
import Ex6.network.packets.LeavePacket;
|
||||||
|
import Ex6.network.packets.NewGamePacket;
|
||||||
|
import Ex6.network.packets.PlayMovePacket;
|
||||||
|
import Ex6.network.packets.PlayerMovePacket;
|
||||||
|
|
||||||
|
public interface PacketVisitor {
|
||||||
|
void visit(EndGamePacket packet);
|
||||||
|
|
||||||
|
void visit(InvalidMovePacket packet);
|
||||||
|
|
||||||
|
void visit(LeavePacket packet);
|
||||||
|
|
||||||
|
void visit(NewGamePacket packet);
|
||||||
|
|
||||||
|
void visit(PlayerMovePacket packet);
|
||||||
|
|
||||||
|
void visit(PlayMovePacket packet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Double-dispatch
|
||||||
|
*/
|
||||||
|
default void visit(Packet packet) {
|
||||||
|
packet.accept(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
29
src/Ex6/network/packets/EndGamePacket.java
Normal file
29
src/Ex6/network/packets/EndGamePacket.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package Ex6.network.packets;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import Ex6.main.Jeu.EtatCase;
|
||||||
|
import Ex6.network.Packet;
|
||||||
|
import Ex6.network.PacketVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet sent to both clients to end a game (providing the winner)
|
||||||
|
*/
|
||||||
|
public class EndGamePacket extends Packet implements Serializable{
|
||||||
|
|
||||||
|
private final EtatCase vainqueur;
|
||||||
|
|
||||||
|
public EndGamePacket(EtatCase vainqueur) {
|
||||||
|
this.vainqueur = vainqueur;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(PacketVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EtatCase getVainqueur() {
|
||||||
|
return vainqueur;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
18
src/Ex6/network/packets/InvalidMovePacket.java
Normal file
18
src/Ex6/network/packets/InvalidMovePacket.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package Ex6.network.packets;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import Ex6.network.Packet;
|
||||||
|
import Ex6.network.PacketVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet send to a client to indicate an invalid move.
|
||||||
|
*/
|
||||||
|
public class InvalidMovePacket extends Packet implements Serializable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(PacketVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
18
src/Ex6/network/packets/LeavePacket.java
Normal file
18
src/Ex6/network/packets/LeavePacket.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package Ex6.network.packets;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import Ex6.network.Packet;
|
||||||
|
import Ex6.network.PacketVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet sent by a client to indicate he is leaving.
|
||||||
|
*/
|
||||||
|
public class LeavePacket extends Packet implements Serializable {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(PacketVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/Ex6/network/packets/NewGamePacket.java
Normal file
28
src/Ex6/network/packets/NewGamePacket.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package Ex6.network.packets;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import Ex6.network.Packet;
|
||||||
|
import Ex6.network.PacketVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet sent to both client to indicate a new game has started (providing the symbol of the player for this game).
|
||||||
|
*/
|
||||||
|
public class NewGamePacket extends Packet implements Serializable {
|
||||||
|
|
||||||
|
private final boolean rond;
|
||||||
|
|
||||||
|
public NewGamePacket(boolean rond) {
|
||||||
|
this.rond = rond;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(PacketVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRond() {
|
||||||
|
return rond;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
27
src/Ex6/network/packets/PlayMovePacket.java
Normal file
27
src/Ex6/network/packets/PlayMovePacket.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package Ex6.network.packets;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import Ex6.network.Packet;
|
||||||
|
import Ex6.network.PacketVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet sent by a client to draw a symbol in a cell.
|
||||||
|
*/
|
||||||
|
public class PlayMovePacket extends Packet implements Serializable{
|
||||||
|
|
||||||
|
private final int cellIndex;
|
||||||
|
|
||||||
|
public PlayMovePacket(int cellIndex) {
|
||||||
|
this.cellIndex = cellIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(PacketVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCellIndex() {
|
||||||
|
return cellIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
28
src/Ex6/network/packets/PlayerMovePacket.java
Normal file
28
src/Ex6/network/packets/PlayerMovePacket.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package Ex6.network.packets;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import Ex6.network.Packet;
|
||||||
|
import Ex6.network.PacketVisitor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Packet sent to both client to confirm a move and switch turns.
|
||||||
|
*/
|
||||||
|
public class PlayerMovePacket extends Packet implements Serializable {
|
||||||
|
|
||||||
|
private final int cellIndex;
|
||||||
|
|
||||||
|
public PlayerMovePacket(int cellIndex) {
|
||||||
|
this.cellIndex = cellIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(PacketVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCellIndex() {
|
||||||
|
return cellIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user