Some fixes

This commit is contained in:
TheMode 2019-09-03 07:36:04 +02:00
parent 81c0626e57
commit c23b937c4b
9 changed files with 110 additions and 88 deletions

View File

@ -13,6 +13,7 @@ import fr.themode.minestom.net.PacketProcessor;
import fr.themode.minestom.net.packet.PacketReader; import fr.themode.minestom.net.packet.PacketReader;
import fr.themode.minestom.net.packet.client.status.LegacyServerListPingPacket; import fr.themode.minestom.net.packet.client.status.LegacyServerListPingPacket;
import fr.themode.minestom.net.packet.server.play.KeepAlivePacket; import fr.themode.minestom.net.packet.server.play.KeepAlivePacket;
import fr.themode.minestom.net.player.PlayerConnection;
import fr.themode.minestom.utils.Utils; import fr.themode.minestom.utils.Utils;
import simplenet.Server; import simplenet.Server;
@ -61,10 +62,12 @@ public class Main {
server.onConnect(client -> { server.onConnect(client -> {
System.out.println("CONNECTION"); System.out.println("CONNECTION");
client.postDisconnect(() -> { client.preDisconnect(() -> {
System.out.println("A Disconnection"); System.out.println("A Disconnection");
if (packetProcessor.hasPlayerConnection(client)) { if (packetProcessor.hasPlayerConnection(client)) {
Player player = connectionManager.getPlayer(packetProcessor.getPlayerConnection(client)); PlayerConnection playerConnection = packetProcessor.getPlayerConnection(client);
playerConnection.refreshOnline(false);
Player player = connectionManager.getPlayer(playerConnection);
if (player != null) { if (player != null) {
player.remove(); player.remove();

View File

@ -26,9 +26,9 @@ public class BoundingBox {
} }
public boolean intersect(BlockPosition blockPosition) { public boolean intersect(BlockPosition blockPosition) {
final float x = 1f; final float x = 1.6f;
final float y = 1; final float y = 1;
final float z = 1f; final float z = 1.6f;
float minX = blockPosition.getX() - (x / 2) + 0.5f; float minX = blockPosition.getX() - (x / 2) + 0.5f;
float maxX = blockPosition.getX() + (x / 2) + 0.5f; float maxX = blockPosition.getX() + (x / 2) + 0.5f;

View File

@ -12,11 +12,13 @@ import fr.themode.minestom.instance.Chunk;
import fr.themode.minestom.instance.Instance; import fr.themode.minestom.instance.Instance;
import fr.themode.minestom.net.packet.server.play.*; import fr.themode.minestom.net.packet.server.play.*;
import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.net.player.PlayerConnection;
import fr.themode.minestom.utils.Vector;
import fr.themode.minestom.utils.*; import fr.themode.minestom.utils.*;
import simplenet.packet.Packet; import simplenet.packet.Packet;
import java.util.*; import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@ -24,7 +26,7 @@ import java.util.function.Consumer;
public abstract class Entity implements Viewable, DataContainer { public abstract class Entity implements Viewable, DataContainer {
private static Map<Integer, Entity> entityById = new HashMap<>(); private static Map<Integer, Entity> entityById = new ConcurrentHashMap<>();
private static AtomicInteger lastEntityId = new AtomicInteger(); private static AtomicInteger lastEntityId = new AtomicInteger();
// Metadata // Metadata
@ -92,15 +94,11 @@ public abstract class Entity implements Viewable, DataContainer {
setBoundingBox(0, 0, 0); setBoundingBox(0, 0, 0);
synchronized (entityById) { entityById.put(id, this);
entityById.put(id, this);
}
} }
public static Entity getEntity(int id) { public static Entity getEntity(int id) {
synchronized (entityById) { return entityById.get(id);
return entityById.get(id);
}
} }
private static int generateId() { private static int generateId() {
@ -538,9 +536,7 @@ public abstract class Entity implements Viewable, DataContainer {
public void remove() { public void remove() {
this.shouldRemove = true; this.shouldRemove = true;
synchronized (entityById) { entityById.remove(id);
entityById.remove(id);
}
if (instance != null) if (instance != null)
instance.removeEntity(this); instance.removeEntity(this);
} }

View File

@ -50,7 +50,7 @@ public class Player extends LivingEntity {
static { static {
ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo(); ChunkGeneratorDemo chunkGeneratorDemo = new ChunkGeneratorDemo();
//instance = Main.getInstanceManager().createInstance(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data")); //instanceContainer = Main.getInstanceManager().createInstanceContainer(new File("C:\\Users\\themo\\OneDrive\\Bureau\\Minestom data"));
instanceContainer = Main.getInstanceManager().createInstanceContainer(); instanceContainer = Main.getInstanceManager().createInstanceContainer();
instanceContainer.enableAutoChunkLoad(true); instanceContainer.enableAutoChunkLoad(true);
instanceContainer.setChunkGenerator(chunkGeneratorDemo); instanceContainer.setChunkGenerator(chunkGeneratorDemo);
@ -156,7 +156,7 @@ public class Player extends LivingEntity {
setEventCallback(PlayerSpawnEvent.class, event -> { setEventCallback(PlayerSpawnEvent.class, event -> {
System.out.println("SPAWN"); System.out.println("SPAWN");
setGameMode(GameMode.SURVIVAL); setGameMode(GameMode.CREATIVE);
teleport(new Position(0, 66, 0)); teleport(new Position(0, 66, 0));
/*ChickenCreature chickenCreature = new ChickenCreature(); /*ChickenCreature chickenCreature = new ChickenCreature();
@ -329,6 +329,7 @@ public class Player extends LivingEntity {
if (getOpenInventory() != null) if (getOpenInventory() != null)
getOpenInventory().removeViewer(this); getOpenInventory().removeViewer(this);
this.viewableEntities.forEach(entity -> entity.removeViewer(this)); this.viewableEntities.forEach(entity -> entity.removeViewer(this));
this.viewableChunks.forEach(chunk -> chunk.removeViewer(this));
super.remove(); super.remove();
} }
@ -607,6 +608,10 @@ public class Player extends LivingEntity {
return playerConnection; return playerConnection;
} }
public boolean isOnline() {
return playerConnection.isOnline();
}
public PlayerSettings getSettings() { public PlayerSettings getSettings() {
return settings; return settings;
} }

View File

@ -1,7 +1,7 @@
package fr.themode.minestom.instance; package fr.themode.minestom.instance;
import com.github.luben.zstd.Zstd;
import fr.themode.minestom.Main; import fr.themode.minestom.Main;
import fr.themode.minestom.utils.CompressionUtils;
import fr.themode.minestom.utils.SerializerUtils; import fr.themode.minestom.utils.SerializerUtils;
import java.io.*; import java.io.*;
@ -29,14 +29,7 @@ public class ChunkLoaderIO {
File chunkFile = getChunkFile(chunk.getChunkX(), chunk.getChunkZ(), folder); File chunkFile = getChunkFile(chunk.getChunkX(), chunk.getChunkZ(), folder);
try (FileOutputStream fos = new FileOutputStream(chunkFile)) { try (FileOutputStream fos = new FileOutputStream(chunkFile)) {
byte[] data = chunk.getSerializedData(); byte[] data = chunk.getSerializedData();
byte[] decompressedLength = SerializerUtils.intToBytes(data.length); fos.write(CompressionUtils.getCompressedData(data));
byte[] compressed = Zstd.compress(data, COMPRESSION_LEVEL);
byte[] result = new byte[decompressedLength.length + compressed.length];
System.arraycopy(decompressedLength, 0, result, 0, decompressedLength.length);
System.arraycopy(compressed, 0, result, decompressedLength.length, compressed.length);
fos.write(result);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} catch (IOException e) { } catch (IOException e) {
@ -65,19 +58,7 @@ public class ChunkLoaderIO {
return; return;
} }
int decompressedLength = SerializerUtils.bytesToInt(array); DataInputStream stream = new DataInputStream(new ByteArrayInputStream(CompressionUtils.getDecompressedData(array)));
byte[] compressedChunkData = new byte[array.length - Integer.BYTES];
System.arraycopy(array, Integer.BYTES, compressedChunkData, 0, compressedChunkData.length); // Remove the decompressed length from the array
byte[] decompressed = new byte[decompressedLength];
long result = Zstd.decompress(decompressed, compressedChunkData); // Decompressed in an array with the max size
array = new byte[(int) result];
System.arraycopy(decompressed, 0, array, 0, (int) result); // Resize the data array properly
DataInputStream stream = new DataInputStream(new ByteArrayInputStream(array));
Chunk chunk = null; Chunk chunk = null;
try { try {

View File

@ -190,37 +190,41 @@ public abstract class Instance implements BlockModifier {
public void addEntityToChunk(Entity entity, Chunk chunk) { public void addEntityToChunk(Entity entity, Chunk chunk) {
long chunkIndex = ChunkUtils.getChunkIndex(chunk.getChunkX(), chunk.getChunkZ()); long chunkIndex = ChunkUtils.getChunkIndex(chunk.getChunkX(), chunk.getChunkZ());
Set<Entity> entities = getEntitiesInChunk(chunkIndex); synchronized (chunkEntities) {
entities.add(entity); Set<Entity> entities = getEntitiesInChunk(chunkIndex);
this.chunkEntities.put(chunkIndex, entities); entities.add(entity);
if (entity instanceof Player) { this.chunkEntities.put(chunkIndex, entities);
this.players.add((Player) entity); if (entity instanceof Player) {
} else if (entity instanceof EntityCreature) { this.players.add((Player) entity);
this.creatures.add((EntityCreature) entity); } else if (entity instanceof EntityCreature) {
} else if (entity instanceof ObjectEntity) { this.creatures.add((EntityCreature) entity);
this.objectEntities.add((ObjectEntity) entity); } else if (entity instanceof ObjectEntity) {
} else if (entity instanceof ExperienceOrb) { this.objectEntities.add((ObjectEntity) entity);
this.experienceOrbs.add((ExperienceOrb) entity); } else if (entity instanceof ExperienceOrb) {
this.experienceOrbs.add((ExperienceOrb) entity);
}
} }
} }
public void removeEntityFromChunk(Entity entity, Chunk chunk) { public void removeEntityFromChunk(Entity entity, Chunk chunk) {
long chunkIndex = ChunkUtils.getChunkIndex(chunk.getChunkX(), chunk.getChunkZ()); long chunkIndex = ChunkUtils.getChunkIndex(chunk.getChunkX(), chunk.getChunkZ());
Set<Entity> entities = getEntitiesInChunk(chunkIndex); synchronized (chunkEntities) {
entities.remove(entity); Set<Entity> entities = getEntitiesInChunk(chunkIndex);
if (entities.isEmpty()) { entities.remove(entity);
this.chunkEntities.remove(chunkIndex); if (entities.isEmpty()) {
} else { this.chunkEntities.remove(chunkIndex);
this.chunkEntities.put(chunkIndex, entities); } else {
} this.chunkEntities.put(chunkIndex, entities);
if (entity instanceof Player) { }
this.players.remove(entity); if (entity instanceof Player) {
} else if (entity instanceof EntityCreature) { this.players.remove(entity);
this.creatures.remove(entity); } else if (entity instanceof EntityCreature) {
} else if (entity instanceof ObjectEntity) { this.creatures.remove(entity);
this.objectEntities.remove(entity); } else if (entity instanceof ObjectEntity) {
} else if (entity instanceof ExperienceOrb) { this.objectEntities.remove(entity);
this.experienceOrbs.remove((ExperienceOrb) entity); } else if (entity instanceof ExperienceOrb) {
this.experienceOrbs.remove((ExperienceOrb) entity);
}
} }
} }

View File

@ -8,6 +8,7 @@ import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
import fr.themode.minestom.net.packet.server.play.ParticlePacket; import fr.themode.minestom.net.packet.server.play.ParticlePacket;
import fr.themode.minestom.utils.BlockPosition; import fr.themode.minestom.utils.BlockPosition;
import fr.themode.minestom.utils.ChunkUtils; import fr.themode.minestom.utils.ChunkUtils;
import simplenet.packet.Packet;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
@ -196,17 +197,6 @@ public class InstanceContainer extends Instance {
if (!chunkViewers.isEmpty()) { if (!chunkViewers.isEmpty()) {
sendChunkUpdate(chunkViewers, chunk); sendChunkUpdate(chunkViewers, chunk);
} }
// Update for players in this instance
/*if (!getPlayers().isEmpty())
sendChunkUpdate(getPlayers(), chunk);
// Update for shared instances
if (!sharedInstances.isEmpty())
this.sharedInstances.forEach(sharedInstance -> {
Set<Player> instancePlayers = sharedInstance.getPlayers();
if (!instancePlayers.isEmpty())
sendChunkUpdate(instancePlayers, chunk);
});*/
} }
@Override @Override
@ -218,19 +208,15 @@ public class InstanceContainer extends Instance {
@Override @Override
public void sendChunk(Player player, Chunk chunk) { public void sendChunk(Player player, Chunk chunk) {
/*Buffer data = chunk.getFullDataPacket(); Packet data = chunk.getFullDataPacket();
if(data == null) { if (data == null) {
PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> { PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> {
chunk.setFullDataPacket(buffer); chunk.setFullDataPacket(buffer);
sendChunkUpdate(player, chunk); sendChunkUpdate(player, chunk);
}); });
}else{ } else {
sendChunkUpdate(player, chunk); sendChunkUpdate(player, chunk);
}*/ }
PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> {
chunk.setFullDataPacket(buffer);
sendChunkUpdate(player, chunk);
});
} }
@Override @Override

View File

@ -10,14 +10,17 @@ public class PlayerConnection {
private Client client; private Client client;
private ConnectionState connectionState; private ConnectionState connectionState;
private boolean online;
public PlayerConnection(Client client) { public PlayerConnection(Client client) {
this.client = client; this.client = client;
this.connectionState = ConnectionState.UNKNOWN; this.connectionState = ConnectionState.UNKNOWN;
this.online = true;
} }
public void sendPacket(Packet packet) { public void sendPacket(Packet packet) {
packet.writeAndFlush(client); if (isOnline())
packet.writeAndFlush(client);
} }
public void writeUnencodedPacket(Packet packet) { public void writeUnencodedPacket(Packet packet) {
@ -25,8 +28,8 @@ public class PlayerConnection {
} }
public void sendPacket(ServerPacket serverPacket) { public void sendPacket(ServerPacket serverPacket) {
PacketUtils.writePacket(serverPacket, packet -> sendPacket(packet)); if (isOnline())
//PacketWriterUtils.writeAndSend(this, serverPacket); PacketUtils.writePacket(serverPacket, packet -> sendPacket(packet));
} }
public void flush() { public void flush() {
@ -37,6 +40,14 @@ public class PlayerConnection {
return client; return client;
} }
public boolean isOnline() {
return online;
}
public void refreshOnline(boolean online) {
this.online = online;
}
public void setConnectionState(ConnectionState connectionState) { public void setConnectionState(ConnectionState connectionState) {
this.connectionState = connectionState; this.connectionState = connectionState;
} }

View File

@ -0,0 +1,36 @@
package fr.themode.minestom.utils;
import com.github.luben.zstd.Zstd;
public class CompressionUtils {
private static final int COMPRESSION_LEVEL = 1;
public static byte[] getCompressedData(byte[] decompressed) {
byte[] decompressedLength = SerializerUtils.intToBytes(decompressed.length);
byte[] compressed = Zstd.compress(decompressed, COMPRESSION_LEVEL);
byte[] result = new byte[decompressedLength.length + compressed.length];
System.arraycopy(decompressedLength, 0, result, 0, decompressedLength.length);
System.arraycopy(compressed, 0, result, decompressedLength.length, compressed.length);
return result;
}
public static byte[] getDecompressedData(byte[] compressed) {
int decompressedLength = SerializerUtils.bytesToInt(compressed);
byte[] compressedChunkData = new byte[compressed.length - Integer.BYTES];
System.arraycopy(compressed, Integer.BYTES, compressedChunkData, 0, compressedChunkData.length); // Remove the decompressed length from the array
byte[] decompressed = new byte[decompressedLength];
long result = Zstd.decompress(decompressed, compressedChunkData); // Decompressed in an array with the max size
compressed = new byte[(int) result];
System.arraycopy(decompressed, 0, compressed, 0, (int) result); // Resize the data array properly
return compressed;
}
}