ProtocolLib

3M Downloads

Add wrappers for 1.16.2 dimension/biome registry in PacketPlayOutLogin

bo3tools opened this issue ยท 0 comments

commented

Is your feature request related to a problem? Please describe.
The latest 1.16.2 version now sends a biome registry in the "dimension codec" field of the Join Game packet. It contains all the biomes supported by the server and their properties, such as sky color, grass color, ambient biome particles and ambient sounds. The dimension codec field includes both "dimension properties" from the previous versions (ambient light, does bed work, etc.) and this new "biome registry" array.

The contents of this codec can be seen in this paste from wiki.vg: https://paste.gg/p/KennyTV/ad46ef552c6443cc808385f060564550

The codec is internally represented in net.minecraft.server.v1_16_R2.IRegistryCustom.Dimension.
The dimension properties can be accessed through IRegistryCustom.a() which then calls IRegistryCustom.b(IRegistry.K).
IRegistry.K is a ResourceKey for the DimensionManager (DIMENSION_TYPE_REGISTRY in deobfuscated source).
Biome registry is accessible in a similar way by calling IRegistryCustom.b(IRegistry.ay).

Describe the solution you'd like
I'd really appreciate if such a StructureModifier wrapper can be added the same way every other specific structure is accessed, for example PacketContainer.getDimensionCodecModifier(), which will then allow access to both dimension properties and the new biome registry.

Describe alternatives you've considered
I've used NMS to find out how to access this new structure:

import net.minecraft.server.v1_16_R2.*;

@Override
public void onPacketSending(PacketEvent event) {
    PacketContainer packet = event.getPacket().deepClone();

    IRegistryCustom.Dimension dimensionCodec = (IRegistryCustom.Dimension)
            packet.getModifier()
            .withType(IRegistryCustom.Dimension.class)
            .read(0);

    IRegistryWritable<DimensionManager> dimensionProperties = dimensionCodec.b(IRegistry.K);
    dimensionProperties.g().forEach(dimensionManager -> {
        System.out.println(dimensionManager.isPiglinSafe());
    });

    IRegistryWritable<BiomeBase> biomeRegistry = dimensionCodec.b(IRegistry.ay);
    biomeRegistry.g().forEach(biomeBase -> {
        System.out.println(biomeBase.t().getName());
    });
}

Unfortunately, I couldn't figure out how to swap this registry for my own registry. This functionality is preferred:

  • Create my own biome registry out of my own biome properties
    • Note: Biome properties have limited access in BiomeBase.class
  • Delete biome entries from the biome registry
  • Add new biome entries to the biome registry
  • Change biome properties
    • Note: Possible with NMS and reflection on BiomeBase, see above example

It would be great if a wrapper for both DimensionManager and BiomeBase can be made.

Additional context