Added more network information, player.
This commit is contained in:
parent
00c22525cb
commit
1bf7074b76
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package nl.andrewl.aos_core.net;
|
||||||
|
|
||||||
|
import nl.andrewl.record_net.Message;
|
||||||
|
|
||||||
|
public record ConnectAcceptMessage () implements Message {}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package nl.andrewl.aos_core.net;
|
||||||
|
|
||||||
|
import nl.andrewl.record_net.Message;
|
||||||
|
|
||||||
|
public record ConnectRejectMessage(String reason) implements Message {}
|
|
@ -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 {}
|
|
|
@ -1,5 +0,0 @@
|
||||||
package nl.andrewl.aos_core.net;
|
|
||||||
|
|
||||||
import nl.andrewl.record_net.Message;
|
|
||||||
|
|
||||||
public record PlayerConnectRejectMessage (String reason) implements Message {}
|
|
|
@ -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 {}
|
|
@ -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.
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue