3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-16 21:10:30 +01:00

Port of #325 for Velocity 1.1.0

Co-authored-by: Five (Xer) <admin@xernium.com>
Dieser Commit ist enthalten in:
Andrew Steinborn 2020-08-05 18:12:36 -04:00
Ursprung 3beaeb2df7
Commit d79c1d0407
6 geänderte Dateien mit 198 neuen und 75 gelöschten Zeilen

Datei anzeigen

@ -38,7 +38,8 @@ public enum ProtocolVersion {
MINECRAFT_1_15_1(575, "1.15.1"), MINECRAFT_1_15_1(575, "1.15.1"),
MINECRAFT_1_15_2(578, "1.15.2"), MINECRAFT_1_15_2(578, "1.15.2"),
MINECRAFT_1_16(735, "1.16"), MINECRAFT_1_16(735, "1.16"),
MINECRAFT_1_16_1(736, "1.16.1"); MINECRAFT_1_16_1(736, "1.16.1"),
MINECRAFT_1_16_2(746, "1.16.2");
private final int protocol; private final int protocol;
private final String name; private final String name;

Datei anzeigen

@ -1,11 +1,13 @@
package com.velocitypowered.proxy.connection.registry; package com.velocitypowered.proxy.connection.registry;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.velocitypowered.api.network.ProtocolVersion;
import net.kyori.nbt.CompoundTag; import net.kyori.nbt.CompoundTag;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public final class DimensionData { public final class DimensionData {
private final String registryIdentifier; private final String registryIdentifier;
private final @Nullable Integer dimensionId;
private final boolean isNatural; private final boolean isNatural;
private final float ambientLight; private final float ambientLight;
private final boolean isShrunk; private final boolean isShrunk;
@ -20,10 +22,12 @@ public final class DimensionData {
private final String burningBehaviourIdentifier; private final String burningBehaviourIdentifier;
private final @Nullable Long fixedTime; private final @Nullable Long fixedTime;
private final @Nullable Boolean createDragonFight; private final @Nullable Boolean createDragonFight;
private final @Nullable Double coordinateScale;
/** /**
* Initializes a new {@link DimensionData} instance. * Initializes a new {@link DimensionData} instance.
* @param registryIdentifier the identifier for the dimension from the registry. * @param registryIdentifier the identifier for the dimension from the registry.
* @param dimensionId the dimension ID contained in the registry (the "id" tag)
* @param isNatural indicates if the dimension use natural world generation (e.g. overworld) * @param isNatural indicates if the dimension use natural world generation (e.g. overworld)
* @param ambientLight the light level the client sees without external lighting * @param ambientLight the light level the client sees without external lighting
* @param isShrunk indicates if the world is shrunk, aka not the full 256 blocks (e.g. nether) * @param isShrunk indicates if the world is shrunk, aka not the full 256 blocks (e.g. nether)
@ -38,24 +42,29 @@ public final class DimensionData {
* @param burningBehaviourIdentifier the identifier for how burning blocks work in the dimension * @param burningBehaviourIdentifier the identifier for how burning blocks work in the dimension
* @param fixedTime optional. If set to any game daytime value will deactivate time cycle * @param fixedTime optional. If set to any game daytime value will deactivate time cycle
* @param createDragonFight optional. Internal flag used in the end dimension * @param createDragonFight optional. Internal flag used in the end dimension
* @param coordinateScale optional, unknown purpose
*/ */
public DimensionData(String registryIdentifier, boolean isNatural, public DimensionData(String registryIdentifier,
float ambientLight, boolean isShrunk, boolean isUltrawarm, @Nullable Integer dimensionId,
boolean hasCeiling, boolean hasSkylight, boolean isNatural,
boolean isPiglinSafe, boolean doBedsWork, float ambientLight, boolean isShrunk, boolean isUltrawarm,
boolean doRespawnAnchorsWork, boolean hasRaids, boolean hasCeiling, boolean hasSkylight,
int logicalHeight, String burningBehaviourIdentifier, boolean isPiglinSafe, boolean doBedsWork,
@Nullable Long fixedTime, @Nullable Boolean createDragonFight) { boolean doRespawnAnchorsWork, boolean hasRaids,
int logicalHeight, String burningBehaviourIdentifier,
@Nullable Long fixedTime, @Nullable Boolean createDragonFight,
@Nullable Double coordinateScale) {
Preconditions.checkNotNull( Preconditions.checkNotNull(
registryIdentifier, "registryIdentifier cannot be null"); registryIdentifier, "registryIdentifier cannot be null");
Preconditions.checkArgument(registryIdentifier.length() > 0, Preconditions.checkArgument(registryIdentifier.length() > 0,
"registryIdentifier cannot be empty"); "registryIdentifier cannot be empty");
Preconditions.checkArgument(logicalHeight >= 0, "localHeight must be >= 0"); Preconditions.checkArgument(logicalHeight >= 0, "localHeight must be >= 0");
Preconditions.checkNotNull( Preconditions.checkNotNull(
burningBehaviourIdentifier, "burningBehaviourIdentifier cannot be null"); burningBehaviourIdentifier, "burningBehaviourIdentifier cannot be null");
Preconditions.checkArgument(burningBehaviourIdentifier.length() > 0, Preconditions.checkArgument(burningBehaviourIdentifier.length() > 0,
"burningBehaviourIdentifier cannot be empty"); "burningBehaviourIdentifier cannot be empty");
this.registryIdentifier = registryIdentifier; this.registryIdentifier = registryIdentifier;
this.dimensionId = dimensionId;
this.isNatural = isNatural; this.isNatural = isNatural;
this.ambientLight = ambientLight; this.ambientLight = ambientLight;
this.isShrunk = isShrunk; this.isShrunk = isShrunk;
@ -70,12 +79,17 @@ public final class DimensionData {
this.burningBehaviourIdentifier = burningBehaviourIdentifier; this.burningBehaviourIdentifier = burningBehaviourIdentifier;
this.fixedTime = fixedTime; this.fixedTime = fixedTime;
this.createDragonFight = createDragonFight; this.createDragonFight = createDragonFight;
this.coordinateScale = coordinateScale;
} }
public String getRegistryIdentifier() { public String getRegistryIdentifier() {
return registryIdentifier; return registryIdentifier;
} }
public @Nullable Integer getDimensionId() {
return dimensionId;
}
public boolean isNatural() { public boolean isNatural() {
return isNatural; return isNatural;
} }
@ -132,43 +146,77 @@ public final class DimensionData {
return createDragonFight; return createDragonFight;
} }
public @Nullable Double getCoordinateScale() {
return coordinateScale;
}
/** /**
* Parses a given CompoundTag to a DimensionData instance. * Parses a given CompoundTag to a DimensionData instance.
* @param toRead the compound from the registry to read * @param dimTag the compound from the registry to read
* @param version the protocol version from the registry
* @return game dimension data * @return game dimension data
*/ */
public static DimensionData decodeCompoundTag(CompoundTag toRead) { public static DimensionData decodeCompoundTag(CompoundTag dimTag, ProtocolVersion version) {
Preconditions.checkNotNull(toRead, "CompoundTag cannot be null"); Preconditions.checkNotNull(dimTag, "CompoundTag cannot be null");
String registryIdentifier = toRead.getString("name"); String registryIdentifier = dimTag.getString("name");
boolean isNatural = toRead.getBoolean("natural"); CompoundTag details;
float ambientLight = toRead.getFloat("ambient_light"); Integer dimensionId = null;
boolean isShrunk = toRead.getBoolean("shrunk"); if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
boolean isUltrawarm = toRead.getBoolean("ultrawarm"); dimensionId = dimTag.getInt("id");
boolean hasCeiling = toRead.getBoolean("has_ceiling"); details = dimTag.getCompound("element");
boolean hasSkylight = toRead.getBoolean("has_skylight"); } else {
boolean isPiglinSafe = toRead.getBoolean("piglin_safe"); details = dimTag;
boolean doBedsWork = toRead.getBoolean("bed_works"); }
boolean doRespawnAnchorsWork = toRead.getBoolean("respawn_anchor_works"); boolean isNatural = details.getBoolean("natural");
boolean hasRaids = toRead.getBoolean("has_raids"); float ambientLight = details.getFloat("ambient_light");
int logicalHeight = toRead.getInt("logical_height"); boolean isShrunk = details.getBoolean("shrunk");
String burningBehaviourIdentifier = toRead.getString("infiniburn"); boolean isUltrawarm = details.getBoolean("ultrawarm");
Long fixedTime = toRead.contains("fixed_time") boolean hasCeiling = details.getBoolean("has_ceiling");
? toRead.getLong("fixed_time") : null; boolean hasSkylight = details.getBoolean("has_skylight");
Boolean hasEnderdragonFight = toRead.contains("has_enderdragon_fight") boolean isPiglinSafe = details.getBoolean("piglin_safe");
? toRead.getBoolean("has_enderdragon_fight") : null; boolean doBedsWork = details.getBoolean("bed_works");
boolean doRespawnAnchorsWork = details.getBoolean("respawn_anchor_works");
boolean hasRaids = details.getBoolean("has_raids");
int logicalHeight = details.getInt("logical_height");
String burningBehaviourIdentifier = details.getString("infiniburn");
Long fixedTime = details.contains("fixed_time")
? details.getLong("fixed_time") : null;
Boolean hasEnderdragonFight = details.contains("has_enderdragon_fight")
? details.getBoolean("has_enderdragon_fight") : null;
Double coordinateScale = details.contains("coordinate_scale")
? details.getDouble("coordinate_scale") : null;
return new DimensionData( return new DimensionData(
registryIdentifier, isNatural, ambientLight, isShrunk, registryIdentifier, dimensionId, isNatural, ambientLight, isShrunk,
isUltrawarm, hasCeiling, hasSkylight, isPiglinSafe, doBedsWork, doRespawnAnchorsWork, isUltrawarm, hasCeiling, hasSkylight, isPiglinSafe, doBedsWork, doRespawnAnchorsWork,
hasRaids, logicalHeight, burningBehaviourIdentifier, fixedTime, hasEnderdragonFight); hasRaids, logicalHeight, burningBehaviourIdentifier, fixedTime, hasEnderdragonFight,
coordinateScale);
} }
/** /**
* Encodes the Dimension data as CompoundTag. * Encodes the Dimension data as CompoundTag.
* @param version the version to serialize as
* @return compound containing the dimension data * @return compound containing the dimension data
*/ */
public CompoundTag encodeAsCompundTag() { public CompoundTag encodeAsCompoundTag(ProtocolVersion version) {
CompoundTag details = serializeDimensionDetails();
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
CompoundTag parent = new CompoundTag();
parent.putString("name", registryIdentifier);
if (dimensionId == null) {
throw new IllegalStateException("Tried to serialize a 1.16.2+ dimension registry entry "
+ "without an ID");
}
parent.putInt("id", dimensionId);
parent.put("element", details);
return parent;
} else {
details.putString("name", registryIdentifier);
return details;
}
}
private CompoundTag serializeDimensionDetails() {
CompoundTag ret = new CompoundTag(); CompoundTag ret = new CompoundTag();
ret.putString("name", registryIdentifier);
ret.putBoolean("natural", isNatural); ret.putBoolean("natural", isNatural);
ret.putFloat("ambient_light", ambientLight); ret.putFloat("ambient_light", ambientLight);
ret.putBoolean("shrunk", isShrunk); ret.putBoolean("shrunk", isShrunk);
@ -187,6 +235,9 @@ public final class DimensionData {
if (createDragonFight != null) { if (createDragonFight != null) {
ret.putBoolean("has_enderdragon_fight", createDragonFight); ret.putBoolean("has_enderdragon_fight", createDragonFight);
} }
if (coordinateScale != null) {
ret.putDouble("coordinate_scale", coordinateScale);
}
return ret; return ret;
} }
} }

Datei anzeigen

@ -4,6 +4,7 @@ import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.velocitypowered.api.network.ProtocolVersion;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -31,17 +32,17 @@ public final class DimensionRegistry {
* @param levelNames a populated {@link ImmutableSet} of the level (world) names the server offers * @param levelNames a populated {@link ImmutableSet} of the level (world) names the server offers
*/ */
public DimensionRegistry(ImmutableSet<DimensionData> registeredDimensions, public DimensionRegistry(ImmutableSet<DimensionData> registeredDimensions,
ImmutableSet<String> levelNames) { ImmutableSet<String> levelNames) {
Preconditions.checkNotNull(registeredDimensions, Preconditions.checkNotNull(registeredDimensions,
"registeredDimensions cannot be null"); "registeredDimensions cannot be null");
Preconditions.checkNotNull(levelNames, Preconditions.checkNotNull(levelNames,
"levelNames cannot be null"); "levelNames cannot be null");
Preconditions.checkArgument(registeredDimensions.size() > 0, Preconditions.checkArgument(registeredDimensions.size() > 0,
"registeredDimensions needs to be populated"); "registeredDimensions needs to be populated");
Preconditions.checkArgument(levelNames.size() > 0, Preconditions.checkArgument(levelNames.size() > 0,
"levelNames needs to populated"); "levelNames needs to populated");
this.registeredDimensions = Maps.uniqueIndex( this.registeredDimensions = Maps.uniqueIndex(
registeredDimensions, DimensionData::getRegistryIdentifier); registeredDimensions, DimensionData::getRegistryIdentifier);
this.levelNames = levelNames; this.levelNames = levelNames;
} }
@ -72,36 +73,31 @@ public final class DimensionRegistry {
return false; return false;
} }
return registeredDimensions.containsKey(toValidate.getRegistryIdentifier()) return registeredDimensions.containsKey(toValidate.getRegistryIdentifier())
&& levelNames.contains(toValidate.getLevelName()); && levelNames.contains(toValidate.getLevelName());
} }
/** /**
* Encodes the stored Dimension registry as CompoundTag. * Encodes the stored Dimension registry as CompoundTag.
* @return the CompoundTag containing identifier:type mappings * @return the CompoundTag containing identifier:type mappings
*/ */
public CompoundTag encodeRegistry() { public ListTag encodeRegistry(ProtocolVersion version) {
CompoundTag ret = new CompoundTag();
ListTag list = new ListTag(TagType.COMPOUND); ListTag list = new ListTag(TagType.COMPOUND);
for (DimensionData iter : registeredDimensions.values()) { for (DimensionData iter : registeredDimensions.values()) {
list.add(iter.encodeAsCompundTag()); list.add(iter.encodeAsCompoundTag(version));
} }
ret.put("dimension", list); return list;
return ret;
} }
/** /**
* Decodes a CompoundTag storing a dimension registry. * Decodes a CompoundTag storing a dimension registry.
* @param toParse CompoundTag containing a dimension registry * @param toParse CompoundTag containing a dimension registry
*/ */
public static ImmutableSet<DimensionData> fromGameData(CompoundTag toParse) { public static ImmutableSet<DimensionData> fromGameData(ListTag toParse, ProtocolVersion version) {
Preconditions.checkNotNull(toParse, "CompoundTag cannot be null"); Preconditions.checkNotNull(toParse, "ListTag cannot be null");
Preconditions.checkArgument(toParse.contains("dimension", TagType.LIST),
"CompoundTag does not contain a dimension list");
ListTag dimensions = toParse.getList("dimension");
ImmutableSet.Builder<DimensionData> mappings = ImmutableSet.builder(); ImmutableSet.Builder<DimensionData> mappings = ImmutableSet.builder();
for (Tag iter : dimensions) { for (Tag iter : toParse) {
if (iter instanceof CompoundTag) { if (iter instanceof CompoundTag) {
mappings.add(DimensionData.decodeCompoundTag((CompoundTag) iter)); mappings.add(DimensionData.decodeCompoundTag((CompoundTag) iter, version));
} }
} }
return mappings.build(); return mappings.build();

Datei anzeigen

@ -7,6 +7,7 @@ import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_13;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_14;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_15;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_16_2;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_7_2; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_7_2;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_8;
import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9; import static com.velocitypowered.api.network.ProtocolVersion.MINECRAFT_1_9;
@ -121,7 +122,8 @@ public enum StateRegistry {
map(0x18, MINECRAFT_1_12, false), map(0x18, MINECRAFT_1_12, false),
map(0x1D, MINECRAFT_1_13, false), map(0x1D, MINECRAFT_1_13, false),
map(0x1F, MINECRAFT_1_14, false), map(0x1F, MINECRAFT_1_14, false),
map(0x20, MINECRAFT_1_16, false)); map(0x20, MINECRAFT_1_16, false),
map(0x21, MINECRAFT_1_16_2, false));
clientbound.register(BossBar.class, BossBar::new, clientbound.register(BossBar.class, BossBar::new,
map(0x0C, MINECRAFT_1_9, false), map(0x0C, MINECRAFT_1_9, false),
@ -138,39 +140,45 @@ public enum StateRegistry {
map(0x0E, MINECRAFT_1_9, false), map(0x0E, MINECRAFT_1_9, false),
map(0x10, MINECRAFT_1_13, false), map(0x10, MINECRAFT_1_13, false),
map(0x11, MINECRAFT_1_15, false), map(0x11, MINECRAFT_1_15, false),
map(0x10, MINECRAFT_1_16, false)); map(0x10, MINECRAFT_1_16, false),
map(0x0F, MINECRAFT_1_16_2, false));
clientbound.register(AvailableCommands.class, AvailableCommands::new, clientbound.register(AvailableCommands.class, AvailableCommands::new,
map(0x11, MINECRAFT_1_13, false), map(0x11, MINECRAFT_1_13, false),
map(0x12, MINECRAFT_1_15, false), map(0x12, MINECRAFT_1_15, false),
map(0x11, MINECRAFT_1_16, false)); map(0x11, MINECRAFT_1_16, false),
map(0x10, MINECRAFT_1_16_2, false));
clientbound.register(PluginMessage.class, PluginMessage::new, clientbound.register(PluginMessage.class, PluginMessage::new,
map(0x3F, MINECRAFT_1_7_2, false), map(0x3F, MINECRAFT_1_7_2, false),
map(0x18, MINECRAFT_1_9, false), map(0x18, MINECRAFT_1_9, false),
map(0x19, MINECRAFT_1_13, false), map(0x19, MINECRAFT_1_13, false),
map(0x18, MINECRAFT_1_14, false), map(0x18, MINECRAFT_1_14, false),
map(0x19, MINECRAFT_1_15, false), map(0x19, MINECRAFT_1_15, false),
map(0x18, MINECRAFT_1_16, false)); map(0x18, MINECRAFT_1_16, false),
map(0x17, MINECRAFT_1_16_2, false));
clientbound.register(Disconnect.class, Disconnect::new, clientbound.register(Disconnect.class, Disconnect::new,
map(0x40, MINECRAFT_1_7_2, false), map(0x40, MINECRAFT_1_7_2, false),
map(0x1A, MINECRAFT_1_9, false), map(0x1A, MINECRAFT_1_9, false),
map(0x1B, MINECRAFT_1_13, false), map(0x1B, MINECRAFT_1_13, false),
map(0x1A, MINECRAFT_1_14, false), map(0x1A, MINECRAFT_1_14, false),
map(0x1B, MINECRAFT_1_15, false), map(0x1B, MINECRAFT_1_15, false),
map(0x1A, MINECRAFT_1_16, false)); map(0x1A, MINECRAFT_1_16, false),
map(0x19, MINECRAFT_1_16_2, false));
clientbound.register(KeepAlive.class, KeepAlive::new, clientbound.register(KeepAlive.class, KeepAlive::new,
map(0x00, MINECRAFT_1_7_2, false), map(0x00, MINECRAFT_1_7_2, false),
map(0x1F, MINECRAFT_1_9, false), map(0x1F, MINECRAFT_1_9, false),
map(0x21, MINECRAFT_1_13, false), map(0x21, MINECRAFT_1_13, false),
map(0x20, MINECRAFT_1_14, false), map(0x20, MINECRAFT_1_14, false),
map(0x21, MINECRAFT_1_15, false), map(0x21, MINECRAFT_1_15, false),
map(0x20, MINECRAFT_1_16, false)); map(0x20, MINECRAFT_1_16, false),
map(0x1F, MINECRAFT_1_16_2, false));
clientbound.register(JoinGame.class, JoinGame::new, clientbound.register(JoinGame.class, JoinGame::new,
map(0x01, MINECRAFT_1_7_2, false), map(0x01, MINECRAFT_1_7_2, false),
map(0x23, MINECRAFT_1_9, false), map(0x23, MINECRAFT_1_9, false),
map(0x25, MINECRAFT_1_13, false), map(0x25, MINECRAFT_1_13, false),
map(0x25, MINECRAFT_1_14, false), map(0x25, MINECRAFT_1_14, false),
map(0x26, MINECRAFT_1_15, false), map(0x26, MINECRAFT_1_15, false),
map(0x25, MINECRAFT_1_16, false)); map(0x25, MINECRAFT_1_16, false),
map(0x24, MINECRAFT_1_16_2, false));
clientbound.register(Respawn.class, Respawn::new, clientbound.register(Respawn.class, Respawn::new,
map(0x07, MINECRAFT_1_7_2, true), map(0x07, MINECRAFT_1_7_2, true),
map(0x33, MINECRAFT_1_9, true), map(0x33, MINECRAFT_1_9, true),
@ -179,7 +187,8 @@ public enum StateRegistry {
map(0x38, MINECRAFT_1_13, true), map(0x38, MINECRAFT_1_13, true),
map(0x3A, MINECRAFT_1_14, true), map(0x3A, MINECRAFT_1_14, true),
map(0x3B, MINECRAFT_1_15, true), map(0x3B, MINECRAFT_1_15, true),
map(0x3A, MINECRAFT_1_16, true)); map(0x3A, MINECRAFT_1_16, true),
map(0x39, MINECRAFT_1_16_2, true));
clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new, clientbound.register(ResourcePackRequest.class, ResourcePackRequest::new,
map(0x48, MINECRAFT_1_8, true), map(0x48, MINECRAFT_1_8, true),
map(0x32, MINECRAFT_1_9, true), map(0x32, MINECRAFT_1_9, true),
@ -188,7 +197,8 @@ public enum StateRegistry {
map(0x37, MINECRAFT_1_13, true), map(0x37, MINECRAFT_1_13, true),
map(0x39, MINECRAFT_1_14, true), map(0x39, MINECRAFT_1_14, true),
map(0x3A, MINECRAFT_1_15, true), map(0x3A, MINECRAFT_1_15, true),
map(0x39, MINECRAFT_1_16, true)); map(0x39, MINECRAFT_1_16, true),
map(0x38, MINECRAFT_1_16_2, true));
clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new, clientbound.register(HeaderAndFooter.class, HeaderAndFooter::new,
map(0x47, MINECRAFT_1_8, true), map(0x47, MINECRAFT_1_8, true),
map(0x48, MINECRAFT_1_9, true), map(0x48, MINECRAFT_1_9, true),
@ -215,7 +225,8 @@ public enum StateRegistry {
map(0x30, MINECRAFT_1_13, false), map(0x30, MINECRAFT_1_13, false),
map(0x33, MINECRAFT_1_14, false), map(0x33, MINECRAFT_1_14, false),
map(0x34, MINECRAFT_1_15, false), map(0x34, MINECRAFT_1_15, false),
map(0x33, MINECRAFT_1_16, false)); map(0x33, MINECRAFT_1_16, false),
map(0x32, MINECRAFT_1_16_2, false));
} }
}, },
LOGIN { LOGIN {

Datei anzeigen

@ -8,6 +8,9 @@ import com.velocitypowered.proxy.connection.registry.DimensionInfo;
import com.velocitypowered.proxy.connection.registry.DimensionRegistry; import com.velocitypowered.proxy.connection.registry.DimensionRegistry;
import com.velocitypowered.proxy.protocol.*; import com.velocitypowered.proxy.protocol.*;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import net.kyori.nbt.CompoundTag;
import net.kyori.nbt.ListTag;
import net.kyori.nbt.TagType;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class JoinGame implements MinecraftPacket { public class JoinGame implements MinecraftPacket {
@ -17,7 +20,8 @@ public class JoinGame implements MinecraftPacket {
private int dimension; private int dimension;
private long partialHashedSeed; // 1.15+ private long partialHashedSeed; // 1.15+
private short difficulty; private short difficulty;
private short maxPlayers; private boolean isHardcore;
private int maxPlayers;
private @Nullable String levelType; private @Nullable String levelType;
private int viewDistance; // 1.14+ private int viewDistance; // 1.14+
private boolean reducedDebugInfo; private boolean reducedDebugInfo;
@ -25,6 +29,7 @@ public class JoinGame implements MinecraftPacket {
private DimensionRegistry dimensionRegistry; // 1.16+ private DimensionRegistry dimensionRegistry; // 1.16+
private DimensionInfo dimensionInfo; // 1.16+ private DimensionInfo dimensionInfo; // 1.16+
private short previousGamemode; // 1.16+ private short previousGamemode; // 1.16+
private CompoundTag biomeRegistry; // 1.16.2+
public int getEntityId() { public int getEntityId() {
return entityId; return entityId;
@ -62,11 +67,11 @@ public class JoinGame implements MinecraftPacket {
this.difficulty = difficulty; this.difficulty = difficulty;
} }
public short getMaxPlayers() { public int getMaxPlayers() {
return maxPlayers; return maxPlayers;
} }
public void setMaxPlayers(short maxPlayers) { public void setMaxPlayers(int maxPlayers) {
this.maxPlayers = maxPlayers; this.maxPlayers = maxPlayers;
} }
@ -118,6 +123,23 @@ public class JoinGame implements MinecraftPacket {
this.previousGamemode = previousGamemode; this.previousGamemode = previousGamemode;
} }
public boolean getIsHardcore() {
return isHardcore;
}
public void setIsHardcore(boolean isHardcore) {
this.isHardcore = isHardcore;
}
public CompoundTag getBiomeRegistry() {
return biomeRegistry;
}
public void setBiomeRegistry(CompoundTag biomeRegistry) {
this.biomeRegistry = biomeRegistry;
}
@Override @Override
public String toString() { public String toString() {
return "JoinGame{" return "JoinGame{"
@ -139,13 +161,30 @@ public class JoinGame implements MinecraftPacket {
@Override @Override
public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { public void decode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
this.entityId = buf.readInt(); this.entityId = buf.readInt();
this.gamemode = buf.readUnsignedByte(); if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
this.isHardcore = buf.readBoolean();
this.gamemode = buf.readByte();
} else {
this.gamemode = buf.readByte();
this.isHardcore = (this.gamemode & 0x08) != 0;
this.gamemode &= ~0x08;
}
String dimensionIdentifier = null; String dimensionIdentifier = null;
String levelName = null; String levelName = null;
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
this.previousGamemode = buf.readByte(); this.previousGamemode = buf.readByte();
ImmutableSet<String> levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf)); ImmutableSet<String> levelNames = ImmutableSet.copyOf(ProtocolUtils.readStringArray(buf));
ImmutableSet<DimensionData> readData = DimensionRegistry.fromGameData(ProtocolUtils.readCompoundTag(buf)); CompoundTag registryContainer = ProtocolUtils.readCompoundTag(buf);
ListTag dimensionRegistryContainer = null;
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
dimensionRegistryContainer = registryContainer.getCompound("minecraft:dimension_type")
.getList("value", TagType.COMPOUND);
this.biomeRegistry = registryContainer.getCompound("minecraft:worldgen/biome");
} else {
dimensionRegistryContainer = registryContainer.getList("dimension", TagType.COMPOUND);
}
ImmutableSet<DimensionData> readData =
DimensionRegistry.fromGameData(dimensionRegistryContainer, version);
this.dimensionRegistry = new DimensionRegistry(readData, levelNames); this.dimensionRegistry = new DimensionRegistry(readData, levelNames);
dimensionIdentifier = ProtocolUtils.readString(buf); dimensionIdentifier = ProtocolUtils.readString(buf);
levelName = ProtocolUtils.readString(buf); levelName = ProtocolUtils.readString(buf);
@ -160,7 +199,11 @@ public class JoinGame implements MinecraftPacket {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
this.partialHashedSeed = buf.readLong(); this.partialHashedSeed = buf.readLong();
} }
this.maxPlayers = buf.readUnsignedByte(); if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
this.maxPlayers = ProtocolUtils.readVarInt(buf);
} else {
this.maxPlayers = buf.readUnsignedByte();
}
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) {
this.levelType = ProtocolUtils.readString(buf, 16); this.levelType = ProtocolUtils.readString(buf, 16);
} }
@ -183,12 +226,28 @@ public class JoinGame implements MinecraftPacket {
@Override @Override
public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) { public void encode(ByteBuf buf, ProtocolUtils.Direction direction, ProtocolVersion version) {
buf.writeInt(entityId); buf.writeInt(entityId);
buf.writeByte(gamemode); if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
buf.writeBoolean(isHardcore);
buf.writeByte(gamemode);
} else {
buf.writeByte(isHardcore ? gamemode | 0x8 : gamemode);
}
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
buf.writeByte(previousGamemode); buf.writeByte(previousGamemode);
ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray( ProtocolUtils.writeStringArray(buf, dimensionRegistry.getLevelNames().toArray(
new String[dimensionRegistry.getLevelNames().size()])); new String[dimensionRegistry.getLevelNames().size()]));
ProtocolUtils.writeCompoundTag(buf, dimensionRegistry.encodeRegistry()); CompoundTag registryContainer = new CompoundTag();
ListTag encodedDimensionRegistry = dimensionRegistry.encodeRegistry(version);
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
CompoundTag dimensionRegistryDummy = new CompoundTag();
dimensionRegistryDummy.putString("type", "minecraft:dimension_type");
dimensionRegistryDummy.put("value", encodedDimensionRegistry);
registryContainer.put("minecraft:dimension_type", dimensionRegistryDummy);
registryContainer.put("minecraft:worldgen/biome", biomeRegistry);
} else {
registryContainer.put("dimension", encodedDimensionRegistry);
}
ProtocolUtils.writeCompoundTag(buf, registryContainer);
ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier()); ProtocolUtils.writeString(buf, dimensionInfo.getRegistryIdentifier());
ProtocolUtils.writeString(buf, dimensionInfo.getLevelName()); ProtocolUtils.writeString(buf, dimensionInfo.getLevelName());
} else if (version.compareTo(ProtocolVersion.MINECRAFT_1_9_1) >= 0) { } else if (version.compareTo(ProtocolVersion.MINECRAFT_1_9_1) >= 0) {
@ -202,7 +261,11 @@ public class JoinGame implements MinecraftPacket {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_15) >= 0) {
buf.writeLong(partialHashedSeed); buf.writeLong(partialHashedSeed);
} }
buf.writeByte(maxPlayers); if (version.compareTo(ProtocolVersion.MINECRAFT_1_16_2) >= 0) {
ProtocolUtils.writeVarInt(buf, maxPlayers);
} else {
buf.writeByte(maxPlayers);
}
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) { if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) < 0) {
if (levelType == null) { if (levelType == null) {
throw new IllegalStateException("No level type specified."); throw new IllegalStateException("No level type specified.");

Datei anzeigen

@ -135,5 +135,6 @@ public class ArgumentPropertyRegistry {
dummy("minecraft:float_range", DUMMY); dummy("minecraft:float_range", DUMMY);
dummy("minecraft:time", DUMMY); // added in 1.14 dummy("minecraft:time", DUMMY); // added in 1.14
dummy("minecraft:uuid", DUMMY); // added in 1.16 dummy("minecraft:uuid", DUMMY); // added in 1.16
dummy("minecraft:angle", DUMMY); // added in 1.16.2
} }
} }