3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-11-06 00:00:47 +01:00
Dieser Commit ist enthalten in:
Five (Xer) 2020-06-04 21:21:54 +02:00
Ursprung 6734ef3a08
Commit 009f207883
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: A3F306B10E6330E7
4 geänderte Dateien mit 84 neuen und 28 gelöschten Zeilen

Datei anzeigen

@ -35,7 +35,7 @@ public enum ProtocolVersion {
MINECRAFT_1_15(573, "1.15"), MINECRAFT_1_15(573, "1.15"),
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(718, "1.16"); MINECRAFT_1_16(721, "1.16");
private final int protocol; private final int protocol;
private final String name; private final String name;

Datei anzeigen

@ -1,5 +1,7 @@
package com.velocitypowered.proxy.protocol; package com.velocitypowered.proxy.protocol;
import com.velocitypowered.proxy.connection.MinecraftConnection;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
public class DimensionInfo { public class DimensionInfo {
@ -9,6 +11,13 @@ public class DimensionInfo {
private final boolean isFlat; private final boolean isFlat;
private final boolean isDebugType; private final boolean isDebugType;
/**
* Initializes a new {@link DimensionInfo} instance.
* @param dimensionIdentifier the identifier for the dimension from the registry
* @param dimensionLevelName the level name as displayed in the F3 menu and logs
* @param isFlat if true will set world lighting below surface-level to not display fog
* @param isDebugType if true constrains the world to the very limited debug-type world
*/
public DimensionInfo(@Nonnull String dimensionIdentifier, @Nonnull String dimensionLevelName, public DimensionInfo(@Nonnull String dimensionIdentifier, @Nonnull String dimensionLevelName,
boolean isFlat, boolean isDebugType) { boolean isFlat, boolean isDebugType) {
if (dimensionIdentifier == null || dimensionIdentifier.isEmpty() if (dimensionIdentifier == null || dimensionIdentifier.isEmpty()

Datei anzeigen

@ -12,15 +12,26 @@ import net.kyori.nbt.TagType;
public class DimensionRegistry { public class DimensionRegistry {
// Mapping:
// dimensionIdentifier (Client connection refers to this),
// dimensionType (The game refers to this).
private final @Nonnull Map<String, String> dimensionRegistry; private final @Nonnull Map<String, String> dimensionRegistry;
private final @Nonnull Set<String> worldNames; private final @Nonnull Set<String> worldNames;
/**
* Initializes a new {@link DimensionRegistry} instance.
* This registry is required for 1.16+ clients/servers to communicate,
* it constrains the dimension types and names the client can be sent
* in a Respawn action (dimension change).
* @param dimensionRegistry a populated map containing dimensionIdentifier and dimensionType sets
* @param worldNames a populated {@link Set} of the dimension level names the server offers
*/
public DimensionRegistry(Map<String, String> dimensionRegistry, public DimensionRegistry(Map<String, String> dimensionRegistry,
Set<String> worldNames) { Set<String> worldNames) {
if (dimensionRegistry == null || dimensionRegistry.isEmpty() if (dimensionRegistry == null || dimensionRegistry.isEmpty()
|| worldNames == null || worldNames.isEmpty()) { || worldNames == null || worldNames.isEmpty()) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"DimensionRegistry requires valid arguments, not null and not empty"); "Dimension registry requires valid arguments, not null and not empty");
} }
this.dimensionRegistry = dimensionRegistry; this.dimensionRegistry = dimensionRegistry;
this.worldNames = worldNames; this.worldNames = worldNames;
@ -34,45 +45,64 @@ public class DimensionRegistry {
return worldNames; return worldNames;
} }
public @Nonnull String getDimensionIdentifier(@Nonnull String dimensionName) { /**
if (dimensionName == null) { * Returns the internal dimension type as used by the game.
throw new IllegalArgumentException("DimensionName cannot be null!"); * @param dimensionIdentifier how the type is identified by the connection
* @return game internal dimension type
*/
public @Nonnull String getDimensionType(@Nonnull String dimensionIdentifier) {
if (dimensionIdentifier == null) {
throw new IllegalArgumentException("Dimension identifier cannot be null!");
} }
if (dimensionName == null || !dimensionRegistry.containsKey(dimensionName)) { if (dimensionIdentifier == null || !dimensionRegistry.containsKey(dimensionIdentifier)) {
throw new NoSuchElementException("DimensionName " + dimensionName throw new NoSuchElementException("Dimension with identifier " + dimensionIdentifier
+ " doesn't exist in this Registry!"); + " doesn't exist in this Registry!");
} }
return dimensionRegistry.get(dimensionName); return dimensionRegistry.get(dimensionIdentifier);
} }
public @Nonnull String getDimensionName(@Nonnull String dimensionIdentifier) { /**
if (dimensionIdentifier == null) { * Returns the dimension identifier as used by the client.
throw new IllegalArgumentException("DimensionIdentifier cannot be null!"); * @param dimensionType the internal dimension type
* @return game dimension identifier
*/
public @Nonnull String getDimensionIdentifier(@Nonnull String dimensionType) {
if (dimensionType == null) {
throw new IllegalArgumentException("Dimension type cannot be null!");
} }
for (Map.Entry<String, String> entry : dimensionRegistry.entrySet()) { for (Map.Entry<String, String> entry : dimensionRegistry.entrySet()) {
if (entry.getValue().equals(dimensionIdentifier)) { if (entry.getValue().equals(dimensionType)) {
return entry.getKey(); return entry.getKey();
} }
} }
throw new NoSuchElementException("DimensionIdentifier " + dimensionIdentifier throw new NoSuchElementException("Dimension type " + dimensionType
+ " doesn't exist in this Registry!"); + " doesn't exist in this Registry!");
} }
/**
* Checks a {@link DimensionInfo} against this registry.
* @param toValidate the {@link DimensionInfo} to validate
* @return true: the dimension information is valid for this registry
*/
public boolean isValidFor(@Nonnull DimensionInfo toValidate) { public boolean isValidFor(@Nonnull DimensionInfo toValidate) {
if (toValidate == null) { if (toValidate == null) {
throw new IllegalArgumentException("DimensionInfo cannot be null"); throw new IllegalArgumentException("Dimension info cannot be null");
} }
try { try {
if (!worldNames.contains(toValidate.getDimensionLevelName())) { if (!worldNames.contains(toValidate.getDimensionLevelName())) {
return false; return false;
} }
getDimensionName(toValidate.getDimensionIdentifier()); getDimensionType(toValidate.getDimensionIdentifier());
return true; return true;
} catch (NoSuchElementException thrown) { } catch (NoSuchElementException thrown) {
return false; return false;
} }
} }
/**
* Encodes the stored Dimension registry as CompoundTag.
* @return the CompoundTag containing identifier:type mappings
*/
public CompoundTag encodeToCompoundTag() { public CompoundTag encodeToCompoundTag() {
CompoundTag ret = new CompoundTag(); CompoundTag ret = new CompoundTag();
ListTag list = new ListTag(TagType.COMPOUND); ListTag list = new ListTag(TagType.COMPOUND);
@ -86,6 +116,10 @@ public class DimensionRegistry {
return ret; return ret;
} }
/**
* Decodes a CompoundTag storing dimension mappings to a Map identifier:type.
* @param toParse CompoundTag containing a dimension registry
*/
public static Map<String, String> parseToMapping(@Nonnull CompoundTag toParse) { public static Map<String, String> parseToMapping(@Nonnull CompoundTag toParse) {
if (toParse == null) { if (toParse == null) {
throw new IllegalArgumentException("CompoundTag cannot be null"); throw new IllegalArgumentException("CompoundTag cannot be null");

Datei anzeigen

@ -126,44 +126,52 @@ public enum StateRegistry {
clientbound.register(BossBar.class, BossBar::new, clientbound.register(BossBar.class, BossBar::new,
map(0x0C, MINECRAFT_1_9, false), map(0x0C, MINECRAFT_1_9, false),
map(0x0D, MINECRAFT_1_15, false)); map(0x0D, MINECRAFT_1_15, false),
map(0x0C, MINECRAFT_1_16, false));
clientbound.register(Chat.class, Chat::new, clientbound.register(Chat.class, Chat::new,
map(0x02, MINECRAFT_1_8, true), map(0x02, MINECRAFT_1_8, true),
map(0x0F, MINECRAFT_1_9, true), map(0x0F, MINECRAFT_1_9, true),
map(0x0E, MINECRAFT_1_13, true), map(0x0E, MINECRAFT_1_13, true),
map(0x0F, MINECRAFT_1_15, true)); map(0x0F, MINECRAFT_1_15, true),
map(0x0E, MINECRAFT_1_16, true));
clientbound.register(TabCompleteResponse.class, TabCompleteResponse::new, clientbound.register(TabCompleteResponse.class, TabCompleteResponse::new,
map(0x3A, MINECRAFT_1_8, false), map(0x3A, MINECRAFT_1_8, false),
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));
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));
clientbound.register(PluginMessage.class, PluginMessage::new, clientbound.register(PluginMessage.class, PluginMessage::new,
map(0x3F, MINECRAFT_1_8, false), map(0x3F, MINECRAFT_1_8, 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));
clientbound.register(Disconnect.class, Disconnect::new, clientbound.register(Disconnect.class, Disconnect::new,
map(0x40, MINECRAFT_1_8, false), map(0x40, MINECRAFT_1_8, 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));
clientbound.register(KeepAlive.class, KeepAlive::new, clientbound.register(KeepAlive.class, KeepAlive::new,
map(0x00, MINECRAFT_1_8, false), map(0x00, MINECRAFT_1_8, 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));
clientbound.register(JoinGame.class, JoinGame::new, clientbound.register(JoinGame.class, JoinGame::new,
map(0x01, MINECRAFT_1_8, false), map(0x01, MINECRAFT_1_8, 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));
clientbound.register(Respawn.class, Respawn::new, clientbound.register(Respawn.class, Respawn::new,
map(0x07, MINECRAFT_1_8, true), map(0x07, MINECRAFT_1_8, true),
map(0x33, MINECRAFT_1_9, true), map(0x33, MINECRAFT_1_9, true),
@ -171,7 +179,8 @@ public enum StateRegistry {
map(0x35, MINECRAFT_1_12_1, true), map(0x35, MINECRAFT_1_12_1, true),
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));
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),
@ -179,7 +188,8 @@ public enum StateRegistry {
map(0x34, MINECRAFT_1_12_1, true), map(0x34, MINECRAFT_1_12_1, true),
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));
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),
@ -188,7 +198,8 @@ public enum StateRegistry {
map(0x4A, MINECRAFT_1_12_1, true), map(0x4A, MINECRAFT_1_12_1, true),
map(0x4E, MINECRAFT_1_13, true), map(0x4E, MINECRAFT_1_13, true),
map(0x53, MINECRAFT_1_14, true), map(0x53, MINECRAFT_1_14, true),
map(0x54, MINECRAFT_1_15, true)); map(0x54, MINECRAFT_1_15, true),
map(0x53, MINECRAFT_1_16, true));
clientbound.register(TitlePacket.class, TitlePacket::new, clientbound.register(TitlePacket.class, TitlePacket::new,
map(0x45, MINECRAFT_1_8, true), map(0x45, MINECRAFT_1_8, true),
map(0x45, MINECRAFT_1_9, true), map(0x45, MINECRAFT_1_9, true),
@ -196,14 +207,16 @@ public enum StateRegistry {
map(0x48, MINECRAFT_1_12_1, true), map(0x48, MINECRAFT_1_12_1, true),
map(0x4B, MINECRAFT_1_13, true), map(0x4B, MINECRAFT_1_13, true),
map(0x4F, MINECRAFT_1_14, true), map(0x4F, MINECRAFT_1_14, true),
map(0x50, MINECRAFT_1_15, true)); map(0x50, MINECRAFT_1_15, true),
map(0x4F, MINECRAFT_1_16, true));
clientbound.register(PlayerListItem.class, PlayerListItem::new, clientbound.register(PlayerListItem.class, PlayerListItem::new,
map(0x38, MINECRAFT_1_8, false), map(0x38, MINECRAFT_1_8, false),
map(0x2D, MINECRAFT_1_9, false), map(0x2D, MINECRAFT_1_9, false),
map(0x2E, MINECRAFT_1_12_1, false), map(0x2E, MINECRAFT_1_12_1, false),
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));
} }
}, },
LOGIN { LOGIN {