Added remote worlds!!!

This commit is contained in:
Andrew Lalis 2022-07-07 01:22:31 +02:00
parent 565d18c89b
commit d5bed83e86
6 changed files with 80 additions and 63 deletions

View File

@ -3,13 +3,10 @@ package nl.andrewl.aos2_client;
import nl.andrewl.aos2_client.render.ChunkMesh;
import nl.andrewl.aos2_client.render.ChunkRenderer;
import nl.andrewl.aos2_client.render.WindowUtils;
import nl.andrewl.aos_core.model.Chunk;
import org.joml.Vector3i;
import nl.andrewl.aos_core.model.World;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Random;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL46.*;
@ -22,81 +19,79 @@ public class Client implements Runnable {
Client client = new Client(serverAddress, serverPort, username);
client.run();
// var windowInfo = WindowUtils.initUI();
// long windowHandle = windowInfo.windowHandle();
//
// Camera cam = new Camera();
// cam.setOrientationDegrees(90, 90);
// cam.setPosition(-3, 3, 0);
// glfwSetCursorPosCallback(windowHandle, cam);
//
// Chunk chunk = Chunk.random(new Vector3i(0, 0, 0), new Random(1));
// Chunk chunk2 = Chunk.random(new Vector3i(1, 0, 0), new Random(1));
// Chunk chunk3 = Chunk.random(new Vector3i(1, 0, 1), new Random(1));
// Chunk chunk4 = Chunk.random(new Vector3i(0, 0, 1), new Random(1));
//
// chunk.setBlockAt(0, 0, 0, (byte) 0);
//
// for (int x = 0; x < Chunk.SIZE; x++) {
// for (int z = 0; z < Chunk.SIZE; z++) {
// chunk.setBlockAt(x, Chunk.SIZE - 1, z, (byte) 0);
// }
// }
//
// ChunkRenderer chunkRenderer = new ChunkRenderer(windowInfo.width(), windowInfo.height());
// chunkRenderer.addChunkMesh(new ChunkMesh(chunk));
// chunkRenderer.addChunkMesh(new ChunkMesh(chunk2));
// chunkRenderer.addChunkMesh(new ChunkMesh(chunk3));
// chunkRenderer.addChunkMesh(new ChunkMesh(chunk4));
//
// while (!glfwWindowShouldClose(windowHandle)) {
// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
// chunkRenderer.draw(cam);
//
// glfwSwapBuffers(windowHandle);
// glfwPollEvents();
//
// if (glfwGetKey(windowHandle, GLFW_KEY_W) == GLFW_PRESS) cam.move(Camera.FORWARD);
// if (glfwGetKey(windowHandle, GLFW_KEY_S) == GLFW_PRESS) cam.move(Camera.BACKWARD);
// if (glfwGetKey(windowHandle, GLFW_KEY_A) == GLFW_PRESS) cam.move(Camera.LEFT);
// if (glfwGetKey(windowHandle, GLFW_KEY_D) == GLFW_PRESS) cam.move(Camera.RIGHT);
// if (glfwGetKey(windowHandle, GLFW_KEY_SPACE) == GLFW_PRESS) cam.move(Camera.UP);
// if (glfwGetKey(windowHandle, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) cam.move(Camera.DOWN);
// }
//
// chunkRenderer.free();
// WindowUtils.clearUI(windowHandle);
}
private InetAddress serverAddress;
private int serverPort;
private String username;
private CommunicationHandler communicationHandler;
private volatile boolean running;
private ChunkRenderer chunkRenderer;
private World world;
public Client(InetAddress serverAddress, int serverPort, String username) {
this.serverAddress = serverAddress;
this.serverPort = serverPort;
this.username = username;
this.communicationHandler = new CommunicationHandler();
this.communicationHandler = new CommunicationHandler(this);
this.world = new World();
}
@Override
public void run() {
running = false;
var windowInfo = WindowUtils.initUI();
long windowHandle = windowInfo.windowHandle();
chunkRenderer = new ChunkRenderer(windowInfo.width(), windowInfo.height());
try {
communicationHandler.establishConnection(serverAddress, serverPort, username);
System.out.println("Established connection to the server.");
} catch (IOException e) {
e.printStackTrace();
running = false;
return; // Exit without starting the game.
}
while (running) {
// Do game stuff
System.out.println("Running!");
System.out.println("Waiting for all world data to arrive...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for (var chunk : world.getChunkMap().values()) {
chunkRenderer.addChunkMesh(new ChunkMesh(chunk));
}
Camera cam = new Camera();
cam.setOrientationDegrees(90, 90);
cam.setPosition(0, 48, 0);
glfwSetCursorPosCallback(windowHandle, cam);
while (!glfwWindowShouldClose(windowHandle)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
chunkRenderer.draw(cam);
glfwSwapBuffers(windowHandle);
glfwPollEvents();
if (glfwGetKey(windowHandle, GLFW_KEY_W) == GLFW_PRESS) cam.move(Camera.FORWARD);
if (glfwGetKey(windowHandle, GLFW_KEY_S) == GLFW_PRESS) cam.move(Camera.BACKWARD);
if (glfwGetKey(windowHandle, GLFW_KEY_A) == GLFW_PRESS) cam.move(Camera.LEFT);
if (glfwGetKey(windowHandle, GLFW_KEY_D) == GLFW_PRESS) cam.move(Camera.RIGHT);
if (glfwGetKey(windowHandle, GLFW_KEY_SPACE) == GLFW_PRESS) cam.move(Camera.UP);
if (glfwGetKey(windowHandle, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) cam.move(Camera.DOWN);
}
chunkRenderer.free();
WindowUtils.clearUI(windowHandle);
}
public World getWorld() {
return world;
}
public ChunkRenderer getChunkRenderer() {
return chunkRenderer;
}
}

View File

@ -1,6 +1,7 @@
package nl.andrewl.aos2_client;
import nl.andrewl.aos_core.Net;
import nl.andrewl.aos_core.model.Chunk;
import nl.andrewl.aos_core.net.*;
import nl.andrewl.aos_core.net.udp.DatagramInit;
import nl.andrewl.record_net.Message;
@ -19,12 +20,16 @@ import java.net.Socket;
* methods for sending messages and processing those we receive.
*/
public class CommunicationHandler {
private final Client client;
private Socket socket;
private DatagramSocket datagramSocket;
private ExtendedDataInputStream in;
private ExtendedDataOutputStream out;
private int clientId;
public CommunicationHandler(Client client) {
this.client = client;
}
public int establishConnection(InetAddress address, int port, String username) throws IOException {
System.out.printf("Connecting to server at %s, port %d, with username \"%s\"...%n", address, port, username);
if (socket != null && !socket.isClosed()) {
@ -32,7 +37,7 @@ public class CommunicationHandler {
}
socket = new Socket(address, port);
socket.setSoTimeout(1000);
in = Net.getInputStream(socket.getInputStream());
ExtendedDataInputStream in = Net.getInputStream(socket.getInputStream());
out = Net.getOutputStream(socket.getOutputStream());
Net.write(new ConnectRequestMessage(username), out);
Message response = Net.read(in);
@ -42,8 +47,8 @@ public class CommunicationHandler {
}
if (response instanceof ConnectAcceptMessage acceptMessage) {
this.clientId = acceptMessage.clientId();
new Thread(new TcpReceiver(in, this::handleMessage)).start();
establishDatagramConnection();
new Thread(new TcpReceiver(in, this::handleMessage)).start();
new Thread(new UdpReceiver(datagramSocket, this::handleUdpMessage)).start();
return acceptMessage.clientId();
} else {
@ -109,6 +114,10 @@ public class CommunicationHandler {
private void handleMessage(Message msg) {
System.out.println("Received message: " + msg);
if (msg instanceof ChunkDataMessage chunkDataMessage) {
Chunk chunk = chunkDataMessage.toChunk();
client.getWorld().addChunk(chunk);
}
}
private void handleUdpMessage(Message msg, DatagramPacket packet) {

View File

@ -29,6 +29,11 @@ public class Chunk {
this.position = new Vector3i(cx, cy, cz);
}
public Chunk(int cx, int cy, int cz, byte[] blocks) {
this(cx, cy, cz);
System.arraycopy(blocks, 0, this.blocks, 0, TOTAL_SIZE);
}
public Chunk(Vector3i position) {
this.position = new Vector3i(position);
}

View File

@ -13,4 +13,8 @@ public record ChunkDataMessage(
public ChunkDataMessage(Chunk chunk) {
this(chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z, chunk.getBlocks());
}
public Chunk toChunk() {
return new Chunk(cx, cy, cz, blocks);
}
}

View File

@ -32,7 +32,7 @@ public class TcpReceiver implements Runnable {
Message msg = Net.read(in);
messageConsumer.accept(msg);
} catch (SocketException e) {
if (e.getMessage().equals("Socket closed")) {
if (e.getMessage().equals("Socket closed") || e.getMessage().equals("Connection reset")) {
running = false;
} else {
e.printStackTrace();

View File

@ -12,6 +12,7 @@ import java.net.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
public class Server implements Runnable {
@ -33,12 +34,15 @@ public class Server implements Runnable {
this.playerClientHandlers = new HashMap<>();
// Generate world. TODO: do this elsewhere.
Random rand = new Random(1);
this.world = new World();
for (int x = -5; x <= 5; x++) {
for (int y = 0; y <= 3; y++) {
for (int z = -3; z <= 3; z++) {
Chunk chunk = new Chunk(x, y, z);
Arrays.fill(chunk.getBlocks(), (byte) 40);
for (int i = 0; i < Chunk.TOTAL_SIZE; i++) {
chunk.getBlocks()[i] = (byte) rand.nextInt(20, 40);
}
world.addChunk(chunk);
}
}