From e7b5ed3df437549b2f191de4608d53bac07e2c03 Mon Sep 17 00:00:00 2001 From: OLEGSHA Date: Sun, 20 Dec 2020 18:05:10 +0300 Subject: [PATCH] Added Player server class - Removed CommsChannel Roles - Replaced with Client class hierarchy on the server - Added ClientPlayer - Added Player (a new server class holding all objects related to a player) - Player class in common renamed to PlayerData - Added PlayerManager for the server --- .../progressia/client/ClientState.java | 3 +- .../client/comms/ServerCommsChannel.java | 4 -- .../client/comms/localhost/LocalClient.java | 16 +++-- .../localhost/LocalServerCommsChannel.java | 4 +- .../client/graphics/world/LocalPlayer.java | 4 +- .../progressia/common/comms/CommsChannel.java | 21 ------- .../common/util/CoordinatePacker.java | 4 ++ .../world/{Player.java => PlayerData.java} | 4 +- .../ru/windcorp/progressia/server/Player.java | 54 +++++++++++++++++ .../progressia/server/PlayerManager.java | 44 ++++++++++++++ .../ru/windcorp/progressia/server/Server.java | 10 ++++ .../progressia/server/comms/Client.java | 3 +- .../progressia/server/comms/ClientChat.java | 9 +++ .../server/comms/ClientManager.java | 60 +++++++++++++------ .../progressia/server/comms/ClientPlayer.java | 11 ++++ .../comms/DefaultServerCommsListener.java | 3 +- .../windcorp/progressia/test/TestContent.java | 8 ++- 17 files changed, 201 insertions(+), 61 deletions(-) rename src/main/java/ru/windcorp/progressia/common/world/{Player.java => PlayerData.java} (77%) create mode 100644 src/main/java/ru/windcorp/progressia/server/Player.java create mode 100644 src/main/java/ru/windcorp/progressia/server/PlayerManager.java create mode 100644 src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java create mode 100644 src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java diff --git a/src/main/java/ru/windcorp/progressia/client/ClientState.java b/src/main/java/ru/windcorp/progressia/client/ClientState.java index a7f9a08..f6e6959 100644 --- a/src/main/java/ru/windcorp/progressia/client/ClientState.java +++ b/src/main/java/ru/windcorp/progressia/client/ClientState.java @@ -7,6 +7,7 @@ import ru.windcorp.progressia.client.graphics.world.LayerWorld; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.server.ServerState; import ru.windcorp.progressia.test.LayerTestGUI; +import ru.windcorp.progressia.test.TestContent; public class ClientState { @@ -32,7 +33,7 @@ public class ClientState { // world.tmp_generate(); - channel.connect(); + channel.connect(TestContent.PLAYER_LOGIN); setInstance(client); diff --git a/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java b/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java index e0cbdd3..e78d8e0 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/ServerCommsChannel.java @@ -4,8 +4,4 @@ import ru.windcorp.progressia.common.comms.CommsChannel; public abstract class ServerCommsChannel extends CommsChannel { - public ServerCommsChannel(Role... roles) { - super(roles); - } - } diff --git a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java index 37235b0..56e1dd6 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalClient.java @@ -3,17 +3,25 @@ package ru.windcorp.progressia.client.comms.localhost; import java.io.IOException; import ru.windcorp.progressia.common.comms.packets.Packet; -import ru.windcorp.progressia.server.comms.Client; +import ru.windcorp.progressia.server.comms.ClientPlayer; -public class LocalClient extends Client { +public class LocalClient extends ClientPlayer { private final LocalServerCommsChannel serverComms; + + private final String login; - public LocalClient(int id, LocalServerCommsChannel serverComms) { - super(id, Role.GAME, Role.CHAT); + public LocalClient(int id, String login, LocalServerCommsChannel serverComms) { + super(id); setState(State.CONNECTED); this.serverComms = serverComms; + this.login = login; + } + + @Override + public String getLogin() { + return this.login; } @Override diff --git a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java index 8c7b6d7..0cba8d4 100644 --- a/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java +++ b/src/main/java/ru/windcorp/progressia/client/comms/localhost/LocalServerCommsChannel.java @@ -10,15 +10,15 @@ public class LocalServerCommsChannel extends ServerCommsChannel { private final Server server; public LocalServerCommsChannel(Server server) { - super(Role.GAME, Role.CHAT); this.server = server; } - public void connect() { + public void connect(String login) { setState(State.CONNECTED); this.localClient = new LocalClient( server.getClientManager().grabClientId(), + login, this ); diff --git a/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java b/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java index 9179bc4..f0b4104 100644 --- a/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java +++ b/src/main/java/ru/windcorp/progressia/client/graphics/world/LocalPlayer.java @@ -2,10 +2,10 @@ package ru.windcorp.progressia.client.graphics.world; import ru.windcorp.progressia.client.world.WorldRender; import ru.windcorp.progressia.client.world.entity.EntityRenderable; -import ru.windcorp.progressia.common.world.Player; +import ru.windcorp.progressia.common.world.PlayerData; import ru.windcorp.progressia.common.world.entity.EntityData; -public class LocalPlayer extends Player { +public class LocalPlayer extends PlayerData { private final Selection selection = new Selection(); diff --git a/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java b/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java index bd443b1..4b51eff 100644 --- a/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java +++ b/src/main/java/ru/windcorp/progressia/common/comms/CommsChannel.java @@ -2,12 +2,8 @@ package ru.windcorp.progressia.common.comms; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.Set; - -import com.google.common.collect.Sets; import ru.windcorp.progressia.common.comms.packets.Packet; @@ -36,24 +32,11 @@ public abstract class CommsChannel { DISCONNECTED } - public static enum Role { - GAME, - CHAT, - RCON - // TODO create role for that thingy that only connects to get server status - } - private State state = State.CONNECTING; - protected final Set roles; - private final Collection listeners = Collections.synchronizedCollection(new ArrayList<>()); - public CommsChannel(Role... roles) { - this.roles = Sets.immutableEnumSet(Arrays.asList(roles)); - } - protected abstract void doSendPacket(Packet packet) throws IOException; private synchronized void sendPacket( @@ -120,10 +103,6 @@ public abstract class CommsChannel { public synchronized State getState() { return state; } - - public Set getRoles() { - return roles; - } public boolean isReady() { return getState() == State.CONNECTED; diff --git a/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java b/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java index 0331df2..5efe66b 100644 --- a/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java +++ b/src/main/java/ru/windcorp/progressia/common/util/CoordinatePacker.java @@ -80,6 +80,8 @@ public class CoordinatePacker { } public static Vec3i unpack3IntsFromLong(long packed, Vec3i output) { + if (output == null) output = new Vec3i(); + output.set( unpack3IntsFromLong(packed, 0), unpack3IntsFromLong(packed, 1), @@ -113,6 +115,8 @@ public class CoordinatePacker { } public static Vec2i unpack2IntsFromLong(long packed, Vec2i output) { + if (output == null) output = new Vec2i(); + output.set( unpack2IntsFromLong(packed, 0), unpack2IntsFromLong(packed, 1) diff --git a/src/main/java/ru/windcorp/progressia/common/world/Player.java b/src/main/java/ru/windcorp/progressia/common/world/PlayerData.java similarity index 77% rename from src/main/java/ru/windcorp/progressia/common/world/Player.java rename to src/main/java/ru/windcorp/progressia/common/world/PlayerData.java index 14d8c76..b56df0c 100644 --- a/src/main/java/ru/windcorp/progressia/common/world/Player.java +++ b/src/main/java/ru/windcorp/progressia/common/world/PlayerData.java @@ -2,11 +2,11 @@ package ru.windcorp.progressia.common.world; import ru.windcorp.progressia.common.world.entity.EntityData; -public class Player { +public class PlayerData { private EntityData entity; - public Player(EntityData entity) { + public PlayerData(EntityData entity) { this.entity = entity; } diff --git a/src/main/java/ru/windcorp/progressia/server/Player.java b/src/main/java/ru/windcorp/progressia/server/Player.java new file mode 100644 index 0000000..f5de3cf --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/Player.java @@ -0,0 +1,54 @@ +package ru.windcorp.progressia.server; + +import java.util.function.Consumer; + +import glm.vec._3.i.Vec3i; +import ru.windcorp.progressia.common.Units; +import ru.windcorp.progressia.common.world.Coordinates; +import ru.windcorp.progressia.common.world.PlayerData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.server.comms.ClientPlayer; + +public class Player extends PlayerData { + + private final Server server; + private final ClientPlayer client; + + public Player(EntityData entity, Server server, ClientPlayer client) { + super(entity); + this.server = server; + this.client = client; + } + + public Server getServer() { + return server; + } + + public ClientPlayer getClient() { + return client; + } + + public void getRequestedChunks(Consumer chunkConsumer) { + Vec3i start = getEntity().getPosition().round_(); + Coordinates.convertInWorldToChunk(start, start); + + Vec3i cursor = new Vec3i(); + float radius = getServer().getLoadDistance(this); + float radiusSq = radius / Units.get(16.0f, "m"); + radiusSq *= radiusSq; + int iRadius = (int) Math.ceil(radius); + + for (cursor.x = -iRadius; cursor.x <= +iRadius; ++cursor.x) { + for (cursor.y = -iRadius; cursor.y <= +iRadius; ++cursor.y) { + for (cursor.z = -iRadius; cursor.z <= +iRadius; ++cursor.z) { + if (cursor.x * cursor.x + cursor.y * cursor.y + cursor.z * cursor.z <= radius) { + cursor.add(start); + chunkConsumer.accept(cursor); + cursor.sub(start); + } + } + } + } + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/PlayerManager.java b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java new file mode 100644 index 0000000..d32b7ea --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/PlayerManager.java @@ -0,0 +1,44 @@ +package ru.windcorp.progressia.server; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import ru.windcorp.progressia.common.util.crash.CrashReports; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.test.TestContent; + +public class PlayerManager { + + private final Server server; + + private final Collection players = Collections.synchronizedCollection(new ArrayList<>()); + + public PlayerManager(Server server) { + this.server = server; + } + + public Collection getPlayers() { + return players; + } + + public void addPlayer(Player player) { + this.players.add(player); + } + + public EntityData conjurePlayerEntity(String login) { + // TODO Live up to the name + if (TestContent.PLAYER_LOGIN.equals(login)) { + // TODO load appropriate chunks + return getServer().getWorld().getData().getEntity(TestContent.PLAYER_ENTITY_ID); + } else { + CrashReports.report(null, "Unknown login %s, javahorse stupid", login); + return null; + } + } + + public Server getServer() { + return server; + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/Server.java b/src/main/java/ru/windcorp/progressia/server/Server.java index 437f854..997dee0 100644 --- a/src/main/java/ru/windcorp/progressia/server/Server.java +++ b/src/main/java/ru/windcorp/progressia/server/Server.java @@ -5,6 +5,7 @@ import java.util.function.Consumer; import org.apache.logging.log4j.LogManager; import ru.windcorp.jputil.functions.ThrowingRunnable; +import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.util.TaskQueue; import ru.windcorp.progressia.common.world.WorldData; import ru.windcorp.progressia.server.comms.ClientManager; @@ -29,6 +30,7 @@ public class Server { private final ServerThread serverThread; private final ClientManager clientManager = new ClientManager(this); + private final PlayerManager playerManager = new PlayerManager(this); private final TaskQueue taskQueue = new TaskQueue(this::isServerThread); @@ -58,6 +60,10 @@ public class Server { return clientManager; } + public PlayerManager getPlayerManager() { + return playerManager; + } + /** * Checks if this thread is the main thread of this server. * @return {@code true} iff the invocation occurs in server main thread @@ -148,6 +154,10 @@ public class Server { public TickingSettings getTickingSettings() { return tickingSettings; } + + public float getLoadDistance(Player player) { + return Units.get(100.0f, "m"); + } /** * Starts the server. This method blocks until the server enters normal operation or fails to start. diff --git a/src/main/java/ru/windcorp/progressia/server/comms/Client.java b/src/main/java/ru/windcorp/progressia/server/comms/Client.java index 94c2ed4..6903289 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/Client.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/Client.java @@ -6,8 +6,7 @@ public abstract class Client extends CommsChannel { private final int id; - public Client(int id, Role... roles) { - super(roles); + public Client(int id) { this.id = id; } diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java new file mode 100644 index 0000000..cf01486 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientChat.java @@ -0,0 +1,9 @@ +package ru.windcorp.progressia.server.comms; + +public abstract class ClientChat extends Client { + + public ClientChat(int id) { + super(id); + } + +} diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java index f371c12..6ab3852 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientManager.java @@ -8,7 +8,6 @@ import java.util.concurrent.atomic.AtomicInteger; import gnu.trove.TCollections; import gnu.trove.map.TIntObjectMap; import gnu.trove.map.hash.TIntObjectHashMap; -import ru.windcorp.progressia.common.comms.CommsChannel.Role; import ru.windcorp.progressia.common.comms.CommsChannel.State; import ru.windcorp.progressia.common.comms.packets.Packet; import ru.windcorp.progressia.common.comms.packets.PacketLoadChunk; @@ -16,6 +15,8 @@ import ru.windcorp.progressia.common.comms.packets.PacketSetLocalPlayer; import ru.windcorp.progressia.common.io.ChunkIO; import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.world.ChunkData; +import ru.windcorp.progressia.common.world.entity.EntityData; +import ru.windcorp.progressia.server.Player; import ru.windcorp.progressia.server.Server; public class ClientManager { @@ -42,28 +43,49 @@ public class ClientManager { synchronized (client) { clientsById.put(client.getId(), client); - client.addListener(new DefaultServerCommsListener(this, client)); - - for (ChunkData chunk : server.getWorld().getData().getChunks()) { - PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk"); - packet.getPosition().set( - chunk.getPosition().x, - chunk.getPosition().y, - chunk.getPosition().z - ); - - try { - ChunkIO.save(chunk, packet.getData().getOutputStream()); - } catch (IOException e) { - CrashReports.report(e, "ClientManager fjcked up. javahorse stupid"); - } - client.sendPacket(packet); + if (client instanceof ClientChat) { + addClientChat((ClientChat) client); } - client.sendPacket(new PacketSetLocalPlayer(0x42)); + if (client instanceof ClientPlayer) { + addClientPlayer((ClientPlayer) client); + } + + client.addListener(new DefaultServerCommsListener(this, client)); } } + private void addClientChat(ClientChat client) { + // Do nothing + } + + private void addClientPlayer(ClientPlayer client) { + String login = client.getLogin(); + EntityData entity = getServer().getPlayerManager().conjurePlayerEntity(login); + + Player player = new Player(entity, getServer(), client); + + getServer().getPlayerManager().getPlayers().add(player); + + for (ChunkData chunk : server.getWorld().getData().getChunks()) { + PacketLoadChunk packet = new PacketLoadChunk("Core:LoadChunk"); + packet.getPosition().set( + chunk.getPosition().x, + chunk.getPosition().y, + chunk.getPosition().z + ); + + try { + ChunkIO.save(chunk, packet.getData().getOutputStream()); + } catch (IOException e) { + CrashReports.report(e, "ClientManager fjcked up. javahorse stupid"); + } + client.sendPacket(packet); + } + + client.sendPacket(new PacketSetLocalPlayer(entity.getEntityId())); + } + public void disconnectClient(Client client) { client.disconnect(); clientsById.remove(client.getId()); @@ -72,7 +94,7 @@ public class ClientManager { public void broadcastGamePacket(Packet packet) { getClients().forEach(c -> { if (c.getState() != State.CONNECTED) return; - if (!c.getRoles().contains(Role.GAME)) return; + if (!(c instanceof ClientPlayer)) return; c.sendPacket(packet); }); } diff --git a/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java b/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java new file mode 100644 index 0000000..3eb14e1 --- /dev/null +++ b/src/main/java/ru/windcorp/progressia/server/comms/ClientPlayer.java @@ -0,0 +1,11 @@ +package ru.windcorp.progressia.server.comms; + +public abstract class ClientPlayer extends Client { + + public ClientPlayer(int id) { + super(id); + } + + public abstract String getLogin(); + +} diff --git a/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java b/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java index dfd10cd..6583f60 100644 --- a/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java +++ b/src/main/java/ru/windcorp/progressia/server/comms/DefaultServerCommsListener.java @@ -2,7 +2,6 @@ package ru.windcorp.progressia.server.comms; import java.io.IOException; -import ru.windcorp.progressia.common.comms.CommsChannel.Role; import ru.windcorp.progressia.common.comms.controls.PacketControl; import ru.windcorp.progressia.common.comms.CommsListener; import ru.windcorp.progressia.common.comms.packets.Packet; @@ -20,7 +19,7 @@ public class DefaultServerCommsListener implements CommsListener { @Override public void onPacketReceived(Packet packet) { - if (client.getRoles().contains(Role.GAME)) { + if (client instanceof ClientPlayer) { if (packet instanceof PacketControl) { PacketControl packetControl = (PacketControl) packet; diff --git a/src/main/java/ru/windcorp/progressia/test/TestContent.java b/src/main/java/ru/windcorp/progressia/test/TestContent.java index fdd6374..df425bd 100644 --- a/src/main/java/ru/windcorp/progressia/test/TestContent.java +++ b/src/main/java/ru/windcorp/progressia/test/TestContent.java @@ -39,6 +39,10 @@ import ru.windcorp.progressia.server.world.tile.*; public class TestContent { + public static final String PLAYER_LOGIN = "Sasha"; + public static final long PLAYER_ENTITY_ID = 0x42; + public static final long STATIE_ENTITY_ID = 0xDEADBEEF; + public static void registerContent() { registerWorldContent(); regsiterControls(); @@ -316,7 +320,7 @@ public class TestContent { if (Glm.equals(chunk.getPosition(), Vectors.ZERO_3i)) { EntityData player = EntityDataRegistry.getInstance().create("Test:Player"); - player.setEntityId(0x42); + player.setEntityId(PLAYER_ENTITY_ID); player.setPosition(new Vec3(-6, -6, 20)); player.setDirection(new Vec2( (float) Math.toRadians(40), (float) Math.toRadians(45) @@ -324,7 +328,7 @@ public class TestContent { chunk.getEntities().add(player); EntityData statie = EntityDataRegistry.getInstance().create("Test:Statie"); - statie.setEntityId(0xDEADBEEF); + statie.setEntityId(STATIE_ENTITY_ID); statie.setPosition(new Vec3(0, 15, 16)); chunk.getEntities().add(statie); }