WIP, start integrating env attributes into dimension types
This commit is contained in:
4 files changed
+215
-2
No files matched your search
@@ -241,6 +241,10 @@ public class NBTCompound extends NBT {
|
||||
return nbtByte != null ? nbtByte.getAsByte() != 0 : defaultValue;
|
||||
}
|
||||
|
||||
public boolean getBooleanOrThrow(String string) {
|
||||
return this.getTagOfTypeOrThrow(string, NBTNumber.class).getAsByte() != 0;
|
||||
}
|
||||
|
||||
@Contract("_, _, !null, _ -> !null")
|
||||
public <T> @Nullable T getOr(String key, NbtDecoder<T> decoder, @Nullable T def, PacketWrapper<?> wrapper) {
|
||||
NBT tag = this.getTagOrNull(key);
|
||||
|
||||
+8
@@ -92,6 +92,14 @@ public class EnvironmentAttributeMap {
|
||||
return new EnvironmentAttributeMap(new HashMap<>(this.entries));
|
||||
}
|
||||
|
||||
public <T> void set(EnvironmentAttribute<T> attribute, T value) {
|
||||
this.set(attribute, value, AttributeModifier.override());
|
||||
}
|
||||
|
||||
public <T, A> void set(EnvironmentAttribute<T> attribute, A value, AttributeModifier<T, A> modifier) {
|
||||
this.entries.put(attribute, new Entry<>(value, modifier));
|
||||
}
|
||||
|
||||
public <T> T applyToDefault(EnvironmentAttribute<T> attribute) {
|
||||
return this.apply(attribute, attribute.getDefaultValue());
|
||||
}
|
||||
|
||||
+202
-1
@@ -19,9 +19,12 @@
|
||||
package com.github.retrooper.packetevents.protocol.world.dimension;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.CopyableEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.DeepComparableEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntity;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntityRefSet;
|
||||
import com.github.retrooper.packetevents.protocol.mapper.MappedEntitySet;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBT;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTByte;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTCompound;
|
||||
@@ -32,8 +35,18 @@ import com.github.retrooper.packetevents.protocol.nbt.NBTLong;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTNumber;
|
||||
import com.github.retrooper.packetevents.protocol.nbt.NBTString;
|
||||
import com.github.retrooper.packetevents.protocol.player.ClientVersion;
|
||||
import com.github.retrooper.packetevents.protocol.util.CodecNameable;
|
||||
import com.github.retrooper.packetevents.protocol.util.NbtCodec;
|
||||
import com.github.retrooper.packetevents.protocol.util.NbtCodecException;
|
||||
import com.github.retrooper.packetevents.protocol.util.NbtCodecs;
|
||||
import com.github.retrooper.packetevents.protocol.util.NbtMapCodec;
|
||||
import com.github.retrooper.packetevents.protocol.world.attributes.EnvironmentAttributeMap;
|
||||
import com.github.retrooper.packetevents.protocol.world.attributes.EnvironmentAttributes;
|
||||
import com.github.retrooper.packetevents.protocol.world.attributes.timelines.Timeline;
|
||||
import com.github.retrooper.packetevents.resources.ResourceLocation;
|
||||
import com.github.retrooper.packetevents.util.mappings.TypesBuilderData;
|
||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
@@ -42,14 +55,117 @@ import java.util.OptionalLong;
|
||||
@NullMarked
|
||||
public interface DimensionType extends MappedEntity, CopyableEntity<DimensionType>, DeepComparableEntity {
|
||||
|
||||
NbtCodec<DimensionType> CODEC = new NbtMapCodec<DimensionType>() {
|
||||
@Override
|
||||
public DimensionType decode(NBTCompound compound, PacketWrapper<?> wrapper) throws NbtCodecException {
|
||||
boolean hasFixedTime;
|
||||
Skybox skybox;
|
||||
CardinalLight cardinalLight;
|
||||
EnvironmentAttributeMap attributes;
|
||||
MappedEntityRefSet<Timeline> timelines;
|
||||
|
||||
ServerVersion version = wrapper.getServerVersion();
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_21_11)) {
|
||||
hasFixedTime = compound.getBooleanOr("has_fixed_time", false);
|
||||
skybox = compound.getOr("skybox", Skybox.CODEC, Skybox.OVERWORLD, wrapper);
|
||||
cardinalLight = compound.getOr("cardinal_light", CardinalLight.CODEC, CardinalLight.DEFAULT, wrapper);
|
||||
attributes = compound.getOr("attributes", EnvironmentAttributeMap.CODEC, EnvironmentAttributeMap.EMPTY, wrapper);
|
||||
timelines = compound.getOr("timelines", MappedEntitySet::decodeRefSet, MappedEntitySet.createEmpty(), wrapper);
|
||||
} else {
|
||||
hasFixedTime = false;
|
||||
skybox = Skybox.NONE;
|
||||
cardinalLight = CardinalLight.DEFAULT;
|
||||
attributes = EnvironmentAttributeMap.create();
|
||||
timelines = MappedEntitySet.createEmpty();
|
||||
}
|
||||
|
||||
double coordinateScale;
|
||||
int minY = 0;
|
||||
int height = 256;
|
||||
NBT monsterSpawnLightLevel = null;
|
||||
int monsterSpawnBlockLightLimit = 0;
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_16_2)) {
|
||||
coordinateScale = compound.getNumberTagOrThrow("coordinate_scale").getAsDouble();
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_17)) {
|
||||
minY = compound.getNumberTagOrThrow("min_y").getAsInt();
|
||||
height = compound.getNumberTagOrThrow("height").getAsInt();
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_19)) {
|
||||
// TODO proper int provider decoding/encoding
|
||||
monsterSpawnLightLevel = compound.getTagOrThrow("monster_spawn_light_level");
|
||||
monsterSpawnBlockLightLimit = compound.getNumberTagOrThrow("monster_spawn_block_light_limit").getAsInt();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
coordinateScale = compound.getBoolean("shrunk") ? 8d : 1d;
|
||||
}
|
||||
|
||||
ResourceLocation effectsLocation = null;
|
||||
OptionalLong fixedTime = OptionalLong.empty();
|
||||
if (version.isOlderThan(ServerVersion.V_1_21_11)) {
|
||||
Number fixedTimeNum = compound.getNumberTagValueOrNull("fixed_time");
|
||||
if (fixedTimeNum != null) {
|
||||
hasFixedTime = true;
|
||||
fixedTime = OptionalLong.of(fixedTimeNum.longValue());
|
||||
}
|
||||
boolean ultrawarm = compound.getBoolean("ultrawarm");
|
||||
boolean natural = compound.getBoolean("natural");
|
||||
boolean bedWorking = compound.getBoolean("bed_works");
|
||||
boolean respawnAnchorWorking = compound.getBoolean("respawn_anchor_works");
|
||||
boolean piglinSafe = compound.getBoolean("piglin_safe");
|
||||
boolean hasRaids = compound.getBoolean("has_raids");
|
||||
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_16_2)) {
|
||||
effectsLocation = compound.getOrThrow("effects", ResourceLocation.CODEC, wrapper);
|
||||
}
|
||||
if (version.isNewerThanOrEquals(ServerVersion.V_1_21_6)) {
|
||||
NBTNumber cloudHeightTag = compound.getNumberTagOrNull("cloud_height");
|
||||
if (cloudHeightTag != null) {
|
||||
attributes.set(EnvironmentAttributes.VISUAL_CLOUD_HEIGHT, cloudHeightTag.getAsFloat());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean hasSkylight = compound.getBooleanOrThrow("has_skylight");
|
||||
boolean hasCeiling = compound.getBooleanOrThrow("has_ceiling");
|
||||
int logicalHeight = compound.getNumberTagValueOrThrow("logical_height").intValue();
|
||||
// TODO proper tag key decoding/encoding
|
||||
String infiniburn = compound.getStringTagValueOrThrow("infiniburn");
|
||||
float ambientLight = compound.getNumberTagValueOrThrow("ambient_light").floatValue();
|
||||
|
||||
// new
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(NBTCompound compound, PacketWrapper<?> wrapper, DimensionType value) throws NbtCodecException {
|
||||
|
||||
}
|
||||
}.codec;
|
||||
|
||||
/**
|
||||
* @versions 1.21.11+
|
||||
*/
|
||||
boolean hasFixedTime();
|
||||
|
||||
/**
|
||||
* @versions -1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
OptionalLong getFixedTime();
|
||||
|
||||
boolean hasSkyLight();
|
||||
|
||||
boolean hasCeiling();
|
||||
|
||||
/**
|
||||
* @versions -1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
boolean isUltraWarm();
|
||||
|
||||
/**
|
||||
* @versions -1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
boolean isNatural();
|
||||
|
||||
double getCoordinateScale();
|
||||
@@ -58,20 +174,40 @@ public interface DimensionType extends MappedEntity, CopyableEntity<DimensionTyp
|
||||
return this.getCoordinateScale() > 1d;
|
||||
}
|
||||
|
||||
/**
|
||||
* @versions -1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
boolean isBedWorking();
|
||||
|
||||
/**
|
||||
* @versions -1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
boolean isRespawnAnchorWorking();
|
||||
|
||||
/**
|
||||
* @versions 1.17+
|
||||
*/
|
||||
default int getMinY() {
|
||||
return this.getMinY(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* @versions 1.17+
|
||||
*/
|
||||
int getMinY(ClientVersion version);
|
||||
|
||||
/**
|
||||
* @versions 1.17+
|
||||
*/
|
||||
default int getHeight() {
|
||||
return this.getHeight(PacketEvents.getAPI().getServerManager().getVersion().toClientVersion());
|
||||
}
|
||||
|
||||
/**
|
||||
* @versions 1.17+
|
||||
*/
|
||||
int getHeight(ClientVersion version);
|
||||
|
||||
default int getLogicalHeight() {
|
||||
@@ -82,23 +218,43 @@ public interface DimensionType extends MappedEntity, CopyableEntity<DimensionTyp
|
||||
|
||||
String getInfiniburnTag();
|
||||
|
||||
/**
|
||||
* @versions 1.16.2-1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
ResourceLocation getEffectsLocation();
|
||||
|
||||
float getAmbientLight();
|
||||
|
||||
/**
|
||||
* Added with 1.21.6
|
||||
* @versions 1.21.6-1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
@Nullable Integer getCloudHeight();
|
||||
|
||||
// monster settings
|
||||
|
||||
/**
|
||||
* @versions -1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
boolean isPiglinSafe();
|
||||
|
||||
/**
|
||||
* @versions -1.21.10
|
||||
*/
|
||||
@ApiStatus.Obsolete
|
||||
boolean hasRaids();
|
||||
|
||||
/**
|
||||
* @versions 1.19+
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
NBT getMonsterSpawnLightLevel();
|
||||
|
||||
/**
|
||||
* @versions 1.19+
|
||||
*/
|
||||
int getMonsterSpawnBlockLightLimit();
|
||||
|
||||
// conversion utilities
|
||||
@@ -193,4 +349,49 @@ public interface DimensionType extends MappedEntity, CopyableEntity<DimensionTyp
|
||||
}
|
||||
return compound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @versions 1.21.11+
|
||||
*/
|
||||
enum Skybox implements CodecNameable {
|
||||
|
||||
NONE("none"),
|
||||
OVERWORLD("overworld"),
|
||||
END("end"),
|
||||
;
|
||||
|
||||
public static final NbtCodec<Skybox> CODEC = NbtCodecs.forEnum(values());
|
||||
|
||||
private final String name;
|
||||
|
||||
Skybox(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodecName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
|
||||
enum CardinalLight implements CodecNameable {
|
||||
|
||||
DEFAULT("default"),
|
||||
NETHER("nether"),
|
||||
;
|
||||
|
||||
public static final NbtCodec<CardinalLight> CODEC = NbtCodecs.forEnum(values());
|
||||
|
||||
private final String name;
|
||||
|
||||
CardinalLight(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCodecName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -94,7 +94,7 @@ public final class SynchronizedRegistriesHandler {
|
||||
// packetevents ignores a few unimportant registries which aren't used anywhere else in the protocol:
|
||||
// test_environment, test_instance
|
||||
Stream.of(
|
||||
new RegistryEntry<>(Biomes.getRegistry(), Biome::decode),
|
||||
new RegistryEntry<>(Biomes.getRegistry(), Biome.CODEC),
|
||||
new RegistryEntry<>(ChatTypes.getRegistry(), ChatType::decode),
|
||||
new RegistryEntry<>(TrimPatterns.getRegistry(), (NbtEntryDecoder<TrimPattern>) TrimPattern::decode),
|
||||
new RegistryEntry<>(TrimMaterials.getRegistry(), (NbtEntryDecoder<TrimMaterial>) TrimMaterial::decode),
|
||||
|
||||
Reference in new issue
Block a user