resent-1.8/sources/main/java/net/lax1dude/eaglercraft/v1_8/EaglercraftUUID.java

232 lines
6.2 KiB
Java
Raw Normal View History

2022-12-27 09:22:08 -08:00
package net.lax1dude.eaglercraft.v1_8;
import net.lax1dude.eaglercraft.v1_8.crypto.MD5Digest;
/**
* Copyright (c) 2022 LAX1DUDE. All Rights Reserved.
*
* WITH THE EXCEPTION OF PATCH FILES, MINIFIED JAVASCRIPT, AND ALL FILES
* NORMALLY FOUND IN AN UNMODIFIED MINECRAFT RESOURCE PACK, YOU ARE NOT ALLOWED
* TO SHARE, DISTRIBUTE, OR REPURPOSE ANY FILE USED BY OR PRODUCED BY THE
* SOFTWARE IN THIS REPOSITORY WITHOUT PRIOR PERMISSION FROM THE PROJECT AUTHOR.
*
* NOT FOR COMMERCIAL OR MALICIOUS USE
*
* (please read the 'LICENSE' file this repo's root directory for more info)
*
*/
public class EaglercraftUUID implements Comparable<EaglercraftUUID> {
public final long msb;
public final long lsb;
public EaglercraftUUID(long msb, long lsb) {
this.msb = msb;
this.lsb = lsb;
}
public EaglercraftUUID(byte[] uuid) {
long msb = 0;
long lsb = 0;
for (int i = 0; i < 8; i++)
msb = (msb << 8) | (uuid[i] & 0xff);
for (int i = 8; i < 16; i++)
lsb = (lsb << 8) | (uuid[i] & 0xff);
this.msb = msb;
this.lsb = lsb;
}
public EaglercraftUUID(String uuid) {
String[] components = uuid.split("-");
if (components.length != 5)
throw new IllegalArgumentException("Invalid UUID string: " + uuid);
for (int i = 0; i < 5; i++)
components[i] = "0x" + components[i];
long mostSigBits = Long.decode(components[0]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[1]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[2]).longValue();
long leastSigBits = Long.decode(components[3]).longValue();
leastSigBits <<= 48;
leastSigBits |= Long.decode(components[4]).longValue();
this.msb = mostSigBits;
this.lsb = leastSigBits;
}
private static byte long7(long x) {
return (byte) (x >> 56);
}
private static byte long6(long x) {
return (byte) (x >> 48);
}
private static byte long5(long x) {
return (byte) (x >> 40);
}
private static byte long4(long x) {
return (byte) (x >> 32);
}
private static byte long3(long x) {
return (byte) (x >> 24);
}
private static byte long2(long x) {
return (byte) (x >> 16);
}
private static byte long1(long x) {
return (byte) (x >> 8);
}
private static byte long0(long x) {
return (byte) (x);
}
public byte[] getBytes() {
byte[] ret = new byte[16];
ret[0] = long7(msb);
ret[1] = long6(msb);
ret[2] = long5(msb);
ret[3] = long4(msb);
ret[4] = long3(msb);
ret[5] = long2(msb);
ret[6] = long1(msb);
ret[7] = long0(msb);
ret[8] = long7(lsb);
ret[9] = long6(lsb);
ret[10] = long5(lsb);
ret[11] = long4(lsb);
ret[12] = long3(lsb);
ret[13] = long2(lsb);
ret[14] = long1(lsb);
ret[15] = long0(lsb);
return ret;
}
@Override
public String toString() {
return (digits(msb >> 32, 8) + "-" + digits(msb >> 16, 4) + "-" + digits(msb, 4) + "-" + digits(lsb >> 48, 4)
+ "-" + digits(lsb, 12));
}
private static String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
@Override
public int hashCode() {
long hilo = msb ^ lsb;
return ((int) (hilo >> 32)) ^ (int) hilo;
}
@Override
public boolean equals(Object o) {
return (o instanceof EaglercraftUUID) && ((EaglercraftUUID) o).lsb == lsb && ((EaglercraftUUID) o).msb == msb;
}
public long getMostSignificantBits() {
return msb;
}
public long getLeastSignificantBits() {
return lsb;
}
private static final String HEX = "0123456789ABCDEF";
private static int nibbleValue(char c) {
int v = HEX.indexOf(Character.toUpperCase(c));
if (v == -1) {
return 0;
} else {
return v;
}
}
private static long parse4Nibbles(String name, int pos) {
int ch1 = nibbleValue(name.charAt(pos));
int ch2 = nibbleValue(name.charAt(pos + 1));
int ch3 = nibbleValue(name.charAt(pos + 2));
int ch4 = nibbleValue(name.charAt(pos + 3));
return (ch1 << 12) | (ch2 << 8) | (ch3 << 4) | ch4;
}
public static EaglercraftUUID fromString(String name) {
if (name.length() == 36) {
char ch1 = name.charAt(8);
char ch2 = name.charAt(13);
char ch3 = name.charAt(18);
char ch4 = name.charAt(23);
if (ch1 == '-' && ch2 == '-' && ch3 == '-' && ch4 == '-') {
long msb1 = parse4Nibbles(name, 0);
long msb2 = parse4Nibbles(name, 4);
long msb3 = parse4Nibbles(name, 9);
long msb4 = parse4Nibbles(name, 14);
long lsb1 = parse4Nibbles(name, 19);
long lsb2 = parse4Nibbles(name, 24);
long lsb3 = parse4Nibbles(name, 28);
long lsb4 = parse4Nibbles(name, 32);
if ((msb1 | msb2 | msb3 | msb4 | lsb1 | lsb2 | lsb3 | lsb4) >= 0) {
return new EaglercraftUUID(msb1 << 48 | msb2 << 32 | msb3 << 16 | msb4,
lsb1 << 48 | lsb2 << 32 | lsb3 << 16 | lsb4);
}
}
}
return fromString1(name);
}
private static EaglercraftUUID fromString1(String name) {
int len = name.length();
if (len > 36) {
throw new IllegalArgumentException("UUID string too large");
}
int dash1 = name.indexOf('-', 0);
int dash2 = name.indexOf('-', dash1 + 1);
int dash3 = name.indexOf('-', dash2 + 1);
int dash4 = name.indexOf('-', dash3 + 1);
int dash5 = name.indexOf('-', dash4 + 1);
if (dash4 < 0 || dash5 >= 0) {
throw new IllegalArgumentException("Invalid UUID string: " + name);
}
long mostSigBits = JDKBackports.parseLong(name, 0, dash1, 16) & 0xffffffffL;
mostSigBits <<= 16;
mostSigBits |= JDKBackports.parseLong(name, dash1 + 1, dash2, 16) & 0xffffL;
mostSigBits <<= 16;
mostSigBits |= JDKBackports.parseLong(name, dash2 + 1, dash3, 16) & 0xffffL;
long leastSigBits = JDKBackports.parseLong(name, dash3 + 1, dash4, 16) & 0xffffL;
leastSigBits <<= 48;
leastSigBits |= JDKBackports.parseLong(name, dash4 + 1, len, 16) & 0xffffffffffffL;
return new EaglercraftUUID(mostSigBits, leastSigBits);
}
public static EaglercraftUUID nameUUIDFromBytes(byte[] bytes) {
MD5Digest dg = new MD5Digest();
dg.update(bytes, 0, bytes.length);
byte[] md5Bytes = new byte[16];
dg.doFinal(md5Bytes, 0);
md5Bytes[6] &= 0x0f;
md5Bytes[6] |= 0x30;
md5Bytes[8] &= 0x3f;
md5Bytes[8] |= 0x80;
return new EaglercraftUUID(md5Bytes);
}
@Override
public int compareTo(EaglercraftUUID val) {
return (this.msb < val.msb ? -1
: (this.msb > val.msb ? 1 : (this.lsb < val.lsb ? -1 : (this.lsb > val.lsb ? 1 : 0))));
}
}