NIO networking transition is now functional, has some issues with usernames not syncing properly and some latency issues on real world testing
This commit is contained in:
parent
3e886e5ba8
commit
c9ef43a2a0
23 changed files with 476 additions and 71 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
package net.halbear.Executable;
|
package net.halbear.Executable;
|
||||||
|
|
||||||
|
import com.oracle.svm.core.annotate.Delete;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
|
|
@ -24,6 +25,9 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
public class Server {
|
public class Server {
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Delete
|
||||||
public static Map<UUID, ServerConnectionThread> ConnectedClients = new ConcurrentHashMap<>();
|
public static Map<UUID, ServerConnectionThread> ConnectedClients = new ConcurrentHashMap<>();
|
||||||
public static Map<UUID, String> ClientNames = new ConcurrentHashMap<>();
|
public static Map<UUID, String> ClientNames = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
@ -57,7 +61,11 @@ public class Server {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ProcessOutgoingPackets(){
|
public static void ProcessOutgoingPackets(){
|
||||||
|
Packet packet;
|
||||||
|
ClientSession.ProcessOutboundPackets();
|
||||||
|
while((packet = OutGoingPacketQueue.poll()) != null){
|
||||||
|
ClientSession.HandOutPacket(packet);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
|
@ -94,13 +102,13 @@ public class Server {
|
||||||
public static void StartServer(String[] args) throws IOException {
|
public static void StartServer(String[] args) throws IOException {
|
||||||
|
|
||||||
|
|
||||||
ServerSocket server = new ServerSocket(ServerConnectionThread.ServerPort);
|
|
||||||
Logger.info("\nLaunching New Terrain4J Powered Software!");
|
Logger.info("\nLaunching New Terrain4J Powered Software!");
|
||||||
|
|
||||||
RenderThread.Headless = true;
|
RenderThread.Headless = true;
|
||||||
PrimaryRuntime.IsServer = true;
|
PrimaryRuntime.IsServer = true;
|
||||||
|
|
||||||
if(LegacyNetworking){
|
if(LegacyNetworking){
|
||||||
|
ServerSocket server = new ServerSocket(ServerConnectionThread.ServerPort);
|
||||||
Thread acceptThread = new Thread(() -> {
|
Thread acceptThread = new Thread(() -> {
|
||||||
while(true) {
|
while(true) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -225,15 +233,24 @@ public class Server {
|
||||||
|
|
||||||
AtomicReference<String> PlayerConnections = new AtomicReference<>("");
|
AtomicReference<String> PlayerConnections = new AtomicReference<>("");
|
||||||
|
|
||||||
Server.ConnectedClients.forEach((uuid, client)->{
|
if(LegacyNetworking) {
|
||||||
String Username = "N/A";
|
Server.ConnectedClients.forEach((uuid, client) -> {
|
||||||
if(Server.ClientNames.containsKey(uuid)){
|
String Username = "N/A";
|
||||||
Username = Server.ClientNames.get(uuid);
|
if (Server.ClientNames.containsKey(uuid)) {
|
||||||
}
|
Username = Server.ClientNames.get(uuid);
|
||||||
PlayerConnections.set(PlayerConnections.get() + "\nConnection UUID: " + uuid.toString() + "\n\tIP address -> " + client.getIP() + "\n\tUsername -> " + Username);
|
}
|
||||||
});
|
PlayerConnections.set(PlayerConnections.get() + "\nConnection UUID: " + uuid.toString() + "\n\tIP address -> " + client.getIP() + "\n\tUsername -> " + Username);
|
||||||
|
});
|
||||||
|
|
||||||
PrimaryRuntime.printLog("\nServer Runtime Info:\n\tPlayers Connected: " + Server.ConnectedClients.size() +"\n" + PlayerConnections.get() + "\n\n" + Profiling);
|
PrimaryRuntime.printLog("\nServer Runtime Info:\n\tPlayers Connected: " + Server.ConnectedClients.size() + "\n" + PlayerConnections.get() + "\n\n" + Profiling);
|
||||||
|
} else{
|
||||||
|
ClientSession.GetClientSessionInstances().forEach((uuid, client) -> {
|
||||||
|
String Username = client.GetClientName();
|
||||||
|
PlayerConnections.set(PlayerConnections.get() + "\nConnection Instance UUID: " + uuid.toString() +"\n\tClient UUID: " + client.GetClientUUID() + "\n\tIP address -> " + client.GetIP() + "\n\tUsername -> " + Username);
|
||||||
|
});
|
||||||
|
|
||||||
|
PrimaryRuntime.printLog("\nServer Runtime Info:\n\tPlayers Connected: " + Server.ConnectedClients.size() + "\n" + PlayerConnections.get() + "\n\n" + Profiling);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "stop":
|
case "stop":
|
||||||
case "end":
|
case "end":
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Logic;
|
package net.halbear.Terrain4J.EngineCore.Logic;
|
||||||
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.SettingsMenu;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import net.halbear.Terrain4J.EngineCore.Logic.Physics.WorldPhysicsManager;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.*;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.InstancedPhysicsThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.InstancedPhysicsThread;
|
||||||
import org.joml.Vector2f;
|
import org.joml.Vector2f;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
|
||||||
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
|
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ServerSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ServerSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.GUI.GuiTexture;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.GUI.GuiTexture;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.MaterialData;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.VkModel.MaterialData;
|
||||||
|
|
@ -479,14 +478,16 @@ public class GameCore implements GameLogic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final boolean UseLegacyNetworking = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
|
||||||
float PhysicsFramerate = 24f;
|
float PhysicsFramerate = 24f;
|
||||||
float PhysicsFrameTime = 1000f/PhysicsFramerate;
|
float PhysicsFrameTime = 1000f/PhysicsFramerate;
|
||||||
float DeltaTime = (float)FrameDiffNanoSeconds/(PhysicsFrameTime*1000000f);
|
float DeltaTime = (float)FrameDiffNanoSeconds/(PhysicsFrameTime*1000000f);
|
||||||
if(PrimaryRuntime.IsServer){
|
if(PrimaryRuntime.IsServer){
|
||||||
Server.LegacyCollectIncomingPackets();
|
if(UseLegacyNetworking) Server.LegacyCollectIncomingPackets(); else Server.CollectIncomingPackets();
|
||||||
Server.LegacyProcessIncomingPackets();
|
if(UseLegacyNetworking) Server.LegacyProcessIncomingPackets(); else Server.ProcessIncomingPackets();
|
||||||
|
|
||||||
WorldPhysicsManager.PhysicsTick2(DeltaTime, PhysicsFramerate);
|
WorldPhysicsManager.PhysicsTick2(DeltaTime, PhysicsFramerate);
|
||||||
|
|
||||||
|
|
@ -498,9 +499,10 @@ public class GameCore implements GameLogic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Server.LegacyProcessOutgoingPackets();
|
if(UseLegacyNetworking) Server.LegacyProcessOutgoingPackets(); else Server.ProcessOutgoingPackets();
|
||||||
} else {
|
} else {
|
||||||
ClientSideNetworkUtils.DecodePackets(engineInstance, this, engineInstance.scene());
|
ClientSideNetworkUtils.DecodePackets(engineInstance, this, engineInstance.scene());
|
||||||
|
if(!UseLegacyNetworking) ClientSideNetworkUtils.SendNIOPacketQueue();
|
||||||
WorldPhysicsManager.PhysicsTick2(DeltaTime, PhysicsFramerate);
|
WorldPhysicsManager.PhysicsTick2(DeltaTime, PhysicsFramerate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
||||||
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
|
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.*;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.FastTickThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.MainThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.io.Console;
|
import java.io.Console;
|
||||||
|
|
@ -51,7 +48,7 @@ public class PrimaryRuntime {
|
||||||
public final CPUMonitor cpuProfiler;
|
public final CPUMonitor cpuProfiler;
|
||||||
private static GameLogic gameLogic;
|
private static GameLogic gameLogic;
|
||||||
|
|
||||||
public static ClientConnectionThread ServerCon;
|
public static ClientConnection ServerCon;
|
||||||
public static Thread MultiplayerConnectionThread;
|
public static Thread MultiplayerConnectionThread;
|
||||||
public static GameLogic GetGameCore(){return gameLogic;}
|
public static GameLogic GetGameCore(){return gameLogic;}
|
||||||
|
|
||||||
|
|
@ -84,9 +81,7 @@ public class PrimaryRuntime {
|
||||||
PrimaryThread = new MainThread(engineInstance, appLogic);
|
PrimaryThread = new MainThread(engineInstance, appLogic);
|
||||||
FastThread = new FastTickThread(engineInstance, appLogic);
|
FastThread = new FastTickThread(engineInstance, appLogic);
|
||||||
if(!IsServer) {
|
if(!IsServer) {
|
||||||
ServerCon = new ClientConnectionThread();
|
CreateNewClientConnection();
|
||||||
MultiplayerConnectionThread = new Thread(ServerCon);
|
|
||||||
MultiplayerConnectionThread.start();
|
|
||||||
DrawingThread = new RenderThread(engineInstance, initData, appLogic);
|
DrawingThread = new RenderThread(engineInstance, initData, appLogic);
|
||||||
}
|
}
|
||||||
cpuProfiler = new CPUMonitor();
|
cpuProfiler = new CPUMonitor();
|
||||||
|
|
@ -94,6 +89,15 @@ public class PrimaryRuntime {
|
||||||
Thread.currentThread().setName("Terrain4J Primary Runtime Thread");
|
Thread.currentThread().setName("Terrain4J Primary Runtime Thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static final boolean UseLegacyNetworking = false;
|
||||||
|
public static void CreateNewClientConnection(){
|
||||||
|
Logger.info("Trying to connect");
|
||||||
|
ServerCon = UseLegacyNetworking ? new ClientConnectionThread() : new NIO_ClientConnectionThread(EngineConfig.getInstance().GetServerIP(), EngineConfig.getInstance().GetServerPort());
|
||||||
|
MultiplayerConnectionThread = ServerCon.GetNetworkedThread();
|
||||||
|
ServerCon.start();
|
||||||
|
}
|
||||||
|
|
||||||
public static void RejoinMultiplayer(){
|
public static void RejoinMultiplayer(){
|
||||||
MultiplayerConnectionThread.interrupt();
|
MultiplayerConnectionThread.interrupt();
|
||||||
try{
|
try{
|
||||||
|
|
@ -101,9 +105,7 @@ public class PrimaryRuntime {
|
||||||
} catch (InterruptedException e){
|
} catch (InterruptedException e){
|
||||||
Logger.error("Cant rejoin multiplayer thread: [{}]",e.getMessage());
|
Logger.error("Cant rejoin multiplayer thread: [{}]",e.getMessage());
|
||||||
}
|
}
|
||||||
ServerCon = new ClientConnectionThread();
|
CreateNewClientConnection();
|
||||||
MultiplayerConnectionThread = new Thread(ServerCon);
|
|
||||||
MultiplayerConnectionThread.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StartPingTimer() {
|
public static void StartPingTimer() {
|
||||||
|
|
@ -145,9 +147,7 @@ public class PrimaryRuntime {
|
||||||
return "Connection Error, IsServer Unreachable";
|
return "Connection Error, IsServer Unreachable";
|
||||||
}
|
}
|
||||||
} else if (!ClientSideNetworkUtils.Connected) {
|
} else if (!ClientSideNetworkUtils.Connected) {
|
||||||
ServerCon = new ClientConnectionThread();
|
CreateNewClientConnection();
|
||||||
MultiplayerConnectionThread = new Thread(ServerCon);
|
|
||||||
MultiplayerConnectionThread.start();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return "Connecting...";
|
return "Connecting...";
|
||||||
|
|
@ -201,7 +201,7 @@ public class PrimaryRuntime {
|
||||||
UpdateTickRateThreshold();
|
UpdateTickRateThreshold();
|
||||||
|
|
||||||
PrimaryThread.StartThread();
|
PrimaryThread.StartThread();
|
||||||
DrawingThread.StartThread();
|
if(!IsServer)DrawingThread.StartThread();
|
||||||
FastThread.StartThread();
|
FastThread.StartThread();
|
||||||
|
|
||||||
FrameAccuracy = EngineConfig.getInstance().getAccuracy();
|
FrameAccuracy = EngineConfig.getInstance().getAccuracy();
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIOverlay;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.DeferredSceneRender;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Structure.DisplayToScreen.ForwardSceneRender;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidBody;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
|
import net.halbear.Terrain4J.EngineCore.Logic.Physics.RigidBody.RigidPhysicsController;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.GameChat;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.Gimbal;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.PerformanceOverlay;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.StartMenu;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.GUIs.StartMenu;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DynamicMesh.DynamicTerrainMesh;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DynamicMesh.DynamicTerrainMesh;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Projection.Project3D;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Projection.Project3D;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.ActorElement;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.ActorElement;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.*;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.*;
|
||||||
|
|
@ -417,7 +417,7 @@ public class DeferredSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
if(i < Actors.size()) {
|
if(i < Actors.size()) {
|
||||||
var Actor = Actors.get(i);
|
var Actor = Actors.get(i);
|
||||||
if(Actor != null && Actor.GetPosition() != null) {
|
if(Actor != null && Actor.GetPosition() != null) {
|
||||||
if(Actor instanceof ActorElement &&( !((ActorElement) Actor).RenderOnTopOfPlayer && Objects.equals(((ActorElement) Actor).GetParentID(), ClientConnectionThread.OwnedActorID) || new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
|
if(Actor instanceof ActorElement &&( !((ActorElement) Actor).RenderOnTopOfPlayer && ClientSideNetworkUtils.OwnsActor(((ActorElement) Actor).GetParentID()) || new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
|
||||||
else {
|
else {
|
||||||
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
|
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
|
||||||
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
|
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.ActorElement;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.ActorElement;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.DeferredRendering.MultiRenderTargetAttachments;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.DefaultPipeline;
|
||||||
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.*;
|
import net.halbear.Terrain4J.EngineCore.RenderingAPI.Vulkan.Rendering.Pipeline.Images.*;
|
||||||
|
|
@ -408,7 +408,7 @@ public class ForwardSceneRender implements SceneRenderer {//dynamic rendering
|
||||||
if(i < Actors.size()) {
|
if(i < Actors.size()) {
|
||||||
var Actor = Actors.get(i);
|
var Actor = Actors.get(i);
|
||||||
if(Actor != null) {
|
if(Actor != null) {
|
||||||
if(Actor instanceof ActorElement &&( !((ActorElement) Actor).RenderOnTopOfPlayer && Objects.equals(((ActorElement) Actor).GetParentID(), ClientConnectionThread.OwnedActorID) || new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
|
if(Actor instanceof ActorElement &&( !((ActorElement) Actor).RenderOnTopOfPlayer && ClientSideNetworkUtils.OwnsActor(((ActorElement) Actor).GetParentID())|| new Vector3f().set(Actor.GetPosition()).sub(instance.scene().GetCamera().GetPosition()).absolute().lengthSquared() < 4f)) continue;
|
||||||
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
|
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
|
||||||
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
|
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
|
||||||
int MeshCount = VkMeshList.size();
|
int MeshCount = VkMeshList.size();
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.IScene;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.PlayerActor;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.PlayerActor;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Threads.EngineThread;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -16,6 +17,7 @@ import java.nio.channels.Selector;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
@ -102,9 +104,14 @@ public class ClientSession implements ServerConnection {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String GetClientName(){return ClientName;}
|
||||||
|
|
||||||
|
public String GetIP(){
|
||||||
|
return IPAddress;
|
||||||
|
}
|
||||||
|
|
||||||
public UUID GetInstanceUUID(){return InstanceUUID;}
|
public UUID GetInstanceUUID(){return InstanceUUID;}
|
||||||
public UUID GetClientUUID(){return InstanceUUID;}
|
public UUID GetClientUUID(){return ClientUUID;}
|
||||||
|
|
||||||
public ClientSession(SocketChannel channel, IP_MODIFIER modifier, Selector connectionSelector, SelectionKey selectionKey) {
|
public ClientSession(SocketChannel channel, IP_MODIFIER modifier, Selector connectionSelector, SelectionKey selectionKey) {
|
||||||
this.Channel = channel;
|
this.Channel = channel;
|
||||||
|
|
@ -112,7 +119,19 @@ public class ClientSession implements ServerConnection {
|
||||||
this.connectionSelector = connectionSelector;
|
this.connectionSelector = connectionSelector;
|
||||||
this.selectionKey = selectionKey;
|
this.selectionKey = selectionKey;
|
||||||
this.InstanceUUID = UUID.randomUUID();
|
this.InstanceUUID = UUID.randomUUID();
|
||||||
|
IPAddress = "COULD_NOT_GET";
|
||||||
|
try {
|
||||||
|
IPAddress = NetworkingUtil.GetIPAddress(channel);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println("Failed to get IP address for client session with UUID " + InstanceUUID);
|
||||||
|
e.printStackTrace();
|
||||||
|
Logger.error("Failed to get IP address for client session with UUID " + InstanceUUID);
|
||||||
|
}
|
||||||
ClientSessionInstances.put(this.InstanceUUID,this);
|
ClientSessionInstances.put(this.InstanceUUID,this);
|
||||||
|
PendingClients.add(this);
|
||||||
|
System.out.println("New Client Session Created with UUID " + InstanceUUID);
|
||||||
|
AddOutgoingPacket(new Packet(Packet.QUERY_MAC_ADDRESS).SetTargetType((byte) 0).SetData(new byte[]{0,0,0,0}).SetID("_"));
|
||||||
|
AddOutgoingPacket(new Packet(Packet.QUERY_CLIENT_UUID).SetTargetType((byte) 0).SetData(new byte[]{0,0,0,0}).SetID("_"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean IsValidated(){
|
public boolean IsValidated(){
|
||||||
|
|
@ -123,7 +142,7 @@ public class ClientSession implements ServerConnection {
|
||||||
if(PendingClients.isEmpty()) return;
|
if(PendingClients.isEmpty()) return;
|
||||||
for(int i = 0; i < PendingClients.size(); i++){
|
for(int i = 0; i < PendingClients.size(); i++){
|
||||||
ClientSession Pending = PendingClients.peek();
|
ClientSession Pending = PendingClients.peek();
|
||||||
if(Pending.IsValidated()){
|
if(Pending.IsValidated() && Pending.CheckedUUID_Cache){
|
||||||
ClientSession session = PendingClients.poll();
|
ClientSession session = PendingClients.poll();
|
||||||
if(session == null) continue;
|
if(session == null) continue;
|
||||||
session.InitialiseJoinedClient();
|
session.InitialiseJoinedClient();
|
||||||
|
|
@ -151,7 +170,7 @@ public class ClientSession implements ServerConnection {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InitialiseJoinedClient(){
|
protected void InitialiseJoinedClient(){
|
||||||
Packet PlayerCountPacket = CreatePlayerCountPacket(Server.ConnectedClients.size());
|
Packet PlayerCountPacket = CreatePlayerCountPacket(ClientSessions.size());
|
||||||
Server.OutGoingPacketQueue.add(PlayerCountPacket);
|
Server.OutGoingPacketQueue.add(PlayerCountPacket);
|
||||||
EngineInstance engineInstance = PrimaryRuntime.GetEngineInstance();
|
EngineInstance engineInstance = PrimaryRuntime.GetEngineInstance();
|
||||||
IScene scene = engineInstance.scene();
|
IScene scene = engineInstance.scene();
|
||||||
|
|
@ -178,8 +197,7 @@ public class ClientSession implements ServerConnection {
|
||||||
|
|
||||||
BroadcastCreateActorPacket(player);
|
BroadcastCreateActorPacket(player);
|
||||||
SendPossessActorPacket(player.GetID());
|
SendPossessActorPacket(player.GetID());
|
||||||
Packet UUIDUpdatePacket = CreatePlayerUUIDPacket(ClientUUID,this);
|
Server.OutGoingPacketQueue.add(ServerSideNetworkUtils.CreateUsernameUpdatePacket(ClientUUID, ClientName));
|
||||||
Server.OutGoingPacketQueue.add(UUIDUpdatePacket);
|
|
||||||
Logger.debug("Queued possess packet for joining player's actor: " + player.GetID());
|
Logger.debug("Queued possess packet for joining player's actor: " + player.GetID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,11 +212,10 @@ public class ClientSession implements ServerConnection {
|
||||||
String Data = Packet.DecodeAsString(Inbound.Data);
|
String Data = Packet.DecodeAsString(Inbound.Data);
|
||||||
if(ClientMacAddressCache.containsKey(Data)){
|
if(ClientMacAddressCache.containsKey(Data)){
|
||||||
UUID clientUUID = ClientMacAddressCache.get(Data);
|
UUID clientUUID = ClientMacAddressCache.get(Data);
|
||||||
ClientSessions.put(clientUUID,PendingClients.poll());
|
ClientUUID = clientUUID;
|
||||||
OutboundPacketQueue.add(new Packet(Packet.PACKET_ASSIGN_UUID).SetData(Packet.EncodeString(clientUUID.toString())).SetID(clientUUID.toString()));
|
OutboundPacketQueue.add(new Packet(Packet.PACKET_ASSIGN_UUID).SetData(Packet.EncodeString(clientUUID.toString())).SetID(clientUUID.toString()));
|
||||||
CheckedUUID_Cache = true;
|
ClientSessions.remove(ClientUUID);
|
||||||
Validated = true;
|
OutboundPacketQueue.add(new Packet(Packet.QUERY_CLIENT_UUID).SetData(new byte[]{0,0,0,0}).SetID("_"));
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
CheckedUUID_Cache = true;
|
CheckedUUID_Cache = true;
|
||||||
}
|
}
|
||||||
|
|
@ -206,11 +223,18 @@ public class ClientSession implements ServerConnection {
|
||||||
String Data = Packet.DecodeAsString(Inbound.Data);
|
String Data = Packet.DecodeAsString(Inbound.Data);
|
||||||
ClientUUID = null;
|
ClientUUID = null;
|
||||||
try{
|
try{
|
||||||
UUID newUUID = UUID.fromString(Data);
|
String[] Halves = Data.split(":");
|
||||||
if(ClientSessions.containsKey(newUUID) || ClientMacAddressCache.containsKey(Data)){
|
UUID newUUID = null;
|
||||||
|
if(!Objects.equals(Halves[0], "NULL")) {
|
||||||
|
newUUID = UUID.fromString(Halves[0]);
|
||||||
|
}
|
||||||
|
if(Halves.length > 1) ClientName = Halves[1];
|
||||||
|
else ClientName = newUUID == null ? "NOT_INITIALISED" : "NewPlayer" + newUUID.toString().substring(0,5);
|
||||||
|
if((newUUID == null || ClientSessions.containsKey(newUUID))){
|
||||||
Validated = false;
|
Validated = false;
|
||||||
UUID AssignUUID = UUID.randomUUID();
|
UUID AssignUUID = UUID.randomUUID();
|
||||||
OutboundPacketQueue.add(new Packet(Packet.PACKET_ASSIGN_UUID).SetData(Packet.EncodeString(AssignUUID.toString())).SetID(AssignUUID.toString()));
|
OutboundPacketQueue.add(CreatePlayerUUIDPacket(AssignUUID, this));
|
||||||
|
OutboundPacketQueue.add(new Packet(Packet.QUERY_CLIENT_UUID).SetData(new byte[]{0,0,0,0}).SetID("_"));
|
||||||
} else{
|
} else{
|
||||||
Validated = CheckedUUID_Cache;
|
Validated = CheckedUUID_Cache;
|
||||||
ClientUUID = newUUID;
|
ClientUUID = newUUID;
|
||||||
|
|
@ -238,7 +262,7 @@ public class ClientSession implements ServerConnection {
|
||||||
|
|
||||||
public void ProcessIncomingPacket() {
|
public void ProcessIncomingPacket() {
|
||||||
InBound.flip();
|
InBound.flip();
|
||||||
while (true) {
|
while (EngineThread.running) {
|
||||||
if (InBound.remaining() < 6) {
|
if (InBound.remaining() < 6) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -275,6 +299,8 @@ public class ClientSession implements ServerConnection {
|
||||||
InBound.get(idData);
|
InBound.get(idData);
|
||||||
String id = new String(idData, StandardCharsets.UTF_8);
|
String id = new String(idData, StandardCharsets.UTF_8);
|
||||||
newIncomingPacket.SetID(id);
|
newIncomingPacket.SetID(id);
|
||||||
|
newIncomingPacket.SessionUUID = InstanceUUID;
|
||||||
|
newIncomingPacket.ClientUUID = ClientUUID;
|
||||||
InboundPacketQueue.add(newIncomingPacket);
|
InboundPacketQueue.add(newIncomingPacket);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.ServerNetworking;
|
package net.halbear.Terrain4J.EngineCore.ServerNetworking;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.Strictness;
|
||||||
|
import com.google.gson.stream.JsonReader;
|
||||||
import net.halbear.Executable.Server;
|
import net.halbear.Executable.Server;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||||
|
|
@ -11,14 +14,17 @@ import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
|
import net.halbear.Terrain4J.EngineCore.Main.Scene.*;
|
||||||
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
import net.halbear.Terrain4J.EngineCore.Threads.ClientConnectionThread;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.Threads.NIO_ClientConnectionThread;
|
||||||
import org.joml.Quaternionf;
|
import org.joml.Quaternionf;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.tinylog.Logger;
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
import java.io.*;
|
||||||
import java.io.DataOutputStream;
|
import java.net.NetworkInterface;
|
||||||
import java.io.IOException;
|
import java.net.SocketException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
@ -30,17 +36,86 @@ public class ClientSideNetworkUtils {
|
||||||
public static final Queue<Packet> OutGoingPacketQueue = new ConcurrentLinkedQueue<>();
|
public static final Queue<Packet> OutGoingPacketQueue = new ConcurrentLinkedQueue<>();
|
||||||
public static final Queue<Packet> IncomingPacketQueue = new ConcurrentLinkedQueue<>();
|
public static final Queue<Packet> IncomingPacketQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
private static final Map<String, UUID> ServerClientUUIDs = new ConcurrentHashMap<>();
|
||||||
|
private static final String CachePath = "resources/ProgramResources/ServerCache/UUIDs.json";
|
||||||
|
private static final Queue<UUIDCache> UUIDCacheQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
public static void CacheUUID(UUID uuid, String ServerIP){
|
||||||
|
UUIDCacheQueue.add(new UUIDCache(ServerIP, uuid.toString()));
|
||||||
|
ServerClientUUIDs.put(ServerIP, uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendNIOPacketQueue(){
|
||||||
|
while(!OutGoingPacketQueue.isEmpty()){
|
||||||
|
Packet packet = OutGoingPacketQueue.poll();
|
||||||
|
NIO_ClientConnectionThread Connection = NIO_ClientConnectionThread.GetInstance();
|
||||||
|
if(packet != null) {
|
||||||
|
Connection.SendPacket(packet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static{
|
||||||
|
if(Files.exists(Path.of(CachePath))) {
|
||||||
|
String FileContents = "NOT_READ";
|
||||||
|
try{
|
||||||
|
FileContents = Files.readString(Path.of(CachePath), StandardCharsets.UTF_8);
|
||||||
|
} catch (IOException e){
|
||||||
|
Logger.error("Error reading UUID cache file: [{}]", e.getMessage());
|
||||||
|
}
|
||||||
|
if(!FileContents.equals("NOT_READ")) {
|
||||||
|
Gson parser = new Gson();
|
||||||
|
try (JsonReader reader = new JsonReader(new StringReader(FileContents))) {
|
||||||
|
reader.setStrictness(Strictness.LENIENT);
|
||||||
|
|
||||||
|
while (reader.hasNext()) {
|
||||||
|
UUIDCache user = parser.fromJson(reader, UUIDCache.class);
|
||||||
|
UUID uuid = null;
|
||||||
|
try {
|
||||||
|
uuid = UUID.fromString(user.getClientUUID());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
Logger.error("Invalid UUID in cache file: [{}]", user.getClientUUID());
|
||||||
|
}
|
||||||
|
if(uuid != null) {
|
||||||
|
ServerClientUUIDs.put(user.getServerIP(), uuid);
|
||||||
|
UUIDCacheQueue.add(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.error("Error parsing UUID cache file: [{}]", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
try {
|
||||||
|
Files.createFile(Path.of(CachePath));
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.error("Could not create UUID cache file: [{}]", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveUUIDCache(){
|
||||||
|
try (FileWriter writer = new FileWriter(CachePath)) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
gson.toJson(UUIDCacheQueue, writer);
|
||||||
|
} catch (IOException e) {
|
||||||
|
Logger.error("Error saving UUID cache file: [{}]", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean Connected = false;
|
public static boolean Connected = false;
|
||||||
public static boolean pinging = false;
|
public static boolean pinging = false;
|
||||||
public static String ServerIP = "localhost";
|
public static String ServerIP = "localhost";
|
||||||
public static String ServerMessage = "Offline";
|
public static String ServerMessage = "Offline";
|
||||||
public static String clientUUID = null;
|
public static String clientUUID = null;
|
||||||
|
public static UUID ClientUUID = null;
|
||||||
private static final Map<String, Actor> NetworkOwnedActors = new ConcurrentHashMap<>();
|
private static final Map<String, Actor> NetworkOwnedActors = new ConcurrentHashMap<>();
|
||||||
private static String PlayerControlledActorID = null;
|
private static String PlayerControlledActorID = null;
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static String OwnedActorID = "NULL";
|
public static String OwnedActorID = "NULL";
|
||||||
public static String PendingPossessActorID = "NULL";
|
public static String PendingPossessActorID = "NULL";
|
||||||
public static int PlayersOnline = 0;
|
public static int PlayersOnline = 0;
|
||||||
|
public static String MacAddress = null;
|
||||||
|
|
||||||
public static boolean IsPlayerControlledActor(String actorID){
|
public static boolean IsPlayerControlledActor(String actorID){
|
||||||
return PlayerControlledActorID.equals(actorID);
|
return PlayerControlledActorID.equals(actorID);
|
||||||
|
|
@ -106,6 +181,43 @@ public class ClientSideNetworkUtils {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static{
|
||||||
|
FetchMacAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void FetchMacAddress(){
|
||||||
|
try {
|
||||||
|
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
|
||||||
|
|
||||||
|
for (NetworkInterface netInterface : Collections.list(interfaces)) {
|
||||||
|
if (netInterface.isLoopback() || !netInterface.isUp()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] MacAddress = netInterface.getHardwareAddress();
|
||||||
|
if (MacAddress != null) {
|
||||||
|
ClientSideNetworkUtils.MacAddress = FormatMacAddress(MacAddress);
|
||||||
|
Logger.info("Interface: %-10s | MAC: %s%n",
|
||||||
|
netInterface.getDisplayName(),
|
||||||
|
FormatMacAddress(MacAddress));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (SocketException e) {
|
||||||
|
Logger.error("Error retrieving network interfaces: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String FormatMacAddress(byte[] mac) {
|
||||||
|
StringBuilder StringBuilder = new StringBuilder();
|
||||||
|
for (int i = 0; i < mac.length; i++) {
|
||||||
|
StringBuilder.append(String.format("%02X", mac[i]));
|
||||||
|
if (i < mac.length - 1) {
|
||||||
|
StringBuilder.append("-");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return StringBuilder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
public static final Map<Byte, Boolean> BypassNullTargets = new HashMap<>();
|
public static final Map<Byte, Boolean> BypassNullTargets = new HashMap<>();
|
||||||
|
|
||||||
static{
|
static{
|
||||||
|
|
@ -118,6 +230,8 @@ public class ClientSideNetworkUtils {
|
||||||
BypassNullTargets.put(Packet.PACKET_FIRE_RESULT, true);
|
BypassNullTargets.put(Packet.PACKET_FIRE_RESULT, true);
|
||||||
BypassNullTargets.put(Packet.GAME_CHAT_DATA_PACKET, true);
|
BypassNullTargets.put(Packet.GAME_CHAT_DATA_PACKET, true);
|
||||||
BypassNullTargets.put(Packet.PACKET_UPDATE_PLAYER_DISPLAY_NAME, true);
|
BypassNullTargets.put(Packet.PACKET_UPDATE_PLAYER_DISPLAY_NAME, true);
|
||||||
|
BypassNullTargets.put(Packet.QUERY_MAC_ADDRESS, true);
|
||||||
|
BypassNullTargets.put(Packet.QUERY_CLIENT_UUID, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DecodePackets(EngineInstance engineInstance, GameCore gameCore, IScene scene){
|
public static void DecodePackets(EngineInstance engineInstance, GameCore gameCore, IScene scene){
|
||||||
|
|
@ -285,6 +399,16 @@ public class ClientSideNetworkUtils {
|
||||||
if(PlayerNameCached) PlayerName = Server.ClientNames.get(chat.clientFrom());
|
if(PlayerNameCached) PlayerName = Server.ClientNames.get(chat.clientFrom());
|
||||||
GameChats.put(chat,PlayerName);
|
GameChats.put(chat,PlayerName);
|
||||||
break;
|
break;
|
||||||
|
case Packet.QUERY_CLIENT_UUID:
|
||||||
|
Logger.info("Querying UUID");
|
||||||
|
CreateUUIDQueryPacket();
|
||||||
|
break;
|
||||||
|
case Packet.QUERY_MAC_ADDRESS:
|
||||||
|
Logger.info("Querying MAC Address");
|
||||||
|
if(MacAddress == null) FetchMacAddress();
|
||||||
|
if(MacAddress == null) break;
|
||||||
|
CreateMacAddressPacket(MacAddress);
|
||||||
|
break;
|
||||||
case Packet.PACKET_DESTROY_ACTOR:
|
case Packet.PACKET_DESTROY_ACTOR:
|
||||||
GameChats.put(new GameChat(true, UUID.randomUUID(),"Destroying Actor " + packet.TargetID, Date.from(Instant.now())),"Server");
|
GameChats.put(new GameChat(true, UUID.randomUUID(),"Destroying Actor " + packet.TargetID, Date.from(Instant.now())),"Server");
|
||||||
Logger.debug("Destroying Actor [{}]", packet.TargetID);
|
Logger.debug("Destroying Actor [{}]", packet.TargetID);
|
||||||
|
|
@ -311,6 +435,14 @@ public class ClientSideNetworkUtils {
|
||||||
case Packet.PACKET_ASSIGN_UUID:
|
case Packet.PACKET_ASSIGN_UUID:
|
||||||
Logger.debug("decoding UUID packet");
|
Logger.debug("decoding UUID packet");
|
||||||
clientUUID = Packet.DecodeAsString(packet.Data);
|
clientUUID = Packet.DecodeAsString(packet.Data);
|
||||||
|
UUID uuidOfClient = null;
|
||||||
|
try{
|
||||||
|
uuidOfClient = UUID.fromString(clientUUID);
|
||||||
|
} catch (Exception e){}
|
||||||
|
if(uuidOfClient != null) {
|
||||||
|
CacheUUID(uuidOfClient, ServerIP);
|
||||||
|
ClientUUID = uuidOfClient;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case Packet.PACKET_FIRE_RESULT:
|
case Packet.PACKET_FIRE_RESULT:
|
||||||
//Logger.debug("Fire Packet Recieved" );//
|
//Logger.debug("Fire Packet Recieved" );//
|
||||||
|
|
@ -332,6 +464,16 @@ public class ClientSideNetworkUtils {
|
||||||
|
|
||||||
public static int ServerPort = 25565;
|
public static int ServerPort = 25565;
|
||||||
|
|
||||||
|
public static void SetServerIP(String ServerIP, Thread serverThread){
|
||||||
|
if(Connected){
|
||||||
|
Connected = false;
|
||||||
|
serverThread.interrupt();
|
||||||
|
ClientSideNetworkUtils.ServerIP = ServerIP;
|
||||||
|
PrimaryRuntime.CreateNewClientConnection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static void LegacySetServerIP(String ServerIP, Thread serverThread){
|
public static void LegacySetServerIP(String ServerIP, Thread serverThread){
|
||||||
if(Connected){
|
if(Connected){
|
||||||
|
|
@ -352,6 +494,22 @@ public class ClientSideNetworkUtils {
|
||||||
OutGoingPacketQueue.add(packet);
|
OutGoingPacketQueue.add(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void CreateUUIDQueryPacket(){
|
||||||
|
Packet packet = new Packet(Packet.QUERY_CLIENT_UUID);
|
||||||
|
packet.SetTargetType((byte) 0);
|
||||||
|
packet.SetData(Packet.EncodeString( (ClientUUID == null ? "NULL" : ClientUUID.toString()) + ":" + EngineConfig.getInstance().GetUserDisplayName()));
|
||||||
|
packet.SetID("NULL");
|
||||||
|
OutGoingPacketQueue.add(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CreateMacAddressPacket(String Address){
|
||||||
|
Packet packet = new Packet(Packet.QUERY_MAC_ADDRESS);
|
||||||
|
packet.SetTargetType((byte) 0);
|
||||||
|
packet.SetData(Packet.EncodeString(Address));
|
||||||
|
packet.SetID("NULL");
|
||||||
|
OutGoingPacketQueue.add(packet);
|
||||||
|
}
|
||||||
|
|
||||||
public static void CreateGameChatPacket(String chatMessage){
|
public static void CreateGameChatPacket(String chatMessage){
|
||||||
Packet packet = new Packet(Packet.GAME_CHAT_DATA_PACKET);
|
Packet packet = new Packet(Packet.GAME_CHAT_DATA_PACKET);
|
||||||
packet.SetTargetType((byte) 0);
|
packet.SetTargetType((byte) 0);
|
||||||
|
|
@ -439,6 +597,16 @@ public class ClientSideNetworkUtils {
|
||||||
private static final boolean UseLegacyConnection = false;
|
private static final boolean UseLegacyConnection = false;
|
||||||
|
|
||||||
public static synchronized void Reconnect() {
|
public static synchronized void Reconnect() {
|
||||||
|
Logger.debug("Reconnecting");
|
||||||
|
Reconnect = true;
|
||||||
|
NIO_ClientConnectionThread.GetInstance().Disconnect();
|
||||||
|
Connected = false;
|
||||||
|
PrimaryRuntime.RejoinMultiplayer();
|
||||||
|
PrimaryRuntime.GetEngineInstance().scene().Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
public static synchronized void LegacyReconnect() {
|
||||||
Logger.debug("Reconnecting");
|
Logger.debug("Reconnecting");
|
||||||
Reconnect = true;
|
Reconnect = true;
|
||||||
if(UseLegacyConnection) {
|
if(UseLegacyConnection) {
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ public class ServerSideNetworkUtils {
|
||||||
//to be implemented later
|
//to be implemented later
|
||||||
break;
|
break;
|
||||||
case Packet.PACKET_UPDATE_MODEL_ID:
|
case Packet.PACKET_UPDATE_MODEL_ID:
|
||||||
if(!packet.TargetID.equals(ConnectedClients.get(packet.SessionUUID).OwnedActorID)) {
|
if(!(sender.OwnsActor(packet.TargetID))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Packet ReboundPacket = CreateUpdateModelIDPacket(packet.TargetID, Packet.DecodeAsString(packet.Data));
|
Packet ReboundPacket = CreateUpdateModelIDPacket(packet.TargetID, Packet.DecodeAsString(packet.Data));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.ServerNetworking;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
public class UUIDCache {
|
||||||
|
@SerializedName("server_ip")
|
||||||
|
private String ServerIP;
|
||||||
|
@SerializedName("client_uuid")
|
||||||
|
private String ClientUUID;
|
||||||
|
|
||||||
|
public UUIDCache(String serverIP, String clientUUID) {
|
||||||
|
this.ServerIP = serverIP;
|
||||||
|
this.ClientUUID = clientUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerIP() {
|
||||||
|
return ServerIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientUUID() {
|
||||||
|
return ClientUUID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package net.halbear.Terrain4J.EngineCore.Threads;
|
||||||
|
|
||||||
|
public interface ClientConnection extends Runnable{
|
||||||
|
public void start();
|
||||||
|
public Thread GetNetworkedThread();
|
||||||
|
}
|
||||||
|
|
@ -29,22 +29,36 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import static net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils.*;
|
import static net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils.*;
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public class ClientConnectionThread implements Runnable{
|
@Delete
|
||||||
|
public class ClientConnectionThread implements ClientConnection{
|
||||||
|
|
||||||
public static Socket SocketToServer;
|
public static Socket SocketToServer;
|
||||||
public static DataOutputStream outToServer;
|
public static DataOutputStream outToServer;
|
||||||
public static DataInputStream in;
|
public static DataInputStream in;
|
||||||
|
private final Thread NetworkThread;
|
||||||
|
|
||||||
public ClientConnectionThread(){
|
public ClientConnectionThread(){
|
||||||
Connected = true;
|
Connected = true;
|
||||||
|
NetworkThread = new Thread(this);
|
||||||
|
NetworkThread.setName("Terrain4J Legacy Client Network Thread");
|
||||||
|
NetworkThread.setDaemon(true);
|
||||||
try {
|
try {
|
||||||
SocketToServer = new Socket(ServerIP, ServerPort);
|
SocketToServer = new Socket(ServerIP, ServerPort);
|
||||||
SocketToServer.setSoTimeout(5);
|
SocketToServer.setSoTimeout(5);
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Connected = false;
|
Connected = false;
|
||||||
//e.printStackTrace();
|
//e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public void start() {
|
||||||
|
NetworkThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Thread GetNetworkedThread() {
|
||||||
|
return NetworkThread;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,28 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Threads;
|
package net.halbear.Terrain4J.EngineCore.Threads;
|
||||||
|
|
||||||
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils;
|
||||||
|
import net.halbear.Terrain4J.EngineCore.ServerNetworking.Packet;
|
||||||
|
import org.tinylog.Logger;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.channels.SelectionKey;
|
import java.nio.channels.SelectionKey;
|
||||||
import java.nio.channels.Selector;
|
import java.nio.channels.Selector;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
public class NIO_ClientConnectionThread implements Runnable {
|
import static net.halbear.Terrain4J.EngineCore.ServerNetworking.ClientSideNetworkUtils.SaveUUIDCache;
|
||||||
|
|
||||||
|
public class NIO_ClientConnectionThread implements ClientConnection {
|
||||||
|
|
||||||
|
public static NIO_ClientConnectionThread Instance;
|
||||||
|
|
||||||
|
public static NIO_ClientConnectionThread GetInstance(){ return Instance;}
|
||||||
|
|
||||||
private final ByteBuffer InBound = ByteBuffer.allocateDirect(4096);
|
private final ByteBuffer InBound = ByteBuffer.allocateDirect(4096);
|
||||||
private final Queue<ByteBuffer> OutBoundQueue = new ConcurrentLinkedQueue<>();
|
private final Queue<ByteBuffer> OutBoundQueue = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
|
|
@ -16,14 +31,14 @@ public class NIO_ClientConnectionThread implements Runnable {
|
||||||
|
|
||||||
private final Thread NetworkThread;
|
private final Thread NetworkThread;
|
||||||
|
|
||||||
private Selector Selector;
|
private Selector NetworkSelector;
|
||||||
private SocketChannel ClientChannel;
|
private SocketChannel ClientChannel;
|
||||||
private SelectionKey ChannelKey;
|
private SelectionKey ChannelKey;
|
||||||
|
|
||||||
public NIO_ClientConnectionThread(String ServerAddress, int ServerPort) {
|
public NIO_ClientConnectionThread(String ServerAddress, int ServerPort) {
|
||||||
this.ServerIP = ServerAddress;
|
this.ServerIP = ServerAddress;
|
||||||
this.ServerPort = ServerPort;
|
this.ServerPort = ServerPort;
|
||||||
|
NIO_ClientConnectionThread.Instance = this;
|
||||||
NetworkThread = new Thread(this);
|
NetworkThread = new Thread(this);
|
||||||
NetworkThread.setName("Terrain4J Client Network Thread");
|
NetworkThread.setName("Terrain4J Client Network Thread");
|
||||||
NetworkThread.setDaemon(true);
|
NetworkThread.setDaemon(true);
|
||||||
|
|
@ -34,7 +49,142 @@ public class NIO_ClientConnectionThread implements Runnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public Thread GetNetworkedThread() {
|
||||||
|
return NetworkThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConnectToServer(SelectionKey key) throws IOException {
|
||||||
|
if (ClientChannel.isConnectionPending()) {
|
||||||
|
if (ClientChannel.finishConnect()) {
|
||||||
|
ClientSideNetworkUtils.Connected = true;
|
||||||
|
this.ChannelKey = key;
|
||||||
|
key.interestOps(SelectionKey.OP_READ);
|
||||||
|
} else {
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
NetworkSelector = Selector.open();
|
||||||
|
ClientChannel = SocketChannel.open();
|
||||||
|
ClientChannel.configureBlocking(false);
|
||||||
|
|
||||||
|
ClientChannel.connect(new InetSocketAddress(ServerIP, ServerPort));
|
||||||
|
|
||||||
|
ClientChannel.register(NetworkSelector, SelectionKey.OP_CONNECT);
|
||||||
|
|
||||||
|
while (ClientChannel.isOpen() && EngineThread.running) {
|
||||||
|
NetworkSelector.select();
|
||||||
|
|
||||||
|
Iterator<SelectionKey> it = NetworkSelector.selectedKeys().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
SelectionKey key = it.next();
|
||||||
|
it.remove();
|
||||||
|
|
||||||
|
if (!key.isValid()) continue;
|
||||||
|
|
||||||
|
if (key.isConnectable()) {
|
||||||
|
ConnectToServer(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.isReadable()) {
|
||||||
|
HandleRead();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.isWritable()) {
|
||||||
|
HandleWrite();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Network client error: " + e.getMessage());
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleWrite() throws IOException {
|
||||||
|
while (!OutBoundQueue.isEmpty()) {
|
||||||
|
ByteBuffer buffer = OutBoundQueue.peek();
|
||||||
|
ClientChannel.write(buffer);
|
||||||
|
|
||||||
|
if (buffer.hasRemaining()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OutBoundQueue.poll();
|
||||||
|
}
|
||||||
|
ChannelKey.interestOps(ChannelKey.interestOps() & ~SelectionKey.OP_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SendPacket(Packet outPacket) {
|
||||||
|
byte[] dataToSend = Packet.GetOutgoingData(outPacket);
|
||||||
|
OutBoundQueue.add(ByteBuffer.wrap(dataToSend));
|
||||||
|
|
||||||
|
if (ChannelKey != null && NetworkSelector != null) {
|
||||||
|
ChannelKey.interestOps(ChannelKey.interestOps() | SelectionKey.OP_WRITE);
|
||||||
|
NetworkSelector.wakeup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Disconnect() {
|
||||||
|
SaveUUIDCache();
|
||||||
|
try {
|
||||||
|
if (ClientChannel != null) ClientChannel.close();
|
||||||
|
if (NetworkSelector != null) NetworkSelector.close();
|
||||||
|
Logger.info("Client network loop cleanly shut down.");
|
||||||
|
} catch (IOException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleRead() throws IOException {
|
||||||
|
int bytesRead = ClientChannel.read(InBound);
|
||||||
|
if (bytesRead == -1) {
|
||||||
|
System.out.println("Disconnected by remote server.");
|
||||||
|
Disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InBound.flip();
|
||||||
|
while (EngineThread.running) {
|
||||||
|
if (InBound.remaining() < 6) break;
|
||||||
|
|
||||||
|
InBound.mark();
|
||||||
|
byte packetTypeByte = InBound.get();
|
||||||
|
byte targetType = InBound.get();
|
||||||
|
int dataLength = InBound.getInt();
|
||||||
|
|
||||||
|
if (InBound.remaining() < dataLength + 4) {
|
||||||
|
InBound.reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int currentPos = InBound.position();
|
||||||
|
InBound.position(currentPos + dataLength);
|
||||||
|
int idLength = InBound.getInt();
|
||||||
|
InBound.position(currentPos);
|
||||||
|
|
||||||
|
if (InBound.remaining() < dataLength + 4 + idLength) {
|
||||||
|
InBound.reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Packet serverPacket = new Packet(packetTypeByte);
|
||||||
|
serverPacket.SetTargetType(targetType);
|
||||||
|
|
||||||
|
byte[] incomingData = new byte[dataLength];
|
||||||
|
InBound.get(incomingData);
|
||||||
|
serverPacket.Data = incomingData;
|
||||||
|
|
||||||
|
InBound.getInt();
|
||||||
|
|
||||||
|
byte[] idData = new byte[idLength];
|
||||||
|
InBound.get(idData);
|
||||||
|
serverPacket.SetID(new String(idData, StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
ClientSideNetworkUtils.IncomingPacketQueue.add(serverPacket);
|
||||||
|
}
|
||||||
|
InBound.compact();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package net.halbear.Terrain4J.EngineCore.Threads;
|
package net.halbear.Terrain4J.EngineCore.Threads;
|
||||||
|
|
||||||
|
import com.oracle.svm.core.annotate.Delete;
|
||||||
import net.halbear.Executable.Server;
|
import net.halbear.Executable.Server;
|
||||||
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
import net.halbear.Terrain4J.EngineCore.Logic.EngineInstance;
|
||||||
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
import net.halbear.Terrain4J.EngineCore.Main.GameCore;
|
||||||
|
|
@ -22,6 +23,7 @@ import static net.halbear.Executable.Server.LegacyRemoveClient;
|
||||||
import static net.halbear.Terrain4J.EngineCore.ServerNetworking.ServerSideNetworkUtils.*;
|
import static net.halbear.Terrain4J.EngineCore.ServerNetworking.ServerSideNetworkUtils.*;
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@Delete
|
||||||
public class ServerConnectionThread implements Runnable, ServerConnection {
|
public class ServerConnectionThread implements Runnable, ServerConnection {
|
||||||
public String OwnedActorID;
|
public String OwnedActorID;
|
||||||
private final Socket clientSocket;
|
private final Socket clientSocket;
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,12 @@ public class ServerMultiClientConnectionThread implements Runnable {
|
||||||
private final Queue<Runnable> taskQueue = new ConcurrentLinkedQueue<>();
|
private final Queue<Runnable> taskQueue = new ConcurrentLinkedQueue<>();
|
||||||
private Thread ConnectionThread;
|
private Thread ConnectionThread;
|
||||||
|
|
||||||
|
static int ThreadNumbers =0;
|
||||||
|
|
||||||
public ServerMultiClientConnectionThread() throws IOException {
|
public ServerMultiClientConnectionThread() throws IOException {
|
||||||
this.selector = Selector.open();
|
this.selector = Selector.open();
|
||||||
ConnectionThread = new Thread(this);
|
ConnectionThread = new Thread(this);
|
||||||
|
ConnectionThread.setName("Server NIO Connection Manager [" + ThreadNumbers++ + "]");
|
||||||
ConnectionThread.setDaemon(true);
|
ConnectionThread.setDaemon(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,11 +59,13 @@ public class ServerMultiClientConnectionThread implements Runnable {
|
||||||
}
|
}
|
||||||
IP_MODIFIER modifier = IP_STATUS_REGISTRY.getOrDefault(IPAddress, IP_MODIFIER.User);
|
IP_MODIFIER modifier = IP_STATUS_REGISTRY.getOrDefault(IPAddress, IP_MODIFIER.User);
|
||||||
if (IP_STATUS_ALLOW_CONNECTION.containsKey(modifier) && IP_STATUS_ALLOW_CONNECTION.get(modifier)) {
|
if (IP_STATUS_ALLOW_CONNECTION.containsKey(modifier) && IP_STATUS_ALLOW_CONNECTION.get(modifier)) {
|
||||||
|
String IP = IPAddress;
|
||||||
taskQueue.add(() -> {
|
taskQueue.add(() -> {
|
||||||
try {
|
try {
|
||||||
channel.configureBlocking(false);
|
channel.configureBlocking(false);
|
||||||
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
|
SelectionKey key = channel.register(selector, SelectionKey.OP_READ);
|
||||||
key.attach(new ClientSession(channel, modifier, selector, key));
|
key.attach(new ClientSession(channel, modifier, selector, key));
|
||||||
|
System.out.println("Accepted new connection from " + IP);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
CloseChannel(channel);
|
CloseChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ public class ServerSelectorMasterThread implements Runnable {
|
||||||
|
|
||||||
int index = Math.abs(ManagerIterator.getAndIncrement() % CONNECTION_MANAGER_COUNT);
|
int index = Math.abs(ManagerIterator.getAndIncrement() % CONNECTION_MANAGER_COUNT);
|
||||||
ServerMultiClientConnectionThread targetWorker = ConnectionManagers[index];
|
ServerMultiClientConnectionThread targetWorker = ConnectionManagers[index];
|
||||||
|
System.out.println("Delegating new Connection [ " + clientChannel.socket().getInetAddress().getHostAddress() + "] to Connection Manager " + index);
|
||||||
targetWorker.acceptNewChannel(clientChannel);
|
targetWorker.acceptNewChannel(clientChannel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +75,7 @@ public class ServerSelectorMasterThread implements Runnable {
|
||||||
serverChannel.bind(new InetSocketAddress(PORT));
|
serverChannel.bind(new InetSocketAddress(PORT));
|
||||||
serverChannel.configureBlocking(false);
|
serverChannel.configureBlocking(false);
|
||||||
serverChannel.register(MasterSelector, SelectionKey.OP_ACCEPT);
|
serverChannel.register(MasterSelector, SelectionKey.OP_ACCEPT);
|
||||||
System.out.println("Boss started on port " + PORT + ". 7 Workers ready to scale to 128+ connections.");
|
System.out.println("Server Master Thread started on port " + PORT + " with " + CONNECTION_MANAGER_COUNT + " connection managers.");
|
||||||
|
|
||||||
ManagerIterator = new AtomicInteger(0);
|
ManagerIterator = new AtomicInteger(0);
|
||||||
acceptThread.start();
|
acceptThread.start();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#created new properties file
|
#created new properties file
|
||||||
#Tue Aug 18 20:22:42 BST 2026
|
#Fri Aug 21 19:04:58 BST 2026
|
||||||
AlphaToCoverage=false
|
AlphaToCoverage=false
|
||||||
Debug_Shaders=false
|
Debug_Shaders=false
|
||||||
DefaultTexturePath=resources/EngineResources/Texture/NoTexture.png
|
DefaultTexturePath=resources/EngineResources/Texture/NoTexture.png
|
||||||
|
|
@ -28,11 +28,11 @@ frame_accuracy=0
|
||||||
main_thread_tickrate=120
|
main_thread_tickrate=120
|
||||||
master_tick_rate=240
|
master_tick_rate=240
|
||||||
server=false
|
server=false
|
||||||
server_port=25565
|
server_ip=gameserver.halbear.net
|
||||||
server_ip=localhost
|
server_port=25566
|
||||||
throttle_accuracy=4000000
|
throttle_accuracy=4000000
|
||||||
throttle_on_unfocus=false
|
throttle_on_unfocus=false
|
||||||
user_display_name=halbear
|
user_display_name=The sigmarest of sigmas
|
||||||
vkValidated=true
|
vkValidated=true
|
||||||
vsync=false
|
vsync=false
|
||||||
z_far_plane=0.1f
|
z_far_plane=0.1f
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue