Minecraft 1.20.6

This commit is contained in:
LOOHP 2024-05-09 01:56:08 +01:00
parent 3c72978f08
commit 3d651bba67
223 changed files with 25579 additions and 16004 deletions

11
pom.xml
View File

@ -24,7 +24,7 @@
<groupId>com.loohp</groupId>
<artifactId>Limbo</artifactId>
<name>Limbo</name>
<version>0.7.8-ALPHA</version>
<version>0.7.9-ALPHA</version>
<description>Standalone Limbo Minecraft Server.</description>
<url>https://github.com/LOOHP/Limbo</url>
@ -136,7 +136,7 @@
</executions>
</plugin>
</plugins>
<finalName>${project.artifactId}-${project.version}-1.20.4</finalName>
<finalName>${project.artifactId}-${project.version}-1.20.6</finalName>
</build>
<profiles>
@ -218,13 +218,18 @@
<id>bungeecord-repo</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</repository>
<repository>
<id>maven_central</id>
<name>Maven Central</name>
<url>https://repo.maven.apache.org/maven2/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
<version>3.14.0</version>
</dependency>
<dependency>
<groupId>com.github.Querz</groupId>

Binary file not shown.

View File

@ -48,7 +48,6 @@ import com.loohp.limbo.scheduler.Tick;
import com.loohp.limbo.utils.CustomStringUtils;
import com.loohp.limbo.utils.ImageUtils;
import com.loohp.limbo.utils.NetworkUtils;
import com.loohp.limbo.world.DimensionRegistry;
import com.loohp.limbo.world.Environment;
import com.loohp.limbo.world.Schematic;
import com.loohp.limbo.world.World;
@ -139,8 +138,8 @@ public final class Limbo {
//===========================
public final String SERVER_IMPLEMENTATION_VERSION = "1.20.4";
public final int SERVER_IMPLEMENTATION_PROTOCOL = 765;
public final String SERVER_IMPLEMENTATION_VERSION = "1.20.6";
public final int SERVER_IMPLEMENTATION_PROTOCOL = 766;
public final String LIMBO_IMPLEMENTATION_VERSION;
private final AtomicBoolean isRunning;
@ -160,8 +159,6 @@ public final class Limbo {
private final PermissionsManager permissionManager;
private final File pluginFolder;
private final DimensionRegistry dimensionRegistry;
private final Tick tick;
private final LimboScheduler scheduler;
@ -296,8 +293,6 @@ public final class Limbo {
console.sendMessage("Loaded all " + mappingsCount + " packet id mappings!");
dimensionRegistry = new DimensionRegistry();
worlds.add(loadDefaultWorld());
Location spawn = properties.getWorldSpawn();
properties.setWorldSpawn(new Location(getWorld(properties.getLevelName().value()), spawn.getX(), spawn.getY(), spawn.getZ(), spawn.getYaw(), spawn.getPitch()));
@ -375,10 +370,6 @@ public final class Limbo {
return scheduler;
}
public DimensionRegistry getDimensionRegistry() {
return dimensionRegistry;
}
public PermissionsManager getPermissionsManager() {
return permissionManager;
}

View File

@ -19,13 +19,14 @@
package com.loohp.limbo.inventory;
import com.loohp.limbo.registry.DataComponentTypes;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.querz.nbt.io.SNBTUtil;
import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.Tag;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class ItemStack implements Cloneable {
@ -34,36 +35,26 @@ public class ItemStack implements Cloneable {
private final Key material;
private final int amount;
private final CompoundTag nbt;
private CompoundTag fullTag;
private final Map<Key, Tag<?>> components;
public ItemStack(Key material) {
this(material, 1);
}
public ItemStack(Key material, int amount) {
this(material, amount, null);
this(material, amount, Collections.emptyMap());
}
public ItemStack(Key material, int amount, CompoundTag nbt) {
public ItemStack(Key material, int amount, Map<Key, Tag<?>> components) {
this.material = material;
this.amount = amount;
this.nbt = nbt;
this.fullTag = null;
}
public ItemStack(CompoundTag fullTag) {
this.material = Key.key(fullTag.getString("id"));
this.amount = fullTag.getInt("Count");
this.nbt = fullTag.containsKey("tag") ? fullTag.getCompoundTag("tag") : null;
this.fullTag = fullTag.clone();
this.components = components;
}
@SuppressWarnings("MethodDoesntCallSuperMethod")
@Override
public ItemStack clone() {
return new ItemStack(material, amount, nbt == null ? null : nbt.clone());
return new ItemStack(material, amount, components);
}
public Key type() {
@ -71,7 +62,7 @@ public class ItemStack implements Cloneable {
}
public ItemStack type(Key material) {
return new ItemStack(material, amount, nbt == null ? null : nbt.clone());
return new ItemStack(material, amount, components);
}
public int amount() {
@ -79,31 +70,33 @@ public class ItemStack implements Cloneable {
}
public ItemStack amount(int amount) {
return new ItemStack(material, amount, nbt == null ? null : nbt.clone());
return new ItemStack(material, amount, components);
}
public CompoundTag nbt() {
return nbt;
public Map<Key, Tag<?>> components() {
return new HashMap<>(components);
}
public ItemStack nbt(CompoundTag nbt) {
return new ItemStack(material, amount, nbt == null ? null : nbt.clone());
public ItemStack components(Map<Key, Tag<?>> components) {
return new ItemStack(material, amount, components);
}
public <T> T component(DataComponentTypes<T> type) {
return type.getCodec().decode(components.get(type.getKey()));
}
public <T> ItemStack component(DataComponentTypes<T> type, T value) {
Map<Key, Tag<?>> components = components();
components.put(type.getKey(), type.getCodec().encode(value));
return components(components);
}
public Component displayName() {
if (type().equals(AIR.type()) || nbt == null) {
return null;
}
CompoundTag displayTag = nbt.getCompoundTag("display");
if (displayTag == null) {
return null;
}
String json = displayTag.getString("Name");
if (json == null) {
if (type().equals(AIR.type()) || components == null) {
return null;
}
try {
return GsonComponentSerializer.gson().deserialize(json);
return component(DataComponentTypes.CUSTOM_NAME);
} catch (Exception e) {
return null;
}
@ -113,61 +106,36 @@ public class ItemStack implements Cloneable {
if (type().equals(AIR.type())) {
return this;
}
try {
String json = GsonComponentSerializer.gson().serialize(component);
CompoundTag nbt = this.nbt.clone();
CompoundTag displayTag = nbt.getCompoundTag("display");
if (displayTag == null) {
nbt.put("display", displayTag = new CompoundTag());
}
displayTag.putString("Name", json);
return nbt(nbt);
} catch (Exception ignore) {
}
return this;
return component(DataComponentTypes.CUSTOM_NAME, component);
}
public int getMaxStackSize() {
return 64;
}
public CompoundTag getFullTag() {
if (fullTag != null) {
return fullTag;
}
CompoundTag compoundTag = new CompoundTag();
compoundTag.putString("id", material.toString());
compoundTag.putInt("Count", amount);
if (nbt != null) {
compoundTag.put("tag", nbt);
}
return fullTag = compoundTag;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ItemStack itemStack = (ItemStack) o;
return amount == itemStack.amount && material.equals(itemStack.material) && Objects.equals(nbt, itemStack.nbt);
return amount == itemStack.amount && material.equals(itemStack.material) && Objects.equals(components, itemStack.components);
}
public boolean isSimilar(ItemStack stack) {
return stack != null && material.equals(stack.material) && Objects.equals(nbt, stack.nbt);
return stack != null && material.equals(stack.material) && Objects.equals(components, stack.components);
}
@Override
public int hashCode() {
return Objects.hash(material, amount, nbt);
return Objects.hash(material, amount, components);
}
@Override
public String toString() {
try {
return SNBTUtil.toSNBT(getFullTag());
} catch (IOException e) {
e.printStackTrace();
}
return "";
return "ItemStack{" +
"material=" + material +
", amount=" + amount +
", components=" + components +
'}';
}
}

View File

@ -99,6 +99,7 @@ import com.loohp.limbo.network.protocol.packets.ServerboundLoginAcknowledgedPack
import com.loohp.limbo.player.Player;
import com.loohp.limbo.player.PlayerInteractManager;
import com.loohp.limbo.player.PlayerInventory;
import com.loohp.limbo.registry.RegistryCustom;
import com.loohp.limbo.utils.BungeecordAdventureConversionUtils;
import com.loohp.limbo.utils.CheckedBiConsumer;
import com.loohp.limbo.utils.CustomStringUtils;
@ -397,6 +398,7 @@ public class ClientConnection extends Thread {
}
break;
case LOGIN:
case TRANSFER:
state = ClientState.LOGIN;
ServerProperties properties = Limbo.getInstance().getServerProperties();
@ -515,7 +517,7 @@ public class ClientConnection extends Thread {
break;
}
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username);
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username, false);
sendPacket(success);
player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
@ -539,7 +541,7 @@ public class ClientConnection extends Thread {
inetAddress = InetAddress.getByName(data.getIpAddress());
forwardedSkin = data.getSkinResponse();
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(data.getUuid(), data.getUsername());
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(data.getUuid(), data.getUsername(), false);
sendPacket(success);
player = new Player(this, data.getUsername(), data.getUuid(), Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
@ -557,7 +559,7 @@ public class ClientConnection extends Thread {
break;
}
} catch (Exception e) {
} catch (Exception ignored) {
channel.close();
clientSocket.close();
state = ClientState.DISCONNECTED;
@ -567,8 +569,22 @@ public class ClientConnection extends Thread {
TimeUnit.MILLISECONDS.sleep(500);
ClientboundRegistryDataPacket registryDataPacket = new ClientboundRegistryDataPacket(Limbo.getInstance().getDimensionRegistry().getCodec());
sendPacket(registryDataPacket);
ClientboundRegistryDataPacket registryDataPacket1 = new ClientboundRegistryDataPacket(RegistryCustom.WORLDGEN_BIOME);
sendPacket(registryDataPacket1);
ClientboundRegistryDataPacket registryDataPacket2 = new ClientboundRegistryDataPacket(RegistryCustom.CHAT_TYPE);
sendPacket(registryDataPacket2);
ClientboundRegistryDataPacket registryDataPacket3 = new ClientboundRegistryDataPacket(RegistryCustom.TRIM_PATTERN);
sendPacket(registryDataPacket3);
ClientboundRegistryDataPacket registryDataPacket4 = new ClientboundRegistryDataPacket(RegistryCustom.TRIM_MATERIAL);
sendPacket(registryDataPacket4);
ClientboundRegistryDataPacket registryDataPacket5 = new ClientboundRegistryDataPacket(RegistryCustom.WOLF_VARIANT);
sendPacket(registryDataPacket5);
ClientboundRegistryDataPacket registryDataPacket6 = new ClientboundRegistryDataPacket(RegistryCustom.DIMENSION_TYPE);
sendPacket(registryDataPacket6);
ClientboundRegistryDataPacket registryDataPacket7 = new ClientboundRegistryDataPacket(RegistryCustom.DAMAGE_TYPE);
sendPacket(registryDataPacket7);
ClientboundRegistryDataPacket registryDataPacket8 = new ClientboundRegistryDataPacket(RegistryCustom.BANNER_PATTERN);
sendPacket(registryDataPacket8);
ClientboundFinishConfigurationPacket clientboundFinishConfigurationPacket = new ClientboundFinishConfigurationPacket();
sendPacket(clientboundFinishConfigurationPacket);
@ -587,7 +603,7 @@ public class ClientConnection extends Thread {
worldSpawn = spawnEvent.getSpawnLocation();
World world = worldSpawn.getWorld();
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, Limbo.getInstance().getWorlds(), (byte) properties.getMaxPlayers(), 8, 8, properties.isReducedDebugInfo(), true, false, world.getEnvironment(), world, 0, properties.getDefaultGamemode(), false, true, 0);
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, Limbo.getInstance().getWorlds(), properties.getMaxPlayers(), 8, 8, properties.isReducedDebugInfo(), true, false, world.getEnvironment(), world, 0, properties.getDefaultGamemode(), false, true, 0, false);
sendPacket(join);
Limbo.getInstance().getUnsafe().a(player, properties.getDefaultGamemode());
@ -861,7 +877,7 @@ public class ClientConnection extends Thread {
}
}
}
} catch (Exception e) {
} catch (Exception ignored) {
break;
}
}

View File

@ -19,7 +19,7 @@
package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.registry.Registry;
import com.loohp.limbo.registry.BuiltInRegistries;
import com.loohp.limbo.utils.BitsUtils;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.world.Environment;
@ -247,7 +247,7 @@ public class ClientboundLevelChunkWithLightPacket extends PacketOut {
int z = each.getInt("z") % 16;
output.writeByte(((x & 15) << 4) | (z & 15));
output.writeShort(y);
Integer id = Registry.BLOCK_ENTITY_TYPE.getId(Key.key(chunk.getBlockStateAt(x, y, z).getString("Name")));
Integer id = BuiltInRegistries.BLOCK_ENTITY_TYPE.getId(Key.key(chunk.getBlockStateAt(x, y, z).getString("Name")));
DataTypeIO.writeVarInt(output, id == null ? -1 : id);
DataTypeIO.writeTag(output, each);
}

View File

@ -19,23 +19,27 @@
package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.registry.RegistryCustom;
import com.loohp.limbo.utils.DataTypeIO;
import net.kyori.adventure.key.Key;
import net.querz.nbt.tag.CompoundTag;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;
public class ClientboundRegistryDataPacket extends PacketOut {
private final CompoundTag dimensionCodec;
private final RegistryCustom registry;
public ClientboundRegistryDataPacket(CompoundTag dimensionCodec) {
this.dimensionCodec = dimensionCodec;
public ClientboundRegistryDataPacket(RegistryCustom registry) {
this.registry = registry;
}
public CompoundTag getDimensionCodec() {
return dimensionCodec;
public RegistryCustom getRegistry() {
return registry;
}
@Override
@ -45,7 +49,18 @@ public class ClientboundRegistryDataPacket extends PacketOut {
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getConfigurationOut().get(getClass()));
DataTypeIO.writeTag(output, dimensionCodec);
DataTypeIO.writeString(output, registry.getIdentifier().asString(), StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, registry.getEntries().size());
for (Map.Entry<Key, CompoundTag> entry : registry.getEntries().entrySet()) {
DataTypeIO.writeString(output, entry.getKey().asString(), StandardCharsets.UTF_8);
CompoundTag data = entry.getValue();
if (data == null) {
output.writeBoolean(false);
} else {
output.writeBoolean(true);
DataTypeIO.writeTag(output, data);
}
}
return buffer.toByteArray();
}

View File

@ -115,6 +115,8 @@ public abstract class Packet {
Class<? extends Packet> type = getClass();
if (handshakeIn.containsValue(type)) {
return ClientConnection.ClientState.HANDSHAKE;
} else if (statusIn.containsValue(type) || statusOut.containsKey(type)) {
return ClientConnection.ClientState.STATUS;
} else if (loginIn.containsValue(type) || loginOut.containsKey(type)) {
return ClientConnection.ClientState.LOGIN;
} else if (configurationIn.containsValue(type) || configurationOut.containsKey(type)) {
@ -122,7 +124,7 @@ public abstract class Packet {
} else if (playIn.containsValue(type) || playOut.containsKey(type)) {
return ClientConnection.ClientState.PLAY;
} else {
throw new IllegalStateException("This packet is not registered!");
throw new IllegalStateException("This packet of class " + type + " is not registered!");
}
}

View File

@ -29,9 +29,10 @@ public class PacketHandshakingIn extends PacketIn {
public enum HandshakeType {
STATUS(1),
LOGIN(2);
LOGIN(2),
TRANSFER(3);
int networkId;
private final int networkId;
HandshakeType(int networkId) {
this.networkId = networkId;

View File

@ -29,12 +29,14 @@ import java.util.UUID;
public class PacketLoginOutLoginSuccess extends PacketOut {
private UUID uuid;
private String username;
private final UUID uuid;
private final String username;
private final boolean strictErrorHandling;
public PacketLoginOutLoginSuccess(UUID uuid, String username) {
public PacketLoginOutLoginSuccess(UUID uuid, String username, boolean strictErrorHandling) {
this.uuid = uuid;
this.username = username;
this.strictErrorHandling = strictErrorHandling;
}
public UUID getUuid() {
@ -45,6 +47,10 @@ public class PacketLoginOutLoginSuccess extends PacketOut {
return username;
}
public boolean isStrictErrorHandling() {
return strictErrorHandling;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@ -54,6 +60,7 @@ public class PacketLoginOutLoginSuccess extends PacketOut {
DataTypeIO.writeUUID(output, uuid);
DataTypeIO.writeString(output, username, StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 0);
output.writeBoolean(strictErrorHandling);
return buffer.toByteArray();
}

View File

@ -19,6 +19,7 @@
package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.registry.RegistryCustom;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.world.Environment;
@ -36,7 +37,7 @@ public class PacketPlayOutLogin extends PacketOut {
private final int entityId;
private final boolean isHardcore;
private final List<World> worlds;
private final byte maxPlayers;
private final int maxPlayers;
private final int viewDistance;
private final int simulationDistance;
private final boolean reducedDebugInfo;
@ -49,8 +50,9 @@ public class PacketPlayOutLogin extends PacketOut {
private final boolean isDebug;
private final boolean isFlat;
private final int portalCooldown;
private final boolean enforcesSecureChat;
public PacketPlayOutLogin(int entityId, boolean isHardcore, List<World> worlds, byte maxPlayers, int viewDistance, int simulationDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean doLimitedCrafting, Environment dimension, World world, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, int portalCooldown) {
public PacketPlayOutLogin(int entityId, boolean isHardcore, List<World> worlds, int maxPlayers, int viewDistance, int simulationDistance, boolean reducedDebugInfo, boolean enableRespawnScreen, boolean doLimitedCrafting, Environment dimension, World world, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, int portalCooldown, boolean enforcesSecureChat) {
this.entityId = entityId;
this.isHardcore = isHardcore;
this.worlds = worlds;
@ -67,6 +69,7 @@ public class PacketPlayOutLogin extends PacketOut {
this.isDebug = isDebug;
this.isFlat = isFlat;
this.portalCooldown = portalCooldown;
this.enforcesSecureChat = enforcesSecureChat;
}
public int getEntityId() {
@ -81,7 +84,7 @@ public class PacketPlayOutLogin extends PacketOut {
return worlds;
}
public byte getMaxPlayers() {
public int getMaxPlayers() {
return maxPlayers;
}
@ -133,6 +136,10 @@ public class PacketPlayOutLogin extends PacketOut {
return portalCooldown;
}
public boolean isEnforcesSecureChat() {
return enforcesSecureChat;
}
@Override
public byte[] serializePacket() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
@ -151,7 +158,7 @@ public class PacketPlayOutLogin extends PacketOut {
output.writeBoolean(reducedDebugInfo);
output.writeBoolean(enableRespawnScreen);
output.writeBoolean(doLimitedCrafting);
DataTypeIO.writeString(output, world.getEnvironment().getKey().toString(), StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, RegistryCustom.DIMENSION_TYPE.indexOf(world.getEnvironment().getKey()));
DataTypeIO.writeString(output, Key.key(world.getName()).toString(), StandardCharsets.UTF_8);
output.writeLong(hashedSeed);
output.writeByte((byte) gamemode.getId());
@ -160,6 +167,7 @@ public class PacketPlayOutLogin extends PacketOut {
output.writeBoolean(isFlat);
output.writeBoolean(false);
DataTypeIO.writeVarInt(output, portalCooldown);
output.writeBoolean(enforcesSecureChat);
return buffer.toByteArray();
}

View File

@ -19,7 +19,7 @@
package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.registry.Registry;
import com.loohp.limbo.registry.BuiltInRegistries;
import com.loohp.limbo.utils.DataTypeIO;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
@ -60,7 +60,7 @@ public class PacketPlayOutOpenWindow extends PacketOut {
output.writeByte(Packet.getPlayOut().get(getClass()));
DataTypeIO.writeVarInt(output, containerId);
DataTypeIO.writeVarInt(output, Registry.MENU_REGISTRY.getId(type));
DataTypeIO.writeVarInt(output, BuiltInRegistries.MENU_REGISTRY.getId(type));
DataTypeIO.writeComponent(output, title);
return buffer.toByteArray();

View File

@ -19,6 +19,7 @@
package com.loohp.limbo.network.protocol.packets;
import com.loohp.limbo.registry.RegistryCustom;
import com.loohp.limbo.utils.DataTypeIO;
import com.loohp.limbo.utils.GameMode;
import com.loohp.limbo.world.Environment;
@ -35,18 +36,16 @@ import java.nio.charset.StandardCharsets;
public class PacketPlayOutRespawn extends PacketOut {
private Environment dimension;
private String worldName;
private CompoundTag dimensionCodec;
private World world;
private long hashedSeed;
private GameMode gamemode;
private boolean isDebug;
private boolean isFlat;
private boolean copyMetaData;
public PacketPlayOutRespawn(World world, CompoundTag dimensionCodec, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, boolean copyMetaData) {
public PacketPlayOutRespawn(World world, long hashedSeed, GameMode gamemode, boolean isDebug, boolean isFlat, boolean copyMetaData) {
this.dimension = world.getEnvironment();
this.dimensionCodec = dimensionCodec;
this.worldName = Key.key(world.getName()).toString();
this.world = world;
this.hashedSeed = hashedSeed;
this.gamemode = gamemode;
this.isDebug = isDebug;
@ -54,16 +53,12 @@ public class PacketPlayOutRespawn extends PacketOut {
this.copyMetaData = copyMetaData;
}
public CompoundTag getDimensionCodec() {
return dimensionCodec;
}
public Environment getDimension() {
return dimension;
}
public String getWorldName() {
return worldName;
public World getWorld() {
return world;
}
public long getHashedSeed() {
@ -92,16 +87,9 @@ public class PacketPlayOutRespawn extends PacketOut {
DataOutputStream output = new DataOutputStream(buffer);
output.writeByte(Packet.getPlayOut().get(getClass()));
CompoundTag tag = null;
ListTag<CompoundTag> list = dimensionCodec.getCompoundTag("minecraft:dimension_type").getListTag("value").asCompoundTagList();
for (CompoundTag each : list) {
if (each.getString("name").equals(dimension.getKey().toString())) {
tag = each.getCompoundTag("element");
break;
}
}
DataTypeIO.writeTag(output, tag != null ? tag : list.get(0));
DataTypeIO.writeString(output, worldName, StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, RegistryCustom.DIMENSION_TYPE.indexOf(world.getEnvironment().getKey()));
DataTypeIO.writeString(output, Key.key(world.getName()).toString(), StandardCharsets.UTF_8);
output.writeLong(hashedSeed);
output.writeByte((byte) gamemode.getId());
output.writeByte((byte) gamemode.getId());

View File

@ -25,7 +25,6 @@ import com.loohp.limbo.utils.DataTypeIO;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.List;
public class PacketPlayOutSetSlot extends PacketOut {

View File

@ -248,7 +248,7 @@ public class Player extends LivingEntity implements CommandSender, InventoryHold
super.teleport(location);
try {
if (!world.equals(location.getWorld())) {
PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), Limbo.getInstance().getDimensionRegistry().getCodec(), 0, gamemode, false, false, true);
PacketPlayOutRespawn respawn = new PacketPlayOutRespawn(location.getWorld(), 0, gamemode, false, false, true);
clientConnection.sendPacket(respawn);
}
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), 1);

View File

@ -27,32 +27,31 @@ import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
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;
public class Registry {
public abstract class BuiltInRegistries {
public static final BlockEntityRegistry BLOCK_ENTITY_TYPE;
public static final ItemRegistry ITEM_REGISTRY;
public static final MenuRegistry MENU_REGISTRY;
public static final DataComponentTypeRegistry DATA_COMPONENT_TYPE;
static {
String name = "registries.json";
String name = "reports/registries.json";
Map<Key, Integer> blockEntityType = new HashMap<>();
Key defaultItemKey = null;
BiMap<Key, Integer> itemIds = HashBiMap.create();
Map<Key, Integer> menuIds = new HashMap<>();
BiMap<Key, Integer> dataComponentTypeIds = HashBiMap.create();
InputStream inputStream = Limbo.class.getClassLoader().getResourceAsStream(name);
if (inputStream == null) {
@ -83,15 +82,25 @@ public class Registry {
int id = ((Number) ((JSONObject) menuEntriesJson.get(key)).get("protocol_id")).intValue();
menuIds.put(Key.key(key), id);
}
JSONObject dataComponentTypeEntriesJson = (JSONObject) ((JSONObject) json.get("minecraft:data_component_type")).get("entries");
for (Object obj : dataComponentTypeEntriesJson.keySet()) {
String key = obj.toString();
int id = ((Number) ((JSONObject) dataComponentTypeEntriesJson.get(key)).get("protocol_id")).intValue();
dataComponentTypeIds.put(Key.key(key), id);
}
} catch (IOException | ParseException e) {
e.printStackTrace();
}
BLOCK_ENTITY_TYPE = new BlockEntityRegistry(blockEntityType);
ITEM_REGISTRY = new ItemRegistry(defaultItemKey, itemIds);
MENU_REGISTRY = new MenuRegistry(menuIds);
DATA_COMPONENT_TYPE = new DataComponentTypeRegistry(dataComponentTypeIds);
}
public static class BlockEntityRegistry {
public abstract int getId(Key key);
public static class BlockEntityRegistry extends BuiltInRegistries {
private Map<Key, Integer> blockEntityType;
@ -99,6 +108,7 @@ public class Registry {
this.blockEntityType = blockEntityType;
}
@Override
public int getId(Key key) {
Integer exact = blockEntityType.get(key);
if (exact != null) {
@ -121,7 +131,7 @@ public class Registry {
}
}
public static class ItemRegistry {
public static class ItemRegistry extends BuiltInRegistries {
private final Key defaultKey;
private final BiMap<Key, Integer> itemIds;
@ -135,6 +145,7 @@ public class Registry {
return defaultKey;
}
@Override
public int getId(Key key) {
Integer id = itemIds.get(key);
if (id != null) {
@ -151,7 +162,7 @@ public class Registry {
}
}
public static class MenuRegistry {
public static class MenuRegistry extends BuiltInRegistries {
private final Map<Key, Integer> menuIds;
@ -159,9 +170,28 @@ public class Registry {
this.menuIds = menuIds;
}
@Override
public int getId(Key key) {
return menuIds.getOrDefault(key, -1);
}
}
public static class DataComponentTypeRegistry extends BuiltInRegistries {
private final BiMap<Key, Integer> dataComponentTypeIds;
private DataComponentTypeRegistry(BiMap<Key, Integer> dataComponentTypeIds) {
this.dataComponentTypeIds = dataComponentTypeIds;
}
@Override
public int getId(Key key) {
return dataComponentTypeIds.getOrDefault(key, -1);
}
public Key fromId(int id) {
return dataComponentTypeIds.inverse().get(id);
}
}
}

View File

@ -0,0 +1,82 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2024. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2024. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.registry;
import com.google.gson.JsonElement;
import com.loohp.limbo.utils.NbtComponentSerializer;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.querz.nbt.tag.Tag;
import java.util.function.Function;
public class DataComponentTypes<T> {
public static final DataComponentTypes<Component> CUSTOM_NAME = new DataComponentTypes<>("custom_name", new DataComponentCodec<>(component -> {
JsonElement element = GsonComponentSerializer.gson().serializeToTree(component);
return NbtComponentSerializer.jsonComponentToTag(element);
}, tag -> {
JsonElement element = NbtComponentSerializer.tagComponentToJson(tag);
return GsonComponentSerializer.gson().deserializeFromTree(element);
}));
private final Key key;
private final DataComponentCodec<T> codec;
@SuppressWarnings("PatternValidation")
public DataComponentTypes(String key, DataComponentCodec<T> codec) {
this(Key.key(key), codec);
}
public DataComponentTypes(Key key, DataComponentCodec<T> codec) {
this.key = key;
this.codec = codec;
}
public Key getKey() {
return key;
}
public DataComponentCodec<T> getCodec() {
return codec;
}
public static class DataComponentCodec<T> {
private final Function<T, Tag<?>> encode;
private final Function<Tag<?>, T> decode;
public DataComponentCodec(Function<T, Tag<?>> encode, Function<Tag<?>, T> decode) {
this.encode = encode;
this.decode = decode;
}
@SuppressWarnings("unchecked")
public Tag<?> encode(T t) {
return encode.apply((T) t);
}
public T decode(Tag<?> tag) {
return decode.apply(tag);
}
}
}

View File

@ -0,0 +1,103 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2024. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2024. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.registry;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.utils.ClasspathResourcesUtils;
import com.loohp.limbo.utils.CustomNBTUtils;
import net.kyori.adventure.key.Key;
import net.querz.nbt.tag.CompoundTag;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;
public class RegistryCustom {
public static final RegistryCustom WORLDGEN_BIOME = new RegistryCustom("worldgen/biome");
public static final RegistryCustom CHAT_TYPE = new RegistryCustom("chat_type");
public static final RegistryCustom TRIM_PATTERN = new RegistryCustom("trim_pattern");
public static final RegistryCustom TRIM_MATERIAL = new RegistryCustom("trim_material");
public static final RegistryCustom WOLF_VARIANT = new RegistryCustom("wolf_variant");
public static final RegistryCustom DIMENSION_TYPE = new RegistryCustom("dimension_type");
public static final RegistryCustom DAMAGE_TYPE = new RegistryCustom("damage_type");
public static final RegistryCustom BANNER_PATTERN = new RegistryCustom("banner_pattern");
private final Key identifier;
private final Map<Key, CompoundTag> entries;
public RegistryCustom(Key identifier, Map<Key, CompoundTag> entries) {
this.identifier = identifier;
this.entries = entries;
}
@SuppressWarnings("PatternValidation")
public RegistryCustom(String identifier) {
this(Key.key(identifier));
}
@SuppressWarnings("PatternValidation")
public RegistryCustom(Key identifier) {
this.identifier = identifier;
Map<Key, CompoundTag> entries = new LinkedHashMap<>();
String pathStart = "data/" + identifier.namespace() + "/" + identifier.value() + "/";
Pattern pattern = Pattern.compile(Pattern.quote(pathStart) + ".*");
for (String path : ClasspathResourcesUtils.getResources(pattern)) {
if (path.endsWith(".json")) {
try (InputStream inputStream = Limbo.class.getClassLoader().getResourceAsStream(path)) {
Key entryKey = Key.key(identifier.namespace(), path.substring(path.lastIndexOf('/') + 1, path.lastIndexOf(".")));
JSONObject jsonObject = (JSONObject) new JSONParser().parse(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
CompoundTag value = CustomNBTUtils.getCompoundTagFromJson(jsonObject);
entries.put(entryKey, value);
} catch (IOException | ParseException e) {
throw new RuntimeException(e);
}
}
}
this.entries = entries;
}
public Key getIdentifier() {
return identifier;
}
public Map<Key, CompoundTag> getEntries() {
return entries;
}
public int indexOf(Key key) {
int i = 0;
for (Key entryKey : entries.keySet()) {
if (key.equals(entryKey)) {
return i;
}
i++;
}
return -1;
}
}

View File

@ -0,0 +1,111 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2024. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2024. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.utils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* list resources available from the classpath @ *
*/
public class ClasspathResourcesUtils {
/**
* for all elements of java.class.path get a Collection of resources Pattern
* pattern = Pattern.compile(".*"); gets all resources
*
* @param pattern
* the pattern to match
* @return the resources in the order they are found
*/
public static Collection<String> getResources(Pattern pattern) {
List<String> retval = new ArrayList<>();
String classPath = System.getProperty("java.class.path", ".");
String[] classPathElements = classPath.split(File.pathSeparator);
for (String element : classPathElements) {
retval.addAll(getResources(element, pattern));
}
return retval;
}
private static Collection<String> getResources(String element, Pattern pattern) {
List<String> retval = new ArrayList<>();
File file = new File(element);
if (file.isDirectory()) {
retval.addAll(getResourcesFromDirectory(file, pattern));
} else{
retval.addAll(getResourcesFromJarFile(file, pattern));
}
return retval;
}
private static Collection<String> getResourcesFromJarFile(final File file, final Pattern pattern) {
List<String> retval = new ArrayList<>();
ZipFile zf;
try {
zf = new ZipFile(file);
} catch (IOException e){
throw new Error(e);
}
Enumeration<? extends ZipEntry> e = zf.entries();
while (e.hasMoreElements()) {
ZipEntry ze = e.nextElement();
String fileName = ze.getName();
boolean accept = pattern.matcher(fileName).matches();
if (accept) {
retval.add(fileName);
}
}
try {
zf.close();
} catch (IOException e1) {
throw new Error(e1);
}
return retval;
}
private static Collection<String> getResourcesFromDirectory(File directory, Pattern pattern){
List<String> retval = new ArrayList<>();
File[] fileList = directory.listFiles();
for (File file : fileList) {
if (file.isDirectory()) {
retval.addAll(getResourcesFromDirectory(file, pattern));
} else {
try {
String fileName = file.getCanonicalPath();
boolean accept = pattern.matcher(fileName).matches();
if (accept) {
retval.add(fileName);
}
} catch (IOException e) {
throw new Error(e);
}
}
}
return retval;
}
}

View File

@ -19,17 +19,11 @@
package com.loohp.limbo.utils;
import net.querz.nbt.tag.ByteArrayTag;
import net.querz.nbt.tag.ByteTag;
import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.DoubleTag;
import net.querz.nbt.tag.FloatTag;
import net.querz.nbt.tag.IntArrayTag;
import net.querz.nbt.tag.IntTag;
import net.querz.nbt.tag.ListTag;
import net.querz.nbt.tag.LongArrayTag;
import net.querz.nbt.tag.LongTag;
import net.querz.nbt.tag.ShortTag;
import net.querz.nbt.tag.StringTag;
import net.querz.nbt.tag.Tag;
import org.json.simple.JSONArray;
@ -38,160 +32,70 @@ import org.json.simple.JSONObject;
@SuppressWarnings("rawtypes")
public class CustomNBTUtils {
public enum TagClass {
CompoundTagClass(CompoundTag.class),
ByteTagClass(ByteTag.class),
ShortTagClass(ShortTag.class),
IntTagClass(IntTag.class),
LongTagClass(LongTag.class),
FloatTagClass(FloatTag.class),
DoubleTagClass(DoubleTag.class),
ByteArrayTagClass(ByteArrayTag.class),
IntArrayTagClass(IntArrayTag.class),
LongArrayTagClass(LongArrayTag.class),
StringTagClass(StringTag.class),
ListTagClass(ListTag.class);
Class<? extends Tag> clazz;
TagClass(Class<? extends Tag> clazz) {
this.clazz = clazz;
}
public Class<? extends Tag> getTagClass() {
return clazz;
}
}
public static Class<? extends Tag> getClassFromName(String name) {
for (TagClass clazz : TagClass.values()) {
if (clazz.getTagClass().getSimpleName().equals(name)) {
return clazz.getTagClass();
}
}
return null;
}
public static CompoundTag getCompoundTagFromJson(JSONObject json) {
CompoundTag tag = new CompoundTag();
for (Object obj : json.keySet()) {
String key = (String) obj;
JSONObject inside = (JSONObject) json.get(key);
String type = (String) inside.get("type");
Object rawValue = json.get(key);
switch (type) {
case "ByteTag":
tag.putByte(key, (byte) (long) inside.get("value"));
break;
case "ShortTag":
tag.putShort(key, (short) (long) inside.get("value"));
break;
case "IntTag":
tag.putInt(key, (int) (long) inside.get("value"));
break;
case "LongTag":
tag.putLong(key, (long) inside.get("value"));
break;
case "FloatTag":
tag.putFloat(key, inside.get("value") instanceof Long ? (float) (long) inside.get("value") : (float) (double) inside.get("value"));
break;
case "DoubleTag":
tag.putDouble(key, inside.get("value") instanceof Long ? (double) (long) inside.get("value") : (double) inside.get("value"));
break;
case "ByteArrayTag":
tag.putByteArray(key, CustomArrayUtils.longArrayToByteArray((long[]) inside.get("value")));
break;
case "IntArrayTag":
tag.putIntArray(key, CustomArrayUtils.longArrayToIntArray((long[]) inside.get("value")));
break;
case "LongArrayTag":
tag.putLongArray(key, (long[]) inside.get("value"));
break;
case "StringTag":
tag.putString(key, (String) inside.get("value"));
break;
case "CompoundTag":
tag.put(key, getCompoundTagFromJson((JSONObject) inside.get("value")));
break;
case "ListTag":
tag.put(key, getListTagFromJson((JSONObject) inside.get("value")));
break;
if (rawValue instanceof JSONObject) {
tag.put(key, getCompoundTagFromJson((JSONObject) rawValue));
} else if (rawValue instanceof JSONArray) {
tag.put(key, getListTagFromJson((JSONArray) rawValue));
} else if (rawValue instanceof Boolean) {
tag.putBoolean(key, (boolean) rawValue);
} else if (rawValue instanceof Long) {
tag.putLong(key, (long) rawValue);
} else if (rawValue instanceof Double) {
tag.putDouble(key, (double) rawValue);
} else if (rawValue instanceof String) {
tag.putString(key, (String) rawValue);
}
}
return tag;
}
public static ListTag<?> getListTagFromJson(JSONObject json) {
String type = (String) json.get("type");
JSONArray array = (JSONArray) json.get("list");
ListTag<?> listTag = ListTag.createUnchecked(getClassFromName(type));
switch (type) {
case "ByteTag":
for (Object obj : array) {
listTag.addByte((byte) (long) obj);
@SuppressWarnings("ExtractMethodRecommender")
public static ListTag<?> getListTagFromJson(JSONArray json) {
if (json.isEmpty()) {
return new ListTag<>(StringTag.class);
}
break;
case "ShortTag":
for (Object obj : array) {
listTag.addShort((short) (long) obj);
}
break;
case "IntTag":
for (Object obj : array) {
listTag.addInt((int) (long) obj);
}
break;
case "LongTag":
for (Object obj : array) {
listTag.addLong((long) obj);
}
break;
case "FloatTag":
for (Object obj : array) {
listTag.addFloat(obj instanceof Long ? (float) (long) obj : (float) (double) obj);
}
break;
case "DoubleTag":
for (Object obj : array) {
listTag.addDouble(obj instanceof Long ? (double) (long) obj : (double) obj);
}
break;
case "ByteArrayTag":
for (Object obj : array) {
listTag.addByteArray(CustomArrayUtils.longArrayToByteArray((long[]) obj));
}
break;
case "IntArrayTag":
for (Object obj : array) {
listTag.addIntArray(CustomArrayUtils.longArrayToIntArray((long[]) obj));
}
break;
case "LongArrayTag":
for (Object obj : array) {
listTag.addLongArray((long[]) obj);
}
break;
case "StringTag":
for (Object obj : array) {
listTag.addString((String) obj);
}
break;
case "CompoundTag":
for (Object obj : array) {
listTag.asCompoundTagList().add(getCompoundTagFromJson((JSONObject) obj));
}
break;
case "ListTag":
for (Object obj : array) {
listTag.asListTagList().add(getListTagFromJson((JSONObject) obj));
}
break;
Object firstValue = json.get(0);
Class<? extends Tag> type;
if (firstValue instanceof JSONObject) {
type = CompoundTag.class;
} else if (firstValue instanceof JSONArray) {
type = ListTag.class;
} else if (firstValue instanceof Boolean) {
type = ByteTag.class;
} else if (firstValue instanceof Long) {
type = LongTag.class;
} else if (firstValue instanceof Double) {
type = DoubleTag.class;
} else if (firstValue instanceof String) {
type = StringTag.class;
} else {
throw new RuntimeException();
}
ListTag<?> listTag = ListTag.createUnchecked(type);
for (Object rawValue : json) {
if (rawValue instanceof JSONObject) {
listTag.asCompoundTagList().add(getCompoundTagFromJson((JSONObject) rawValue));
} else if (rawValue instanceof JSONArray) {
listTag.asListTagList().add(getListTagFromJson((JSONArray) rawValue));
} else if (rawValue instanceof Boolean) {
listTag.addBoolean((boolean) rawValue);
} else if (rawValue instanceof Long) {
listTag.addLong((long) rawValue);
} else if (rawValue instanceof Double) {
listTag.addDouble((double) rawValue);
} else if (rawValue instanceof String) {
listTag.addString((String) rawValue);
}
}
return listTag;
}

View File

@ -24,14 +24,13 @@ import com.loohp.limbo.inventory.ItemStack;
import com.loohp.limbo.location.BlockFace;
import com.loohp.limbo.location.MovingObjectPositionBlock;
import com.loohp.limbo.location.Vector;
import com.loohp.limbo.registry.Registry;
import com.loohp.limbo.registry.BuiltInRegistries;
import com.loohp.limbo.world.BlockPosition;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.querz.nbt.io.NBTInputStream;
import net.querz.nbt.io.NBTOutputStream;
import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.EndTag;
import net.querz.nbt.tag.Tag;
@ -44,29 +43,43 @@ import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.BitSet;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class DataTypeIO {
public static void writeItemStack(DataOutputStream out, ItemStack itemstack) throws IOException {
if (itemstack == null || itemstack.isSimilar(ItemStack.AIR) || itemstack.amount() == 0) {
out.writeBoolean(false);
DataTypeIO.writeVarInt(out, 0);
} else {
out.writeBoolean(true);
writeVarInt(out, Registry.ITEM_REGISTRY.getId(itemstack.type()));
out.writeByte(itemstack.amount());
writeTag(out, itemstack.nbt());
DataTypeIO.writeVarInt(out, itemstack.amount());
writeVarInt(out, BuiltInRegistries.ITEM_REGISTRY.getId(itemstack.type()));
Map<Key, Tag<?>> components = itemstack.components();
DataTypeIO.writeVarInt(out, components.size());
DataTypeIO.writeVarInt(out, 0);
for (Map.Entry<Key, Tag<?>> entry : components.entrySet()) {
DataTypeIO.writeVarInt(out, BuiltInRegistries.DATA_COMPONENT_TYPE.getId(entry.getKey()));
DataTypeIO.writeTag(out, entry.getValue());
}
}
}
public static ItemStack readItemStack(DataInputStream in) throws IOException {
if (!in.readBoolean()) {
int amount = DataTypeIO.readVarInt(in);
if (amount <= 0) {
return ItemStack.AIR;
} else {
Key key = Registry.ITEM_REGISTRY.fromId(readVarInt(in));
byte amount = in.readByte();
CompoundTag nbt = readTag(in, CompoundTag.class);
return new ItemStack(key, amount, nbt);
Key key = BuiltInRegistries.ITEM_REGISTRY.fromId(readVarInt(in));
int size = DataTypeIO.readVarInt(in);
DataTypeIO.readVarInt(in);
Map<Key, Tag<?>> components = new HashMap<>();
for (int i = 0; i < size; i++) {
Key componentKey = BuiltInRegistries.DATA_COMPONENT_TYPE.fromId(DataTypeIO.readVarInt(in));
Tag<?> component = readTag(in, Tag.class);
components.put(componentKey, component);
}
return new ItemStack(key, amount, components);
}
}

View File

@ -1,67 +0,0 @@
/*
* This file is part of Limbo.
*
* Copyright (C) 2022. LoohpJames <jamesloohp@gmail.com>
* Copyright (C) 2022. Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.loohp.limbo.world;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.utils.CustomNBTUtils;
import net.querz.nbt.tag.CompoundTag;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
public class DimensionRegistry {
private CompoundTag defaultTag;
private CompoundTag codec;
public DimensionRegistry() {
this.defaultTag = new CompoundTag();
String name = "dimension_registry.json";
InputStream inputStream = Limbo.class.getClassLoader().getResourceAsStream(name);
if (inputStream == null) {
throw new RuntimeException("Failed to load " + name + " from jar!");
}
try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) {
JSONObject json = (JSONObject) new JSONParser().parse(reader);
CompoundTag tag = CustomNBTUtils.getCompoundTagFromJson((JSONObject) json.get("value"));
defaultTag = tag;
codec = defaultTag.clone();
} catch (IOException | ParseException e) {
e.printStackTrace();
}
}
public void resetCodec() {
codec = defaultTag.clone();
}
public CompoundTag getCodec() {
return codec;
}
}

View File

@ -42,7 +42,7 @@ public class GeneratedBlockDataMappings {
private static JSONObject globalPalette = new JSONObject();
static {
String block = "blocks.json";
String block = "reports/blocks.json";
InputStream inputStream = Limbo.class.getClassLoader().getResourceAsStream(block);
if (inputStream == null) {
throw new RuntimeException("Failed to load " + block + " from jar!");

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:base",
"translation_key": "block.minecraft.banner.base"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:border",
"translation_key": "block.minecraft.banner.border"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:bricks",
"translation_key": "block.minecraft.banner.bricks"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:circle",
"translation_key": "block.minecraft.banner.circle"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:creeper",
"translation_key": "block.minecraft.banner.creeper"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:cross",
"translation_key": "block.minecraft.banner.cross"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:curly_border",
"translation_key": "block.minecraft.banner.curly_border"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:diagonal_left",
"translation_key": "block.minecraft.banner.diagonal_left"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:diagonal_right",
"translation_key": "block.minecraft.banner.diagonal_right"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:diagonal_up_left",
"translation_key": "block.minecraft.banner.diagonal_up_left"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:diagonal_up_right",
"translation_key": "block.minecraft.banner.diagonal_up_right"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:flower",
"translation_key": "block.minecraft.banner.flower"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:globe",
"translation_key": "block.minecraft.banner.globe"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:gradient",
"translation_key": "block.minecraft.banner.gradient"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:gradient_up",
"translation_key": "block.minecraft.banner.gradient_up"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:half_horizontal",
"translation_key": "block.minecraft.banner.half_horizontal"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:half_horizontal_bottom",
"translation_key": "block.minecraft.banner.half_horizontal_bottom"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:half_vertical",
"translation_key": "block.minecraft.banner.half_vertical"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:half_vertical_right",
"translation_key": "block.minecraft.banner.half_vertical_right"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:mojang",
"translation_key": "block.minecraft.banner.mojang"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:piglin",
"translation_key": "block.minecraft.banner.piglin"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:rhombus",
"translation_key": "block.minecraft.banner.rhombus"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:skull",
"translation_key": "block.minecraft.banner.skull"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:small_stripes",
"translation_key": "block.minecraft.banner.small_stripes"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:square_bottom_left",
"translation_key": "block.minecraft.banner.square_bottom_left"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:square_bottom_right",
"translation_key": "block.minecraft.banner.square_bottom_right"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:square_top_left",
"translation_key": "block.minecraft.banner.square_top_left"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:square_top_right",
"translation_key": "block.minecraft.banner.square_top_right"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:straight_cross",
"translation_key": "block.minecraft.banner.straight_cross"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_bottom",
"translation_key": "block.minecraft.banner.stripe_bottom"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_center",
"translation_key": "block.minecraft.banner.stripe_center"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_downleft",
"translation_key": "block.minecraft.banner.stripe_downleft"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_downright",
"translation_key": "block.minecraft.banner.stripe_downright"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_left",
"translation_key": "block.minecraft.banner.stripe_left"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_middle",
"translation_key": "block.minecraft.banner.stripe_middle"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_right",
"translation_key": "block.minecraft.banner.stripe_right"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:stripe_top",
"translation_key": "block.minecraft.banner.stripe_top"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:triangle_bottom",
"translation_key": "block.minecraft.banner.triangle_bottom"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:triangle_top",
"translation_key": "block.minecraft.banner.triangle_top"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:triangles_bottom",
"translation_key": "block.minecraft.banner.triangles_bottom"
}

View File

@ -0,0 +1,4 @@
{
"asset_id": "minecraft:triangles_top",
"translation_key": "block.minecraft.banner.triangles_top"
}

View File

@ -0,0 +1,16 @@
{
"chat": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.text"
},
"narration": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.text.narrate"
}
}

View File

@ -0,0 +1,16 @@
{
"chat": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.emote"
},
"narration": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.emote"
}
}

View File

@ -0,0 +1,20 @@
{
"chat": {
"parameters": [
"sender",
"content"
],
"style": {
"color": "gray",
"italic": true
},
"translation_key": "commands.message.display.incoming"
},
"narration": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.text.narrate"
}
}

View File

@ -0,0 +1,20 @@
{
"chat": {
"parameters": [
"target",
"content"
],
"style": {
"color": "gray",
"italic": true
},
"translation_key": "commands.message.display.outgoing"
},
"narration": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.text.narrate"
}
}

View File

@ -0,0 +1,16 @@
{
"chat": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.announcement"
},
"narration": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.text.narrate"
}
}

View File

@ -0,0 +1,17 @@
{
"chat": {
"parameters": [
"target",
"sender",
"content"
],
"translation_key": "chat.type.team.text"
},
"narration": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.text.narrate"
}
}

View File

@ -0,0 +1,17 @@
{
"chat": {
"parameters": [
"target",
"sender",
"content"
],
"translation_key": "chat.type.team.sent"
},
"narration": {
"parameters": [
"sender",
"content"
],
"translation_key": "chat.type.text.narrate"
}
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "arrow",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"death_message_type": "intentional_game_design",
"exhaustion": 0.1,
"message_id": "badRespawnPoint",
"scaling": "always"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "cactus",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "cramming",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "dragonBreath",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"effects": "drowning",
"exhaustion": 0.0,
"message_id": "drown",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "dryout",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "explosion",
"scaling": "always"
}

View File

@ -0,0 +1,6 @@
{
"death_message_type": "fall_variants",
"exhaustion": 0.0,
"message_id": "fall",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "anvil",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "fallingBlock",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "fallingStalactite",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"effects": "burning",
"exhaustion": 0.1,
"message_id": "fireball",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "fireworks",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "flyIntoWall",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"effects": "freezing",
"exhaustion": 0.0,
"message_id": "freeze",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "generic",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "genericKill",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"effects": "burning",
"exhaustion": 0.1,
"message_id": "hotFloor",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"effects": "burning",
"exhaustion": 0.1,
"message_id": "inFire",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "inWall",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "indirectMagic",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"effects": "burning",
"exhaustion": 0.1,
"message_id": "lava",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "lightningBolt",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.0,
"message_id": "magic",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "mob",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "mob",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,5 @@
{
"exhaustion": 0.1,
"message_id": "mob",
"scaling": "when_caused_by_living_non_player"
}

View File

@ -0,0 +1,6 @@
{
"effects": "burning",
"exhaustion": 0.0,
"message_id": "onFire",
"scaling": "when_caused_by_living_non_player"
}

Some files were not shown because too many files have changed in this diff Show More