forked from BLOCKFANTASY/LOOHP-Limbo
Minecraft 1.21.5
This commit is contained in:
@@ -132,8 +132,8 @@ public final class Limbo {
|
||||
|
||||
//===========================
|
||||
|
||||
public final String SERVER_IMPLEMENTATION_VERSION = "1.21.4";
|
||||
public final int SERVER_IMPLEMENTATION_PROTOCOL = 769;
|
||||
public final String SERVER_IMPLEMENTATION_VERSION = "1.21.5";
|
||||
public final int SERVER_IMPLEMENTATION_PROTOCOL = 770;
|
||||
public final String LIMBO_IMPLEMENTATION_VERSION;
|
||||
|
||||
private final AtomicBoolean isRunning;
|
||||
@@ -163,7 +163,6 @@ public final class Limbo {
|
||||
@SuppressWarnings("deprecation")
|
||||
private Unsafe unsafe;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Limbo() throws IOException, ParseException, NumberFormatException, ClassNotFoundException, InterruptedException {
|
||||
instance = this;
|
||||
unsafe = new Unsafe(this);
|
||||
|
||||
@@ -31,8 +31,8 @@ import java.util.Map.Entry;
|
||||
|
||||
public class DataWatcher {
|
||||
|
||||
private Entity entity;
|
||||
private Map<Field, WatchableObject> values;
|
||||
private final Entity entity;
|
||||
private final Map<Field, WatchableObject> values;
|
||||
|
||||
public DataWatcher(Entity entity) {
|
||||
this.entity = entity;
|
||||
@@ -147,7 +147,7 @@ public class DataWatcher {
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public static @interface WatchableField {
|
||||
public @interface WatchableField {
|
||||
int MetadataIndex();
|
||||
WatchableObjectType WatchableObjectType();
|
||||
boolean IsOptional() default false;
|
||||
@@ -155,26 +155,37 @@ public class DataWatcher {
|
||||
int Bitmask() default 0x00;
|
||||
}
|
||||
|
||||
public static enum WatchableObjectType {
|
||||
public enum WatchableObjectType {
|
||||
BYTE(0),
|
||||
VARINT(1, 17),
|
||||
FLOAT(2),
|
||||
STRING(3),
|
||||
CHAT(4, 5),
|
||||
SLOT(6),
|
||||
BOOLEAN(7),
|
||||
ROTATION(8),
|
||||
POSITION(9, 10),
|
||||
DIRECTION(11),
|
||||
UUID(-1, 12),
|
||||
BLOCKID(-1, 13),
|
||||
NBT(14),
|
||||
PARTICLE(15),
|
||||
VILLAGER_DATA(16),
|
||||
POSE(18);
|
||||
VARINT(1, 20),
|
||||
VARLONG(2, 17),
|
||||
FLOAT(3),
|
||||
STRING(4),
|
||||
CHAT(5, 6),
|
||||
SLOT(7),
|
||||
BOOLEAN(8),
|
||||
ROTATION(9),
|
||||
POSITION(10, 11),
|
||||
DIRECTION(12),
|
||||
UUID(-1, 13),
|
||||
BLOCKID(14, 15),
|
||||
NBT(16),
|
||||
PARTICLE(17),
|
||||
PARTICLES(18),
|
||||
VILLAGER_DATA(19),
|
||||
POSE(21),
|
||||
CAT_VARIANT(22),
|
||||
WOLF_VARIANT(23),
|
||||
FROG_VARIANT(24),
|
||||
GLOBAL_POSITION(-1, 25),
|
||||
PAINTING_VARIANT(26),
|
||||
SNIFFER_STATE(27),
|
||||
ARMADILLO_STATE(28),
|
||||
VECTOR3(29),
|
||||
QUATERNION(30);
|
||||
|
||||
int typeId;
|
||||
int optionalTypeId;
|
||||
private final int typeId;
|
||||
private final int optionalTypeId;
|
||||
|
||||
WatchableObjectType(int typeId, int optionalTypeId) {
|
||||
this.typeId = typeId;
|
||||
|
||||
@@ -601,6 +601,7 @@ public class ClientConnection extends Thread {
|
||||
|
||||
PacketPlayOutGameStateChange gameEvent = new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.GameStateChangeEvent.LEVEL_CHUNKS_LOAD_START, 0);
|
||||
sendPacket(gameEvent);
|
||||
|
||||
player.playerInteractManager.update();
|
||||
|
||||
PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandsPacket(player);
|
||||
|
||||
+28
-16
@@ -28,6 +28,7 @@ import com.loohp.limbo.world.GeneratedBlockDataMappings;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.querz.mca.Chunk;
|
||||
import net.querz.mca.Section;
|
||||
import net.querz.nbt.io.SNBTUtil;
|
||||
import net.querz.nbt.tag.CompoundTag;
|
||||
import net.querz.nbt.tag.ListTag;
|
||||
|
||||
@@ -120,7 +121,14 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
|
||||
output.writeInt(chunkX);
|
||||
output.writeInt(chunkZ);
|
||||
DataTypeIO.writeTag(output, chunk.getHeightMaps());
|
||||
|
||||
DataTypeIO.writeVarInt(output, 1);
|
||||
DataTypeIO.writeVarInt(output, 4);
|
||||
long[] motionBlocking = chunk.getHeightMaps().getLongArray("MOTION_BLOCKING");
|
||||
DataTypeIO.writeVarInt(output, motionBlocking.length);
|
||||
for (long l : motionBlocking) {
|
||||
output.writeLong(l);
|
||||
}
|
||||
|
||||
ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
|
||||
DataOutputStream dataOut = new DataOutputStream(dataBuffer);
|
||||
@@ -164,7 +172,7 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
long[] formattedLongs = bits.toLongArray();
|
||||
//Limbo.getInstance().getConsole().sendMessage(longsNeeded + "");
|
||||
|
||||
DataTypeIO.writeVarInt(dataOut, longsNeeded);
|
||||
//DataTypeIO.writeVarInt(dataOut, longsNeeded); ???
|
||||
for (int u = 0; u < longsNeeded; u++) {
|
||||
if (u < formattedLongs.length) {
|
||||
dataOut.writeLong(formattedLongs[u]);
|
||||
@@ -203,7 +211,7 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
currentLong = currentLong << 16;
|
||||
currentLong |= id;
|
||||
}
|
||||
DataTypeIO.writeVarInt(dataOut, longsNeeded);
|
||||
//DataTypeIO.writeVarInt(dataOut, longsNeeded); ???
|
||||
for (int j = 0; j < longsNeeded; j++) {
|
||||
if (j < globalLongs.size()) {
|
||||
dataOut.writeLong(globalLongs.get(j));
|
||||
@@ -219,21 +227,21 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
dataOut.writeShort(0);
|
||||
dataOut.writeByte(0);
|
||||
DataTypeIO.writeVarInt(dataOut, 0);
|
||||
DataTypeIO.writeVarInt(dataOut, 0);
|
||||
//DataTypeIO.writeVarInt(dataOut, 0); ???
|
||||
}
|
||||
int biome;
|
||||
if (environment.equals(Environment.END)) {
|
||||
biome = 55; //the_end
|
||||
biome = 56; //the_end
|
||||
} else if (environment.equals(Environment.NETHER)) {
|
||||
biome = 34; //nether_waste
|
||||
} else if (environment.equals(Environment.NORMAL)) {
|
||||
biome = 39; //plains
|
||||
biome = 40; //plains
|
||||
} else {
|
||||
biome = 39; //plains
|
||||
biome = 40; //plains
|
||||
}
|
||||
dataOut.writeByte(0);
|
||||
DataTypeIO.writeVarInt(dataOut, biome);
|
||||
DataTypeIO.writeVarInt(dataOut, 0);
|
||||
//DataTypeIO.writeVarInt(dataOut, 0); ???
|
||||
}
|
||||
|
||||
byte[] data = dataBuffer.toByteArray();
|
||||
@@ -246,10 +254,14 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
int x = each.getInt("x") % 16;
|
||||
int y = each.getInt("y");
|
||||
int z = each.getInt("z") % 16;
|
||||
Key key = Key.key(chunk.getBlockStateAt(x, y, z).getString("Name"));
|
||||
int id = BuiltInRegistries.BLOCK_ENTITY_TYPE.getId(key);
|
||||
if (id < 0) {
|
||||
new IllegalStateException("Unable to get block entity type for " + key + " (Is this scheme created in the same Minecraft version as Limbo?)").printStackTrace();
|
||||
}
|
||||
output.writeByte(((x & 15) << 4) | (z & 15));
|
||||
output.writeShort(y);
|
||||
Integer id = BuiltInRegistries.BLOCK_ENTITY_TYPE.getId(Key.key(chunk.getBlockStateAt(x, y, z).getString("Name")));
|
||||
DataTypeIO.writeVarInt(output, id == null ? -1 : id);
|
||||
DataTypeIO.writeVarInt(output, Math.max(0, id));
|
||||
DataTypeIO.writeTag(output, each);
|
||||
}
|
||||
|
||||
@@ -276,9 +288,9 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
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]);
|
||||
}
|
||||
for (Byte aByte : array) {
|
||||
output.writeByte(aByte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,9 +300,9 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
|
||||
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]);
|
||||
}
|
||||
for (Byte aByte : array) {
|
||||
output.writeByte(aByte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -72,11 +72,11 @@ public class PacketPlayOutPlayerAbilities extends PacketOut {
|
||||
|
||||
DataOutputStream output = new DataOutputStream(buffer);
|
||||
output.writeByte(PacketRegistry.getPacketId(getClass()));
|
||||
|
||||
byte value = 0;
|
||||
for (PlayerAbilityFlags flag : flags) {
|
||||
value = (byte) (value | flag.getValue());
|
||||
}
|
||||
|
||||
output.writeByte(value);
|
||||
output.writeFloat(flySpeed);
|
||||
output.writeFloat(fieldOfField);
|
||||
|
||||
+8
-13
@@ -20,6 +20,8 @@
|
||||
package com.loohp.limbo.network.protocol.packets;
|
||||
|
||||
import com.loohp.limbo.registry.PacketRegistry;
|
||||
import com.loohp.limbo.utils.DataTypeIO;
|
||||
import com.loohp.limbo.world.ChunkPosition;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
@@ -27,20 +29,14 @@ import java.io.IOException;
|
||||
|
||||
public class PacketPlayOutUnloadChunk extends PacketOut {
|
||||
|
||||
private final int chunkX;
|
||||
private final int chunkZ;
|
||||
private final ChunkPosition chunkPosition;
|
||||
|
||||
public PacketPlayOutUnloadChunk(int chunkX, int chunkZ) {
|
||||
this.chunkX = chunkX;
|
||||
this.chunkZ = chunkZ;
|
||||
public PacketPlayOutUnloadChunk(ChunkPosition chunkPosition) {
|
||||
this.chunkPosition = chunkPosition;
|
||||
}
|
||||
|
||||
public int getChunkX() {
|
||||
return chunkX;
|
||||
}
|
||||
|
||||
public int getChunkZ() {
|
||||
return chunkZ;
|
||||
public ChunkPosition getChunkPosition() {
|
||||
return chunkPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,8 +45,7 @@ public class PacketPlayOutUnloadChunk extends PacketOut {
|
||||
|
||||
DataOutputStream output = new DataOutputStream(buffer);
|
||||
output.writeByte(PacketRegistry.getPacketId(getClass()));
|
||||
output.writeInt(chunkX);
|
||||
output.writeInt(chunkZ);
|
||||
DataTypeIO.writeChunkPosition(output, chunkPosition);
|
||||
|
||||
return buffer.toByteArray();
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ public class PlayerInteractManager {
|
||||
for (Entry<ChunkPosition, Chunk> entry : currentViewing.entrySet()) {
|
||||
ChunkPosition chunkPos = entry.getKey();
|
||||
if (!chunksInRange.containsKey(chunkPos)) {
|
||||
PacketPlayOutUnloadChunk packet = new PacketPlayOutUnloadChunk(chunkPos.getChunkX(), chunkPos.getChunkZ());
|
||||
PacketPlayOutUnloadChunk packet = new PacketPlayOutUnloadChunk(chunkPos);
|
||||
player.clientConnection.sendPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,10 +42,16 @@ public class RegistryCustom {
|
||||
|
||||
private static final Map<Key, RegistryCustom> REGISTRIES = new HashMap<>();
|
||||
|
||||
public static final RegistryCustom CAT_VARIANT = register("cat_variant");
|
||||
public static final RegistryCustom CHAT_TYPE = register("chat_type");
|
||||
public static final RegistryCustom CHICKEN_VARIANT = register("chicken_variant");
|
||||
public static final RegistryCustom COW_VARIANT = register("cow_variant");
|
||||
public static final RegistryCustom DAMAGE_TYPE = register("damage_type");
|
||||
public static final RegistryCustom DIMENSION_TYPE = register("dimension_type");
|
||||
public static final RegistryCustom FROG_VARIANT = register("frog_variant");
|
||||
public static final RegistryCustom PAINTING_VARIANT = register("painting_variant");
|
||||
public static final RegistryCustom PIG_VARIANT = register("pig_variant");
|
||||
public static final RegistryCustom WOLF_SOUND_VARIANT = register("wolf_sound_variant");
|
||||
public static final RegistryCustom WOLF_VARIANT = register("wolf_variant");
|
||||
public static final RegistryCustom WORLDGEN_BIOME = register("worldgen/biome");
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.loohp.limbo.location.Vector;
|
||||
import com.loohp.limbo.registry.BuiltInRegistries;
|
||||
import com.loohp.limbo.registry.DataComponentType;
|
||||
import com.loohp.limbo.world.BlockPosition;
|
||||
import com.loohp.limbo.world.ChunkPosition;
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
@@ -186,7 +187,7 @@ public class DataTypeIO {
|
||||
tag = EndTag.INSTANCE;
|
||||
}
|
||||
out.writeByte(tag.getID());
|
||||
if (tag.getID() != 0) {
|
||||
if (tag.getID() != EndTag.ID) {
|
||||
new NBTOutputStream(out).writeRawTag(tag, Tag.DEFAULT_MAX_DEPTH);
|
||||
}
|
||||
}
|
||||
@@ -194,7 +195,7 @@ public class DataTypeIO {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Tag<?>> T readTag(DataInputStream in, Class<T> type) throws IOException {
|
||||
byte b = in.readByte();
|
||||
if (b == 0) {
|
||||
if (b == EndTag.ID) {
|
||||
return type.isInstance(EndTag.INSTANCE) ? (T) EndTag.INSTANCE : null;
|
||||
}
|
||||
PushbackInputStream buffered = new PushbackInputStream(in);
|
||||
@@ -226,47 +227,31 @@ public class DataTypeIO {
|
||||
}
|
||||
|
||||
public static int readVarInt(DataInputStream in) throws IOException {
|
||||
int numRead = 0;
|
||||
int result = 0;
|
||||
byte read;
|
||||
do {
|
||||
read = in.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;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
byte b;
|
||||
do {
|
||||
b = in.readByte();
|
||||
i |= (b & 127) << j++ * 7;
|
||||
if (j > 5) {
|
||||
throw new RuntimeException("VarInt too big");
|
||||
}
|
||||
} while ((b & 128) == 128);
|
||||
return i;
|
||||
}
|
||||
|
||||
public static void writeVarInt(DataOutputStream out, int value) throws IOException {
|
||||
do {
|
||||
byte temp = (byte)(value & 0b01111111);
|
||||
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
out.writeByte(temp);
|
||||
} while (value != 0);
|
||||
while ((value & -128) != 0) {
|
||||
out.writeByte(value & 127 | 128);
|
||||
value >>>= 7;
|
||||
}
|
||||
out.writeByte(value);
|
||||
}
|
||||
|
||||
public static int getVarIntLength(int value) throws IOException {
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
DataOutputStream out = new DataOutputStream(buffer);
|
||||
do {
|
||||
byte temp = (byte)(value & 0b01111111);
|
||||
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
|
||||
value >>>= 7;
|
||||
if (value != 0) {
|
||||
temp |= 0b10000000;
|
||||
}
|
||||
out.writeByte(temp);
|
||||
} while (value != 0);
|
||||
writeVarInt(out, value);
|
||||
return buffer.toByteArray().length;
|
||||
}
|
||||
|
||||
@@ -316,4 +301,9 @@ public class DataTypeIO {
|
||||
writeTag(out, tag);
|
||||
}
|
||||
|
||||
public static void writeChunkPosition(DataOutputStream out, ChunkPosition chunkPosition) throws IOException {
|
||||
long l = (long) chunkPosition.getChunkX() & 4294967295L | ((long) chunkPosition.getChunkZ() & 4294967295L) << 32;
|
||||
out.writeLong(l);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -65,19 +65,22 @@ public class LastSeenMessages {
|
||||
|
||||
private final int offset;
|
||||
private final BitSet acknowledged;
|
||||
private final byte checksum;
|
||||
|
||||
public b(int offset, BitSet acknowledged) {
|
||||
public b(int offset, BitSet acknowledged, byte checksum) {
|
||||
this.offset = offset;
|
||||
this.acknowledged = acknowledged;
|
||||
this.checksum = checksum;
|
||||
}
|
||||
|
||||
public b(DataInputStream in) throws IOException {
|
||||
this(DataTypeIO.readVarInt(in), DataTypeIO.readFixedBitSet(in, 20));
|
||||
this(DataTypeIO.readVarInt(in), DataTypeIO.readFixedBitSet(in, 20), in.readByte());
|
||||
}
|
||||
|
||||
public void write(DataOutputStream out) throws IOException {
|
||||
DataTypeIO.writeVarInt(out, this.offset);
|
||||
DataTypeIO.writeFixedBitSet(out, this.acknowledged, 20);
|
||||
out.writeByte(checksum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,9 @@ package com.loohp.limbo.utils;
|
||||
|
||||
import net.kyori.adventure.key.Key;
|
||||
import net.querz.nbt.tag.CompoundTag;
|
||||
import net.querz.nbt.tag.ListTag;
|
||||
import net.querz.nbt.tag.StringTag;
|
||||
import net.querz.nbt.tag.Tag;
|
||||
|
||||
public class SchematicConversionUtils {
|
||||
|
||||
@@ -31,6 +34,27 @@ public class SchematicConversionUtils {
|
||||
tag.putInt("x", pos[0]);
|
||||
tag.putInt("y", pos[1]);
|
||||
tag.putInt("z", pos[2]);
|
||||
for (Tag<?> subTag : tag.values()) {
|
||||
removeStringTagQuote(subTag);
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static Tag<?> removeStringTagQuote(Tag<?> tag) {
|
||||
if (tag instanceof StringTag) {
|
||||
String value = ((StringTag) tag).getValue();
|
||||
if (value.startsWith("\"") && value.endsWith("\"")) {
|
||||
((StringTag) tag).setValue(value.substring(1, value.length() - 1));
|
||||
}
|
||||
} else if (tag instanceof CompoundTag) {
|
||||
for (Tag<?> subTag : ((CompoundTag) tag).values()) {
|
||||
removeStringTagQuote(subTag);
|
||||
}
|
||||
} else if (tag instanceof ListTag<?>) {
|
||||
for (Tag<?> subTag : (ListTag<?>) tag) {
|
||||
removeStringTagQuote(subTag);
|
||||
}
|
||||
}
|
||||
return tag;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ public class World {
|
||||
EMPTY_CHUNK.cleanupPalettesAndBlockStates();
|
||||
EMPTY_CHUNK.setHeightMaps(HEIGHT_MAP.clone());
|
||||
EMPTY_CHUNK.setBiomes(new int[256]);
|
||||
EMPTY_CHUNK.setTileEntities(new ListTag<CompoundTag>(CompoundTag.class));
|
||||
EMPTY_CHUNK.setTileEntities(new ListTag<>(CompoundTag.class));
|
||||
}
|
||||
|
||||
private String name;
|
||||
|
||||
Reference in New Issue
Block a user