101 lines
3.2 KiB
Java
101 lines
3.2 KiB
Java
package server;
|
|
|
|
import java.net.DatagramSocket;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.SocketException;
|
|
import java.time.Instant;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import network.PacketHandler;
|
|
import network.SocketReader;
|
|
import network.protocol.Packet;
|
|
import network.protocol.packets.ChatMessagePacket;
|
|
import network.protocol.packets.SendChatMessagePacket;
|
|
|
|
public class Server implements PacketHandler {
|
|
|
|
private final DatagramSocket serverSocket;
|
|
private final Map<InetSocketAddress, ServerConnexion> connexions;
|
|
private final SocketReader reader;
|
|
private final Map<String, ArrayList<ServerConnexion>> roomNames;
|
|
|
|
public Server(int port) throws SocketException {
|
|
this.serverSocket = new DatagramSocket(port);
|
|
this.connexions = new HashMap<>();
|
|
this.reader = new SocketReader(serverSocket, this);
|
|
this.roomNames = new HashMap<>();
|
|
}
|
|
|
|
public ArrayList<String> getRoomNames() {
|
|
return roomNames.keySet().stream().collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
|
|
}
|
|
|
|
public String getRoomName(ServerConnexion connexion) {
|
|
for (Map.Entry<String, ArrayList<ServerConnexion>> entry : roomNames.entrySet()) {
|
|
if(entry.getValue().contains(connexion)) {
|
|
return entry.getKey();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public void createRoom(String roomName, ServerConnexion connexion) throws SocketException {
|
|
if(roomNames.containsKey(roomName)) {
|
|
throw new SocketException("Room already exists");
|
|
}
|
|
roomNames.put(roomName, new ArrayList<>());
|
|
roomNames.get(roomName).add(connexion);
|
|
}
|
|
|
|
public void leaveRoom(ServerConnexion connexion) throws SocketException {
|
|
String roomName = getRoomName(connexion);
|
|
if(roomName != null) {
|
|
roomNames.get(roomName).remove(connexion);
|
|
// Remove the room if it is empty
|
|
if(roomNames.get(roomName).isEmpty()) {
|
|
roomNames.remove(roomName);
|
|
}
|
|
return;
|
|
}
|
|
throw new SocketException("Room does not exist");
|
|
}
|
|
|
|
public void joinRoom(String roomName, ServerConnexion connexion) throws SocketException {
|
|
if(roomNames.containsKey(roomName) && !roomNames.get(roomName).contains(connexion)) {
|
|
roomNames.get(roomName).add(connexion);
|
|
return;
|
|
}
|
|
throw new SocketException("Room does not exist");
|
|
}
|
|
|
|
public void sendToRoom(ServerConnexion connexion, SendChatMessagePacket packet) throws SocketException {
|
|
String roomName = getRoomName(connexion);
|
|
ChatMessagePacket chatPacket = new ChatMessagePacket(Instant.now(), connexion.getChatterName(), packet.getContent());
|
|
if(roomName != null && roomNames.containsKey(roomName)) {
|
|
roomNames.get(roomName).forEach(con -> con.sendPacket(chatPacket));
|
|
return;
|
|
}
|
|
throw new SocketException("You are not in a room or the room does not exist");
|
|
}
|
|
|
|
public void close() {
|
|
this.reader.stop();
|
|
}
|
|
|
|
public boolean hasChatterName(String pseudo) {
|
|
return this.connexions.values().stream()
|
|
.anyMatch(connexion -> pseudo.equals(connexion.getChatterName()));
|
|
}
|
|
|
|
@Override
|
|
public void handlePacket(Packet packet, InetSocketAddress address) {
|
|
if (!connexions.containsKey(address)) {
|
|
this.connexions.put(address, new ServerConnexion(this, serverSocket, address));
|
|
}
|
|
this.connexions.get(address).visit(packet);
|
|
}
|
|
|
|
}
|