Added more network information, player.

This commit is contained in:
Andrew Lalis 2022-07-05 23:34:54 +02:00
parent 00c22525cb
commit 1bf7074b76
10 changed files with 62 additions and 19 deletions

View File

@ -1,6 +1,6 @@
package nl.andrewl.aos_core; package nl.andrewl.aos_core;
import nl.andrewl.aos_core.net.PlayerConnectRequestMessage; import nl.andrewl.aos_core.net.ConnectRequestMessage;
import nl.andrewl.record_net.Message; import nl.andrewl.record_net.Message;
import nl.andrewl.record_net.Serializer; import nl.andrewl.record_net.Serializer;
import nl.andrewl.record_net.util.ExtendedDataInputStream; import nl.andrewl.record_net.util.ExtendedDataInputStream;
@ -19,7 +19,7 @@ public final class Net {
private static final Serializer serializer = new Serializer(); private static final Serializer serializer = new Serializer();
static { static {
serializer.registerType(1, PlayerConnectRequestMessage.class); serializer.registerType(1, ConnectRequestMessage.class);
} }
public static ExtendedDataInputStream getInputStream(InputStream in) { public static ExtendedDataInputStream getInputStream(InputStream in) {

View File

@ -0,0 +1,18 @@
package nl.andrewl.aos_core.model;
import org.joml.Vector2f;
import org.joml.Vector3f;
public class Player {
private final Vector3f position;
private final Vector3f velocity;
private final Vector2f orientation;
private final String username;
public Player(String username) {
this.position = new Vector3f();
this.velocity = new Vector3f();
this.orientation = new Vector2f();
this.username = username;
}
}

View File

@ -3,10 +3,13 @@ package nl.andrewl.aos_core.model;
import org.joml.Vector3i; import org.joml.Vector3i;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
public class World { public class World {
Map<Vector3i, Chunk> chunkMap = new HashMap<>(); private final Map<Vector3i, Chunk> chunkMap = new HashMap<>();
private final Set<Player> players = new HashSet<>();
public byte getBlockAt(int x, int y, int z) { public byte getBlockAt(int x, int y, int z) {
int chunkX = x / Chunk.SIZE; int chunkX = x / Chunk.SIZE;

View File

@ -0,0 +1,5 @@
package nl.andrewl.aos_core.net;
import nl.andrewl.record_net.Message;
public record ConnectAcceptMessage () implements Message {}

View File

@ -0,0 +1,5 @@
package nl.andrewl.aos_core.net;
import nl.andrewl.record_net.Message;
public record ConnectRejectMessage(String reason) implements Message {}

View File

@ -2,7 +2,4 @@ package nl.andrewl.aos_core.net;
import nl.andrewl.record_net.Message; import nl.andrewl.record_net.Message;
public record PlayerConnectRequestMessage ( public record ConnectRequestMessage(String username, int udpPort) implements Message {}
String username,
int udpPort
) implements Message {}

View File

@ -1,5 +0,0 @@
package nl.andrewl.aos_core.net;
import nl.andrewl.record_net.Message;
public record PlayerConnectRejectMessage (String reason) implements Message {}

View File

@ -2,4 +2,4 @@ package nl.andrewl.aos_core.net.udp;
import nl.andrewl.record_net.Message; import nl.andrewl.record_net.Message;
public record InitPacket () implements Message {} public record DatagramInit() implements Message {}

View File

@ -8,5 +8,15 @@ When referring to the names of packets, we will assume a common package name of
### Player Connection ### Player Connection
This workflow is involved in the establishment of a connection between the client and server. This workflow is involved in the establishment of a connection between the client and server.
1. Player sends a `PlayerConnectRequestMessage` via TCP, immediately upon opening a socket connection. It contains the player's desired `username`, and their `udpPort` that they will use to connect. 1. Player sends a `ConnectRequestMessage` via TCP, immediately upon opening a socket connection. It contains the player's desired `username`, and their `udpPort` that they will use to connect.
2. The server will respond with either a `PlayerConnectRejectMessage` with a `reason` for the rejection, or a `PlayerConnectAcceptMessage`. 2. The server will respond with either a `ConnectRejectMessage` with a `reason` for the rejection, or a `ConnectAcceptMessage`.
3. If the player received an acceptance message, they will then send a `DatagramInit` to the server's UDP socket (on the same address/port). The player should keep sending such an init message until they receive a `DatagramInit` message echoed back as a response. The player should then stop sending init messages, and expect to begin receiving normal communication data through the datagram socket.
### World Data
A combination of TCP and UDP communication is used to ensure that all connected clients have the latest information about the state of the world.
Initially when the player connects to a server, the server will begin sending `ChunkDataMessage` packets via TCP to the player, with the full chunk data of an individual chunk.
If, during the course of a game tick, a chunk is updated, at the end of the tick, a `ChunkUpdateMessage` message is sent which provides the coordinates and new block data for a block in a chunk.
A player should regularly send a `ChunkHashMessage` to the server that contains a hash of a certain chunk, to verify that the player's chunk data matches the server's. The server will send a `ChunkDataMessage` if the player's hash is incorrect and the player should replace their chunk data.

View File

@ -1,8 +1,8 @@
package nl.andrewl.aos2_server; package nl.andrewl.aos2_server;
import nl.andrewl.aos_core.Net; import nl.andrewl.aos_core.Net;
import nl.andrewl.aos_core.net.PlayerConnectRejectMessage; import nl.andrewl.aos_core.net.ConnectRejectMessage;
import nl.andrewl.aos_core.net.PlayerConnectRequestMessage; import nl.andrewl.aos_core.net.ConnectRequestMessage;
import nl.andrewl.record_net.Message; import nl.andrewl.record_net.Message;
import nl.andrewl.record_net.util.ExtendedDataInputStream; import nl.andrewl.record_net.util.ExtendedDataInputStream;
import nl.andrewl.record_net.util.ExtendedDataOutputStream; import nl.andrewl.record_net.util.ExtendedDataOutputStream;
@ -60,16 +60,26 @@ public class ClientHandler extends Thread {
} }
private void establishConnection() { private void establishConnection() {
try {
socket.setSoTimeout(1000);
} catch (SocketException e) {
throw new RuntimeException(e);
}
boolean connectionEstablished = false; boolean connectionEstablished = false;
int attempts = 0; int attempts = 0;
while (!connectionEstablished && attempts < 100) { while (!connectionEstablished && attempts < 100) {
try { try {
Message msg = Net.read(in); Message msg = Net.read(in);
if (msg instanceof PlayerConnectRequestMessage connectMsg) { if (msg instanceof ConnectRequestMessage connectMsg) {
this.clientAddress = socket.getInetAddress(); this.clientAddress = socket.getInetAddress();
this.clientUdpPort = connectMsg.udpPort(); this.clientUdpPort = connectMsg.udpPort();
System.out.println("Player connected: " + connectMsg.username()); System.out.println("Player connected: " + connectMsg.username());
connectionEstablished = true; connectionEstablished = true;
try {
socket.setSoTimeout(0);
} catch (SocketException e) {
throw new RuntimeException(e);
}
} }
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -78,7 +88,7 @@ public class ClientHandler extends Thread {
} }
if (!connectionEstablished) { if (!connectionEstablished) {
try { try {
Net.write(new PlayerConnectRejectMessage("Too many connect attempts failed."), out); Net.write(new ConnectRejectMessage("Too many connect attempts failed."), out);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }