package net.fourbytes.shadow.network; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.IntMap; import com.badlogic.gdx.utils.LongMap; import com.esotericsoftware.kryonet.Connection; import net.fourbytes.shadow.*; import net.fourbytes.shadow.map.DataChunk; import net.fourbytes.shadow.map.MapObject; import net.fourbytes.shadow.map.ShadowMap; import net.fourbytes.shadow.systems.ISystem; import net.fourbytes.shadow.systems.ITimeDaySystem; import net.fourbytes.shadow.systems.IWeatherSystem; import net.fourbytes.shadow.systems.SystemData; import net.fourbytes.shadow.utils.gdx.IntLongMap; import net.fourbytes.shadow.utils.gdx.LongIntMap; public class ServerLevel extends Level { public Array<NetPlayer> players = new Array<NetPlayer>(NetPlayer.class); protected MapObject playerData = new MapObject(); public LongIntMap playerCIDMap = new LongIntMap(); public IntLongMap cidPlayerMap = new IntLongMap(); public Array<String> usernames = new Array<String>(String.class); public LongMap<String> usernameMap = new LongMap<String>(); public ServerLevel() { this("test"); } public ServerLevel(String name) { super(name); systems.get(ITimeDaySystem.class).tick(0f); systems.get(ITimeDaySystem.class).setTime(0f); systems.get(IWeatherSystem.class).setWeather("SnowWeather"); Shadow.server.start(); } @Override public void tick(float delta) { super.tick(delta); playerData.setOrdered(false); //UDP for (int i = 0; i < players.size; i++) { NetPlayer player = players.items[i]; long id = player.getID(); int cid = playerCIDMap.get(id, 0); ShadowMap.update(playerData, player); ((KryoNetServer)Shadow.server).server.sendToAllExceptUDP(cid, playerData); } ShadowMap.update(playerData, player); playerData.subtype = "NetPlayer"; playerData.args.put("timestamp", System.currentTimeMillis()); playerData.args.put("username", Shadow.playerInfo.getUserName()); ((KryoNetServer)Shadow.server).server.sendToAllUDP(playerData); } public void handle(Data data, Connection c) { if (data instanceof DataHandshake) { DataHandshake dh = ((DataHandshake)data); usernames.add(dh.clientName); usernameMap.put(c.getID(), dh.clientName); } if (data instanceof MapObject) { MapObject mo = ((MapObject)data); if (mo.subtype.equals("NetPlayer")) { int cid = c.getID(); long id = mo.id; GameObject go = goIDMap.get(id); if (go == null) { go = ShadowMap.convert(mo, this); go.layer = player.layer; go.layer.add(go); players.add((NetPlayer) go); playerCIDMap.put(id, cid); cidPlayerMap.put(cid, id); } else if (go instanceof NetPlayer && ((NetPlayer)go).timestamp < ((Long) mo.args.get("timestamp"))) { mo.args.put("username", usernameMap.get(cid)); ShadowMap.update(go, mo); } } } if (data instanceof DataMapUpdate) { DataMapUpdate dmu = ((DataMapUpdate)data); if (dmu.mode == DataMapUpdate.MapUpdateModes.ADD) { GameObject go = ShadowMap.convert(dmu.object, this); go.layer.add(go); } else if (dmu.mode == DataMapUpdate.MapUpdateModes.REMOVE) { Layer layer = layers.get(dmu.object.layer); if (dmu.object.type == null) { Array<Block> blocks = layer.get(Coord.get(dmu.object.x, dmu.object.y)); if (blocks != null) { for (int i = 0; i < blocks.size; i++) { layer.remove(blocks.items[i]); } } } else { GameObject go = goIDMap.get(dmu.object.id); if (go != null) { go.layer.remove(go); } } } else if (dmu.mode == DataMapUpdate.MapUpdateModes.UPDATE) { GameObject go = goIDMap.get(dmu.object.id); if (go != null) { ShadowMap.update(go, dmu.object); } } ((KryoNetServer)Shadow.server).server.sendToAllExceptTCP(c.getID(), dmu); } } public void send(Connection c) { map.createFrom(this); MapObject playerSpawned = null; for (DataChunk chunk : map.chunkmap.values()) { for (int i = 0; i < chunk.objects.size; i++) { MapObject mo = chunk.objects.items[i]; if (mo.subtype.equals("Player") || mo.subtype.equals("NetPlayer")) { if (playerSpawned != null) { chunk.objects.removeIndex(i); i--; continue; } playerSpawned = mo; Vector2 spawnpos = (Vector2) mo.args.get("spawnpos"); mo.x = spawnpos.x; mo.y = spawnpos.y; } else if (mo.subtype.equals("PlayerSpawn")) { if (playerSpawned != null) { chunk.objects.removeValue(playerSpawned, true); i--; } playerSpawned = mo; } } Shadow.server.send(chunk, c, false); } for (ISystem system : systems.getAll()) { SystemData data = new SystemData(system); Shadow.server.send(data, c, false); } } }