forked from BLOCKFANTASY/LOOHP-Limbo
Minecraft 1.18
This commit is contained in:
parent
2909c77d62
commit
14a1f50abf
4
pom.xml
4
pom.xml
|
|
@ -5,7 +5,7 @@
|
|||
<groupId>com.loohp</groupId>
|
||||
<artifactId>Limbo</artifactId>
|
||||
<name>Limbo</name>
|
||||
<version>0.6.4-ALPHA</version>
|
||||
<version>0.6.5-ALPHA</version>
|
||||
|
||||
<description>Standalone Limbo Minecraft Server.</description>
|
||||
<url>https://github.com/LOOHP/Limbo</url>
|
||||
|
|
@ -117,7 +117,7 @@
|
|||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>${project.artifactId}-${project.version}-1.17.1</finalName>
|
||||
<finalName>${project.artifactId}-${project.version}-1.18</finalName>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
|
|
|
|||
|
|
@ -106,8 +106,8 @@ public class Limbo {
|
|||
|
||||
//===========================
|
||||
|
||||
public final String serverImplementationVersion = "1.17.1";
|
||||
public final int serverImplmentationProtocol = 756;
|
||||
public final String serverImplementationVersion = "1.18";
|
||||
public final int serverImplmentationProtocol = 757;
|
||||
public final String limboImplementationVersion;
|
||||
|
||||
private AtomicBoolean isRunning;
|
||||
|
|
|
|||
|
|
@ -15,8 +15,7 @@ import com.loohp.limbo.entity.Entity;
|
|||
import com.loohp.limbo.location.Location;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutEntityDestroy;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutEntityMetadata;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutLightUpdate;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutMapChunk;
|
||||
import com.loohp.limbo.server.packets.ClientboundLevelChunkWithLightPacket;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntity;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutSpawnEntityLiving;
|
||||
import com.loohp.limbo.server.packets.PacketPlayOutUnloadChunk;
|
||||
|
|
@ -112,9 +111,6 @@ public class PlayerInteractManager {
|
|||
for (Chunk chunk : chunksInRange) {
|
||||
if (!chunks.containsKey(chunk)) {
|
||||
int[] chunkPos = world.getChunkXZ(chunk);
|
||||
PacketPlayOutMapChunk packet0 = new PacketPlayOutMapChunk(chunkPos[0], chunkPos[1], chunk, world.getEnvironment());
|
||||
player.clientConnection.sendPacket(packet0);
|
||||
|
||||
List<Byte[]> blockChunk = world.getLightEngineBlock().getBlockLightBitMask(chunkPos[0], chunkPos[1]);
|
||||
if (blockChunk == null) {
|
||||
blockChunk = new ArrayList<>();
|
||||
|
|
@ -126,7 +122,7 @@ public class PlayerInteractManager {
|
|||
if (skyChunk == null) {
|
||||
skyChunk = new ArrayList<>();
|
||||
}
|
||||
PacketPlayOutLightUpdate chunkdata = new PacketPlayOutLightUpdate(chunkPos[0], chunkPos[1], true, skyChunk, blockChunk);
|
||||
ClientboundLevelChunkWithLightPacket chunkdata = new ClientboundLevelChunkWithLightPacket(chunkPos[0], chunkPos[1], chunk, world.getEnvironment(), true, skyChunk, blockChunk);
|
||||
player.clientConnection.sendPacket(chunkdata);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,84 @@
|
|||
package com.loohp.limbo.registry;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
import org.json.simple.parser.ParseException;
|
||||
|
||||
import com.loohp.limbo.Limbo;
|
||||
import com.loohp.limbo.utils.NamespacedKey;
|
||||
|
||||
public class Registry {
|
||||
|
||||
public static final BlockEntityRegistry BLOCK_ENTITY_TYPE;
|
||||
|
||||
static {
|
||||
String name = "registries.json";
|
||||
File file = new File(Limbo.getInstance().getInternalDataFolder(), name);
|
||||
if (!file.exists()) {
|
||||
try (InputStream in = Limbo.class.getClassLoader().getResourceAsStream(name)) {
|
||||
Files.copy(in, file.toPath());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
Map<NamespacedKey, Integer> blockEntityType = new HashMap<>();
|
||||
try (InputStreamReader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
|
||||
JSONObject json = (JSONObject) new JSONParser().parse(reader);
|
||||
|
||||
JSONObject blockEntityJson = (JSONObject) ((JSONObject) json.get("minecraft:block_entity_type")).get("entries");
|
||||
for (Object obj : blockEntityJson.keySet()) {
|
||||
String key = obj.toString();
|
||||
int id = (int) (long) ((JSONObject) blockEntityJson.get(key)).get("protocol_id");
|
||||
blockEntityType.put(new NamespacedKey(key), id);
|
||||
}
|
||||
} catch (IOException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
BLOCK_ENTITY_TYPE = new BlockEntityRegistry(blockEntityType);
|
||||
}
|
||||
|
||||
public static class BlockEntityRegistry {
|
||||
|
||||
private Map<NamespacedKey, Integer> blockEntityType;
|
||||
|
||||
private BlockEntityRegistry(Map<NamespacedKey, Integer> blockEntityType) {
|
||||
this.blockEntityType = blockEntityType;
|
||||
}
|
||||
|
||||
public int getId(NamespacedKey key) {
|
||||
Integer exact = blockEntityType.get(key);
|
||||
if (exact != null) {
|
||||
return exact;
|
||||
}
|
||||
List<String> toTest = new LinkedList<>();
|
||||
toTest.add(key.getKey());
|
||||
if (key.getKey().contains("head")) {
|
||||
toTest.add("skull");
|
||||
}
|
||||
for (Entry<NamespacedKey, Integer> entry : blockEntityType.entrySet()) {
|
||||
NamespacedKey namespacedKey = entry.getKey();
|
||||
for (String each : toTest) {
|
||||
if (namespacedKey.getNamespace().equals(key.getNamespace()) && (each.contains(namespacedKey.getKey()) || namespacedKey.getKey().contains(each))) {
|
||||
return entry.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -374,7 +374,7 @@ public class ClientConnection extends Thread {
|
|||
worldSpawn = joinEvent.getSpawnLocation();
|
||||
World world = worldSpawn.getWorld();
|
||||
|
||||
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds(), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, properties.isReducedDebugInfo(), true, false, true);
|
||||
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds(), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, 8, properties.isReducedDebugInfo(), true, false, true);
|
||||
sendPacket(join);
|
||||
Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode());
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,304 @@
|
|||
package com.loohp.limbo.server.packets;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.loohp.limbo.registry.Registry;
|
||||
import com.loohp.limbo.utils.BitsUtils;
|
||||
import com.loohp.limbo.utils.DataTypeIO;
|
||||
import com.loohp.limbo.utils.NamespacedKey;
|
||||
import com.loohp.limbo.world.Environment;
|
||||
import com.loohp.limbo.world.GeneratedBlockDataMappings;
|
||||
|
||||
import net.querz.mca.Chunk;
|
||||
import net.querz.mca.Section;
|
||||
import net.querz.nbt.tag.CompoundTag;
|
||||
import net.querz.nbt.tag.ListTag;
|
||||
|
||||
public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
private Chunk chunk;
|
||||
private Environment environment;
|
||||
private boolean trustEdges;
|
||||
private long[] skyLightBitMasks;
|
||||
private long[] blockLightBitMasks;
|
||||
private long[] skyLightBitMasksEmpty;
|
||||
private long[] blockLightBitMasksEmpty;
|
||||
private List<Byte[]> skylightArrays;
|
||||
private List<Byte[]> blocklightArrays;
|
||||
|
||||
public ClientboundLevelChunkWithLightPacket(int chunkX, int chunkZ, Chunk chunk, Environment environment, boolean trustEdges, List<Byte[]> skylightArrays, List<Byte[]> blocklightArrays) {
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
this.chunk = chunk;
|
||||
this.environment = environment;
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
this.trustEdges = trustEdges;
|
||||
this.skylightArrays = skylightArrays;
|
||||
this.blocklightArrays = blocklightArrays;
|
||||
|
||||
BitSet skyLightBitSet = new BitSet();
|
||||
BitSet skyLightBitSetInverse = new BitSet();
|
||||
for (int i = Math.min(17, skylightArrays.size() - 1); i >= 0; i--) {
|
||||
skyLightBitSet.set(i, skylightArrays.get(i) != null);
|
||||
skyLightBitSetInverse.set(i, skylightArrays.get(i) == null);
|
||||
}
|
||||
skyLightBitMasks = skyLightBitSet.toLongArray();
|
||||
skyLightBitMasksEmpty = skyLightBitSetInverse.toLongArray();
|
||||
|
||||
BitSet blockLightBitSet = new BitSet();
|
||||
BitSet blockLightBitSetInverse = new BitSet();
|
||||
for (int i = Math.min(17, blocklightArrays.size() - 1); i >= 0; i--) {
|
||||
blockLightBitSet.set(i, blocklightArrays.get(i) != null);
|
||||
blockLightBitSetInverse.set(i, blocklightArrays.get(i) == null);
|
||||
}
|
||||
blockLightBitMasks = blockLightBitSet.toLongArray();
|
||||
blockLightBitMasksEmpty = blockLightBitSetInverse.toLongArray();
|
||||
}
|
||||
|
||||
public Chunk getChunk() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
return chunkX;
|
||||
}
|
||||
|
||||
public int getChunkZ() {
|
||||
return chunkZ;
|
||||
}
|
||||
|
||||
public Environment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
public boolean isTrustEdges() {
|
||||
return trustEdges;
|
||||
}
|
||||
|
||||
public long[] getSkyLightBitMasks() {
|
||||
return skyLightBitMasks;
|
||||
}
|
||||
|
||||
public long[] getBlockLightBitMasks() {
|
||||
return blockLightBitMasks;
|
||||
}
|
||||
|
||||
public List<Byte[]> getSkylightArrays() {
|
||||
return skylightArrays;
|
||||
}
|
||||
|
||||
public List<Byte[]> getBlocklightArrays() {
|
||||
return blocklightArrays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serializePacket() throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
DataOutputStream output = new DataOutputStream(buffer);
|
||||
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||
|
||||
output.writeInt(chunkX);
|
||||
output.writeInt(chunkZ);
|
||||
DataTypeIO.writeCompoundTag(output, chunk.getHeightMaps());
|
||||
|
||||
ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
|
||||
DataOutputStream dataOut = new DataOutputStream(dataBuffer);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
Section section = chunk.getSection(i);
|
||||
if (section != null) {
|
||||
int counter = 0;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
CompoundTag tag = section.getBlockStateAt(x, y, z);
|
||||
if (tag != null && !tag.getString("Name").equals("minecraft:air")) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dataOut.writeShort(counter);
|
||||
|
||||
int newBits = 32 - Integer.numberOfLeadingZeros(section.getPalette().size() - 1);
|
||||
newBits = Math.max(newBits, 4);
|
||||
//Limbo.getInstance().getConsole().sendMessage(i + " " + newBits);
|
||||
if (newBits <= 8) {
|
||||
/*
|
||||
if (newBits == 4) {
|
||||
dataOut.writeByte(4);
|
||||
} else {
|
||||
newBits = 8;
|
||||
ChunkDataUtils.adjustBlockStateBits(newBits, section, chunk.getDataVersion());
|
||||
dataOut.writeByte(8);
|
||||
}
|
||||
*/
|
||||
dataOut.writeByte(newBits);
|
||||
|
||||
DataTypeIO.writeVarInt(dataOut, section.getPalette().size());
|
||||
//Limbo.getInstance().getConsole().sendMessage(section.getPalette().size());
|
||||
Iterator<CompoundTag> itr1 = section.getPalette().iterator();
|
||||
//Limbo.getInstance().getConsole().sendMessage("Nonnull -> " + i + " " + newBits);
|
||||
while (itr1.hasNext()) {
|
||||
CompoundTag tag = itr1.next();
|
||||
DataTypeIO.writeVarInt(dataOut, GeneratedBlockDataMappings.getGlobalPaletteIDFromState(tag));
|
||||
//Limbo.getInstance().getConsole().sendMessage(tag + " -> " + GeneratedDataUtils.getGlobalPaletteIDFromState(tag));
|
||||
}
|
||||
|
||||
BitSet bits = BitSet.valueOf(section.getBlockStates());
|
||||
int shift = 64 % newBits;
|
||||
int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits));
|
||||
for (int u = 64; u <= bits.length(); u += 64) {
|
||||
bits = BitsUtils.shiftAfter(bits, u - shift, shift);
|
||||
}
|
||||
|
||||
long[] formattedLongs = bits.toLongArray();
|
||||
//Limbo.getInstance().getConsole().sendMessage(longsNeeded + "");
|
||||
|
||||
DataTypeIO.writeVarInt(dataOut, longsNeeded);
|
||||
for (int u = 0; u < longsNeeded; u++) {
|
||||
if (u < formattedLongs.length) {
|
||||
dataOut.writeLong(formattedLongs[u]);
|
||||
} else {
|
||||
dataOut.writeLong(0);
|
||||
}
|
||||
//Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates()));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
dataOut.writeByte(15);
|
||||
section.getBlockStates();
|
||||
int longsNeeded = 1024;
|
||||
List<Integer> list = new LinkedList<>();
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
list.add(GeneratedBlockDataMappings.getGlobalPaletteIDFromState(section.getBlockStateAt(x, y, z)));
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Long> globalLongs = new ArrayList<>();
|
||||
long currentLong = 0;
|
||||
int pos = 0;
|
||||
int u = 0;
|
||||
while (pos < longsNeeded) {
|
||||
if (u == 3) {
|
||||
globalLongs.add(currentLong);
|
||||
currentLong = 0;
|
||||
u = 0;
|
||||
pos++;
|
||||
} else {
|
||||
u++;
|
||||
}
|
||||
int id = list.isEmpty() ? 0 : list.remove(0);
|
||||
currentLong = currentLong << 15;
|
||||
currentLong |= (long) id;
|
||||
}
|
||||
DataTypeIO.writeVarInt(dataOut, longsNeeded);
|
||||
for (int j = 0; j < longsNeeded; j++) {
|
||||
if (j < globalLongs.size()) {
|
||||
dataOut.writeLong(globalLongs.get(j));
|
||||
} else {
|
||||
dataOut.writeLong(0);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
dataOut.writeShort(0);
|
||||
dataOut.writeByte(0);
|
||||
DataTypeIO.writeVarInt(dataOut, 0);
|
||||
DataTypeIO.writeVarInt(dataOut, 0);
|
||||
}
|
||||
int biome;
|
||||
if (environment.equals(Environment.END)) {
|
||||
biome = 9; //the_end
|
||||
} else if (environment.equals(Environment.NETHER)) {
|
||||
biome = 8; //nether_waste
|
||||
} else if (environment.equals(Environment.NORMAL)) {
|
||||
biome = 1; //plains
|
||||
} else {
|
||||
biome = 1; //plains
|
||||
}
|
||||
dataOut.writeByte(0);
|
||||
DataTypeIO.writeVarInt(dataOut, biome);
|
||||
DataTypeIO.writeVarInt(dataOut, 0);
|
||||
}
|
||||
|
||||
byte[] data = dataBuffer.toByteArray();
|
||||
DataTypeIO.writeVarInt(output, data.length);
|
||||
output.write(data);
|
||||
|
||||
ListTag<CompoundTag> tileEntities = chunk.getTileEntities();
|
||||
DataTypeIO.writeVarInt(output, tileEntities.size());
|
||||
for (CompoundTag each : tileEntities) {
|
||||
int x = each.getInt("x") % 16;
|
||||
int y = each.getInt("y");
|
||||
int z = each.getInt("z") % 16;
|
||||
output.writeByte((x << 4) | z);
|
||||
output.writeShort(y);
|
||||
Integer id = Registry.BLOCK_ENTITY_TYPE.getId(new NamespacedKey(chunk.getBlockStateAt(x, y, z).getString("Name")));
|
||||
System.out.println(chunk.getBlockStateAt(x, y, z).toString());
|
||||
System.out.println(each.toString());
|
||||
DataTypeIO.writeVarInt(output, id == null ? -1 : id);
|
||||
DataTypeIO.writeCompoundTag(output, each);
|
||||
}
|
||||
|
||||
output.writeBoolean(trustEdges);
|
||||
DataTypeIO.writeVarInt(output, skyLightBitMasks.length);
|
||||
for (long l : skyLightBitMasks) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
DataTypeIO.writeVarInt(output, blockLightBitMasks.length);
|
||||
for (long l : blockLightBitMasks) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
DataTypeIO.writeVarInt(output, skyLightBitMasksEmpty.length);
|
||||
for (long l : skyLightBitMasksEmpty) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
DataTypeIO.writeVarInt(output, blockLightBitMasksEmpty.length);
|
||||
for (long l : blockLightBitMasksEmpty) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
|
||||
DataTypeIO.writeVarInt(output, skylightArrays.stream().mapToInt(each -> each == null ? 0 : 1).sum());
|
||||
for (int i = skylightArrays.size() - 1; i >= 0; i--) {
|
||||
Byte[] array = skylightArrays.get(i);
|
||||
if (array != null) {
|
||||
DataTypeIO.writeVarInt(output, 2048);
|
||||
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
|
||||
for (int u = 0; u < array.length; u++) {
|
||||
output.writeByte(array[u]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DataTypeIO.writeVarInt(output, blocklightArrays.stream().mapToInt(each -> each == null ? 0 : 1).sum());
|
||||
for (int i = blocklightArrays.size() - 1; i >= 0; i--) {
|
||||
Byte[] array = blocklightArrays.get(i);
|
||||
if (array != null) {
|
||||
DataTypeIO.writeVarInt(output, 2048);
|
||||
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
|
||||
for (int u = 0; u < array.length; u++) {
|
||||
output.writeByte(array[u]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
package com.loohp.limbo.server.packets;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
import com.loohp.limbo.utils.DataTypeIO;
|
||||
|
||||
public class PacketPlayOutLightUpdate extends PacketOut {
|
||||
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
private boolean trustEdges;
|
||||
private long[] skyLightBitMasks;
|
||||
private long[] blockLightBitMasks;
|
||||
private long[] skyLightBitMasksEmpty;
|
||||
private long[] blockLightBitMasksEmpty;
|
||||
private List<Byte[]> skylightArrays;
|
||||
private List<Byte[]> blocklightArrays;
|
||||
|
||||
public PacketPlayOutLightUpdate(int chunkX, int chunkZ, boolean trustEdges, List<Byte[]> skylightArrays, List<Byte[]> blocklightArrays) {
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
this.trustEdges = trustEdges;
|
||||
this.skylightArrays = skylightArrays;
|
||||
this.blocklightArrays = blocklightArrays;
|
||||
|
||||
BitSet skyLightBitSet = new BitSet();
|
||||
BitSet skyLightBitSetInverse = new BitSet();
|
||||
for (int i = Math.min(17, skylightArrays.size() - 1); i >= 0; i--) {
|
||||
skyLightBitSet.set(i, skylightArrays.get(i) != null);
|
||||
skyLightBitSetInverse.set(i, skylightArrays.get(i) == null);
|
||||
}
|
||||
skyLightBitMasks = skyLightBitSet.toLongArray();
|
||||
skyLightBitMasksEmpty = skyLightBitSetInverse.toLongArray();
|
||||
|
||||
BitSet blockLightBitSet = new BitSet();
|
||||
BitSet blockLightBitSetInverse = new BitSet();
|
||||
for (int i = Math.min(17, blocklightArrays.size() - 1); i >= 0; i--) {
|
||||
blockLightBitSet.set(i, blocklightArrays.get(i) != null);
|
||||
blockLightBitSetInverse.set(i, blocklightArrays.get(i) == null);
|
||||
}
|
||||
blockLightBitMasks = blockLightBitSet.toLongArray();
|
||||
blockLightBitMasksEmpty = blockLightBitSetInverse.toLongArray();
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
return chunkX;
|
||||
}
|
||||
|
||||
public int getChunkZ() {
|
||||
return chunkZ;
|
||||
}
|
||||
|
||||
public boolean isTrustEdges() {
|
||||
return trustEdges;
|
||||
}
|
||||
|
||||
public long[] getSkyLightBitMasks() {
|
||||
return skyLightBitMasks;
|
||||
}
|
||||
|
||||
public long[] getBlockLightBitMasks() {
|
||||
return blockLightBitMasks;
|
||||
}
|
||||
|
||||
public List<Byte[]> getSkylightArrays() {
|
||||
return skylightArrays;
|
||||
}
|
||||
|
||||
public List<Byte[]> getBlocklightArrays() {
|
||||
return blocklightArrays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serializePacket() throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
DataOutputStream output = new DataOutputStream(buffer);
|
||||
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||
DataTypeIO.writeVarInt(output, chunkX);
|
||||
DataTypeIO.writeVarInt(output, chunkZ);
|
||||
output.writeBoolean(trustEdges);
|
||||
DataTypeIO.writeVarInt(output, skyLightBitMasks.length);
|
||||
for (long l : skyLightBitMasks) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
DataTypeIO.writeVarInt(output, blockLightBitMasks.length);
|
||||
for (long l : blockLightBitMasks) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
DataTypeIO.writeVarInt(output, skyLightBitMasksEmpty.length);
|
||||
for (long l : skyLightBitMasksEmpty) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
DataTypeIO.writeVarInt(output, blockLightBitMasksEmpty.length);
|
||||
for (long l : blockLightBitMasksEmpty) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
|
||||
DataTypeIO.writeVarInt(output, skylightArrays.stream().mapToInt(each -> each == null ? 0 : 1).sum());
|
||||
for (int i = skylightArrays.size() - 1; i >= 0; i--) {
|
||||
Byte[] array = skylightArrays.get(i);
|
||||
if (array != null) {
|
||||
DataTypeIO.writeVarInt(output, 2048);
|
||||
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
|
||||
for (int u = 0; u < array.length; u++) {
|
||||
output.writeByte(array[u]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DataTypeIO.writeVarInt(output, blocklightArrays.stream().mapToInt(each -> each == null ? 0 : 1).sum());
|
||||
for (int i = blocklightArrays.size() - 1; i >= 0; i--) {
|
||||
Byte[] array = blocklightArrays.get(i);
|
||||
if (array != null) {
|
||||
DataTypeIO.writeVarInt(output, 2048);
|
||||
//System.out.println(Arrays.toString(ArrayUtils.toPrimitive(array)));
|
||||
for (int u = 0; u < array.length; u++) {
|
||||
output.writeByte(array[u]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -27,12 +27,13 @@ public class PacketPlayOutLogin extends PacketOut {
|
|||
private long hashedSeed;
|
||||
private byte maxPlayers;
|
||||
private int viewDistance;
|
||||
private int simulationDistance;
|
||||
private boolean reducedDebugInfo;
|
||||
private boolean enableRespawnScreen;
|
||||
private boolean isDebug;
|
||||
private boolean isFlat;
|
||||
|
||||
public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, List<World> worlds, CompoundTag dimensionCodec, World world, long hashedSeed, byte maxPlayers, int viewDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, boolean isFlat) {
|
||||
public PacketPlayOutLogin(int entityId, boolean isHardcore, GameMode gamemode, List<World> worlds, CompoundTag dimensionCodec, World world, long hashedSeed, byte maxPlayers, int viewDistance, int simulationDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean isDebug, boolean isFlat) {
|
||||
this.entityId = entityId;
|
||||
this.isHardcore = isHardcore;
|
||||
this.gamemode = gamemode;
|
||||
|
|
@ -43,6 +44,7 @@ public class PacketPlayOutLogin extends PacketOut {
|
|||
this.hashedSeed = hashedSeed;
|
||||
this.maxPlayers = maxPlayers;
|
||||
this.viewDistance = viewDistance;
|
||||
this.simulationDistance = simulationDistance;
|
||||
this.reducedDebugInfo = reducedDebugInfo;
|
||||
this.enableRespawnScreen = enableRespawnScreen;
|
||||
this.isDebug = isDebug;
|
||||
|
|
@ -89,6 +91,10 @@ public class PacketPlayOutLogin extends PacketOut {
|
|||
return viewDistance;
|
||||
}
|
||||
|
||||
public int getSimulationDistance() {
|
||||
return simulationDistance;
|
||||
}
|
||||
|
||||
public boolean isReducedDebugInfo() {
|
||||
return reducedDebugInfo;
|
||||
}
|
||||
|
|
@ -133,6 +139,7 @@ public class PacketPlayOutLogin extends PacketOut {
|
|||
output.writeLong(hashedSeed);
|
||||
DataTypeIO.writeVarInt(output, maxPlayers);
|
||||
DataTypeIO.writeVarInt(output, viewDistance);
|
||||
DataTypeIO.writeVarInt(output, simulationDistance);
|
||||
output.writeBoolean(reducedDebugInfo);
|
||||
output.writeBoolean(enableRespawnScreen);
|
||||
output.writeBoolean(isDebug);
|
||||
|
|
|
|||
|
|
@ -1,212 +0,0 @@
|
|||
package com.loohp.limbo.server.packets;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import com.loohp.limbo.utils.BitsUtils;
|
||||
import com.loohp.limbo.utils.DataTypeIO;
|
||||
import com.loohp.limbo.world.Environment;
|
||||
import com.loohp.limbo.world.GeneratedBlockDataMappings;
|
||||
|
||||
import net.querz.mca.Chunk;
|
||||
import net.querz.mca.Section;
|
||||
import net.querz.nbt.tag.CompoundTag;
|
||||
import net.querz.nbt.tag.ListTag;
|
||||
|
||||
public class PacketPlayOutMapChunk extends PacketOut {
|
||||
|
||||
private int chunkX;
|
||||
private int chunkZ;
|
||||
private Chunk chunk;
|
||||
private Environment environment;
|
||||
|
||||
public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk, Environment environment) {
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
this.chunk = chunk;
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public PacketPlayOutMapChunk(int chunkX, int chunkZ, Chunk chunk) {
|
||||
this(chunkZ, chunkZ, chunk, Environment.NORMAL);
|
||||
}
|
||||
|
||||
public Chunk getChunk() {
|
||||
return chunk;
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
return chunkX;
|
||||
}
|
||||
|
||||
public int getChunkZ() {
|
||||
return chunkZ;
|
||||
}
|
||||
|
||||
public Environment getEnvironment() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serializePacket() throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
|
||||
DataOutputStream output = new DataOutputStream(buffer);
|
||||
output.writeByte(Packet.getPlayOut().get(getClass()));
|
||||
|
||||
output.writeInt(chunkX);
|
||||
output.writeInt(chunkZ);
|
||||
BitSet chunkPresent = new BitSet();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
Section section = chunk.getSection(i);
|
||||
chunkPresent.set(i, section != null);
|
||||
}
|
||||
long[] bitmasks = chunkPresent.toLongArray();
|
||||
DataTypeIO.writeVarInt(output, bitmasks.length);
|
||||
for (long l : bitmasks) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
DataTypeIO.writeCompoundTag(output, chunk.getHeightMaps());
|
||||
|
||||
DataTypeIO.writeVarInt(output, 1024);
|
||||
int biome;
|
||||
if (environment.equals(Environment.END)) {
|
||||
biome = 9; //the_end
|
||||
} else if (environment.equals(Environment.NETHER)) {
|
||||
biome = 8; //nether_waste
|
||||
} else if (environment.equals(Environment.NORMAL)) {
|
||||
biome = 1; //plains
|
||||
} else {
|
||||
biome = 1; //plains
|
||||
}
|
||||
for (int i = 0; i < 1024; i++) {
|
||||
DataTypeIO.writeVarInt(output, biome);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
|
||||
DataOutputStream dataOut = new DataOutputStream(dataBuffer);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
Section section = chunk.getSection(i);
|
||||
if (section != null) {
|
||||
int counter = 0;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
CompoundTag tag = section.getBlockStateAt(x, y, z);
|
||||
if (tag != null && !tag.getString("Name").equals("minecraft:air")) {
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dataOut.writeShort(counter);
|
||||
|
||||
int newBits = 32 - Integer.numberOfLeadingZeros(section.getPalette().size() - 1);
|
||||
newBits = Math.max(newBits, 4);
|
||||
//Limbo.getInstance().getConsole().sendMessage(i + " " + newBits);
|
||||
if (newBits <= 8) {
|
||||
/*
|
||||
if (newBits == 4) {
|
||||
dataOut.writeByte(4);
|
||||
} else {
|
||||
newBits = 8;
|
||||
ChunkDataUtils.adjustBlockStateBits(newBits, section, chunk.getDataVersion());
|
||||
dataOut.writeByte(8);
|
||||
}
|
||||
*/
|
||||
dataOut.writeByte(newBits);
|
||||
|
||||
DataTypeIO.writeVarInt(dataOut, section.getPalette().size());
|
||||
//Limbo.getInstance().getConsole().sendMessage(section.getPalette().size());
|
||||
Iterator<CompoundTag> itr1 = section.getPalette().iterator();
|
||||
//Limbo.getInstance().getConsole().sendMessage("Nonnull -> " + i + " " + newBits);
|
||||
while (itr1.hasNext()) {
|
||||
CompoundTag tag = itr1.next();
|
||||
DataTypeIO.writeVarInt(dataOut, GeneratedBlockDataMappings.getGlobalPaletteIDFromState(tag));
|
||||
//Limbo.getInstance().getConsole().sendMessage(tag + " -> " + GeneratedDataUtils.getGlobalPaletteIDFromState(tag));
|
||||
}
|
||||
|
||||
BitSet bits = BitSet.valueOf(section.getBlockStates());
|
||||
int shift = 64 % newBits;
|
||||
int longsNeeded = (int) Math.ceil(4096 / (double) (64 / newBits));
|
||||
for (int u = 64; u <= bits.length(); u += 64) {
|
||||
bits = BitsUtils.shiftAfter(bits, u - shift, shift);
|
||||
}
|
||||
|
||||
long[] formattedLongs = bits.toLongArray();
|
||||
//Limbo.getInstance().getConsole().sendMessage(longsNeeded + "");
|
||||
|
||||
DataTypeIO.writeVarInt(dataOut, longsNeeded);
|
||||
for (int u = 0; u < longsNeeded; u++) {
|
||||
if (u < formattedLongs.length) {
|
||||
dataOut.writeLong(formattedLongs[u]);
|
||||
} else {
|
||||
dataOut.writeLong(0);
|
||||
}
|
||||
//Limbo.getInstance().getConsole().sendMessage(Arrays.toString(section.getBlockStates()));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
dataOut.writeByte(15);
|
||||
section.getBlockStates();
|
||||
int longsNeeded = 1024;
|
||||
List<Integer> list = new LinkedList<>();
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
list.add(GeneratedBlockDataMappings.getGlobalPaletteIDFromState(section.getBlockStateAt(x, y, z)));
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Long> globalLongs = new ArrayList<>();
|
||||
long currentLong = 0;
|
||||
int pos = 0;
|
||||
int u = 0;
|
||||
while (pos < longsNeeded) {
|
||||
if (u == 3) {
|
||||
globalLongs.add(currentLong);
|
||||
currentLong = 0;
|
||||
u = 0;
|
||||
pos++;
|
||||
} else {
|
||||
u++;
|
||||
}
|
||||
int id = list.isEmpty() ? 0 : list.remove(0);
|
||||
currentLong = currentLong << 15;
|
||||
currentLong |= (long) id;
|
||||
}
|
||||
DataTypeIO.writeVarInt(dataOut, longsNeeded);
|
||||
for (int j = 0; j < longsNeeded; j++) {
|
||||
if (j < globalLongs.size()) {
|
||||
dataOut.writeLong(globalLongs.get(j));
|
||||
} else {
|
||||
dataOut.writeLong(0);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
byte[] data = dataBuffer.toByteArray();
|
||||
DataTypeIO.writeVarInt(output, data.length);
|
||||
output.write(data);
|
||||
|
||||
ListTag<CompoundTag> tileEntities = chunk.getTileEntities();
|
||||
DataTypeIO.writeVarInt(output, tileEntities.size());
|
||||
for (CompoundTag each : tileEntities) {
|
||||
DataTypeIO.writeCompoundTag(output, each);
|
||||
}
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
|
@ -28,9 +28,8 @@
|
|||
"PacketPlayOutSpawnPosition": "0x4B",
|
||||
"PacketPlayOutChat": "0x0F",
|
||||
"PacketPlayOutPlayerAbilities": "0x32",
|
||||
"PacketPlayOutMapChunk": "0x22",
|
||||
"ClientboundLevelChunkWithLightPacket": "0x22",
|
||||
"PacketPlayOutUnloadChunk": "0x1D",
|
||||
"PacketPlayOutLightUpdate": "0x25",
|
||||
"PacketPlayOutKeepAlive": "0x21",
|
||||
"PacketPlayOutPlayerInfo": "0x36",
|
||||
"PacketPlayOutUpdateViewPosition": "0x49",
|
||||
|
|
@ -45,7 +44,7 @@
|
|||
"PacketPlayOutSpawnEntity": "0x00",
|
||||
"PacketPlayOutSpawnEntityLiving": "0x02",
|
||||
"PacketPlayOutHeldItemChange": "0x48",
|
||||
"PacketPlayOutPlayerListHeaderFooter": "0x5E",
|
||||
"PacketPlayOutPlayerListHeaderFooter": "0x5F",
|
||||
"PacketPlayOutResourcePackSend": "0x3C"
|
||||
},
|
||||
"StatusIn": {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue