Added remote worlds!!!
This commit is contained in:
		
							parent
							
								
									565d18c89b
								
							
						
					
					
						commit
						d5bed83e86
					
				| 
						 | 
					@ -3,13 +3,10 @@ package nl.andrewl.aos2_client;
 | 
				
			||||||
import nl.andrewl.aos2_client.render.ChunkMesh;
 | 
					import nl.andrewl.aos2_client.render.ChunkMesh;
 | 
				
			||||||
import nl.andrewl.aos2_client.render.ChunkRenderer;
 | 
					import nl.andrewl.aos2_client.render.ChunkRenderer;
 | 
				
			||||||
import nl.andrewl.aos2_client.render.WindowUtils;
 | 
					import nl.andrewl.aos2_client.render.WindowUtils;
 | 
				
			||||||
import nl.andrewl.aos_core.model.Chunk;
 | 
					import nl.andrewl.aos_core.model.World;
 | 
				
			||||||
import org.joml.Vector3i;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
import java.net.InetAddress;
 | 
					import java.net.InetAddress;
 | 
				
			||||||
import java.net.UnknownHostException;
 | 
					 | 
				
			||||||
import java.util.Random;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import static org.lwjgl.glfw.GLFW.*;
 | 
					import static org.lwjgl.glfw.GLFW.*;
 | 
				
			||||||
import static org.lwjgl.opengl.GL46.*;
 | 
					import static org.lwjgl.opengl.GL46.*;
 | 
				
			||||||
| 
						 | 
					@ -22,81 +19,79 @@ public class Client implements Runnable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Client client = new Client(serverAddress, serverPort, username);
 | 
							Client client = new Client(serverAddress, serverPort, username);
 | 
				
			||||||
		client.run();
 | 
							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 InetAddress serverAddress;
 | 
				
			||||||
	private int serverPort;
 | 
						private int serverPort;
 | 
				
			||||||
	private String username;
 | 
						private String username;
 | 
				
			||||||
	private CommunicationHandler communicationHandler;
 | 
						private CommunicationHandler communicationHandler;
 | 
				
			||||||
	private volatile boolean running;
 | 
						private ChunkRenderer chunkRenderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private World world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public Client(InetAddress serverAddress, int serverPort, String username) {
 | 
						public Client(InetAddress serverAddress, int serverPort, String username) {
 | 
				
			||||||
		this.serverAddress = serverAddress;
 | 
							this.serverAddress = serverAddress;
 | 
				
			||||||
		this.serverPort = serverPort;
 | 
							this.serverPort = serverPort;
 | 
				
			||||||
		this.username = username;
 | 
							this.username = username;
 | 
				
			||||||
		this.communicationHandler = new CommunicationHandler();
 | 
							this.communicationHandler = new CommunicationHandler(this);
 | 
				
			||||||
 | 
							this.world = new World();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void run() {
 | 
						public void run() {
 | 
				
			||||||
		running = false;
 | 
							var windowInfo = WindowUtils.initUI();
 | 
				
			||||||
 | 
							long windowHandle = windowInfo.windowHandle();
 | 
				
			||||||
 | 
							chunkRenderer = new ChunkRenderer(windowInfo.width(), windowInfo.height());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			communicationHandler.establishConnection(serverAddress, serverPort, username);
 | 
								communicationHandler.establishConnection(serverAddress, serverPort, username);
 | 
				
			||||||
			System.out.println("Established connection to the server.");
 | 
								System.out.println("Established connection to the server.");
 | 
				
			||||||
		} catch (IOException e) {
 | 
							} catch (IOException e) {
 | 
				
			||||||
			e.printStackTrace();
 | 
								e.printStackTrace();
 | 
				
			||||||
			running = false;
 | 
								return; // Exit without starting the game.
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		while (running) {
 | 
					
 | 
				
			||||||
			// Do game stuff
 | 
							System.out.println("Waiting for all world data to arrive...");
 | 
				
			||||||
			System.out.println("Running!");
 | 
							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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
package nl.andrewl.aos2_client;
 | 
					package nl.andrewl.aos2_client;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import nl.andrewl.aos_core.Net;
 | 
					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.*;
 | 
				
			||||||
import nl.andrewl.aos_core.net.udp.DatagramInit;
 | 
					import nl.andrewl.aos_core.net.udp.DatagramInit;
 | 
				
			||||||
import nl.andrewl.record_net.Message;
 | 
					import nl.andrewl.record_net.Message;
 | 
				
			||||||
| 
						 | 
					@ -19,12 +20,16 @@ import java.net.Socket;
 | 
				
			||||||
 * methods for sending messages and processing those we receive.
 | 
					 * methods for sending messages and processing those we receive.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
public class CommunicationHandler {
 | 
					public class CommunicationHandler {
 | 
				
			||||||
 | 
						private final Client client;
 | 
				
			||||||
	private Socket socket;
 | 
						private Socket socket;
 | 
				
			||||||
	private DatagramSocket datagramSocket;
 | 
						private DatagramSocket datagramSocket;
 | 
				
			||||||
	private ExtendedDataInputStream in;
 | 
					 | 
				
			||||||
	private ExtendedDataOutputStream out;
 | 
						private ExtendedDataOutputStream out;
 | 
				
			||||||
	private int clientId;
 | 
						private int clientId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public CommunicationHandler(Client client) {
 | 
				
			||||||
 | 
							this.client = client;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public int establishConnection(InetAddress address, int port, String username) throws IOException {
 | 
						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);
 | 
							System.out.printf("Connecting to server at %s, port %d, with username \"%s\"...%n", address, port, username);
 | 
				
			||||||
		if (socket != null && !socket.isClosed()) {
 | 
							if (socket != null && !socket.isClosed()) {
 | 
				
			||||||
| 
						 | 
					@ -32,7 +37,7 @@ public class CommunicationHandler {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		socket = new Socket(address, port);
 | 
							socket = new Socket(address, port);
 | 
				
			||||||
		socket.setSoTimeout(1000);
 | 
							socket.setSoTimeout(1000);
 | 
				
			||||||
		in = Net.getInputStream(socket.getInputStream());
 | 
							ExtendedDataInputStream in = Net.getInputStream(socket.getInputStream());
 | 
				
			||||||
		out = Net.getOutputStream(socket.getOutputStream());
 | 
							out = Net.getOutputStream(socket.getOutputStream());
 | 
				
			||||||
		Net.write(new ConnectRequestMessage(username), out);
 | 
							Net.write(new ConnectRequestMessage(username), out);
 | 
				
			||||||
		Message response = Net.read(in);
 | 
							Message response = Net.read(in);
 | 
				
			||||||
| 
						 | 
					@ -42,8 +47,8 @@ public class CommunicationHandler {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (response instanceof ConnectAcceptMessage acceptMessage) {
 | 
							if (response instanceof ConnectAcceptMessage acceptMessage) {
 | 
				
			||||||
			this.clientId = acceptMessage.clientId();
 | 
								this.clientId = acceptMessage.clientId();
 | 
				
			||||||
			new Thread(new TcpReceiver(in, this::handleMessage)).start();
 | 
					 | 
				
			||||||
			establishDatagramConnection();
 | 
								establishDatagramConnection();
 | 
				
			||||||
 | 
								new Thread(new TcpReceiver(in, this::handleMessage)).start();
 | 
				
			||||||
			new Thread(new UdpReceiver(datagramSocket, this::handleUdpMessage)).start();
 | 
								new Thread(new UdpReceiver(datagramSocket, this::handleUdpMessage)).start();
 | 
				
			||||||
			return acceptMessage.clientId();
 | 
								return acceptMessage.clientId();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
| 
						 | 
					@ -109,6 +114,10 @@ public class CommunicationHandler {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private void handleMessage(Message msg) {
 | 
						private void handleMessage(Message msg) {
 | 
				
			||||||
		System.out.println("Received 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) {
 | 
						private void handleUdpMessage(Message msg, DatagramPacket packet) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +29,11 @@ public class Chunk {
 | 
				
			||||||
		this.position = new Vector3i(cx, cy, cz);
 | 
							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) {
 | 
						public Chunk(Vector3i position) {
 | 
				
			||||||
		this.position = new Vector3i(position);
 | 
							this.position = new Vector3i(position);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,4 +13,8 @@ public record ChunkDataMessage(
 | 
				
			||||||
	public ChunkDataMessage(Chunk chunk) {
 | 
						public ChunkDataMessage(Chunk chunk) {
 | 
				
			||||||
		this(chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z, chunk.getBlocks());
 | 
							this(chunk.getPosition().x, chunk.getPosition().y, chunk.getPosition().z, chunk.getBlocks());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public Chunk toChunk() {
 | 
				
			||||||
 | 
							return new Chunk(cx, cy, cz, blocks);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ public class TcpReceiver implements Runnable {
 | 
				
			||||||
				Message msg = Net.read(in);
 | 
									Message msg = Net.read(in);
 | 
				
			||||||
				messageConsumer.accept(msg);
 | 
									messageConsumer.accept(msg);
 | 
				
			||||||
			} catch (SocketException e) {
 | 
								} catch (SocketException e) {
 | 
				
			||||||
				if (e.getMessage().equals("Socket closed")) {
 | 
									if (e.getMessage().equals("Socket closed") || e.getMessage().equals("Connection reset")) {
 | 
				
			||||||
					running = false;
 | 
										running = false;
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					e.printStackTrace();
 | 
										e.printStackTrace();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@ import java.net.*;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
import java.util.HashMap;
 | 
					import java.util.HashMap;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.Random;
 | 
				
			||||||
import java.util.concurrent.ForkJoinPool;
 | 
					import java.util.concurrent.ForkJoinPool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class Server implements Runnable {
 | 
					public class Server implements Runnable {
 | 
				
			||||||
| 
						 | 
					@ -33,12 +34,15 @@ public class Server implements Runnable {
 | 
				
			||||||
		this.playerClientHandlers = new HashMap<>();
 | 
							this.playerClientHandlers = new HashMap<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Generate world. TODO: do this elsewhere.
 | 
							// Generate world. TODO: do this elsewhere.
 | 
				
			||||||
 | 
							Random rand = new Random(1);
 | 
				
			||||||
		this.world = new World();
 | 
							this.world = new World();
 | 
				
			||||||
		for (int x = -5; x <= 5; x++) {
 | 
							for (int x = -5; x <= 5; x++) {
 | 
				
			||||||
			for (int y = 0; y <= 3; y++) {
 | 
								for (int y = 0; y <= 3; y++) {
 | 
				
			||||||
				for (int z = -3; z <= 3; z++) {
 | 
									for (int z = -3; z <= 3; z++) {
 | 
				
			||||||
					Chunk chunk = new Chunk(x, y, 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);
 | 
										world.addChunk(chunk);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue