Optimization

This commit is contained in:
TheMode 2019-09-06 16:05:36 +02:00
parent c23b937c4b
commit b517c1091e
25 changed files with 197 additions and 147 deletions

View File

@ -14,12 +14,9 @@ repositories {
dependencies { dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12' testCompile group: 'junit', name: 'junit', version: '4.12'
implementation 'com.github.Adamaq01:ozao-net:2.3.1'
compile 'com.github.Querz:NBT:4.1' compile 'com.github.Querz:NBT:4.1'
// https://mvnrepository.com/artifact/org.lz4/lz4-java
implementation 'com.github.luben:zstd-jni:1.4.3-1' implementation 'com.github.luben:zstd-jni:1.4.3-1'
implementation 'com.esotericsoftware:reflectasm:1.11.9' implementation 'com.esotericsoftware:reflectasm:1.11.9'
implementation 'com.github.LynnOwens:starlite:9971b899f7' implementation 'com.github.LynnOwens:starlite:9971b899f7'
implementation 'com.github.jhg023:SimpleNet:1.4.14' implementation 'com.github.jhg023:SimpleNet:1.5.0'
} }

View File

@ -1,5 +1,6 @@
package fr.themode.minestom; package fr.themode.minestom;
import com.github.simplenet.Server;
import fr.themode.minestom.data.DataManager; import fr.themode.minestom.data.DataManager;
import fr.themode.minestom.entity.EntityManager; import fr.themode.minestom.entity.EntityManager;
import fr.themode.minestom.entity.Player; import fr.themode.minestom.entity.Player;
@ -15,7 +16,6 @@ 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.net.player.PlayerConnection;
import fr.themode.minestom.utils.Utils; import fr.themode.minestom.utils.Utils;
import simplenet.Server;
public class Main { public class Main {
@ -64,15 +64,14 @@ public class Main {
client.preDisconnect(() -> { client.preDisconnect(() -> {
System.out.println("A Disconnection"); System.out.println("A Disconnection");
if (packetProcessor.hasPlayerConnection(client)) { PlayerConnection playerConnection = packetProcessor.getPlayerConnection(client);
PlayerConnection playerConnection = packetProcessor.getPlayerConnection(client); if (playerConnection != null) {
playerConnection.refreshOnline(false); playerConnection.refreshOnline(false);
Player player = connectionManager.getPlayer(playerConnection); Player player = connectionManager.getPlayer(playerConnection);
if (player != null) { if (player != null) {
player.remove(); player.remove();
connectionManager.removePlayer(player.getPlayerConnection()); connectionManager.removePlayer(playerConnection);
} }
packetProcessor.removePlayerConnection(client); packetProcessor.removePlayerConnection(client);
} }

View File

@ -1,5 +1,6 @@
package fr.themode.minestom.entity; package fr.themode.minestom.entity;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.Main; import fr.themode.minestom.Main;
import fr.themode.minestom.Viewable; import fr.themode.minestom.Viewable;
import fr.themode.minestom.collision.BoundingBox; import fr.themode.minestom.collision.BoundingBox;
@ -13,7 +14,6 @@ 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.*; import fr.themode.minestom.utils.*;
import simplenet.packet.Packet;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;

View File

@ -1,8 +1,8 @@
package fr.themode.minestom.entity; package fr.themode.minestom.entity;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.item.ItemStack;
import fr.themode.minestom.utils.Utils; import fr.themode.minestom.utils.Utils;
import simplenet.packet.Packet;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -1,5 +1,6 @@
package fr.themode.minestom.entity; package fr.themode.minestom.entity;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.collision.BoundingBox; import fr.themode.minestom.collision.BoundingBox;
import fr.themode.minestom.entity.property.Attribute; import fr.themode.minestom.entity.property.Attribute;
import fr.themode.minestom.event.PickupItemEvent; import fr.themode.minestom.event.PickupItemEvent;
@ -8,7 +9,6 @@ import fr.themode.minestom.item.ItemStack;
import fr.themode.minestom.net.packet.server.play.AnimationPacket; import fr.themode.minestom.net.packet.server.play.AnimationPacket;
import fr.themode.minestom.net.packet.server.play.CollectItemPacket; import fr.themode.minestom.net.packet.server.play.CollectItemPacket;
import fr.themode.minestom.net.packet.server.play.EntityPropertiesPacket; import fr.themode.minestom.net.packet.server.play.EntityPropertiesPacket;
import simplenet.packet.Packet;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -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.CREATIVE); setGameMode(GameMode.SURVIVAL);
teleport(new Position(0, 66, 0)); teleport(new Position(0, 66, 0));
/*ChickenCreature chickenCreature = new ChickenCreature(); /*ChickenCreature chickenCreature = new ChickenCreature();
@ -173,11 +173,8 @@ public class Player extends LivingEntity {
//itemEntity.remove(); //itemEntity.remove();
}*/ }*/
ExperienceOrb experienceOrb = new ExperienceOrb((short) 500); getInventory().addItemStack(new ItemStack(541, (byte) 1));
experienceOrb.refreshPosition(5, 66, 0); //getInventory().addItemStack(new ItemStack(1, (byte) 100));
experienceOrb.setInstance(getInstance());
getInventory().addItemStack(new ItemStack(1, (byte) 100));
TeamsPacket teamsPacket = new TeamsPacket(); TeamsPacket teamsPacket = new TeamsPacket();
teamsPacket.teamName = "TEAMNAME" + new Random().nextInt(100); teamsPacket.teamName = "TEAMNAME" + new Random().nextInt(100);

View File

@ -1,12 +1,12 @@
package fr.themode.minestom.instance; package fr.themode.minestom.instance;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.Main; import fr.themode.minestom.Main;
import fr.themode.minestom.Viewable; import fr.themode.minestom.Viewable;
import fr.themode.minestom.entity.Player; import fr.themode.minestom.entity.Player;
import fr.themode.minestom.net.packet.server.play.ChunkDataPacket; import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
import fr.themode.minestom.utils.PacketUtils; import fr.themode.minestom.utils.PacketUtils;
import fr.themode.minestom.utils.SerializerUtils; import fr.themode.minestom.utils.SerializerUtils;
import simplenet.packet.Packet;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream; import java.io.DataOutputStream;
@ -33,6 +33,7 @@ public class Chunk implements Viewable {
// Cache // Cache
private Set<Player> viewers = new CopyOnWriteArraySet<>(); private Set<Player> viewers = new CopyOnWriteArraySet<>();
private Packet fullDataPacket; private Packet fullDataPacket;
protected volatile boolean packetUpdated;
public Chunk(Biome biome, int chunkX, int chunkZ) { public Chunk(Biome biome, int chunkX, int chunkZ) {
this.biome = biome; this.biome = biome;
@ -69,6 +70,7 @@ public class Chunk implements Viewable {
} else { } else {
blockEntities.remove(index); blockEntities.remove(index);
} }
this.packetUpdated = false;
} }
public short getBlockId(byte x, byte y, byte z) { public short getBlockId(byte x, byte y, byte z) {
@ -149,8 +151,12 @@ public class Chunk implements Viewable {
return fullDataPacket; return fullDataPacket;
} }
// Write the packet in the current thread
protected void refreshDataPacket() { protected void refreshDataPacket() {
PacketUtils.writePacket(getFreshFullDataPacket(), packet -> fullDataPacket = packet); // TODO write packet buffer in another thread (heavy calculations) PacketUtils.writePacket(getFreshFullDataPacket(), packet -> {
fullDataPacket = packet;
packetUpdated = true;
});
} }
@Override @Override

View File

@ -1,11 +1,13 @@
package fr.themode.minestom.instance; package fr.themode.minestom.instance;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.Main; import fr.themode.minestom.Main;
import fr.themode.minestom.entity.*; import fr.themode.minestom.entity.*;
import fr.themode.minestom.net.PacketWriterUtils;
import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
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 fr.themode.minestom.utils.Position; import fr.themode.minestom.utils.Position;
import simplenet.packet.Packet;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
@ -29,8 +31,10 @@ public abstract class Instance implements BlockModifier {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
} }
// Used to call BlockBreakEvent and sending particle packet if true
public abstract void breakBlock(Player player, BlockPosition blockPosition); public abstract void breakBlock(Player player, BlockPosition blockPosition);
// Force the generation of the chunk, even if no file and ChunkGenerator are defined
public abstract void loadChunk(int chunkX, int chunkZ, Consumer<Chunk> callback); public abstract void loadChunk(int chunkX, int chunkZ, Consumer<Chunk> callback);
// Load only if auto chunk load is enabled // Load only if auto chunk load is enabled
@ -54,8 +58,6 @@ public abstract class Instance implements BlockModifier {
public abstract void sendChunkUpdate(Player player, Chunk chunk); public abstract void sendChunkUpdate(Player player, Chunk chunk);
public abstract void sendChunkSectionUpdate(Chunk chunk, int section, Player player);
protected abstract void retrieveChunk(int chunkX, int chunkZ, Consumer<Chunk> callback); protected abstract void retrieveChunk(int chunkX, int chunkZ, Consumer<Chunk> callback);
public abstract void createChunk(int chunkX, int chunkZ, Consumer<Chunk> callback); public abstract void createChunk(int chunkX, int chunkZ, Consumer<Chunk> callback);
@ -75,6 +77,24 @@ public abstract class Instance implements BlockModifier {
player.getPlayerConnection().sendPacket(chunkData); player.getPlayerConnection().sendPacket(chunkData);
}); });
} }
protected void sendChunkSectionUpdate(Chunk chunk, int section, Collection<Player> players) {
PacketWriterUtils.writeAndSend(players, getChunkSectionUpdatePacket(chunk, section));
}
public void sendChunkSectionUpdate(Chunk chunk, int section, Player player) {
PacketWriterUtils.writeAndSend(player, getChunkSectionUpdatePacket(chunk, section));
}
protected ChunkDataPacket getChunkSectionUpdatePacket(Chunk chunk, int section) {
ChunkDataPacket chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.fullChunk = false;
chunkDataPacket.chunk = chunk;
int[] sections = new int[16];
sections[section] = 1;
chunkDataPacket.sections = sections;
return chunkDataPacket;
}
// //
public Set<Player> getPlayers() { public Set<Player> getPlayers() {
@ -223,7 +243,7 @@ public abstract class Instance implements BlockModifier {
} else if (entity instanceof ObjectEntity) { } else if (entity instanceof ObjectEntity) {
this.objectEntities.remove(entity); this.objectEntities.remove(entity);
} else if (entity instanceof ExperienceOrb) { } else if (entity instanceof ExperienceOrb) {
this.experienceOrbs.remove((ExperienceOrb) entity); this.experienceOrbs.remove(entity);
} }
} }
} }

View File

@ -1,14 +1,13 @@
package fr.themode.minestom.instance; package fr.themode.minestom.instance;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.entity.Player; import fr.themode.minestom.entity.Player;
import fr.themode.minestom.event.PlayerBlockBreakEvent; import fr.themode.minestom.event.PlayerBlockBreakEvent;
import fr.themode.minestom.net.PacketWriterUtils; import fr.themode.minestom.net.PacketWriterUtils;
import fr.themode.minestom.net.packet.server.play.BlockChangePacket; import fr.themode.minestom.net.packet.server.play.BlockChangePacket;
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.*;
@ -154,17 +153,6 @@ public class InstanceContainer extends Instance {
player.getPlayerConnection().sendPacket(chunk.getFullDataPacket()); player.getPlayerConnection().sendPacket(chunk.getFullDataPacket());
} }
@Override
public void sendChunkSectionUpdate(Chunk chunk, int section, Player player) {
ChunkDataPacket chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.fullChunk = false;
chunkDataPacket.chunk = chunk;
int[] sections = new int[16];
sections[section] = 1;
chunkDataPacket.sections = sections;
PacketWriterUtils.writeAndSend(player, chunkDataPacket);
}
@Override @Override
protected void retrieveChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) { protected void retrieveChunk(int chunkX, int chunkZ, Consumer<Chunk> callback) {
if (folder != null) { if (folder != null) {
@ -209,9 +197,10 @@ public class InstanceContainer extends Instance {
@Override @Override
public void sendChunk(Player player, Chunk chunk) { public void sendChunk(Player player, Chunk chunk) {
Packet data = chunk.getFullDataPacket(); Packet data = chunk.getFullDataPacket();
if (data == null) { if (data == null || !chunk.packetUpdated) {
PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> { PacketWriterUtils.writeCallbackPacket(chunk.getFreshFullDataPacket(), buffer -> {
chunk.setFullDataPacket(buffer); chunk.setFullDataPacket(buffer);
chunk.packetUpdated = true;
sendChunkUpdate(player, chunk); sendChunkUpdate(player, chunk);
}); });
} else { } else {

View File

@ -9,19 +9,21 @@ public class ItemStack implements DataContainer {
private Material material; private Material material;
private byte amount; private byte amount;
private short damage;
private String displayName; private String displayName;
private boolean unbreakable; private boolean unbreakable;
private Data data; private Data data;
public ItemStack(Material material, byte amount) { public ItemStack(Material material, byte amount, short damage) {
this.material = material; this.material = material;
this.amount = amount; this.amount = amount;
this.damage = damage;
} }
public ItemStack(int id, byte amount) { public ItemStack(int id, byte amount) {
this(Material.fromId(id), amount); this(Material.fromId(id), amount, (short) 0);
} }
public boolean isAir() { public boolean isAir() {
@ -29,13 +31,20 @@ public class ItemStack implements DataContainer {
} }
public boolean isSimilar(ItemStack itemStack) { public boolean isSimilar(ItemStack itemStack) {
return itemStack.getMaterial() == material && itemStack.getDisplayName() == displayName && itemStack.isUnbreakable() == unbreakable; return itemStack.getMaterial() == material &&
itemStack.getDisplayName() == displayName &&
itemStack.isUnbreakable() == unbreakable &&
itemStack.getDamage() == damage;
} }
public byte getAmount() { public byte getAmount() {
return amount; return amount;
} }
public short getDamage() {
return damage;
}
public Material getMaterial() { public Material getMaterial() {
return material; return material;
} }
@ -44,6 +53,10 @@ public class ItemStack implements DataContainer {
this.amount = amount; this.amount = amount;
} }
public void setDamage(short damage) {
this.damage = damage;
}
public String getDisplayName() { public String getDisplayName() {
return displayName; return displayName;
} }
@ -61,7 +74,7 @@ public class ItemStack implements DataContainer {
} }
public ItemStack clone() { public ItemStack clone() {
ItemStack itemStack = new ItemStack(material, amount); ItemStack itemStack = new ItemStack(material, amount, damage);
itemStack.setDisplayName(displayName); itemStack.setDisplayName(displayName);
itemStack.setUnbreakable(unbreakable); itemStack.setUnbreakable(unbreakable);
itemStack.setData(getData()); itemStack.setData(getData());

View File

@ -8,7 +8,8 @@ public enum Material {
AIR(0, 0), AIR(0, 0),
STONE(1, 1), STONE(1, 1),
BOW(525, 0), BOW(525, 0),
ARROW(526, 0); ARROW(526, 0),
DIAMOND_SWORD(541, 0);
private static Map<Integer, Material> idToMaterial = new HashMap<>(); private static Map<Integer, Material> idToMaterial = new HashMap<>();

View File

@ -1,9 +1,9 @@
package fr.themode.minestom.net; package fr.themode.minestom.net;
import simplenet.Client; import com.github.simplenet.Client;
import simplenet.packet.Packet; import com.github.simplenet.packet.Packet;
import simplenet.utility.exposed.consumer.ByteConsumer; import com.github.simplenet.utility.exposed.consumer.ByteConsumer;
import simplenet.utility.exposed.predicate.BytePredicate; import com.github.simplenet.utility.exposed.predicate.BytePredicate;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;

View File

@ -1,5 +1,6 @@
package fr.themode.minestom.net; package fr.themode.minestom.net;
import com.github.simplenet.Client;
import fr.themode.minestom.Main; import fr.themode.minestom.Main;
import fr.themode.minestom.entity.Player; import fr.themode.minestom.entity.Player;
import fr.themode.minestom.net.packet.PacketReader; import fr.themode.minestom.net.packet.PacketReader;
@ -10,7 +11,6 @@ import fr.themode.minestom.net.packet.client.handler.ClientPlayPacketsHandler;
import fr.themode.minestom.net.packet.client.handler.ClientStatusPacketsHandler; import fr.themode.minestom.net.packet.client.handler.ClientStatusPacketsHandler;
import fr.themode.minestom.net.packet.client.handshake.HandshakePacket; import fr.themode.minestom.net.packet.client.handshake.HandshakePacket;
import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.net.player.PlayerConnection;
import simplenet.Client;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;

View File

@ -1,11 +1,11 @@
package fr.themode.minestom.net; package fr.themode.minestom.net;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.Main; import fr.themode.minestom.Main;
import fr.themode.minestom.entity.Player; import fr.themode.minestom.entity.Player;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import fr.themode.minestom.net.player.PlayerConnection; import fr.themode.minestom.net.player.PlayerConnection;
import fr.themode.minestom.utils.PacketUtils; import fr.themode.minestom.utils.PacketUtils;
import simplenet.packet.Packet;
import java.util.Collection; import java.util.Collection;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;

View File

@ -1,14 +1,14 @@
package fr.themode.minestom.net.packet; package fr.themode.minestom.net.packet;
import com.github.simplenet.Client;
import com.github.simplenet.utility.exposed.consumer.BooleanConsumer;
import com.github.simplenet.utility.exposed.consumer.ByteConsumer;
import com.github.simplenet.utility.exposed.consumer.FloatConsumer;
import com.github.simplenet.utility.exposed.consumer.ShortConsumer;
import fr.themode.minestom.net.ConnectionUtils; import fr.themode.minestom.net.ConnectionUtils;
import fr.themode.minestom.utils.BlockPosition; import fr.themode.minestom.utils.BlockPosition;
import fr.themode.minestom.utils.Utils; import fr.themode.minestom.utils.Utils;
import fr.themode.minestom.utils.consumer.StringConsumer; import fr.themode.minestom.utils.consumer.StringConsumer;
import simplenet.Client;
import simplenet.utility.exposed.consumer.BooleanConsumer;
import simplenet.utility.exposed.consumer.ByteConsumer;
import simplenet.utility.exposed.consumer.FloatConsumer;
import simplenet.utility.exposed.consumer.ShortConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.DoubleConsumer; import java.util.function.DoubleConsumer;

View File

@ -1,10 +1,12 @@
package fr.themode.minestom.net.packet; package fr.themode.minestom.net.packet;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.item.ItemStack;
import fr.themode.minestom.utils.BlockPosition; import fr.themode.minestom.utils.BlockPosition;
import fr.themode.minestom.utils.Utils; import fr.themode.minestom.utils.Utils;
import simplenet.packet.Packet; import fr.themode.minestom.utils.buffer.BufferWrapper;
import java.nio.ByteBuffer;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -83,6 +85,15 @@ public class PacketWriter {
consumer.accept(packet); consumer.accept(packet);
} }
public void writeBufferAndFree(BufferWrapper buffer) {
ByteBuffer byteBuffer = buffer.getByteBuffer();
int size = buffer.getSize();
byte[] cache = new byte[size];
byteBuffer.position(0).get(cache, 0, size);
writeBytes(cache);
buffer.free();
}
public void writeUuid(UUID uuid) { public void writeUuid(UUID uuid) {
writeLong(uuid.getMostSignificantBits()); writeLong(uuid.getMostSignificantBits());
writeLong(uuid.getLeastSignificantBits()); writeLong(uuid.getLeastSignificantBits());

View File

@ -1,12 +1,13 @@
package fr.themode.minestom.net.packet.server.play; package fr.themode.minestom.net.packet.server.play;
import fr.adamaq01.ozao.net.Buffer;
import fr.themode.minestom.instance.Chunk; import fr.themode.minestom.instance.Chunk;
import fr.themode.minestom.net.packet.PacketWriter; import fr.themode.minestom.net.packet.PacketWriter;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import fr.themode.minestom.utils.BlockPosition; import fr.themode.minestom.utils.BlockPosition;
import fr.themode.minestom.utils.SerializerUtils; import fr.themode.minestom.utils.SerializerUtils;
import fr.themode.minestom.utils.Utils; import fr.themode.minestom.utils.Utils;
import fr.themode.minestom.utils.buffer.BufferUtils;
import fr.themode.minestom.utils.buffer.BufferWrapper;
import net.querz.nbt.CompoundTag; import net.querz.nbt.CompoundTag;
import net.querz.nbt.DoubleTag; import net.querz.nbt.DoubleTag;
import net.querz.nbt.LongArrayTag; import net.querz.nbt.LongArrayTag;
@ -22,34 +23,35 @@ public class ChunkDataPacket implements ServerPacket {
public Chunk chunk; public Chunk chunk;
public int[] sections; public int[] sections;
private static final int CHUNK_SECTION_COUNT = 16;
private static final int BITS_PER_ENTRY = 14;
private static final int MAX_BUFFER_SIZE = (Short.BYTES + Byte.BYTES + 5 * Byte.BYTES + (4096 * BITS_PER_ENTRY / Long.SIZE * Long.BYTES)) * CHUNK_SECTION_COUNT + 256 * Integer.BYTES;
@Override @Override
public void write(PacketWriter writer) { public void write(PacketWriter writer) {
writer.writeInt(chunk.getChunkX()); writer.writeInt(chunk.getChunkX());
writer.writeInt(chunk.getChunkZ()); writer.writeInt(chunk.getChunkZ());
writer.writeBoolean(fullChunk); writer.writeBoolean(fullChunk);
int mask = 0; int mask = 0;
Buffer blocks = Buffer.create(); BufferWrapper blocks = BufferUtils.getBuffer(MAX_BUFFER_SIZE);
for (int i = 0; i < 16; i++) { for (int i = 0; i < CHUNK_SECTION_COUNT; i++) {
if (fullChunk || (sections.length == 16 && sections[i] != 0)) { if (fullChunk || (sections.length == CHUNK_SECTION_COUNT && sections[i] != 0)) {
mask |= 1 << i; mask |= 1 << i;
short[] section = getSection(chunk, i); short[] section = getSection(chunk, i);
Utils.writeBlocks(blocks, section, 14); Utils.writeBlocks(blocks, section, BITS_PER_ENTRY);
} }
} }
// Biome data // Biome data
if (fullChunk) { if (fullChunk) {
int[] biomeData = new int[256];
for (int z = 0; z < 16; z++) { for (int z = 0; z < 16; z++) {
for (int x = 0; x < 16; x++) { for (int x = 0; x < 16; x++) {
biomeData[z * 16 | x] = chunk.getBiome().getId(); blocks.putInt(chunk.getBiome().getId());
} }
} }
for (int i = 0; i < biomeData.length; i++) {
blocks.putInt(biomeData[i]);
}
} }
writer.writeVarInt(mask); writer.writeVarInt(mask);
// Heightmap // Heightmap
@ -76,8 +78,8 @@ public class ChunkDataPacket implements ServerPacket {
writer.writeBytes(data); writer.writeBytes(data);
} }
writer.writeVarInt(blocks.length()); writer.writeVarInt(blocks.getSize());
writer.writeBytes(blocks.getAllBytes()); writer.writeBufferAndFree(blocks);
// Block entities // Block entities
Set<Integer> blockEntities = chunk.getBlockEntities(); Set<Integer> blockEntities = chunk.getBlockEntities();

View File

@ -1,8 +1,8 @@
package fr.themode.minestom.net.packet.server.play; package fr.themode.minestom.net.packet.server.play;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.net.packet.PacketWriter; import fr.themode.minestom.net.packet.PacketWriter;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import simplenet.packet.Packet;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -1,9 +1,9 @@
package fr.themode.minestom.net.packet.server.play; package fr.themode.minestom.net.packet.server.play;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.net.packet.PacketWriter; import fr.themode.minestom.net.packet.PacketWriter;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import fr.themode.minestom.utils.Position; import fr.themode.minestom.utils.Position;
import simplenet.packet.Packet;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -1,9 +1,9 @@
package fr.themode.minestom.net.packet.server.play; package fr.themode.minestom.net.packet.server.play;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.net.packet.PacketWriter; import fr.themode.minestom.net.packet.PacketWriter;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import fr.themode.minestom.utils.Position; import fr.themode.minestom.utils.Position;
import simplenet.packet.Packet;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -1,10 +1,10 @@
package fr.themode.minestom.net.player; package fr.themode.minestom.net.player;
import com.github.simplenet.Client;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.net.ConnectionState; import fr.themode.minestom.net.ConnectionState;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import fr.themode.minestom.utils.PacketUtils; import fr.themode.minestom.utils.PacketUtils;
import simplenet.Client;
import simplenet.packet.Packet;
public class PlayerConnection { public class PlayerConnection {
@ -20,11 +20,11 @@ public class PlayerConnection {
public void sendPacket(Packet packet) { public void sendPacket(Packet packet) {
if (isOnline()) if (isOnline())
packet.writeAndFlush(client); packet.queueAndFlush(client);
} }
public void writeUnencodedPacket(Packet packet) { public void writeUnencodedPacket(Packet packet) {
packet.write(client); packet.queue(client);
} }
public void sendPacket(ServerPacket serverPacket) { public void sendPacket(ServerPacket serverPacket) {

View File

@ -1,8 +1,8 @@
package fr.themode.minestom.utils; package fr.themode.minestom.utils;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.net.packet.PacketWriter; import fr.themode.minestom.net.packet.PacketWriter;
import fr.themode.minestom.net.packet.server.ServerPacket; import fr.themode.minestom.net.packet.server.ServerPacket;
import simplenet.packet.Packet;
import java.util.function.Consumer; import java.util.function.Consumer;

View File

@ -1,12 +1,12 @@
package fr.themode.minestom.utils; package fr.themode.minestom.utils;
import fr.adamaq01.ozao.net.Buffer; import com.github.simplenet.Client;
import com.github.simplenet.packet.Packet;
import fr.themode.minestom.chat.Chat; import fr.themode.minestom.chat.Chat;
import fr.themode.minestom.item.ItemStack; import fr.themode.minestom.item.ItemStack;
import fr.themode.minestom.net.ConnectionUtils; import fr.themode.minestom.net.ConnectionUtils;
import fr.themode.minestom.utils.buffer.BufferWrapper;
import fr.themode.minestom.utils.consumer.StringConsumer; import fr.themode.minestom.utils.consumer.StringConsumer;
import simplenet.Client;
import simplenet.packet.Packet;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -42,7 +42,7 @@ public class Utils {
}); });
} }
public static void writeVarIntBuffer(Buffer buffer, int value) { public static void writeVarIntBuffer(BufferWrapper buffer, int value) {
do { do {
byte temp = (byte) (value & 0b01111111); byte temp = (byte) (value & 0b01111111);
value >>>= 7; value >>>= 7;
@ -64,25 +64,6 @@ public class Utils {
} while (value != 0); } while (value != 0);
} }
public static int readVarInt(Client client) {
int numRead = 0;
int result = 0;
byte read;
do {
read = client.readByte();
int value = (read & 0b01111111);
result |= (value << (7 * numRead));
numRead++;
if (numRead > 5) {
throw new RuntimeException("VarInt is too big");
}
} while ((read & 0b10000000) != 0);
return result;
}
// ??
public static int lengthVarInt(int value) { public static int lengthVarInt(int value) {
int i = 0; int i = 0;
do { do {
@ -96,48 +77,6 @@ public class Utils {
return i; return i;
} }
public static int lengthVarLong(long value) {
int i = 0;
do {
i++;
byte temp = (byte) (value & 0b01111111);
value >>>= 7;
if (value != 0) {
temp |= 0b10000000;
}
} while (value != 0);
return i;
}
public static void writeVarLong(Packet packet, long value) {
do {
byte temp = (byte) (value & 0b01111111);
value >>>= 7;
if (value != 0) {
temp |= 0b10000000;
}
packet.putByte(temp);
} while (value != 0);
}
public static long readVarLong(Client client) {
int numRead = 0;
long result = 0;
byte read;
do {
read = client.readByte();
int value = (read & 0b01111111);
result |= (value << (7 * numRead));
numRead++;
if (numRead > 10) {
throw new RuntimeException("VarLong is too big");
}
} while ((read & 0b10000000) != 0);
return result;
}
public static void writePosition(Packet packet, int x, int y, int z) { public static void writePosition(Packet packet, int x, int y, int z) {
packet.putLong(SerializerUtils.positionToLong(x, y, z)); packet.putLong(SerializerUtils.positionToLong(x, y, z));
} }
@ -170,6 +109,11 @@ public class Utils {
packet.putInt(1); packet.putInt(1);
} }
// Damage
packet.putByte((byte) 0x02);
packet.putString("Damage");
packet.putShort(itemStack.getDamage());
// Display // Display
packet.putByte((byte) 0x0A); // Compound packet.putByte((byte) 0x0A); // Compound
packet.putString("display"); packet.putString("display");
@ -181,18 +125,18 @@ public class Utils {
} }
// TODO lore // TODO lore
packet.putByte((byte) 0x08); /*packet.putByte((byte) 0x08);
packet.putString("Lore"); packet.putString("Lore");
packet.putString(Chat.rawText("a line")); packet.putString(Chat.rawText("a line"));*/
packet.putByte((byte) 0); // End display compound packet.putByte((byte) 0); // End display compound
packet.putByte((byte) 0); // End nbt packet.putByte((byte) 0); // End nbt
} }
} }
public static void writeBlocks(Buffer buffer, short[] blocksId, int bitsPerEntry) { public static void writeBlocks(BufferWrapper buffer, short[] blocksId, int bitsPerEntry) {
short count = 0; short count = 0;
for (short id : blocksId) for (short id : blocksId)
if (id != 0) if (id != 0)
@ -210,8 +154,8 @@ public class Utils {
} }
} }
} }
long[] data = encodeBlocks(blocksData, 14); long[] data = encodeBlocks(blocksData, bitsPerEntry);
writeVarIntBuffer(buffer, data.length); buffer.putVarInt(data.length);
for (int i = 0; i < data.length; i++) { for (int i = 0; i < data.length; i++) {
buffer.putLong(data[i]); buffer.putLong(data[i]);
} }

View File

@ -0,0 +1,19 @@
package fr.themode.minestom.utils.buffer;
import pbbl.heap.HeapByteBufferPool;
import java.nio.ByteBuffer;
public class BufferUtils {
private static HeapByteBufferPool pool = new HeapByteBufferPool();
public static BufferWrapper getBuffer(int size) {
return new BufferWrapper(pool.take(size));
}
protected static void giveBuffer(ByteBuffer byteBuffer) {
pool.give(byteBuffer);
}
}

View File

@ -0,0 +1,52 @@
package fr.themode.minestom.utils.buffer;
import fr.themode.minestom.utils.Utils;
import java.nio.ByteBuffer;
public class BufferWrapper {
private ByteBuffer byteBuffer;
private int size;
protected BufferWrapper(ByteBuffer byteBuffer) {
this.byteBuffer = byteBuffer;
}
public void putByte(byte b) {
this.byteBuffer.put(b);
size += Byte.BYTES;
}
public void putShort(short s) {
this.byteBuffer.putShort(s);
size += Short.BYTES;
}
public void putInt(int n) {
this.byteBuffer.putInt(n);
size += Integer.BYTES;
}
public void putLong(long l) {
this.byteBuffer.putLong(l);
size += Long.BYTES;
}
public void putVarInt(int n) {
Utils.writeVarIntBuffer(this, n);
size += Utils.lengthVarInt(n);
}
public void free() {
BufferUtils.giveBuffer(getByteBuffer());
}
public int getSize() {
return size;
}
public ByteBuffer getByteBuffer() {
return byteBuffer;
}
}