mirror of
https://github.com/LOOHP/Limbo.git
synced 2026-06-08 05:51:43 +00:00
reupload
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user