ace-of-shades-2/server/src/main/java/nl/andrewl/aos2_server/ClientCommunicationHandler....

111 lines
3.3 KiB
Java
Raw Normal View History

package nl.andrewl.aos2_server;
import nl.andrewl.aos_core.Net;
import nl.andrewl.aos_core.model.Player;
import nl.andrewl.aos_core.net.ConnectAcceptMessage;
import nl.andrewl.aos_core.net.ConnectRejectMessage;
import nl.andrewl.aos_core.net.ConnectRequestMessage;
import nl.andrewl.aos_core.net.TcpReceiver;
import nl.andrewl.record_net.Message;
import nl.andrewl.record_net.util.ExtendedDataInputStream;
import nl.andrewl.record_net.util.ExtendedDataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
public class ClientCommunicationHandler {
private final Server server;
private final Socket socket;
private final DatagramSocket datagramSocket;
private final ExtendedDataInputStream in;
private final ExtendedDataOutputStream out;
private InetAddress clientAddress;
private int clientUdpPort;
private Player player;
public ClientCommunicationHandler(Server server, Socket socket, DatagramSocket datagramSocket) throws IOException {
this.server = server;
this.socket = socket;
this.datagramSocket = datagramSocket;
this.in = Net.getInputStream(socket.getInputStream());
this.out = Net.getOutputStream(socket.getOutputStream());
establishConnection();
new Thread(new TcpReceiver(in, this::handleTcpMessage)).start();
}
public void shutdown() {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void setClientUdpPort(int port) {
this.clientUdpPort = port;
}
private void handleTcpMessage(Message msg) {
System.out.println("Message received from client " + player.getUsername() + ": " + msg);
}
private void establishConnection() throws IOException {
socket.setSoTimeout(1000);
boolean connectionEstablished = false;
int attempts = 0;
while (!connectionEstablished && attempts < 100) {
try {
Message msg = Net.read(in);
if (msg instanceof ConnectRequestMessage connectMsg) {
// Try to set the TCP timeout back to 0 now that we've got the correct request.
socket.setSoTimeout(0);
this.clientAddress = socket.getInetAddress();
System.out.println("Player connected: " + connectMsg.username());
connectionEstablished = true;
this.player = server.registerPlayer(this, connectMsg.username());
Net.write(new ConnectAcceptMessage(player.getId()), out);
}
} catch (IOException e) {
e.printStackTrace();
}
attempts++;
}
if (!connectionEstablished) {
try {
Net.write(new ConnectRejectMessage("Too many connect attempts failed."), out);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Player couldn't connect after " + attempts + " attempts. Aborting.");
socket.close();
}
}
public void sendDatagramPacket(Message msg) {
try {
sendDatagramPacket(Net.write(msg));
} catch (IOException e) {
e.printStackTrace();
}
}
public void sendDatagramPacket(byte[] data) {
DatagramPacket packet = new DatagramPacket(data, data.length, clientAddress, clientUdpPort);
sendDatagramPacket(packet);
}
public void sendDatagramPacket(DatagramPacket packet) {
try {
packet.setAddress(clientAddress);
packet.setPort(clientUdpPort);
datagramSocket.send(packet);
} catch (IOException e) {
e.printStackTrace();
}
}
}