Waterfall/BungeeCord-Patches/0011-Optimize-uuid-conversions.patch
Shane Freeder cca83dfaf6
Updated Upstream (BungeeCord)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

BungeeCord Changes:
a3ab2bf5 Update checkstyle
adee7bd2 Source jar does not need to fork build
7bd8a027 Always print remote IP in InitialHandler
0cf27a09 Update scriptus
bf673c5d Add pretty colours to console log levels
2235a323 Optimize ColouredWriter slightly
1dee0490 Don't send/construct redundant kick messages
e9ba95b9 Don't log full CorruptedFrameException
d3bd7852 #2762: Work correctly with disabled timeout
3ce4132c Switch keepalive queue to ArrayDeque
ce2dcaf7 #2763: Fix .DS_Store entry in .gitignore
cf72c3a7 Show slow event times in milliseconds
cd7a3ab2 #2758: Improve server list ping response where remote ping failed
0a4b9b49 #2752: Configurable connect and ping timeouts
2020-02-01 15:39:53 +00:00

268 lines
9.7 KiB
Diff

From 6f40b978b1b45fccab4e33c16778680fb33e91d0 Mon Sep 17 00:00:00 2001
From: Techcable <Techcable@outlook.com>
Date: Mon, 14 Mar 2016 15:40:44 -0700
Subject: [PATCH] Optimize uuid conversions
Optimizes converting to and from mojang format.
Manually decode uuids to and from hex.
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/utils/Hex.java b/api/src/main/java/io/github/waterfallmc/waterfall/utils/Hex.java
new file mode 100644
index 00000000..ece5f798
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/utils/Hex.java
@@ -0,0 +1,113 @@
+package io.github.waterfallmc.waterfall.utils;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+public class Hex {
+
+ public static byte[] decode(CharSequence chars) {
+ byte[] bytes = new byte[chars.length() >> 1];
+ decode(chars, 0, bytes, 0, bytes.length);
+ return bytes;
+ }
+
+ public static void decode(char[] chars, int charOffset, byte[] dest, int offset, int length) {
+ decode(new CharSequence() {
+ @Override
+ public int length() {
+ return chars.length;
+ }
+
+ @Override
+ public char charAt(int index) {
+ return chars[index];
+ }
+
+ @Override
+ public CharSequence subSequence(int start, int end) {
+ return toString().substring(start, end);
+ }
+
+ @Override
+ public String toString() {
+ return new String(chars, charOffset, chars.length);
+ }
+ });
+ }
+
+ public static void decode(CharSequence chars, int charOffset, byte[] dest, int offset, int length) {
+ Objects.requireNonNull(chars, "Null chars");
+ Objects.requireNonNull(chars, "Null destination");
+ final int numChars = chars.length();
+ if ((numChars & 0x01) != 0) {
+ throw new IllegalArgumentException("Odd number of characters: " + numChars);
+ } else if (length < (numChars - charOffset) >> 1) {
+ throw new IllegalArgumentException("Too many bytes to fill with " + numChars + " characters: " + length);
+ } else if (offset < 0 || charOffset < 0 || length < 0 || length * 2 > numChars - charOffset || length > dest.length - offset) {
+ throw new IndexOutOfBoundsException();
+ }
+ for (int i = 0, charIndex = charOffset; i < length; i++) {
+ char first = chars.charAt(charIndex++);
+ char second = chars.charAt(charIndex++);
+ dest[i + offset] = (byte) ((toDigit(first) << 4) | (toDigit(second)));
+ }
+ }
+
+ public static String encodeString(byte[] bytes) {
+ return new String(encode(bytes));
+ }
+
+ public static char[] encode(byte[] bytes) {
+ char[] chars = new char[bytes.length << 1];
+ encode(chars, 0, bytes, 0, bytes.length);
+ return chars;
+ }
+
+ public static void encode(char[] chars, int charOffset, byte[] source, int offset, int length) {
+ Objects.requireNonNull(chars, "Null chars");
+ Objects.requireNonNull(chars, "Null bytes");
+ if (offset < 0 || charOffset < 0 || length < 0 || length * 2 > chars.length - charOffset || length > source.length - offset) {
+ throw new IndexOutOfBoundsException();
+ } else if (length == 0) {
+ return;
+ }
+ for (int i = 0, charIndex = charOffset; i < length; i++) {
+ byte b = source[i + offset];
+ chars[charIndex++] = fromDigit((byte) ((b >> 4) & 0xF));
+ chars[charIndex++] = fromDigit((byte) (b & 0xF));
+ }
+ }
+ private static final char[] ENCODE_TABLE = new char[]{
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+ };
+ private static final byte[] DECODE_TABLE = new byte[128];
+
+ static {
+ Arrays.fill(DECODE_TABLE, (byte) -1);
+ for (int value = 0; value < ENCODE_TABLE.length; value++) {
+ char c = ENCODE_TABLE[value];
+ DECODE_TABLE[c] = (byte) value;
+ char upper;
+ if ((upper = Character.toUpperCase(c)) != c) {
+ DECODE_TABLE[upper] = (byte) value;
+ }
+ }
+ }
+
+ public static byte toDigit(char c) {
+ byte value;
+ if (c < DECODE_TABLE.length) {
+ value = DECODE_TABLE[c];
+ } else {
+ value = -1;
+ }
+ if (value < 0) throw new IllegalArgumentException("Invalid character " + c);
+ return value;
+ }
+
+ private static char fromDigit(byte b) {
+ assert (b & 0xF) == b : "Out of range " + b;
+ return ENCODE_TABLE[b];
+ }
+}
\ No newline at end of file
diff --git a/api/src/main/java/io/github/waterfallmc/waterfall/utils/UUIDUtils.java b/api/src/main/java/io/github/waterfallmc/waterfall/utils/UUIDUtils.java
new file mode 100644
index 00000000..cc24dd35
--- /dev/null
+++ b/api/src/main/java/io/github/waterfallmc/waterfall/utils/UUIDUtils.java
@@ -0,0 +1,74 @@
+package io.github.waterfallmc.waterfall.utils;
+import java.util.UUID;
+
+import com.google.common.base.Preconditions;
+import com.google.common.primitives.Longs;
+
+public class UUIDUtils {
+ private UUIDUtils() {}
+
+ public static String undash(String id) {
+ return new StringBuilder( 32 ).append( id, 0, 8 ).append( id, 9, 13 ).append( id, 14, 18 ).append( id, 19, 23 ).append( id, 24, 36 ).toString();
+ }
+
+ public static String toMojangString(UUID id) {
+ Preconditions.checkNotNull(id, "Null id");
+ return Hex.encodeString(toBytes(id));
+ }
+
+ public static UUID fromString(String s) {
+ Preconditions.checkNotNull(s, "Null string");
+ if (s.length() == 36) { // UUID.toString() uuid
+ s = UUIDUtils.undash(s);
+ } else if (s.length() != 32) {
+ throw new IllegalArgumentException("Invalid UUID: " + s);
+ }
+ return fromMojangString0(s);
+ }
+
+ public static UUID fromMojangString(String s) {
+ Preconditions.checkNotNull(s, "Null string");
+ if (s.length() != 32) {
+ throw new IllegalArgumentException("UUID not in mojang format: " + s);
+ }
+ return fromMojangString0(s);
+ }
+
+ private static UUID fromMojangString0(String s) {
+ assert s != null : "Null string";
+ assert s.length() == 32 : "invalid length: " + s;
+ try {
+ return fromBytes(Hex.decode(s));
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid UUID: " + s);
+ }
+ }
+
+ public static byte[] toBytes(UUID id) {
+ Preconditions.checkNotNull(id, "Null id");
+ byte[] result = new byte[16];
+ long lsb = id.getLeastSignificantBits();
+ for (int i = 15; i >= 8; i--) {
+ result[i] = (byte) (lsb & 0xffL);
+ lsb >>= 8;
+ }
+ long msb = id.getMostSignificantBits();
+ for (int i = 7; i >= 0; i--) {
+ result[i] = (byte) (msb & 0xffL);
+ msb >>= 8;
+ }
+ return result;
+ }
+
+ public static UUID fromBytes(byte[] bytes) {
+ Preconditions.checkNotNull(bytes, "Null bytes");
+ if (bytes.length != 16) {
+ throw new IllegalArgumentException("Invalid length: " + bytes.length);
+ }
+ long msb = Longs.fromBytes(bytes[0], bytes[1], bytes[2], bytes[3],
+ bytes[4], bytes[5], bytes[6], bytes[7]);
+ long lsb = Longs.fromBytes(bytes[8], bytes[9], bytes[10], bytes[11],
+ bytes[12], bytes[13], bytes[14], bytes[15]);
+ return new UUID(msb, lsb);
+ }
+}
\ No newline at end of file
diff --git a/api/src/main/java/net/md_5/bungee/Util.java b/api/src/main/java/net/md_5/bungee/Util.java
index 31101f6b..77eb64a1 100644
--- a/api/src/main/java/net/md_5/bungee/Util.java
+++ b/api/src/main/java/net/md_5/bungee/Util.java
@@ -3,12 +3,15 @@ package net.md_5.bungee;
import com.google.common.base.Joiner;
import com.google.common.primitives.UnsignedLongs;
import io.netty.channel.unix.DomainSocketAddress;
+import com.google.common.primitives.Ints;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.UUID;
+import io.github.waterfallmc.waterfall.utils.Hex;
+
/**
* Series of utility classes to perform various operations.
*/
@@ -65,7 +68,7 @@ public class Util
*/
public static String hex(int i)
{
- return String.format( "0x%02X", i );
+ return Hex.encodeString(Ints.toByteArray(i));
}
/**
diff --git a/api/src/main/java/net/md_5/bungee/api/ServerPing.java b/api/src/main/java/net/md_5/bungee/api/ServerPing.java
index 88d36ad2..fc92a7b5 100644
--- a/api/src/main/java/net/md_5/bungee/api/ServerPing.java
+++ b/api/src/main/java/net/md_5/bungee/api/ServerPing.java
@@ -74,7 +74,7 @@ public class ServerPing
public String getId()
{
- return uniqueId.toString().replace( "-", "" );
+ return io.github.waterfallmc.waterfall.utils.UUIDUtils.undash( uniqueId.toString() ); // Waterfall
}
}
diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
index 8fbb6221..9b9641d2 100644
--- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
+++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java
@@ -647,7 +647,7 @@ public class InitialHandler extends PacketHandler implements PendingConnection
@Override
public String getUUID()
{
- return uniqueId.toString().replace( "-", "" );
+ return io.github.waterfallmc.waterfall.utils.UUIDUtils.undash( uniqueId.toString() ); // Waterfall
}
@Override
--
2.25.0