Add proper ProtocolVersion comparison

This commit is contained in:
Nassim Jahnke 2024-02-13 18:40:21 +01:00
parent a8dc5f0f07
commit 22bd350e35
No known key found for this signature in database
GPG Key ID: EF6771C01F6EF02F
16 changed files with 267 additions and 92 deletions

View File

@ -25,6 +25,7 @@ package com.viaversion.viaversion.api.connection;
import com.viaversion.viaversion.api.protocol.ProtocolPipeline; import com.viaversion.viaversion.api.protocol.ProtocolPipeline;
import com.viaversion.viaversion.api.protocol.packet.Direction; import com.viaversion.viaversion.api.protocol.packet.Direction;
import com.viaversion.viaversion.api.protocol.packet.State; import com.viaversion.viaversion.api.protocol.packet.State;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import java.util.UUID; import java.util.UUID;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
@ -93,12 +94,22 @@ public interface ProtocolInfo {
void setServerState(State serverState); void setServerState(State serverState);
/** /**
* Returns the user's protocol version, or -1 if not set. * Returns the user's release protocol version, or -1 if not set.
* This is set during the {@link State#HANDSHAKE} state. * This is set during the {@link State#HANDSHAKE} state.
* *
* @return protocol version, or -1 if not set * @return release protocol version, or -1 if not set
* @see ProtocolVersion
*/ */
int getProtocolVersion(); default int getProtocolVersion() {
return protocolVersion() != null ? protocolVersion().getVersion() : -1;
}
/**
* Returns the user's protocol version, or null if not set.
*
* @return protocol version if set
*/
@Nullable ProtocolVersion protocolVersion();
void setProtocolVersion(int protocolVersion); void setProtocolVersion(int protocolVersion);

View File

@ -27,35 +27,29 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
public class ProtocolVersion { public class ProtocolVersion implements Comparable<ProtocolVersion> {
// These need to be at the top of the class to be initialized first
private static final Int2ObjectMap<ProtocolVersion> VERSIONS = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<ProtocolVersion> VERSIONS = new Int2ObjectOpenHashMap<>();
private static final List<ProtocolVersion> VERSION_LIST = new ArrayList<>(); private static final List<ProtocolVersion> VERSION_LIST = new ArrayList<>();
// Before the Netty rewrite
public static final ProtocolVersion v1_4_6 = register(51, "1.4.6/7", new VersionRange("1.4", 6, 7));
public static final ProtocolVersion v1_5_1 = register(60, "1.5/1.5.1", new VersionRange("1.5", 0, 1));
public static final ProtocolVersion v1_5_2 = register(61, "1.5.2");
public static final ProtocolVersion v_1_6_1 = register(73, "1.6.1");
public static final ProtocolVersion v_1_6_2 = register(74, "1.6.2");
public static final ProtocolVersion v_1_6_3 = register(77, "1.6.3");
public static final ProtocolVersion v_1_6_4 = register(78, "1.6.4");
// After the Netty rewrite
public static final ProtocolVersion v1_7_1 = register(4, "1.7.2-1.7.5", new VersionRange("1.7", 2, 5)); public static final ProtocolVersion v1_7_1 = register(4, "1.7.2-1.7.5", new VersionRange("1.7", 2, 5));
public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new VersionRange("1.7", 6, 10)); public static final ProtocolVersion v1_7_6 = register(5, "1.7.6-1.7.10", new VersionRange("1.7", 6, 10));
public static final ProtocolVersion v1_8 = register(47, "1.8.x"); public static final ProtocolVersion v1_8 = register(47, "1.8.x", new VersionRange("1.8", 0, 9));
public static final ProtocolVersion v1_9 = register(107, "1.9"); public static final ProtocolVersion v1_9 = register(107, "1.9");
public static final ProtocolVersion v1_9_1 = register(108, "1.9.1"); public static final ProtocolVersion v1_9_1 = register(108, "1.9.1");
public static final ProtocolVersion v1_9_2 = register(109, "1.9.2"); public static final ProtocolVersion v1_9_2 = register(109, "1.9.2");
public static final ProtocolVersion v1_9_3 = register(110, "1.9.3/4", new VersionRange("1.9", 3, 4)); public static final ProtocolVersion v1_9_3 = register(110, "1.9.3/1.9.4", new VersionRange("1.9", 3, 4));
public static final ProtocolVersion v1_10 = register(210, "1.10.x"); public static final ProtocolVersion v1_10 = register(210, "1.10.x", new VersionRange("1.10", 0, 2));
public static final ProtocolVersion v1_11 = register(315, "1.11"); public static final ProtocolVersion v1_11 = register(315, "1.11");
public static final ProtocolVersion v1_11_1 = register(316, "1.11.1/2", new VersionRange("1.11", 1, 2)); public static final ProtocolVersion v1_11_1 = register(316, "1.11.1/1.11.2", new VersionRange("1.11", 1, 2));
public static final ProtocolVersion v1_12 = register(335, "1.12"); public static final ProtocolVersion v1_12 = register(335, "1.12");
public static final ProtocolVersion v1_12_1 = register(338, "1.12.1"); public static final ProtocolVersion v1_12_1 = register(338, "1.12.1");
public static final ProtocolVersion v1_12_2 = register(340, "1.12.2"); public static final ProtocolVersion v1_12_2 = register(340, "1.12.2");
@ -74,13 +68,13 @@ public class ProtocolVersion {
public static final ProtocolVersion v1_16_1 = register(736, "1.16.1"); public static final ProtocolVersion v1_16_1 = register(736, "1.16.1");
public static final ProtocolVersion v1_16_2 = register(751, "1.16.2"); public static final ProtocolVersion v1_16_2 = register(751, "1.16.2");
public static final ProtocolVersion v1_16_3 = register(753, "1.16.3"); public static final ProtocolVersion v1_16_3 = register(753, "1.16.3");
public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/5", new VersionRange("1.16", 4, 5)); public static final ProtocolVersion v1_16_4 = register(754, "1.16.4/1.16.5", new VersionRange("1.16", 4, 5));
public static final ProtocolVersion v1_17 = register(755, "1.17"); public static final ProtocolVersion v1_17 = register(755, "1.17");
public static final ProtocolVersion v1_17_1 = register(756, "1.17.1"); public static final ProtocolVersion v1_17_1 = register(756, "1.17.1");
public static final ProtocolVersion v1_18 = register(757, "1.18/1.18.1", new VersionRange("1.18", 0, 1)); public static final ProtocolVersion v1_18 = register(757, "1.18/1.18.1", new VersionRange("1.18", 0, 1));
public static final ProtocolVersion v1_18_2 = register(758, "1.18.2"); public static final ProtocolVersion v1_18_2 = register(758, "1.18.2");
public static final ProtocolVersion v1_19 = register(759, "1.19"); public static final ProtocolVersion v1_19 = register(759, "1.19");
public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/2", new VersionRange("1.19", 1, 2)); public static final ProtocolVersion v1_19_1 = register(760, "1.19.1/1.19.2", new VersionRange("1.19", 1, 2));
public static final ProtocolVersion v1_19_3 = register(761, "1.19.3"); public static final ProtocolVersion v1_19_3 = register(761, "1.19.3");
public static final ProtocolVersion v1_19_4 = register(762, "1.19.4"); public static final ProtocolVersion v1_19_4 = register(762, "1.19.4");
public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new VersionRange("1.20", 0, 1)); public static final ProtocolVersion v1_20 = register(763, "1.20/1.20.1", new VersionRange("1.20", 0, 1));
@ -94,30 +88,28 @@ public class ProtocolVersion {
} }
public static ProtocolVersion register(int version, int snapshotVersion, String name) { public static ProtocolVersion register(int version, int snapshotVersion, String name) {
return register(version, snapshotVersion, name, null); final ProtocolVersion protocolVersion = new ProtocolVersion(VersionType.RELEASE, version, snapshotVersion, name, null);
register(protocolVersion);
return protocolVersion;
} }
public static ProtocolVersion register(int version, String name, @Nullable VersionRange versionRange) { public static ProtocolVersion register(int version, String name, @Nullable VersionRange versionRange) {
return register(version, -1, name, versionRange); final ProtocolVersion protocolVersion = new ProtocolVersion(VersionType.RELEASE, version, -1, name, versionRange);
register(protocolVersion);
return protocolVersion;
} }
/** /**
* Registers a protocol version. * Registers a protocol version.
* *
* @param version release protocol version * @param protocolVersion protocol version to register
* @param snapshotVersion snapshot protocol version, or -1 if not a snapshot
* @param name version name
* @param versionRange range of versions that are supported by this protocol version, null if not a range
* @return registered ProtocolVersion
*/ */
public static ProtocolVersion register(int version, int snapshotVersion, String name, @Nullable VersionRange versionRange) { public static void register(ProtocolVersion protocolVersion) {
ProtocolVersion protocol = new ProtocolVersion(version, snapshotVersion, name, versionRange); VERSION_LIST.add(protocolVersion);
VERSION_LIST.add(protocol); VERSIONS.put(protocolVersion.getVersion(), protocolVersion);
VERSIONS.put(protocol.getVersion(), protocol); if (protocolVersion.isSnapshot()) {
if (protocol.isSnapshot()) { VERSIONS.put(protocolVersion.getFullSnapshotVersion(), protocolVersion);
VERSIONS.put(protocol.getFullSnapshotVersion(), protocol);
} }
return protocol;
} }
/** /**
@ -137,12 +129,12 @@ public class ProtocolVersion {
* @param version protocol version * @param version protocol version
* @return registered or unknown ProtocolVersion * @return registered or unknown ProtocolVersion
*/ */
public static @NonNull ProtocolVersion getProtocol(int version) { public static @NonNull ProtocolVersion getProtocol(final int version) {
ProtocolVersion protocolVersion = VERSIONS.get(version); final ProtocolVersion protocolVersion = VERSIONS.get(version);
if (protocolVersion != null) { if (protocolVersion != null) {
return protocolVersion; return protocolVersion;
} else { } else {
return new ProtocolVersion(version, "Unknown (" + version + ")"); return new ProtocolVersion(VersionType.SPECIAL, version, -1, "Unknown (" + version + ")", null);
} }
} }
@ -151,7 +143,9 @@ public class ProtocolVersion {
* *
* @param version protocol version instance * @param version protocol version instance
* @return internal index of the stored protocol version * @return internal index of the stored protocol version
* @deprecated comparison should be done via the comparison methods
*/ */
@Deprecated/*(forRemoval = true)*/
public static int getIndex(ProtocolVersion version) { public static int getIndex(ProtocolVersion version) {
return VERSION_LIST.indexOf(version); return VERSION_LIST.indexOf(version);
} }
@ -167,7 +161,7 @@ public class ProtocolVersion {
/** /**
* Returns the registered protocol version if present, else null. * Returns the registered protocol version if present, else null.
* This accepts the actual registered names (like "1.16.4/5") as well as * This accepts the actual registered names (like "1.16.4/1.16.5") as well as
* included versions for version ranges and wildcards. * included versions for version ranges and wildcards.
* *
* @param protocol version name, e.g. "1.16.3" * @param protocol version name, e.g. "1.16.3"
@ -176,50 +170,49 @@ public class ProtocolVersion {
public static @Nullable ProtocolVersion getClosest(String protocol) { public static @Nullable ProtocolVersion getClosest(String protocol) {
for (ProtocolVersion version : VERSIONS.values()) { for (ProtocolVersion version : VERSIONS.values()) {
String name = version.getName(); String name = version.getName();
if (name.equals(protocol)) { if (name.equals(protocol) || version.isRange() && version.getIncludedVersions().contains(protocol)) {
return version;
}
if (version.isVersionWildcard()) {
// Test against the major version with and without a minor version
String majorVersion = name.substring(0, name.length() - 2);
if (majorVersion.equals(protocol) || (protocol.startsWith(name.substring(0, name.length() - 1)))) {
return version;
}
} else if (version.isRange() && version.getIncludedVersions().contains(protocol)) {
return version; return version;
} }
} }
return null; return null;
} }
private final VersionType versionType;
private final int version; private final int version;
private final int snapshotVersion; private final int snapshotVersion;
private final String name; private final String name;
private final boolean versionWildcard;
private final Set<String> includedVersions; private final Set<String> includedVersions;
/** /**
* @param version protocol version * @param version protocol version
* @param name version name * @param name version name
*/ */
@Deprecated/*(forRemoval = true)*/
public ProtocolVersion(int version, String name) { public ProtocolVersion(int version, String name) {
this(version, -1, name, null); this(version, -1, name, null);
} }
@Deprecated/*(forRemoval = true)*/
public ProtocolVersion(int version, int snapshotVersion, String name, @Nullable VersionRange versionRange) {
this(VersionType.RELEASE, version, snapshotVersion, name, versionRange);
}
/** /**
* Constructs a new ProtocolVersion instance.
*
* @param versionType protocol version type
* @param version protocol version * @param version protocol version
* @param snapshotVersion actual snapshot protocol version, -1 if not a snapshot * @param snapshotVersion actual snapshot protocol version, -1 if not a snapshot
* @param name version name * @param name version name
* @param versionRange range of versions that are supported by this protocol version, null if not a range * @param versionRange range of versions that are supported by this protocol version, null if not a range
*/ */
public ProtocolVersion(int version, int snapshotVersion, String name, @Nullable VersionRange versionRange) { public ProtocolVersion(VersionType versionType, int version, int snapshotVersion, String name, @Nullable VersionRange versionRange) {
this.versionType = versionType;
this.version = version; this.version = version;
this.snapshotVersion = snapshotVersion; this.snapshotVersion = snapshotVersion;
this.name = name; this.name = name;;
this.versionWildcard = name.endsWith(".x");
Preconditions.checkArgument(!versionWildcard || versionRange == null, "A version cannot be a wildcard and a range at the same time!"); Preconditions.checkArgument(!(isVersionWildcard() && versionRange == null), "A wildcard name must have a version range");
if (versionRange != null) { if (versionRange != null) {
includedVersions = new LinkedHashSet<>(); includedVersions = new LinkedHashSet<>();
for (int i = versionRange.rangeFrom(); i <= versionRange.rangeTo(); i++) { for (int i = versionRange.rangeFrom(); i <= versionRange.rangeTo(); i++) {
@ -234,6 +227,16 @@ public class ProtocolVersion {
} }
} }
/**
* Returns the type of version (excluding whether it is a snapshot).
*
* @return version type
* @see #isSnapshot()
*/
public VersionType getVersionType() {
return versionType;
}
/** /**
* Returns the release protocol version. * Returns the release protocol version.
* *
@ -313,7 +316,7 @@ public class ProtocolVersion {
* @return true if the protocol includes an entire major version range * @return true if the protocol includes an entire major version range
*/ */
public boolean isVersionWildcard() { public boolean isVersionWildcard() {
return versionWildcard; return this.name.endsWith(".x");
} }
/** /**
@ -334,22 +337,92 @@ public class ProtocolVersion {
return snapshotVersion != -1; return snapshotVersion != -1;
} }
/**
* Returns whether this protocol version is higher than the other protocol version.
*
* @param other other protocol version
* @return true if this protocol version is higher than the other protocol version
*/
public boolean higherThan(final ProtocolVersion other) {
return this.compareTo(other) > 0;
}
/**
* Returns whether this protocol version is higher than or equal to the other protocol version.
*
* @param other other protocol version
* @return true if this protocol version is higher than or equal to the other protocol version
*/
public boolean higherThanOrEquals(final ProtocolVersion other) {
return this.compareTo(other) >= 0;
}
/**
* Returns whether this protocol version is lower than the other protocol version.
*
* @param other other protocol version
* @return true if this protocol version is lower than the other protocol version
*/
public boolean lowerThan(final ProtocolVersion other) {
return this.compareTo(other) < 0;
}
/**
* Returns whether this protocol version is lower than or equal to the other protocol version.
*
* @param other other protocol version
* @return true if this protocol version is lower than or equal to the other protocol version
*/
public boolean lowerThanOrEquals(final ProtocolVersion other) {
return this.compareTo(other) <= 0;
}
/**
* Returns a custom comparator used to compare protocol versions.
* Must be overridden if the version type is {@link VersionType#SPECIAL}
*
* @return custom comparator
*/
protected @Nullable Comparator<ProtocolVersion> customComparator() {
return null;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(final Object o) {
if (this == o) return true; if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass()) return false;
ProtocolVersion that = (ProtocolVersion) o; final ProtocolVersion that = (ProtocolVersion) o;
return version == that.version; return version == that.version && versionType == that.versionType && snapshotVersion == that.snapshotVersion;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return version; int result = versionType.hashCode();
result = 31 * result + version;
result = 31 * result + snapshotVersion;
return result;
} }
@Override @Override
public String toString() { public String toString() {
return String.format("%s (%d)", this.name, this.version); return String.format("%s (%d)", this.name, this.version);
} }
@Override
public int compareTo(final ProtocolVersion other) {
if (customComparator() != null) {
return customComparator().compare(this, other);
} else if (other.customComparator() != null) {
return other.customComparator().compare(other, this);
} else if (this.versionType != other.versionType) {
// Compare by version type first since version ids have reset multiple times
return this.versionType.ordinal() < other.versionType.ordinal() ? -1 : 1;
} else if (this.version != other.version) {
// Compare by release version
return this.version < other.version ? -1 : 1;
}
// Finally, compare by snapshot version
return Integer.compare(this.snapshotVersion, other.snapshotVersion);
}
} }

View File

@ -34,6 +34,13 @@ public interface ServerProtocolVersion {
*/ */
int lowestSupportedVersion(); int lowestSupportedVersion();
/**
* @see #highestSupportedVersion()
*/
default ProtocolVersion lowestSupportedProtocolVersion() {
return ProtocolVersion.getProtocol(lowestSupportedVersion());
}
/** /**
* Returns the highest supported protocol version by this server. * Returns the highest supported protocol version by this server.
* This and {@link #lowestSupportedVersion()} should only differ on proxy servers supporting multiple versions. * This and {@link #lowestSupportedVersion()} should only differ on proxy servers supporting multiple versions.
@ -42,6 +49,13 @@ public interface ServerProtocolVersion {
*/ */
int highestSupportedVersion(); int highestSupportedVersion();
/**
* @see #lowestSupportedVersion()
*/
default ProtocolVersion highestSupportedProtocolVersion() {
return ProtocolVersion.getProtocol(highestSupportedVersion());
}
/** /**
* Returns a sorted set of all supported protocol version by this server. * Returns a sorted set of all supported protocol version by this server.
* For non-proxy servers, this should return a singleton set. * For non-proxy servers, this should return a singleton set.

View File

@ -0,0 +1,64 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2024 ViaVersion and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.viaversion.viaversion.api.protocol.version;
/**
* Categories of Minecraft versions from classic to modern releases, ordered by date.
*/
public enum VersionType {
/**
* Classic versions of Minecraft.
*/
CLASSIC,
/**
* Alpha versions of Minecraft (Alpha 1.0.0 to 1.0.16).
*/
ALPHA_INITIAL,
/**
* Alpha versions of Minecraft (Alpha 1.0.17 to 1.2.6).
*/
ALPHA_LATER,
/**
* Beta versions of Minecraft (Beta 1.0 to 1.1_02).
*/
BETA_INITIAL,
/**
* Beta versions of Minecraft (Beta 1.2 to 1.9-pre6/1.0.0-RC2).
*/
BETA_LATER,
/**
* Pre-netty release versions of Minecraft (1.0.0 to the 1.7.2 snapshot 13w39b).
*/
RELEASE_INITIAL,
/**
* Modern release versions of Minecraft (13w41a to latest).
*/
RELEASE,
/**
* Any version that doesn't fit in the above categories (e.g. April Fools).
* <p>
* Protocol versions using this type must override the compareTo method.
*/
SPECIAL
}

View File

@ -71,7 +71,7 @@ public class PlayerSneakListener extends ViaBukkitListener {
// From 1.9 upwards the server hitbox is set in every entity tick, so we have to reset it everytime // From 1.9 upwards the server hitbox is set in every entity tick, so we have to reset it everytime
if (Via.getAPI().getServerVersion().lowestSupportedVersion() >= ProtocolVersion.v1_9.getVersion()) { if (Via.getAPI().getServerVersion().lowestSupportedProtocolVersion().higherThan(ProtocolVersion.v1_8)) {
sneaking = new WeakHashMap<>(); sneaking = new WeakHashMap<>();
useCache = true; useCache = true;
plugin.getServer().getScheduler().runTaskTimer(plugin, () -> { plugin.getServer().getScheduler().runTaskTimer(plugin, () -> {
@ -95,8 +95,8 @@ public class PlayerSneakListener extends ViaBukkitListener {
ProtocolInfo info = userConnection.getProtocolInfo(); ProtocolInfo info = userConnection.getProtocolInfo();
if (info == null) return; if (info == null) return;
int protocolVersion = info.getProtocolVersion(); ProtocolVersion protocolVersion = info.protocolVersion();
if (is1_14Fix && protocolVersion >= ProtocolVersion.v1_14.getVersion()) { if (is1_14Fix && protocolVersion.higherThanOrEquals(ProtocolVersion.v1_14)) {
setHeight(player, event.isSneaking() ? HEIGHT_1_14 : STANDING_HEIGHT); setHeight(player, event.isSneaking() ? HEIGHT_1_14 : STANDING_HEIGHT);
if (event.isSneaking()) if (event.isSneaking())
sneakingUuids.add(player.getUniqueId()); sneakingUuids.add(player.getUniqueId());
@ -108,7 +108,7 @@ public class PlayerSneakListener extends ViaBukkitListener {
sneaking.put(player, true); sneaking.put(player, true);
else else
sneaking.remove(player); sneaking.remove(player);
} else if (is1_9Fix && protocolVersion >= ProtocolVersion.v1_9.getVersion()) { } else if (is1_9Fix && protocolVersion.higherThanOrEquals(ProtocolVersion.v1_9)) {
setHeight(player, event.isSneaking() ? HEIGHT_1_9 : STANDING_HEIGHT); setHeight(player, event.isSneaking() ? HEIGHT_1_9 : STANDING_HEIGHT);
if (!useCache) return; if (!useCache) return;
if (event.isSneaking()) if (event.isSneaking())

View File

@ -87,10 +87,10 @@ public class BukkitViaLoader implements ViaPlatformLoader {
return; return;
} }
int serverProtocolVersion = Via.getAPI().getServerVersion().lowestSupportedVersion(); ProtocolVersion serverProtocolVersion = Via.getAPI().getServerVersion().lowestSupportedProtocolVersion();
/* 1.9 client to 1.8 server */ /* 1.9 client to 1.8 server */
if (serverProtocolVersion < ProtocolVersion.v1_9.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_9)) {
new ArmorListener(plugin).register(); new ArmorListener(plugin).register();
new DeathListener(plugin).register(); new DeathListener(plugin).register();
new BlockListener(plugin).register(); new BlockListener(plugin).register();
@ -101,8 +101,8 @@ public class BukkitViaLoader implements ViaPlatformLoader {
} }
} }
if (serverProtocolVersion < ProtocolVersion.v1_14.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_14)) {
boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && serverProtocolVersion < ProtocolVersion.v1_9.getVersion(); boolean use1_9Fix = plugin.getConf().is1_9HitboxFix() && serverProtocolVersion.lowerThan(ProtocolVersion.v1_9);
if (use1_9Fix || plugin.getConf().is1_14HitboxFix()) { if (use1_9Fix || plugin.getConf().is1_14HitboxFix()) {
try { try {
new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix()).register(); new PlayerSneakListener(plugin, use1_9Fix, plugin.getConf().is1_14HitboxFix()).register();
@ -112,7 +112,7 @@ public class BukkitViaLoader implements ViaPlatformLoader {
} }
} }
if (serverProtocolVersion < ProtocolVersion.v1_15.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_15)) {
try { try {
Class.forName("org.bukkit.event.entity.EntityToggleGlideEvent"); Class.forName("org.bukkit.event.entity.EntityToggleGlideEvent");
new EntityToggleGlideListener(plugin).register(); new EntityToggleGlideListener(plugin).register();
@ -120,7 +120,7 @@ public class BukkitViaLoader implements ViaPlatformLoader {
} }
} }
if (serverProtocolVersion < ProtocolVersion.v1_12.getVersion() && !Boolean.getBoolean("com.viaversion.ignorePaperBlockPlacePatch")) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_12) && !Boolean.getBoolean("com.viaversion.ignorePaperBlockPlacePatch")) {
boolean paper = true; boolean paper = true;
try { try {
Class.forName("org.github.paperspigot.PaperSpigotConfig"); // Paper 1.8 ? Class.forName("org.github.paperspigot.PaperSpigotConfig"); // Paper 1.8 ?
@ -136,12 +136,12 @@ public class BukkitViaLoader implements ViaPlatformLoader {
} }
} }
if (serverProtocolVersion < ProtocolVersion.v1_19_4.getVersion() && plugin.getConf().isArmorToggleFix() && hasGetHandMethod()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_19_4) && plugin.getConf().isArmorToggleFix() && hasGetHandMethod()) {
new ArmorToggleListener(plugin).register(); new ArmorToggleListener(plugin).register();
} }
/* Providers */ /* Providers */
if (serverProtocolVersion < ProtocolVersion.v1_9.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_9)) {
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter()); Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BukkitViaMovementTransmitter());
Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() { Via.getManager().getProviders().use(HandItemProvider.class, new HandItemProvider() {
@ -167,19 +167,19 @@ public class BukkitViaLoader implements ViaPlatformLoader {
}); });
} }
if (serverProtocolVersion < ProtocolVersion.v1_12.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_12)) {
if (plugin.getConf().is1_12QuickMoveActionFix()) { if (plugin.getConf().is1_12QuickMoveActionFix()) {
Via.getManager().getProviders().use(InventoryQuickMoveProvider.class, new BukkitInventoryQuickMoveProvider()); Via.getManager().getProviders().use(InventoryQuickMoveProvider.class, new BukkitInventoryQuickMoveProvider());
} }
} }
if (serverProtocolVersion < ProtocolVersion.v1_13.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_13)) {
if (Via.getConfig().getBlockConnectionMethod().equalsIgnoreCase("world")) { if (Via.getConfig().getBlockConnectionMethod().equalsIgnoreCase("world")) {
BukkitBlockConnectionProvider blockConnectionProvider = new BukkitBlockConnectionProvider(); BukkitBlockConnectionProvider blockConnectionProvider = new BukkitBlockConnectionProvider();
Via.getManager().getProviders().use(BlockConnectionProvider.class, blockConnectionProvider); Via.getManager().getProviders().use(BlockConnectionProvider.class, blockConnectionProvider);
ConnectionData.blockConnectionProvider = blockConnectionProvider; ConnectionData.blockConnectionProvider = blockConnectionProvider;
} }
} }
if (serverProtocolVersion < ProtocolVersion.v1_19.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_19)) {
Via.getManager().getProviders().use(AckSequenceProvider.class, new BukkitAckSequenceProvider(plugin)); Via.getManager().getProviders().use(AckSequenceProvider.class, new BukkitAckSequenceProvider(plugin));
new BlockBreakListener(plugin).register(); new BlockBreakListener(plugin).register();
} }

View File

@ -22,6 +22,7 @@ import io.netty.channel.Channel;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import net.kyori.adventure.key.Key; import net.kyori.adventure.key.Key;
import org.bukkit.Bukkit;
public final class PaperViaInjector { public final class PaperViaInjector {
public static final boolean PAPER_INJECTION_METHOD = hasPaperInjectionMethod(); public static final boolean PAPER_INJECTION_METHOD = hasPaperInjectionMethod();
@ -31,6 +32,14 @@ public final class PaperViaInjector {
private PaperViaInjector() { private PaperViaInjector() {
} }
public static int getServerProtocolVersion() {
if (!PaperViaInjector.PAPER_PROTOCOL_METHOD) {
throw new UnsupportedOperationException("Paper method not available");
}
//noinspection deprecation
return Bukkit.getUnsafe().getProtocolVersion();
}
public static void setPaperChannelInitializeListener() throws ReflectiveOperationException { public static void setPaperChannelInitializeListener() throws ReflectiveOperationException {
// Call io.papermc.paper.network.ChannelInitializeListenerHolder.addListener(net.kyori.adventure.key.Key, io.papermc.paper.network.ChannelInitializeListener) // Call io.papermc.paper.network.ChannelInitializeListenerHolder.addListener(net.kyori.adventure.key.Key, io.papermc.paper.network.ChannelInitializeListener)
// Create an interface proxy of ChannelInitializeListener // Create an interface proxy of ChannelInitializeListener

View File

@ -60,7 +60,8 @@ public class BungeeViaLoader implements ViaPlatformLoader {
registerListener(new UpdateListener()); registerListener(new UpdateListener());
registerListener(new BungeeServerHandler()); registerListener(new BungeeServerHandler());
if (Via.getAPI().getServerVersion().lowestSupportedVersion() < ProtocolVersion.v1_9.getVersion()) { final ProtocolVersion protocolVersion = Via.getAPI().getServerVersion().lowestSupportedProtocolVersion();
if (protocolVersion.lowerThan(ProtocolVersion.v1_9)) {
registerListener(new ElytraPatch()); registerListener(new ElytraPatch());
} }
@ -68,7 +69,7 @@ public class BungeeViaLoader implements ViaPlatformLoader {
Via.getManager().getProviders().use(VersionProvider.class, new BungeeVersionProvider()); Via.getManager().getProviders().use(VersionProvider.class, new BungeeVersionProvider());
Via.getManager().getProviders().use(EntityIdProvider.class, new BungeeEntityIdProvider()); Via.getManager().getProviders().use(EntityIdProvider.class, new BungeeEntityIdProvider());
if (Via.getAPI().getServerVersion().lowestSupportedVersion() < ProtocolVersion.v1_9.getVersion()) { if (protocolVersion.lowerThan(ProtocolVersion.v1_9)) {
Via.getManager().getProviders().use(BossBarProvider.class, new BungeeBossBarProvider()); Via.getManager().getProviders().use(BossBarProvider.class, new BungeeBossBarProvider());
Via.getManager().getProviders().use(MainHandProvider.class, new BungeeMainHandProvider()); Via.getManager().getProviders().use(MainHandProvider.class, new BungeeMainHandProvider());
} }

View File

@ -42,8 +42,9 @@ public class BungeeVersionProvider extends BaseVersionProvider {
ProtocolInfo info = user.getProtocolInfo(); ProtocolInfo info = user.getProtocolInfo();
// Bungee supports it // Bungee supports it
if (sorted.contains(info.getProtocolVersion())) if (sorted.contains(info.getProtocolVersion())) {
return info.getProtocolVersion(); return info.getProtocolVersion();
}
// Older than bungee supports, get the lowest version // Older than bungee supports, get the lowest version
if (info.getProtocolVersion() < sorted.get(0)) { if (info.getProtocolVersion() < sorted.get(0)) {
@ -55,8 +56,9 @@ public class BungeeVersionProvider extends BaseVersionProvider {
// TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work. // TODO: This needs a better fix, i.e checking ProtocolRegistry to see if it would work.
// This is more of a workaround for snapshot support by bungee. // This is more of a workaround for snapshot support by bungee.
for (Integer protocol : Lists.reverse(sorted)) { for (Integer protocol : Lists.reverse(sorted)) {
if (info.getProtocolVersion() > protocol && ProtocolVersion.isRegistered(protocol)) if (info.getProtocolVersion() > protocol && ProtocolVersion.isRegistered(protocol)) {
return protocol; return protocol;
}
} }
Via.getPlatform().getLogger().severe("Panic, no protocol id found for " + info.getProtocolVersion()); Via.getPlatform().getLogger().severe("Panic, no protocol id found for " + info.getProtocolVersion());

View File

@ -130,7 +130,7 @@ public class ViaManagerImpl implements ViaManager {
ServerProtocolVersion protocolVersion = protocolManager.getServerProtocolVersion(); ServerProtocolVersion protocolVersion = protocolManager.getServerProtocolVersion();
if (protocolVersion.isKnown()) { if (protocolVersion.isKnown()) {
if (platform.isProxy()) { if (platform.isProxy()) {
platform.getLogger().info("ViaVersion detected lowest supported version by the proxy: " + ProtocolVersion.getProtocol(protocolVersion.lowestSupportedVersion())); platform.getLogger().info("ViaVersion detected lowest supported version by the proxy: " + protocolVersion.lowestSupportedProtocolVersion());
platform.getLogger().info("Highest supported version by the proxy: " + ProtocolVersion.getProtocol(protocolVersion.highestSupportedVersion())); platform.getLogger().info("Highest supported version by the proxy: " + ProtocolVersion.getProtocol(protocolVersion.highestSupportedVersion()));
if (debugHandler.enabled()) { if (debugHandler.enabled()) {
platform.getLogger().info("Supported version range: " + Arrays.toString(protocolVersion.supportedVersions().toArray(new int[0]))); platform.getLogger().info("Supported version range: " + Arrays.toString(protocolVersion.supportedVersions().toArray(new int[0])));
@ -145,7 +145,7 @@ public class ViaManagerImpl implements ViaManager {
platform.getLogger().warning("If you need support for older versions you may need to use one or more ViaVersion addons too."); platform.getLogger().warning("If you need support for older versions you may need to use one or more ViaVersion addons too.");
platform.getLogger().warning("In that case please read the ViaVersion resource page carefully or use https://viaversion.com/setup"); platform.getLogger().warning("In that case please read the ViaVersion resource page carefully or use https://viaversion.com/setup");
platform.getLogger().warning("and if you're still unsure, feel free to join our Discord-Server for further assistance."); platform.getLogger().warning("and if you're still unsure, feel free to join our Discord-Server for further assistance.");
} else if (protocolVersion.highestSupportedVersion() <= ProtocolVersion.v1_12_2.getVersion()) { } else if (protocolVersion.highestSupportedProtocolVersion().lowerThan(ProtocolVersion.v1_13)) {
platform.getLogger().warning("This version of Minecraft is extremely outdated and support for it has reached its end of life. " platform.getLogger().warning("This version of Minecraft is extremely outdated and support for it has reached its end of life. "
+ "You will still be able to run Via on this Minecraft version, but we are unlikely to provide any further fixes or help with problems specific to legacy Minecraft versions. " + "You will still be able to run Via on this Minecraft version, but we are unlikely to provide any further fixes or help with problems specific to legacy Minecraft versions. "
+ "Please consider updating to give your players a better experience and to avoid issues that have long been fixed."); + "Please consider updating to give your players a better experience and to avoid issues that have long been fixed.");
@ -167,13 +167,13 @@ public class ViaManagerImpl implements ViaManager {
} }
}, 10L); }, 10L);
int serverProtocolVersion = protocolManager.getServerProtocolVersion().lowestSupportedVersion(); final ProtocolVersion serverProtocolVersion = protocolManager.getServerProtocolVersion().lowestSupportedProtocolVersion();
if (serverProtocolVersion < ProtocolVersion.v1_9.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_9)) {
if (Via.getConfig().isSimulatePlayerTick()) { if (Via.getConfig().isSimulatePlayerTick()) {
Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L); Via.getPlatform().runRepeatingSync(new ViaIdleThread(), 1L);
} }
} }
if (serverProtocolVersion < ProtocolVersion.v1_13.getVersion()) { if (serverProtocolVersion.lowerThan(ProtocolVersion.v1_13)) {
if (Via.getConfig().get1_13TabCompleteDelay() > 0) { if (Via.getConfig().get1_13TabCompleteDelay() > 0) {
Via.getPlatform().runRepeatingSync(new TabCompleteThread(), 1L); Via.getPlatform().runRepeatingSync(new TabCompleteThread(), 1L);
} }

View File

@ -44,7 +44,7 @@ public class ListSubCmd extends ViaSubCommand {
@Override @Override
public boolean execute(ViaCommandSender sender, String[] args) { public boolean execute(ViaCommandSender sender, String[] args) {
Map<ProtocolVersion, Set<String>> playerVersions = new TreeMap<>((o1, o2) -> ProtocolVersion.getIndex(o2) - ProtocolVersion.getIndex(o1)); Map<ProtocolVersion, Set<String>> playerVersions = new TreeMap<>(ProtocolVersion::compareTo);
for (ViaCommandSender p : Via.getPlatform().getOnlinePlayers()) { for (ViaCommandSender p : Via.getPlatform().getOnlinePlayers()) {
int playerVersion = Via.getAPI().getPlayerVersion(p.getUUID()); int playerVersion = Via.getAPI().getPlayerVersion(p.getUUID());

View File

@ -18,6 +18,7 @@
package com.viaversion.viaversion.configuration; package com.viaversion.viaversion.configuration;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.api.configuration.ViaVersionConfig; import com.viaversion.viaversion.api.configuration.ViaVersionConfig;
import com.viaversion.viaversion.api.minecraft.WorldIdentifiers; import com.viaversion.viaversion.api.minecraft.WorldIdentifiers;
import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions; import com.viaversion.viaversion.api.protocol.version.BlockedProtocolVersions;
@ -100,6 +101,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
} }
protected void loadFields() { protected void loadFields() {
final ProtocolVersion protocolVersion = Via.getAPI().getServerVersion().lowestSupportedProtocolVersion();
checkForUpdates = getBoolean("checkforupdates", true); checkForUpdates = getBoolean("checkforupdates", true);
preventCollision = getBoolean("prevent-collision", true); preventCollision = getBoolean("prevent-collision", true);
useNewEffectIndicator = getBoolean("use-new-effect-indicator", true); useNewEffectIndicator = getBoolean("use-new-effect-indicator", true);
@ -136,7 +138,7 @@ public abstract class AbstractViaConfig extends Config implements ViaVersionConf
teamColourFix = getBoolean("team-colour-fix", true); teamColourFix = getBoolean("team-colour-fix", true);
suppressConversionWarnings = getBoolean("suppress-conversion-warnings", false); suppressConversionWarnings = getBoolean("suppress-conversion-warnings", false);
disable1_13TabComplete = getBoolean("disable-1_13-auto-complete", false); disable1_13TabComplete = getBoolean("disable-1_13-auto-complete", false);
serversideBlockConnections = getBoolean("serverside-blockconnections", true); serversideBlockConnections = getBoolean("serverside-blockconnections", true) && protocolVersion.lowerThan(ProtocolVersion.v1_13);
reduceBlockStorageMemory = getBoolean("reduce-blockstorage-memory", false); reduceBlockStorageMemory = getBoolean("reduce-blockstorage-memory", false);
flowerStemWhenBlockAbove = getBoolean("flowerstem-when-block-above", false); flowerStemWhenBlockAbove = getBoolean("flowerstem-when-block-above", false);
vineClimbFix = getBoolean("vine-climb-fix", false); vineClimbFix = getBoolean("vine-climb-fix", false);

View File

@ -29,8 +29,8 @@ public class ProtocolInfoImpl implements ProtocolInfo {
private final UserConnection connection; private final UserConnection connection;
private State clientState = State.HANDSHAKE; private State clientState = State.HANDSHAKE;
private State serverState = State.HANDSHAKE; private State serverState = State.HANDSHAKE;
private int protocolVersion = -1;
private int serverProtocolVersion = -1; private int serverProtocolVersion = -1;
private ProtocolVersion protocolVersion;
private String username; private String username;
private UUID uuid; private UUID uuid;
private ProtocolPipeline pipeline; private ProtocolPipeline pipeline;
@ -66,15 +66,13 @@ public class ProtocolInfoImpl implements ProtocolInfo {
} }
@Override @Override
public int getProtocolVersion() { public ProtocolVersion protocolVersion() {
return protocolVersion; return protocolVersion;
} }
@Override @Override
public void setProtocolVersion(int protocolVersion) { public void setProtocolVersion(int protocolVersion) {
// Map snapshot versions to the higher/orderer release version this.protocolVersion = ProtocolVersion.getProtocol(protocolVersion);
ProtocolVersion protocol = ProtocolVersion.getProtocol(protocolVersion);
this.protocolVersion = protocol.getVersion();
} }
@Override @Override

View File

@ -127,7 +127,7 @@ public class BaseProtocol1_7 extends AbstractProtocol<BaseClientboundPacket, Bas
// Login Success Packet // Login Success Packet
registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> { registerClientbound(ClientboundLoginPackets.GAME_PROFILE, wrapper -> {
ProtocolInfo info = wrapper.user().getProtocolInfo(); ProtocolInfo info = wrapper.user().getProtocolInfo();
if (info.getProtocolVersion() < ProtocolVersion.v1_20_2.getVersion()) { // On 1.20.2+, wait for the login ack if (info.protocolVersion().lowerThan(ProtocolVersion.v1_20_2)) { // On 1.20.2+, wait for the login ack
info.setState(State.PLAY); info.setState(State.PLAY);
} }

View File

@ -135,7 +135,7 @@ public final class DumpUtil {
// Player versions // Player versions
final JsonObject versions = new JsonObject(); final JsonObject versions = new JsonObject();
playerSample.add("versions", versions); playerSample.add("versions", versions);
final Map<ProtocolVersion, Integer> playerVersions = new TreeMap<>((o1, o2) -> ProtocolVersion.getIndex(o2) - ProtocolVersion.getIndex(o1)); final Map<ProtocolVersion, Integer> playerVersions = new TreeMap<>(ProtocolVersion::compareTo);
for (final UserConnection connection : Via.getManager().getConnectionManager().getConnections()) { for (final UserConnection connection : Via.getManager().getConnectionManager().getConnections()) {
final ProtocolVersion protocolVersion = ProtocolVersion.getProtocol(connection.getProtocolInfo().getProtocolVersion()); final ProtocolVersion protocolVersion = ProtocolVersion.getProtocol(connection.getProtocolInfo().getProtocolVersion());
playerVersions.compute(protocolVersion, (v, num) -> num != null ? num + 1 : 1); playerVersions.compute(protocolVersion, (v, num) -> num != null ? num + 1 : 1);

View File

@ -35,7 +35,8 @@ public class VelocityViaLoader implements ViaPlatformLoader {
Object plugin = VelocityPlugin.PROXY.getPluginManager() Object plugin = VelocityPlugin.PROXY.getPluginManager()
.getPlugin("viaversion").flatMap(PluginContainer::getInstance).get(); .getPlugin("viaversion").flatMap(PluginContainer::getInstance).get();
if (Via.getAPI().getServerVersion().lowestSupportedVersion() < ProtocolVersion.v1_9.getVersion()) { final ProtocolVersion protocolVersion = Via.getAPI().getServerVersion().lowestSupportedProtocolVersion();
if (protocolVersion.lowerThan(ProtocolVersion.v1_9)) {
Via.getManager().getProviders().use(BossBarProvider.class, new VelocityBossBarProvider()); Via.getManager().getProviders().use(BossBarProvider.class, new VelocityBossBarProvider());
} }