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
This commit is contained in:
parent
be1c1ab9ab
commit
e7b5ed3df4
@ -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);
|
||||
|
||||
|
@ -4,8 +4,4 @@ import ru.windcorp.progressia.common.comms.CommsChannel;
|
||||
|
||||
public abstract class ServerCommsChannel extends CommsChannel {
|
||||
|
||||
public ServerCommsChannel(Role... roles) {
|
||||
super(roles);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
public LocalClient(int id, LocalServerCommsChannel serverComms) {
|
||||
super(id, Role.GAME, Role.CHAT);
|
||||
private final String login;
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
);
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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<Role> roles;
|
||||
|
||||
private final Collection<CommsListener> 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(
|
||||
@ -121,10 +104,6 @@ public abstract class CommsChannel {
|
||||
return state;
|
||||
}
|
||||
|
||||
public Set<Role> getRoles() {
|
||||
return roles;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return getState() == State.CONNECTED;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
54
src/main/java/ru/windcorp/progressia/server/Player.java
Normal file
54
src/main/java/ru/windcorp/progressia/server/Player.java
Normal file
@ -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<Vec3i> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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<Player> players = Collections.synchronizedCollection(new ArrayList<>());
|
||||
|
||||
public PlayerManager(Server server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
public Collection<Player> 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;
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
@ -149,6 +155,10 @@ public class Server {
|
||||
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.
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
package ru.windcorp.progressia.server.comms;
|
||||
|
||||
public abstract class ClientChat extends Client {
|
||||
|
||||
public ClientChat(int id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
Reference in New Issue
Block a user