mirror of https://github.com/Minestom/Minestom.git
Initial non-working 1.18 commit
Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
parent
83ab75d1bf
commit
d3b55700e2
|
@ -54,8 +54,8 @@ public final class MinecraftServer {
|
|||
|
||||
public final static Logger LOGGER = LoggerFactory.getLogger(MinecraftServer.class);
|
||||
|
||||
public static final String VERSION_NAME = "1.17.1";
|
||||
public static final int PROTOCOL_VERSION = 756;
|
||||
public static final String VERSION_NAME = "21w42a";
|
||||
public static final int PROTOCOL_VERSION = 1073741870;
|
||||
|
||||
// Threads
|
||||
public static final String THREAD_NAME_BENCHMARK = "Ms-Benchmark";
|
||||
|
|
|
@ -291,7 +291,8 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
|
|||
// Recipes end
|
||||
|
||||
// Tags
|
||||
this.playerConnection.sendPacket(TagsPacket.DEFAULT_TAGS);
|
||||
// FIXME: 1.18
|
||||
//this.playerConnection.sendPacket(TagsPacket.DEFAULT_TAGS);
|
||||
|
||||
// Some client updates
|
||||
this.playerConnection.sendPacket(getPropertiesPacket()); // Send default properties
|
||||
|
|
|
@ -11,6 +11,8 @@ import net.minestom.server.instance.block.BlockHandler;
|
|||
import net.minestom.server.network.packet.server.CachedPacket;
|
||||
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
|
||||
import net.minestom.server.network.packet.server.play.UpdateLightPacket;
|
||||
import net.minestom.server.network.packet.server.play.data.ChunkPacketData;
|
||||
import net.minestom.server.network.packet.server.play.data.LightPacketData;
|
||||
import net.minestom.server.utils.ArrayUtils;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.Utils;
|
||||
|
@ -20,10 +22,7 @@ import org.jetbrains.annotations.NotNull;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Represents a {@link Chunk} which store each individual block in memory.
|
||||
|
@ -125,14 +124,14 @@ public class DynamicChunk extends Chunk {
|
|||
@Override
|
||||
public void sendChunk(@NotNull Player player) {
|
||||
if (!isLoaded()) return;
|
||||
player.sendPackets(lightCache, chunkCache);
|
||||
player.sendPacket(chunkCache.retrieve());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk() {
|
||||
if (!isLoaded()) return;
|
||||
if (getViewers().isEmpty()) return;
|
||||
sendPacketsToViewers(lightCache, chunkCache);
|
||||
sendPacketToViewers(chunkCache.retrieve());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
@ -153,42 +152,49 @@ public class DynamicChunk extends Chunk {
|
|||
}
|
||||
|
||||
private synchronized @NotNull ChunkDataPacket createChunkPacket() {
|
||||
ChunkDataPacket packet = new ChunkDataPacket();
|
||||
packet.biomes = biomes;
|
||||
packet.chunkX = chunkX;
|
||||
packet.chunkZ = chunkZ;
|
||||
packet.sections = sectionMap.clone(); // TODO deep clone
|
||||
packet.entries = entries.clone();
|
||||
|
||||
final NBTCompound heightmapsNBT;
|
||||
// TODO: don't hardcode heightmaps
|
||||
// Heightmap
|
||||
int dimensionHeight = getInstance().getDimensionType().getHeight();
|
||||
int[] motionBlocking = new int[16 * 16];
|
||||
int[] worldSurface = new int[16 * 16];
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
motionBlocking[x + z * 16] = 0;
|
||||
worldSurface[x + z * 16] = dimensionHeight - 1;
|
||||
{
|
||||
int dimensionHeight = getInstance().getDimensionType().getHeight();
|
||||
int[] motionBlocking = new int[16 * 16];
|
||||
int[] worldSurface = new int[16 * 16];
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
motionBlocking[x + z * 16] = 0;
|
||||
worldSurface[x + z * 16] = dimensionHeight - 1;
|
||||
}
|
||||
}
|
||||
final int bitsForHeight = MathUtils.bitsToRepresent(dimensionHeight);
|
||||
heightmapsNBT = new NBTCompound()
|
||||
.setLongArray("MOTION_BLOCKING", Utils.encodeBlocks(motionBlocking, bitsForHeight))
|
||||
.setLongArray("WORLD_SURFACE", Utils.encodeBlocks(worldSurface, bitsForHeight));
|
||||
}
|
||||
final int bitsForHeight = MathUtils.bitsToRepresent(dimensionHeight);
|
||||
packet.heightmapsNBT = new NBTCompound()
|
||||
.setLongArray("MOTION_BLOCKING", Utils.encodeBlocks(motionBlocking, bitsForHeight))
|
||||
.setLongArray("WORLD_SURFACE", Utils.encodeBlocks(worldSurface, bitsForHeight));
|
||||
|
||||
ChunkDataPacket packet = new ChunkDataPacket();
|
||||
packet.chunkX = chunkX;
|
||||
packet.chunkZ = chunkZ;
|
||||
// TODO deep clone sections
|
||||
packet.chunkData = new ChunkPacketData(heightmapsNBT, sectionMap, entries);
|
||||
packet.lightData = createLightData();
|
||||
return packet;
|
||||
}
|
||||
|
||||
private synchronized @NotNull UpdateLightPacket createLightPacket() {
|
||||
List<byte[]> skyLights = new ArrayList<>();
|
||||
List<byte[]> blockLights = new ArrayList<>();
|
||||
|
||||
UpdateLightPacket updateLightPacket = new UpdateLightPacket();
|
||||
updateLightPacket.chunkX = getChunkX();
|
||||
updateLightPacket.chunkZ = getChunkZ();
|
||||
updateLightPacket.lightData = createLightData();
|
||||
return updateLightPacket;
|
||||
}
|
||||
|
||||
updateLightPacket.skyLight = skyLights;
|
||||
updateLightPacket.blockLight = blockLights;
|
||||
private LightPacketData createLightData() {
|
||||
BitSet skyMask = new BitSet();
|
||||
BitSet blockMask = new BitSet();
|
||||
BitSet emptySkyMask = new BitSet();
|
||||
BitSet emptyBlockMask = new BitSet();
|
||||
List<byte[]> skyLights = new ArrayList<>();
|
||||
List<byte[]> blockLights = new ArrayList<>();
|
||||
|
||||
final var sections = getSections();
|
||||
for (var entry : sections.entrySet()) {
|
||||
|
@ -200,14 +206,17 @@ public class DynamicChunk extends Chunk {
|
|||
|
||||
if (!ArrayUtils.empty(skyLight)) {
|
||||
skyLights.add(skyLight);
|
||||
updateLightPacket.skyLightMask.set(index);
|
||||
skyMask.set(index);
|
||||
}
|
||||
if (!ArrayUtils.empty(blockLight)) {
|
||||
blockLights.add(blockLight);
|
||||
updateLightPacket.blockLightMask.set(index);
|
||||
blockMask.set(index);
|
||||
}
|
||||
}
|
||||
return updateLightPacket;
|
||||
return new LightPacketData(true,
|
||||
skyMask, blockMask,
|
||||
emptySkyMask, emptyBlockMask,
|
||||
skyLights, blockLights);
|
||||
}
|
||||
|
||||
private @Nullable Section getOptionalSection(int y) {
|
||||
|
|
|
@ -4,6 +4,8 @@ import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap;
|
|||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.instance.Chunk;
|
||||
import net.minestom.server.utils.MathUtils;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.binary.Writeable;
|
||||
import net.minestom.server.utils.clone.PublicCloneable;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -16,7 +18,7 @@ import static net.minestom.server.instance.Chunk.CHUNK_SECTION_SIZE;
|
|||
* 0 is always interpreted as being air, reason being that the block array will be filled with it during initialization.
|
||||
*/
|
||||
@ApiStatus.Internal
|
||||
public final class Palette implements PublicCloneable<Palette> {
|
||||
public final class Palette implements Writeable, PublicCloneable<Palette> {
|
||||
|
||||
/**
|
||||
* The maximum bits per entry value.
|
||||
|
@ -286,6 +288,26 @@ public final class Palette implements PublicCloneable<Palette> {
|
|||
return bitsPerEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeByte((byte) bitsPerEntry);
|
||||
// Palette
|
||||
if (bitsPerEntry < 9) {
|
||||
// Palette has to exist
|
||||
final short[] paletteBlockArray = getPaletteBlockArray();
|
||||
final int paletteSize = getLastPaletteIndex() + 1;
|
||||
writer.writeVarInt(paletteSize);
|
||||
for (int i = 0; i < paletteSize; i++) {
|
||||
writer.writeVarInt(paletteBlockArray[i]);
|
||||
}
|
||||
}
|
||||
// Raw
|
||||
writer.writeVarInt(blocks.length);
|
||||
for (long datum : blocks) {
|
||||
writer.writeLong(datum);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Palette clone() {
|
||||
try {
|
||||
|
|
|
@ -95,20 +95,21 @@ public class ServerPacketIdentifier {
|
|||
public static final int SET_PASSENGERS = 0x54;
|
||||
public static final int TEAMS = 0x55;
|
||||
public static final int UPDATE_SCORE = 0x56;
|
||||
public static final int SET_TITLE_SUBTITLE = 0x57;
|
||||
public static final int TIME_UPDATE = 0x58;
|
||||
public static final int SET_TITLE_TEXT = 0x59;
|
||||
public static final int SET_TITLE_TIME = 0x5A;
|
||||
public static final int ENTITY_SOUND_EFFECT = 0x5B;
|
||||
public static final int SOUND_EFFECT = 0x5C;
|
||||
public static final int STOP_SOUND = 0x5D;
|
||||
public static final int PLAYER_LIST_HEADER_AND_FOOTER = 0x5E;
|
||||
public static final int NBT_QUERY_RESPONSE = 0x5F;
|
||||
public static final int COLLECT_ITEM = 0x60;
|
||||
public static final int ENTITY_TELEPORT = 0x61;
|
||||
public static final int ADVANCEMENTS = 0x62;
|
||||
public static final int ENTITY_PROPERTIES = 0x63;
|
||||
public static final int ENTITY_EFFECT = 0x64;
|
||||
public static final int DECLARE_RECIPES = 0x65;
|
||||
public static final int TAGS = 0x66;
|
||||
public static final int SET_SIMULATION_DISTANCE = 0x57;
|
||||
public static final int SET_TITLE_SUBTITLE = 0x58;
|
||||
public static final int TIME_UPDATE = 0x59;
|
||||
public static final int SET_TITLE_TEXT = 0x5A;
|
||||
public static final int SET_TITLE_TIME = 0x5B;
|
||||
public static final int ENTITY_SOUND_EFFECT = 0x5C;
|
||||
public static final int SOUND_EFFECT = 0x5D;
|
||||
public static final int STOP_SOUND = 0x5E;
|
||||
public static final int PLAYER_LIST_HEADER_AND_FOOTER = 0x5F;
|
||||
public static final int NBT_QUERY_RESPONSE = 0x60;
|
||||
public static final int COLLECT_ITEM = 0x61;
|
||||
public static final int ENTITY_TELEPORT = 0x62;
|
||||
public static final int ADVANCEMENTS = 0x63;
|
||||
public static final int ENTITY_PROPERTIES = 0x64;
|
||||
public static final int ENTITY_EFFECT = 0x65;
|
||||
public static final int DECLARE_RECIPES = 0x66;
|
||||
public static final int TAGS = 0x67;
|
||||
}
|
||||
|
|
|
@ -1,40 +1,17 @@
|
|||
package net.minestom.server.network.packet.server.play;
|
||||
|
||||
import it.unimi.dsi.fastutil.ints.Int2LongRBTreeMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.instance.Section;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.block.BlockHandler;
|
||||
import net.minestom.server.instance.palette.Palette;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.tag.Tag;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.Utils;
|
||||
import net.minestom.server.network.packet.server.play.data.ChunkPacketData;
|
||||
import net.minestom.server.network.packet.server.play.data.LightPacketData;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||
import net.minestom.server.world.biomes.Biome;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
|
||||
public class ChunkDataPacket implements ServerPacket {
|
||||
|
||||
public Biome[] biomes;
|
||||
public int chunkX, chunkZ;
|
||||
|
||||
public Map<Integer, Section> sections = new HashMap<>();
|
||||
public Map<Integer, Block> entries = new HashMap<>();
|
||||
|
||||
private static final byte CHUNK_SECTION_COUNT = 16;
|
||||
|
||||
public NBTCompound heightmapsNBT = new NBTCompound();
|
||||
public ChunkPacketData chunkData;
|
||||
public LightPacketData lightData;
|
||||
|
||||
public ChunkDataPacket() {
|
||||
}
|
||||
|
@ -43,159 +20,15 @@ public class ChunkDataPacket implements ServerPacket {
|
|||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeInt(chunkX);
|
||||
writer.writeInt(chunkZ);
|
||||
|
||||
ByteBuffer blocks = PacketUtils.localBuffer();
|
||||
|
||||
Int2LongRBTreeMap maskMap = new Int2LongRBTreeMap();
|
||||
|
||||
for (var entry : sections.entrySet()) {
|
||||
final int index = entry.getKey();
|
||||
final Section section = entry.getValue();
|
||||
|
||||
final int lengthIndex = index % 64;
|
||||
final int maskIndex = index / 64;
|
||||
|
||||
long mask = maskMap.get(maskIndex);
|
||||
mask |= 1L << lengthIndex;
|
||||
maskMap.put(maskIndex, mask);
|
||||
|
||||
Utils.writePaletteBlocks(blocks, section.getPalette());
|
||||
}
|
||||
|
||||
final int maskSize = maskMap.size();
|
||||
writer.writeVarInt(maskSize);
|
||||
for (int i = 0; i < maskSize; i++) {
|
||||
final long value = maskMap.getOrDefault(i, 0);
|
||||
writer.writeLong(value);
|
||||
}
|
||||
|
||||
// Heightmap
|
||||
writer.writeNBT("", heightmapsNBT);
|
||||
|
||||
// Biomes
|
||||
if (biomes == null || biomes.length == 0) {
|
||||
writer.writeVarInt(0);
|
||||
} else {
|
||||
writer.writeVarInt(biomes.length);
|
||||
for (Biome biome : biomes) {
|
||||
writer.writeVarInt(biome.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// Data
|
||||
writer.writeVarInt(blocks.position());
|
||||
writer.write(blocks);
|
||||
|
||||
// Block entities
|
||||
if (entries == null || entries.isEmpty()) {
|
||||
writer.writeVarInt(0);
|
||||
} else {
|
||||
List<NBTCompound> compounds = new ArrayList<>();
|
||||
for (var entry : entries.entrySet()) {
|
||||
final int index = entry.getKey();
|
||||
final Block block = entry.getValue();
|
||||
final String blockEntity = block.registry().blockEntity();
|
||||
if (blockEntity == null) continue; // Only send block entities to client
|
||||
NBTCompound resultNbt = new NBTCompound();
|
||||
// Append handler tags
|
||||
final BlockHandler handler = block.handler();
|
||||
if (handler != null) {
|
||||
final NBTCompound blockNbt = Objects.requireNonNullElseGet(block.nbt(), NBTCompound::new);
|
||||
for (Tag<?> tag : handler.getBlockEntityTags()) {
|
||||
final var value = tag.read(blockNbt);
|
||||
if (value != null) {
|
||||
// Tag is present and valid
|
||||
tag.writeUnsafe(resultNbt, value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Complete nbt shall be sent if the block has no handler
|
||||
// Necessary to support all vanilla blocks
|
||||
final NBTCompound blockNbt = block.nbt();
|
||||
if (blockNbt != null) resultNbt = blockNbt;
|
||||
}
|
||||
// Add block entity
|
||||
final var blockPosition = ChunkUtils.getBlockPosition(index, chunkX, chunkZ);
|
||||
resultNbt.setString("id", blockEntity)
|
||||
.setInt("x", blockPosition.blockX())
|
||||
.setInt("y", blockPosition.blockY())
|
||||
.setInt("z", blockPosition.blockZ());
|
||||
compounds.add(resultNbt);
|
||||
}
|
||||
writer.writeVarInt(compounds.size());
|
||||
compounds.forEach(nbtCompound -> writer.writeNBT("", nbtCompound));
|
||||
}
|
||||
this.chunkData.write(writer);
|
||||
this.lightData.write(writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(@NotNull BinaryReader reader) {
|
||||
this.chunkX = reader.readInt();
|
||||
this.chunkZ = reader.readInt();
|
||||
|
||||
int maskCount = reader.readVarInt();
|
||||
long[] masks = new long[maskCount];
|
||||
for (int i = 0; i < maskCount; i++) {
|
||||
masks[i] = reader.readLong();
|
||||
}
|
||||
try {
|
||||
// TODO: Use heightmaps
|
||||
// unused at the moment
|
||||
this.heightmapsNBT = (NBTCompound) reader.readTag();
|
||||
|
||||
// Biomes
|
||||
int[] biomesIds = reader.readVarIntArray();
|
||||
this.biomes = new Biome[biomesIds.length];
|
||||
for (int i = 0; i < biomesIds.length; i++) {
|
||||
this.biomes[i] = MinecraftServer.getBiomeManager().getById(biomesIds[i]);
|
||||
}
|
||||
|
||||
// Data
|
||||
this.sections = new HashMap<>();
|
||||
int blockArrayLength = reader.readVarInt();
|
||||
if (maskCount > 0) {
|
||||
final long mask = masks[0]; // TODO support for variable size
|
||||
for (int sectionIndex = 0; sectionIndex < CHUNK_SECTION_COUNT; sectionIndex++) {
|
||||
final boolean hasSection = (mask & 1 << sectionIndex) != 0;
|
||||
if (!hasSection) continue;
|
||||
final Section section = sections.computeIfAbsent(sectionIndex, i -> new Section());
|
||||
final Palette palette = section.getPalette();
|
||||
final short blockCount = reader.readShort();
|
||||
palette.setBlockCount(blockCount);
|
||||
final byte bitsPerEntry = reader.readByte();
|
||||
// Resize palette if necessary
|
||||
if (bitsPerEntry > palette.getBitsPerEntry()) {
|
||||
palette.resize(bitsPerEntry);
|
||||
}
|
||||
// Retrieve palette values
|
||||
if (bitsPerEntry < 9) {
|
||||
int paletteSize = reader.readVarInt();
|
||||
for (int i = 0; i < paletteSize; i++) {
|
||||
final int paletteValue = reader.readVarInt();
|
||||
palette.getPaletteBlockArray()[i] = (short) paletteValue;
|
||||
palette.getBlockPaletteMap().put((short) paletteValue, (short) i);
|
||||
}
|
||||
}
|
||||
// Read blocks
|
||||
palette.setBlocks(reader.readLongArray());
|
||||
}
|
||||
}
|
||||
|
||||
// Block entities
|
||||
final int blockEntityCount = reader.readVarInt();
|
||||
this.entries = new Int2ObjectOpenHashMap<>(blockEntityCount);
|
||||
for (int i = 0; i < blockEntityCount; i++) {
|
||||
NBTCompound tag = (NBTCompound) reader.readTag();
|
||||
final String id = tag.getString("id");
|
||||
final BlockHandler handler = MinecraftServer.getBlockManager().getHandlerOrDummy(id);
|
||||
final int x = tag.getInt("x");
|
||||
final int y = tag.getInt("y");
|
||||
final int z = tag.getInt("z");
|
||||
// TODO add to handlerMap & nbtMap
|
||||
}
|
||||
} catch (IOException | NBTException e) {
|
||||
MinecraftServer.getExceptionManager().handleException(e);
|
||||
// TODO: should we throw to avoid an invalid packet?
|
||||
}
|
||||
// TODO read
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -24,6 +24,7 @@ public class JoinGamePacket implements ServerPacket {
|
|||
public long hashedSeed;
|
||||
public int maxPlayers = 0; // Unused
|
||||
public int viewDistance;
|
||||
public int simulationViewDistance = 8;
|
||||
public boolean reducedDebugInfo = false;
|
||||
public boolean enableRespawnScreen = true;
|
||||
public boolean isDebug = false;
|
||||
|
@ -63,6 +64,7 @@ public class JoinGamePacket implements ServerPacket {
|
|||
writer.writeLong(hashedSeed);
|
||||
writer.writeVarInt(maxPlayers);
|
||||
writer.writeVarInt(viewDistance);
|
||||
writer.writeVarInt(simulationViewDistance);
|
||||
writer.writeBoolean(reducedDebugInfo);
|
||||
writer.writeBoolean(enableRespawnScreen);
|
||||
//debug
|
||||
|
|
|
@ -2,29 +2,16 @@ package net.minestom.server.network.packet.server.play;
|
|||
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.network.packet.server.ServerPacketIdentifier;
|
||||
import net.minestom.server.network.packet.server.play.data.LightPacketData;
|
||||
import net.minestom.server.utils.binary.BinaryReader;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
public class UpdateLightPacket implements ServerPacket {
|
||||
|
||||
public int chunkX;
|
||||
public int chunkZ;
|
||||
//todo make changeable
|
||||
public boolean trustEdges = true;
|
||||
|
||||
public BitSet skyLightMask = new BitSet();
|
||||
public BitSet blockLightMask = new BitSet();
|
||||
|
||||
public BitSet emptySkyLightMask = new BitSet();
|
||||
public BitSet emptyBlockLightMask = new BitSet();
|
||||
|
||||
public List<byte[]> skyLight = new ArrayList<>();
|
||||
public List<byte[]> blockLight = new ArrayList<>();
|
||||
public LightPacketData lightData;
|
||||
|
||||
/**
|
||||
* Default constructor, required for reflection operations.
|
||||
|
@ -37,25 +24,7 @@ public class UpdateLightPacket implements ServerPacket {
|
|||
writer.writeVarInt(chunkX);
|
||||
writer.writeVarInt(chunkZ);
|
||||
|
||||
writer.writeBoolean(trustEdges);
|
||||
|
||||
writer.writeLongArray(skyLightMask.toLongArray());
|
||||
writer.writeLongArray(blockLightMask.toLongArray());
|
||||
|
||||
writer.writeLongArray(emptySkyLightMask.toLongArray());
|
||||
writer.writeLongArray(emptyBlockLightMask.toLongArray());
|
||||
|
||||
writer.writeVarInt(skyLight.size());
|
||||
for (byte[] bytes : skyLight) {
|
||||
writer.writeVarInt(2048); // Always 2048 length
|
||||
writer.writeBytes(bytes);
|
||||
}
|
||||
|
||||
writer.writeVarInt(blockLight.size());
|
||||
for (byte[] bytes : blockLight) {
|
||||
writer.writeVarInt(2048); // Always 2048 length
|
||||
writer.writeBytes(bytes);
|
||||
}
|
||||
this.lightData.write(writer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,38 +32,7 @@ public class UpdateLightPacket implements ServerPacket {
|
|||
chunkX = reader.readVarInt();
|
||||
chunkZ = reader.readVarInt();
|
||||
|
||||
trustEdges = reader.readBoolean();
|
||||
|
||||
skyLightMask = BitSet.valueOf(reader.readLongArray());
|
||||
blockLightMask = BitSet.valueOf(reader.readLongArray());
|
||||
|
||||
emptySkyLightMask = BitSet.valueOf(reader.readLongArray());
|
||||
emptyBlockLightMask = BitSet.valueOf(reader.readLongArray());
|
||||
|
||||
// sky light
|
||||
skyLight.clear();
|
||||
final int skyLightCount = reader.readVarInt();
|
||||
for (int i = 0; i < skyLightCount; i++) {
|
||||
int length = reader.readVarInt();
|
||||
if (length != 2048) {
|
||||
throw new IllegalStateException("Length must be 2048.");
|
||||
}
|
||||
byte[] bytes = reader.readBytes(length);
|
||||
skyLight.add(bytes);
|
||||
}
|
||||
|
||||
// block light
|
||||
blockLight.clear();
|
||||
final int blockLightCount = reader.readVarInt();
|
||||
for (int i = 0; i < blockLightCount; i++) {
|
||||
int length = reader.readVarInt();
|
||||
if (length != 2048) {
|
||||
throw new IllegalStateException("Length must be 2048.");
|
||||
}
|
||||
|
||||
byte[] bytes = reader.readBytes(length);
|
||||
blockLight.add(bytes);
|
||||
}
|
||||
// TODO read light data
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package net.minestom.server.network.packet.server.play.data;
|
||||
|
||||
import net.minestom.server.instance.Section;
|
||||
import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.instance.palette.Palette;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.binary.Writeable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class ChunkPacketData implements Writeable {
|
||||
private final NBTCompound heightmaps;
|
||||
private final Map<Integer, Section> sections;
|
||||
private final Map<Integer, Block> blockEntities;
|
||||
|
||||
public ChunkPacketData(NBTCompound heightmaps, Map<Integer, Section> sections, Map<Integer, Block> blockEntities) {
|
||||
this.heightmaps = heightmaps.deepClone();
|
||||
this.sections = Map.copyOf(sections);
|
||||
this.blockEntities = Map.copyOf(blockEntities);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeNBT("", this.heightmaps);
|
||||
// Data
|
||||
ByteBuffer localBuffer = PacketUtils.localBuffer();
|
||||
for (int i = 0; i < 0; i++) { // FIXME: palettes
|
||||
final Section section = Objects.requireNonNullElseGet(sections.get(i), Section::new);
|
||||
final Palette blockPalette = section.getPalette();
|
||||
writer.writeShort(blockPalette.getBlockCount());
|
||||
blockPalette.write(writer); // Blocks
|
||||
new Palette(2, 2).write(writer); // Biomes
|
||||
}
|
||||
writer.writeVarInt(localBuffer.position());
|
||||
writer.write(localBuffer);
|
||||
// Block entities
|
||||
writer.writeVarInt(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package net.minestom.server.network.packet.server.play.data;
|
||||
|
||||
import net.minestom.server.utils.binary.BinaryWriter;
|
||||
import net.minestom.server.utils.binary.Writeable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
public final class LightPacketData implements Writeable {
|
||||
private final boolean trustEdges;
|
||||
private final BitSet skyMask;
|
||||
private final BitSet blockMask;
|
||||
private final BitSet emptySkyMask;
|
||||
private final BitSet emptyBlockMask;
|
||||
private final List<byte[]> skyLight;
|
||||
private final List<byte[]> blockLight;
|
||||
|
||||
public LightPacketData(boolean trustEdges,
|
||||
BitSet skyMask, BitSet blockMask,
|
||||
BitSet emptySkyMask, BitSet emptyBlockMask,
|
||||
List<byte[]> skyLight, List<byte[]> blockLight) {
|
||||
this.trustEdges = trustEdges;
|
||||
this.skyMask = skyMask;
|
||||
this.blockMask = blockMask;
|
||||
this.emptySkyMask = emptySkyMask;
|
||||
this.emptyBlockMask = emptyBlockMask;
|
||||
this.skyLight = skyLight;
|
||||
this.blockLight = blockLight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(@NotNull BinaryWriter writer) {
|
||||
writer.writeBoolean(trustEdges);
|
||||
|
||||
writer.writeLongArray(skyMask.toLongArray());
|
||||
writer.writeLongArray(blockMask.toLongArray());
|
||||
|
||||
writer.writeLongArray(emptySkyMask.toLongArray());
|
||||
writer.writeLongArray(emptyBlockMask.toLongArray());
|
||||
|
||||
writer.writeVarInt(skyLight.size());
|
||||
for (byte[] bytes : skyLight) {
|
||||
writer.writeVarInt(2048); // Always 2048 length
|
||||
writer.writeBytes(bytes);
|
||||
}
|
||||
|
||||
writer.writeVarInt(blockLight.size());
|
||||
for (byte[] bytes : blockLight) {
|
||||
writer.writeVarInt(2048); // Always 2048 length
|
||||
writer.writeBytes(bytes);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package net.minestom.server.utils;
|
||||
|
||||
import net.minestom.server.instance.palette.Palette;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
@ -110,31 +109,6 @@ public final class Utils {
|
|||
return new UUID(uuidMost, uuidLeast);
|
||||
}
|
||||
|
||||
public static void writePaletteBlocks(ByteBuffer buffer, Palette palette) {
|
||||
final short blockCount = palette.getBlockCount();
|
||||
final int bitsPerEntry = palette.getBitsPerEntry();
|
||||
|
||||
buffer.putShort(blockCount);
|
||||
buffer.put((byte) bitsPerEntry);
|
||||
|
||||
// Palette
|
||||
if (bitsPerEntry < 9) {
|
||||
// Palette has to exist
|
||||
final short[] paletteBlockArray = palette.getPaletteBlockArray();
|
||||
final int paletteSize = palette.getLastPaletteIndex() + 1;
|
||||
writeVarInt(buffer, paletteSize);
|
||||
for (int i = 0; i < paletteSize; i++) {
|
||||
writeVarInt(buffer, paletteBlockArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final long[] blocks = palette.getBlocks();
|
||||
writeVarInt(buffer, blocks.length);
|
||||
for (long datum : blocks) {
|
||||
buffer.putLong(datum);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int[] MAGIC = {
|
||||
-1, -1, 0, Integer.MIN_VALUE, 0, 0, 1431655765, 1431655765, 0, Integer.MIN_VALUE,
|
||||
0, 1, 858993459, 858993459, 0, 715827882, 715827882, 0, 613566756, 613566756,
|
||||
|
|
Loading…
Reference in New Issue