1
0
mirror of https://github.com/LOOHP/Limbo.git synced 2026-06-08 05:51:43 +00:00
This commit is contained in:
LOOHP
2021-04-06 21:14:05 +08:00
parent 05cfdb73a9
commit 6d14314bd9
126 changed files with 191394 additions and 0 deletions
@@ -0,0 +1,31 @@
package com.loohp.limbo.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.List;
public class BitsUtils {
public static BitSet shiftAfter(BitSet bitset, int from, int shift) {
BitSet subset = bitset.get(from, bitset.length());
for (int i = 0; i < subset.length(); i++) {
bitset.set(from + shift + i, subset.get(i));
}
if (shift > 0) {
for (int i = 0; i < shift; i++) {
bitset.set(from + i, false);
}
}
return bitset;
}
public static String toLongString(BitSet bitset) {
List<String> list = new ArrayList<>();
for (long l : bitset.toLongArray()) {
list.add(Long.toBinaryString(l));
}
return Arrays.toString(list.toArray());
}
}
@@ -0,0 +1,58 @@
package com.loohp.limbo.utils;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.UUID;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import com.loohp.limbo.server.packets.PacketPlayOutPluginMessaging;
public class BungeeLoginMessageUtils {
public static void sendUUIDRequest(DataOutputStream output) throws IOException {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("UUID");
PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray());
byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length);
output.write(packetByte);
}
public static UUID readUUIDResponse(byte[] data) {
ByteArrayDataInput in = ByteStreams.newDataInput(data);
String subchannel = in.readUTF();
if (subchannel.equals("UUID")) {
return UUID.fromString(in.readUTF());
} else {
throw new RuntimeException("Bungeecord Message receieved is not an IP");
}
}
public static void sendIPRequest(DataOutputStream output) throws IOException {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("IP");
PacketPlayOutPluginMessaging packet = new PacketPlayOutPluginMessaging(new NamespacedKey("bungeecord", "main"), out.toByteArray());
byte[] packetByte = packet.serializePacket();
DataTypeIO.writeVarInt(output, packetByte.length);
output.write(packetByte);
}
public static InetAddress readIPResponse(byte[] data) throws UnknownHostException {
ByteArrayDataInput in = ByteStreams.newDataInput(data);
String subchannel = in.readUTF();
if (subchannel.equals("IP")) {
String ip = in.readUTF();
in.readInt();
return InetAddress.getByName(ip);
} else {
throw new RuntimeException("Bungeecord Message receieved is not an IP");
}
}
}
@@ -0,0 +1,26 @@
package com.loohp.limbo.utils;
import net.querz.mca.Section;
public class ChunkDataUtils {
public static void adjustBlockStateBits(int newBits, Section section, int dataVersion) {
//increases or decreases the amount of bits used per BlockState
//based on the size of the palette.
long[] blockStates = section.getBlockStates();
long[] newBlockStates;
if (dataVersion < 2527) {
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newBits * 64];
} else {
int newLength = (int) Math.ceil(4096D / (64D / newBits));
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newLength];
}
for (int i = 0; i < 4096; i++) {
section.setPaletteIndex(i, section.getPaletteIndex(i), newBlockStates);
}
section.setBlockStates(newBlockStates);
}
}
@@ -0,0 +1,21 @@
package com.loohp.limbo.utils;
public class CustomArrayUtils {
public static int[] longArrayToIntArray(long[] numbers) {
int[] intNumbers = new int[numbers.length];
for(int i = 0; i < numbers.length; i++) {
intNumbers[i] = (int) numbers[i];
}
return intNumbers;
}
public static byte[] longArrayToByteArray(long[] numbers) {
byte[] intNumbers = new byte[numbers.length];
for(int i = 0; i < numbers.length; i++) {
intNumbers[i] = (byte) numbers[i];
}
return intNumbers;
}
}
@@ -0,0 +1,180 @@
package com.loohp.limbo.utils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import net.querz.nbt.tag.ByteArrayTag;
import net.querz.nbt.tag.ByteTag;
import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.DoubleTag;
import net.querz.nbt.tag.FloatTag;
import net.querz.nbt.tag.IntArrayTag;
import net.querz.nbt.tag.IntTag;
import net.querz.nbt.tag.ListTag;
import net.querz.nbt.tag.LongArrayTag;
import net.querz.nbt.tag.LongTag;
import net.querz.nbt.tag.ShortTag;
import net.querz.nbt.tag.StringTag;
import net.querz.nbt.tag.Tag;
@SuppressWarnings("rawtypes")
public class CustomNBTUtils {
public enum TagClass {
CompoundTagClass(CompoundTag.class),
ByteTagClass(ByteTag.class),
ShortTagClass(ShortTag.class),
IntTagClass(IntTag.class),
LongTagClass(LongTag.class),
FloatTagClass(FloatTag.class),
DoubleTagClass(DoubleTag.class),
ByteArrayTagClass(ByteArrayTag.class),
IntArrayTagClass(IntArrayTag.class),
LongArrayTagClass(LongArrayTag.class),
StringTagClass(StringTag.class),
ListTagClass(ListTag.class);
Class<? extends Tag> clazz;
TagClass(Class<? extends Tag> clazz) {
this.clazz = clazz;
}
public Class<? extends Tag> getTagClass() {
return clazz;
}
}
public static Class<? extends Tag> getClassFromName(String name) {
for (TagClass clazz : TagClass.values()) {
if (clazz.getTagClass().getSimpleName().equals(name)) {
return clazz.getTagClass();
}
}
return null;
}
public static CompoundTag getCompoundTagFromJson(JSONObject json) {
CompoundTag tag = new CompoundTag();
for (Object obj : json.keySet()) {
String key = (String) obj;
JSONObject inside = (JSONObject) json.get(key);
String type = (String) inside.get("type");
switch (type) {
case "ByteTag":
tag.putByte(key, (byte) (long) inside.get("value"));
break;
case "ShortTag":
tag.putShort(key, (short) (long) inside.get("value"));
break;
case "IntTag":
tag.putInt(key, (int) (long) inside.get("value"));
break;
case "LongTag":
tag.putLong(key, (long) inside.get("value"));
break;
case "FloatTag":
tag.putFloat(key, inside.get("value") instanceof Long ? (float) (long) inside.get("value") : (float) (double) inside.get("value"));
break;
case "DoubleTag":
tag.putDouble(key, inside.get("value") instanceof Long ? (double) (long) inside.get("value") : (double) inside.get("value"));
break;
case "ByteArrayTag":
tag.putByteArray(key, CustomArrayUtils.longArrayToByteArray((long[]) inside.get("value")));
break;
case "IntArrayTag":
tag.putIntArray(key, CustomArrayUtils.longArrayToIntArray((long[]) inside.get("value")));
break;
case "LongArrayTag":
tag.putLongArray(key, (long[]) inside.get("value"));
break;
case "StringTag":
tag.putString(key, (String) inside.get("value"));
break;
case "CompoundTag":
tag.put(key, getCompoundTagFromJson((JSONObject) inside.get("value")));
break;
case "ListTag":
tag.put(key, getListTagFromJson((JSONObject) inside.get("value")));
break;
}
}
return tag;
}
public static ListTag<?> getListTagFromJson(JSONObject json) {
String type = (String) json.get("type");
JSONArray array = (JSONArray) json.get("list");
ListTag<?> listTag = ListTag.createUnchecked(getClassFromName(type));
switch (type) {
case "ByteTag":
for (Object obj : array) {
listTag.addByte((byte) (long) obj);
}
break;
case "ShortTag":
for (Object obj : array) {
listTag.addShort((short) (long) obj);
}
break;
case "IntTag":
for (Object obj : array) {
listTag.addInt((int) (long) obj);
}
break;
case "LongTag":
for (Object obj : array) {
listTag.addLong((long) obj);
}
break;
case "FloatTag":
for (Object obj : array) {
listTag.addFloat(obj instanceof Long ? (float) (long) obj : (float) (double) obj);
}
break;
case "DoubleTag":
for (Object obj : array) {
listTag.addDouble(obj instanceof Long ? (double) (long) obj : (double) obj);
}
break;
case "ByteArrayTag":
for (Object obj : array) {
listTag.addByteArray(CustomArrayUtils.longArrayToByteArray((long[]) obj));
}
break;
case "IntArrayTag":
for (Object obj : array) {
listTag.addIntArray(CustomArrayUtils.longArrayToIntArray((long[]) obj));
}
break;
case "LongArrayTag":
for (Object obj : array) {
listTag.addLongArray((long[]) obj);
}
break;
case "StringTag":
for (Object obj : array) {
listTag.addString((String) obj);
}
break;
case "CompoundTag":
for (Object obj : array) {
listTag.asCompoundTagList().add(getCompoundTagFromJson((JSONObject) obj));
}
break;
case "ListTag":
for (Object obj : array) {
listTag.asListTagList().add(getListTagFromJson((JSONObject) obj));
}
break;
}
return listTag;
}
}
@@ -0,0 +1,67 @@
package com.loohp.limbo.utils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CustomStringUtils {
public static boolean arrayContains(String compare, String[] args, boolean IgnoreCase) {
return IgnoreCase ? Arrays.asList(args).stream().anyMatch(each -> each.equalsIgnoreCase(compare)) : Arrays.asList(args).stream().anyMatch(each -> each.equals(compare));
}
public static boolean arrayContains(String compare, String[] args) {
return arrayContains(compare, args, true);
}
public static String[] splitStringToArgs(String str) {
List<String> tokens = new ArrayList<String>();
StringBuilder sb = new StringBuilder();
boolean insideQuote = false;
for (char c : str.toCharArray()) {
if (c == '"') {
insideQuote = !insideQuote;
} else if (c == ' ' && !insideQuote) {
if (sb.length() > 0) {
tokens.add(sb.toString());
}
sb.delete(0, sb.length());
} else {
sb.append(c);
}
}
tokens.add(sb.toString());
return tokens.toArray(new String[tokens.size()]);
}
public static int getIndexOfArg(String str, int ordinal) {
StringBuilder sb = new StringBuilder();
boolean insideQuote = false;
int pos = 0;
int found = 0;
for (char c : str.toCharArray()) {
if (c == '"') {
insideQuote = !insideQuote;
} else if (c == ' ' && !insideQuote) {
if (sb.length() > 0) {
found++;
}
sb.delete(0, sb.length());
} else {
sb.append(c);
}
if (found == ordinal) {
return pos;
}
pos++;
}
return -1;
}
}
@@ -0,0 +1,135 @@
package com.loohp.limbo.utils;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.UUID;
import com.loohp.limbo.world.BlockPosition;
import net.querz.nbt.io.NBTOutputStream;
import net.querz.nbt.tag.CompoundTag;
import net.querz.nbt.tag.Tag;
public class DataTypeIO {
public static void writeBlockPosition(DataOutputStream out, BlockPosition position) throws IOException {
out.writeLong(((position.getX() & 0x3FFFFFF) << 38) | ((position.getZ() & 0x3FFFFFF) << 12) | (position.getY() & 0xFFF));
}
public static void writeUUID(DataOutputStream out, UUID uuid) throws IOException {
out.writeLong(uuid.getMostSignificantBits());
out.writeLong(uuid.getLeastSignificantBits());
}
public static void writeCompoundTag(DataOutputStream out, CompoundTag tag) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
new NBTOutputStream(output).writeTag(tag, Tag.DEFAULT_MAX_DEPTH);
byte[] b = buffer.toByteArray();
out.write(b);
}
public static String readString(DataInputStream in, Charset charset) throws IOException {
int length = readVarInt(in);
if (length == -1) {
throw new IOException("Premature end of stream.");
}
byte[] b = new byte[length];
in.readFully(b);
return new String(b, charset);
}
public static int getStringLength(String string, Charset charset) throws IOException {
byte[] bytes = string.getBytes(charset);
return bytes.length;
}
public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException {
byte[] bytes = string.getBytes(charset);
writeVarInt(out, bytes.length);
out.write(bytes);
}
public static int readVarInt(DataInputStream in) throws IOException {
int numRead = 0;
int result = 0;
byte read;
do {
read = in.readByte();
int value = (read & 0b01111111);
result |= (value << (7 * numRead));
numRead++;
if (numRead > 5) {
throw new RuntimeException("VarInt is too big");
}
} while ((read & 0b10000000) != 0);
return result;
}
public static void writeVarInt(DataOutputStream out, int value) throws IOException {
do {
byte temp = (byte)(value & 0b01111111);
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
value >>>= 7;
if (value != 0) {
temp |= 0b10000000;
}
out.writeByte(temp);
} while (value != 0);
}
public static int getVarIntLength(int value) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(buffer);
do {
byte temp = (byte)(value & 0b01111111);
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
value >>>= 7;
if (value != 0) {
temp |= 0b10000000;
}
out.writeByte(temp);
} while (value != 0);
return buffer.toByteArray().length;
}
public static long readVarLong(DataInputStream in) throws IOException {
int numRead = 0;
long result = 0;
byte read;
do {
read = in.readByte();
long value = (read & 0b01111111);
result |= (value << (7 * numRead));
numRead++;
if (numRead > 10) {
throw new RuntimeException("VarLong is too big");
}
} while ((read & 0b10000000) != 0);
return result;
}
public static void writeVarLong(DataOutputStream out, long value) throws IOException {
do {
byte temp = (byte)(value & 0b01111111);
// Note: >>> means that the sign bit is shifted with the rest of the number rather than being left alone
value >>>= 7;
if (value != 0) {
temp |= 0b10000000;
}
out.writeByte(temp);
} while (value != 0);
}
}
@@ -0,0 +1,56 @@
package com.loohp.limbo.utils;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import com.loohp.limbo.Limbo;
import com.loohp.limbo.server.packets.PacketPlayOutDeclareCommands;
import com.loohp.limbo.commands.CommandSender;
public class DeclareCommands {
public static PacketPlayOutDeclareCommands getDeclareCommandsPacket(CommandSender sender) throws IOException {
List<String> commands = Limbo.getInstance().getPluginManager().getTabOptions(sender, new String[0]);
if (commands.isEmpty()) {
return null;
}
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataOutputStream output = new DataOutputStream(buffer);
DataTypeIO.writeVarInt(output, commands.size() * 2 + 1);
output.writeByte(0);
DataTypeIO.writeVarInt(output, commands.size());
for (int i = 1; i <= commands.size() * 2; i++) {
DataTypeIO.writeVarInt(output, i++);
}
int i = 1;
for (String label : commands) {
output.writeByte(1 | 0x04);
DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeVarInt(output, i + 1);
DataTypeIO.writeString(output, label, StandardCharsets.UTF_8);
i++;
output.writeByte(2 | 0x04 | 0x10);
DataTypeIO.writeVarInt(output, 1);
DataTypeIO.writeVarInt(output, i);
DataTypeIO.writeString(output, "arg", StandardCharsets.UTF_8);
DataTypeIO.writeString(output, "brigadier:string", StandardCharsets.UTF_8);
DataTypeIO.writeVarInt(output, 0);
DataTypeIO.writeString(output, "minecraft:ask_server", StandardCharsets.UTF_8);
i++;
}
DataTypeIO.writeVarInt(output, 0);
return new PacketPlayOutDeclareCommands(buffer.toByteArray());
}
}
@@ -0,0 +1,44 @@
package com.loohp.limbo.utils;
public enum GameMode {
SURVIVAL(0, "survival"),
CREATIVE(1, "creative"),
ADVENTURE(2, "adventure"),
SPECTATOR(3, "spectator");
int id;
String name;
GameMode(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public static GameMode fromId(int id) {
for (GameMode mode : GameMode.values()) {
if (mode.getId() == id) {
return mode;
}
}
return null;
}
public static GameMode fromName(String name) {
for (GameMode mode : GameMode.values()) {
if (mode.getName().equalsIgnoreCase(name)) {
return mode;
}
}
return null;
}
}
@@ -0,0 +1,18 @@
package com.loohp.limbo.utils;
import java.awt.image.RenderedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import javax.imageio.ImageIO;
public class ImageUtils {
public static String imgToBase64String(final RenderedImage img, String formatName) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(img, formatName, out);
return Base64.getEncoder().encodeToString(out.toByteArray());
}
}
@@ -0,0 +1,93 @@
package com.loohp.limbo.utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.UUID;
import java.util.stream.Collectors;
import javax.net.ssl.HttpsURLConnection;
public class MojangAPIUtils {
public static class SkinResponse {
String skin;
String signature;
public SkinResponse(String skin, String signature) {
this.skin = skin;
this.signature = signature;
}
public String getSkin() {
return skin;
}
public String getSignature() {
return signature;
}
}
public static UUID getOnlineUUIDOfPlayerFromMojang(String username) {
try {
URL url = new URL("https://api.mojang.com/users/profiles/minecraft/" + username);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setDefaultUseCaches(false);
connection.addRequestProperty("User-Agent", "Mozilla/5.0");
connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate");
connection.addRequestProperty("Pragma", "no-cache");
if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
String reply = new BufferedReader(new InputStreamReader(connection.getInputStream())).readLine();
if (!reply.contains("\"error\":\"BadRequestException\"")) {
String uuid = reply.split("\"id\":\"")[1].split("\"")[0];
return UUID.fromString(uuid.replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5"));
} else {
return null;
}
} else {
System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")");
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public static SkinResponse getSkinFromMojangServer(String username) {
UUID uuid = getOnlineUUIDOfPlayerFromMojang(username);
if (uuid == null) {
return null;
}
return getSkinFromMojangServer(uuid);
}
public static SkinResponse getSkinFromMojangServer(UUID uuid) {
try {
URL url = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid.toString() + "?unsigned=false");
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setUseCaches(false);
connection.setDefaultUseCaches(false);
connection.addRequestProperty("User-Agent", "Mozilla/5.0");
connection.addRequestProperty("Cache-Control", "no-cache, no-store, must-revalidate");
connection.addRequestProperty("Pragma", "no-cache");
if (connection.getResponseCode() == HttpsURLConnection.HTTP_OK) {
String reply = String.join("", new BufferedReader(new InputStreamReader(connection.getInputStream())).lines().collect(Collectors.toList())).replace(" ", "");
String skin = reply.split("\"value\":\"")[1].split("\"")[0];
String signature = reply.split("\"signature\":\"")[1].split("\"")[0];
return new SkinResponse(skin, signature);
} else {
System.err.println("Connection could not be opened (Response code " + connection.getResponseCode() + ", " + connection.getResponseMessage() + ")");
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
@@ -0,0 +1,74 @@
package com.loohp.limbo.utils;
public class NamespacedKey {
public static final String MINECRAFT_KEY = "minecraft";
private String namespace;
private String key;
public NamespacedKey(String namespacedKey) {
int index = namespacedKey.indexOf(":");
if (index >= 0) {
this.namespace = namespacedKey.substring(0, index);
this.key = namespacedKey.substring(index + 1);
} else {
this.namespace = "minecraft";
this.key = namespacedKey;
}
}
public NamespacedKey(String namespace, String key) {
this.namespace = namespace;
this.key = key;
}
public static NamespacedKey minecraft(String key) {
return new NamespacedKey(MINECRAFT_KEY, key);
}
public String getNamespace() {
return namespace;
}
public String getKey() {
return key;
}
@Override
public String toString() {
return namespace + ":" + key;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((key == null) ? 0 : key.hashCode());
result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
NamespacedKey other = (NamespacedKey) obj;
if (key == null) {
if (other.key != null)
return false;
} else if (!key.equals(other.key))
return false;
if (namespace == null) {
if (other.namespace != null)
return false;
} else if (!namespace.equals(other.namespace))
return false;
return true;
}
}
@@ -0,0 +1,36 @@
package com.loohp.limbo.utils;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.ServerSocket;
public class NetworkUtils {
public static boolean available(int port) {
ServerSocket ss = null;
DatagramSocket ds = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
ds = new DatagramSocket(port);
ds.setReuseAddress(true);
return true;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
}
@@ -0,0 +1,124 @@
package com.loohp.limbo.utils;
/**
* Utils for casting number types to other number types
*/
public final class NumberConversions {
private NumberConversions() {}
public static int floor(double num) {
final int floor = (int) num;
return floor == num ? floor : floor - (int) (Double.doubleToRawLongBits(num) >>> 63);
}
public static int ceil(final double num) {
final int floor = (int) num;
return floor == num ? floor : floor + (int) (~Double.doubleToRawLongBits(num) >>> 63);
}
public static int round(double num) {
return floor(num + 0.5d);
}
public static double square(double num) {
return num * num;
}
public static int toInt(Object object) {
if (object instanceof Number) {
return ((Number) object).intValue();
}
try {
return Integer.parseInt(object.toString());
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
return 0;
}
public static float toFloat(Object object) {
if (object instanceof Number) {
return ((Number) object).floatValue();
}
try {
return Float.parseFloat(object.toString());
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
return 0;
}
public static double toDouble(Object object) {
if (object instanceof Number) {
return ((Number) object).doubleValue();
}
try {
return Double.parseDouble(object.toString());
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
return 0;
}
public static long toLong(Object object) {
if (object instanceof Number) {
return ((Number) object).longValue();
}
try {
return Long.parseLong(object.toString());
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
return 0;
}
public static short toShort(Object object) {
if (object instanceof Number) {
return ((Number) object).shortValue();
}
try {
return Short.parseShort(object.toString());
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
return 0;
}
public static byte toByte(Object object) {
if (object instanceof Number) {
return ((Number) object).byteValue();
}
try {
return Byte.parseByte(object.toString());
} catch (NumberFormatException e) {
} catch (NullPointerException e) {
}
return 0;
}
public static boolean isFinite(double d) {
return Math.abs(d) <= Double.MAX_VALUE;
}
public static boolean isFinite(float f) {
return Math.abs(f) <= Float.MAX_VALUE;
}
public static void checkFinite(double d, String message) {
if (!isFinite(d)) {
throw new IllegalArgumentException(message);
}
}
public static void checkFinite(float d, String message) {
if (!isFinite(d)) {
throw new IllegalArgumentException(message);
}
}
}
@@ -0,0 +1,77 @@
package com.loohp.limbo.utils;
public class Rotation3f {
private double x;
private double y;
private double z;
public Rotation3f(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getZ() {
return z;
}
public void setZ(double z) {
this.z = z;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result + (int) (temp ^ (temp >>> 32));
temp = Double.doubleToLongBits(z);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Rotation3f other = (Rotation3f) obj;
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x)) {
return false;
}
if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y)) {
return false;
}
if (Double.doubleToLongBits(z) != Double.doubleToLongBits(other.z)) {
return false;
}
return true;
}
}
@@ -0,0 +1,41 @@
package com.loohp.limbo.utils;
import net.querz.nbt.tag.CompoundTag;
public class SchematicConvertionUtils {
public static CompoundTag toTileEntityTag(CompoundTag tag) {
int[] pos = tag.getIntArray("Pos");
tag.remove("Pos");
tag.remove("Id");
tag.putInt("x", pos[0]);
tag.putInt("y", pos[1]);
tag.putInt("z", pos[2]);
return tag;
}
public static CompoundTag toBlockTag(String input) {
int index = input.indexOf("[");
CompoundTag tag = new CompoundTag();
if (index < 0) {
tag.putString("Name", new NamespacedKey(input).toString());
return tag;
}
tag.putString("Name", new NamespacedKey(input.substring(0, index)).toString());
String[] states = input.substring(index + 1, input.lastIndexOf("]")).replace(" ", "").split(",");
CompoundTag properties = new CompoundTag();
for (String state : states) {
String key = state.substring(0, state.indexOf("="));
String value = state.substring(state.indexOf("=") + 1);
properties.putString(key, value);
}
tag.put("Properties", properties);
return tag;
}
}
@@ -0,0 +1,184 @@
package com.loohp.limbo.utils;
import java.beans.FeatureDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.introspector.BeanAccess;
import org.yaml.snakeyaml.introspector.FieldProperty;
import org.yaml.snakeyaml.introspector.MethodProperty;
import org.yaml.snakeyaml.introspector.MissingProperty;
import org.yaml.snakeyaml.introspector.Property;
import org.yaml.snakeyaml.introspector.PropertyUtils;
import org.yaml.snakeyaml.util.PlatformFeatureDetector;
public class YamlOrder extends PropertyUtils {
private final Map<Class<?>, Map<String, Property>> propertiesCache = new HashMap<Class<?>, Map<String, Property>>();
private final Map<Class<?>, Set<Property>> readableProperties = new HashMap<Class<?>, Set<Property>>();
private BeanAccess beanAccess = BeanAccess.DEFAULT;
private boolean allowReadOnlyProperties = false;
private boolean skipMissingProperties = false;
private PlatformFeatureDetector platformFeatureDetector;
public YamlOrder() {
this(new PlatformFeatureDetector());
}
YamlOrder(PlatformFeatureDetector platformFeatureDetector) {
this.platformFeatureDetector = platformFeatureDetector;
if (platformFeatureDetector.isRunningOnAndroid()) {
beanAccess = BeanAccess.FIELD;
}
}
protected Map<String, Property> getPropertiesMap(Class<?> type, BeanAccess bAccess) {
if (propertiesCache.containsKey(type)) {
return propertiesCache.get(type);
}
Map<String, Property> properties = new LinkedHashMap<String, Property>();
boolean inaccessableFieldsExist = false;
switch (bAccess) {
case FIELD:
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) {
int modifiers = field.getModifiers();
if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)
&& !properties.containsKey(field.getName())) {
properties.put(field.getName(), new FieldProperty(field));
}
}
}
break;
default:
try {
for (PropertyDescriptor property : Introspector.getBeanInfo(type)
.getPropertyDescriptors()) {
Method readMethod = property.getReadMethod();
if ((readMethod == null || !readMethod.getName().equals("getClass"))
&& !isTransient(property)) {
properties.put(property.getName(), new MethodProperty(property));
}
}
} catch (IntrospectionException e) {
throw new YAMLException(e);
}
for (Class<?> c = type; c != null; c = c.getSuperclass()) {
for (Field field : c.getDeclaredFields()) {
int modifiers = field.getModifiers();
if (!Modifier.isStatic(modifiers) && !Modifier.isTransient(modifiers)) {
if (Modifier.isPublic(modifiers)) {
properties.put(field.getName(), new FieldProperty(field));
} else {
inaccessableFieldsExist = true;
}
}
}
}
break;
}
if (properties.isEmpty() && inaccessableFieldsExist) {
throw new YAMLException("No JavaBean properties found in " + type.getName());
}
System.out.println(properties);
propertiesCache.put(type, properties);
return properties;
}
private static final String TRANSIENT = "transient";
private boolean isTransient(FeatureDescriptor fd) {
return Boolean.TRUE.equals(fd.getValue(TRANSIENT));
}
public Set<Property> getProperties(Class<? extends Object> type) {
return getProperties(type, beanAccess);
}
public Set<Property> getProperties(Class<? extends Object> type, BeanAccess bAccess) {
if (readableProperties.containsKey(type)) {
return readableProperties.get(type);
}
Set<Property> properties = createPropertySet(type, bAccess);
readableProperties.put(type, properties);
return properties;
}
protected Set<Property> createPropertySet(Class<? extends Object> type, BeanAccess bAccess) {
Set<Property> properties = new LinkedHashSet<>();
Collection<Property> props = getPropertiesMap(type, bAccess).values();
for (Property property : props) {
if (property.isReadable() && (allowReadOnlyProperties || property.isWritable())) {
properties.add(property);
}
}
return properties;
}
public Property getProperty(Class<? extends Object> type, String name) {
return getProperty(type, name, beanAccess);
}
public Property getProperty(Class<? extends Object> type, String name, BeanAccess bAccess) {
Map<String, Property> properties = getPropertiesMap(type, bAccess);
Property property = properties.get(name);
if (property == null && skipMissingProperties) {
property = new MissingProperty(name);
}
if (property == null) {
throw new YAMLException(
"Unable to find property '" + name + "' on class: " + type.getName());
}
return property;
}
public void setBeanAccess(BeanAccess beanAccess) {
if (platformFeatureDetector.isRunningOnAndroid() && beanAccess != BeanAccess.FIELD) {
throw new IllegalArgumentException(
"JVM is Android - only BeanAccess.FIELD is available");
}
if (this.beanAccess != beanAccess) {
this.beanAccess = beanAccess;
propertiesCache.clear();
readableProperties.clear();
}
}
public void setAllowReadOnlyProperties(boolean allowReadOnlyProperties) {
if (this.allowReadOnlyProperties != allowReadOnlyProperties) {
this.allowReadOnlyProperties = allowReadOnlyProperties;
readableProperties.clear();
}
}
public boolean isAllowReadOnlyProperties() {
return allowReadOnlyProperties;
}
public void setSkipMissingProperties(boolean skipMissingProperties) {
if (this.skipMissingProperties != skipMissingProperties) {
this.skipMissingProperties = skipMissingProperties;
readableProperties.clear();
}
}
public boolean isSkipMissingProperties() {
return skipMissingProperties;
}
}