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:
		| @@ -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