diff --git a/Client/src/main/java/com/baseband/client/BaseBand.java b/Client/src/main/java/com/baseband/client/BaseBand.java index 997fc17..7b813ba 100644 --- a/Client/src/main/java/com/baseband/client/BaseBand.java +++ b/Client/src/main/java/com/baseband/client/BaseBand.java @@ -37,11 +37,11 @@ import java.util.function.Consumer; public class BaseBand { public static int majorVersion = 1; - public static int buildNumber = 487; - public static String hash = "36c1edbaa0c2f6b3"; + public static int buildNumber = 497; + public static String hash = "06b9a1db4ba97794"; public static String name = "BaseBand"; - public long timeOfCompile = 1700171942984L; + public long timeOfCompile = 1710629129384L; public CommandManager commandRegistry; public EventBus eventBus; public ArrayList modules = new ArrayList<>(); diff --git a/Installer/src/main/java/org/baseband/installer/Installer.java b/Installer/src/main/java/old/baseband/installer/Installer.java similarity index 90% rename from Installer/src/main/java/org/baseband/installer/Installer.java rename to Installer/src/main/java/old/baseband/installer/Installer.java index a157172..259be95 100644 --- a/Installer/src/main/java/org/baseband/installer/Installer.java +++ b/Installer/src/main/java/old/baseband/installer/Installer.java @@ -3,7 +3,7 @@ * Unauthorized copying of this file via any medium is Strictly Prohibited. */ -package org.baseband.installer; +package old.baseband.installer; import javax.swing.*; diff --git a/Installer/src/main/java/org/baseband/installer/InstallerApp.java b/Installer/src/main/java/old/baseband/installer/InstallerApp.java similarity index 98% rename from Installer/src/main/java/org/baseband/installer/InstallerApp.java rename to Installer/src/main/java/old/baseband/installer/InstallerApp.java index 9de85d7..40a2e76 100644 --- a/Installer/src/main/java/org/baseband/installer/InstallerApp.java +++ b/Installer/src/main/java/old/baseband/installer/InstallerApp.java @@ -3,15 +3,14 @@ * Unauthorized copying of this file via any medium is Strictly Prohibited. */ -package org.baseband.installer; +package old.baseband.installer; -import org.baseband.installer.util.minecraft.MinecraftFiles; +import old.baseband.installer.util.minecraft.MinecraftFiles; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; import javax.swing.*; import java.awt.*; import java.awt.event.ItemEvent; @@ -19,7 +18,6 @@ import java.awt.event.ItemListener; import java.io.*; import java.net.Socket; import java.security.*; -import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import java.util.UUID; @@ -29,7 +27,7 @@ public class InstallerApp { private JFrame installerFrame; public static String username; public static String password; - public static Key keyinstance; + public static old.baseband.installer.Key keyinstance; public InstallerApp() { try { @@ -134,7 +132,7 @@ public class InstallerApp { //We need this to make sure we're not being poked at String ticket = getRandomTicket(); - keyinstance = new Key(ticket); + keyinstance = new old.baseband.installer.Key(ticket); byte[] encryptedTicket = aesE.doFinal(ticket.getBytes()); outputF.writeInt(encryptedTicket.length); outputF.write(encryptedTicket); @@ -294,7 +292,7 @@ public class InstallerApp { //We need this to make sure we're not being poked at String ticket = getRandomTicket(); - keyinstance = new Key(ticket); + keyinstance = new old.baseband.installer.Key(ticket); byte[] encryptedTicket = aesE.doFinal(ticket.getBytes()); outputF.writeInt(encryptedTicket.length); outputF.write(encryptedTicket); diff --git a/Installer/src/main/java/org/baseband/installer/Key.java b/Installer/src/main/java/old/baseband/installer/Key.java similarity index 98% rename from Installer/src/main/java/org/baseband/installer/Key.java rename to Installer/src/main/java/old/baseband/installer/Key.java index 1a9f79b..314dee5 100644 --- a/Installer/src/main/java/org/baseband/installer/Key.java +++ b/Installer/src/main/java/old/baseband/installer/Key.java @@ -3,7 +3,7 @@ * Unauthorized copying of this file via any medium is Strictly Prohibited. */ -package org.baseband.installer; +package old.baseband.installer; import java.nio.charset.StandardCharsets; import java.util.UUID; diff --git a/Installer/src/main/java/org/baseband/installer/util/minecraft/MinecraftFiles.java b/Installer/src/main/java/old/baseband/installer/util/minecraft/MinecraftFiles.java similarity index 94% rename from Installer/src/main/java/org/baseband/installer/util/minecraft/MinecraftFiles.java rename to Installer/src/main/java/old/baseband/installer/util/minecraft/MinecraftFiles.java index 058e8e1..9ecd2cc 100644 --- a/Installer/src/main/java/org/baseband/installer/util/minecraft/MinecraftFiles.java +++ b/Installer/src/main/java/old/baseband/installer/util/minecraft/MinecraftFiles.java @@ -3,7 +3,7 @@ * Unauthorized copying of this file via any medium is Strictly Prohibited. */ -package org.baseband.installer.util.minecraft; +package old.baseband.installer.util.minecraft; import java.io.File; diff --git a/Loader/build.gradle b/Loader/build.gradle index 8ad0b0d..7d4f052 100644 --- a/Loader/build.gradle +++ b/Loader/build.gradle @@ -70,6 +70,10 @@ dependencies { exclude module: 'log4j-core' } + jarLibs(fileTree(dir: "lib", include: "*.jar")); + + jarLibs(group: 'com.github.oshi', name: 'oshi-core', version: '6.5.0'); + annotationProcessor('org.spongepowered:mixin:0.8.5:processor') { exclude module: 'gson' } diff --git a/Loader/lib/TuddyLIB.jar b/Loader/lib/TuddyLIB.jar new file mode 100644 index 0000000..b6f4e0a Binary files /dev/null and b/Loader/lib/TuddyLIB.jar differ diff --git a/Loader/src/main/java/de/tudbut/io/CLSPrintWriter.java b/Loader/src/main/java/de/tudbut/io/CLSPrintWriter.java deleted file mode 100644 index 70a44e5..0000000 --- a/Loader/src/main/java/de/tudbut/io/CLSPrintWriter.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.io; - -import de.tudbut.tools.ReflectUtil; - -import java.io.*; - -public class CLSPrintWriter extends PrintWriter { - - public String customLineSeparator = "\n"; - - public CLSPrintWriter(Writer writer) { - super(writer); - } - - public CLSPrintWriter(Writer writer, boolean b) { - super(writer, b); - } - - public CLSPrintWriter(OutputStream outputStream) { - super(outputStream); - } - - public CLSPrintWriter(OutputStream outputStream, boolean b) { - super(outputStream, b); - } - - public CLSPrintWriter(String s) throws FileNotFoundException { - super(s); - } - - public CLSPrintWriter(String s, String s1) throws FileNotFoundException, UnsupportedEncodingException { - super(s, s1); - } - - public CLSPrintWriter(File file) throws FileNotFoundException { - super(file); - } - - public CLSPrintWriter(File file, String s) throws FileNotFoundException, UnsupportedEncodingException { - super(file, s); - } - - @Override - public void println() { - try { - synchronized(this.lock) { - if (this.out == null) { - throw new IOException("Stream closed"); - } - this.out.write(customLineSeparator); - if (ReflectUtil.getPrivateFieldByTypeIndex(PrintWriter.class, this, boolean.class, 0)) { - this.out.flush(); - } - } - } catch (InterruptedIOException var4) { - Thread.currentThread().interrupt(); - } catch (IOException var5) { - ReflectUtil.setPrivateFieldByTypeIndex(PrintWriter.class, this, boolean.class, 1, true); - } - } -} diff --git a/Loader/src/main/java/de/tudbut/io/StreamReader.java b/Loader/src/main/java/de/tudbut/io/StreamReader.java deleted file mode 100644 index db3ab8c..0000000 --- a/Loader/src/main/java/de/tudbut/io/StreamReader.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.io; - -import de.tudbut.obj.CarrierException; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; - - -/** - * Helper for reading {@link java.io.InputStream} - */ -public class StreamReader { - - /** - * Buffer size for reading. Directly affects speed. - */ - public static int BUFFER_SIZE = 4096; - - /** - * The stream to read from - */ - public final InputStream inputStream; - - private boolean endReached = false; - - /** - * Constructs a StreamReader for an InputStream - * @param stream The stream to read - */ - public StreamReader(InputStream stream) { - this.inputStream = stream; - } - - /** - * Reads a byte from the input stream. Unaffected by {@link StreamReader#BUFFER_SIZE} - * @return read byte - * @throws IOException Inherited from {@link InputStream#read} - * @throws ArrayIndexOutOfBoundsException When the stream end was reached - */ - public byte readNextByte() throws IOException, ArrayIndexOutOfBoundsException { - int got = inputStream.read(); - if (got < 0) { - endReached = true; - throw new ArrayIndexOutOfBoundsException("Stream end reached"); - } - return (byte) got; - } - - /** - * Reads a byte from the input stream. Unaffected by {@link StreamReader#BUFFER_SIZE}. - * Byte is converted to int, being unsigned in the process. - * @return read unsigned bytes - * @throws IOException Inherited from {@link StreamReader#readNextByte()} - * @throws ArrayIndexOutOfBoundsException Inherited from {@link StreamReader#readNextByte()} - */ - public int readNextUnsignedByte() throws IOException, ArrayIndexOutOfBoundsException { - return Byte.toUnsignedInt(readNextByte()); - } - - - /** - * Reads bytes from the input stream until end is reached. Affected by {@link StreamReader#BUFFER_SIZE}. - * @return read bytes - * @throws IOException Inherited from {@link StreamReader#readNextByte()} - */ - public byte[] readAllAsBytes() throws IOException { - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - byte[] currentBytes = new byte[BUFFER_SIZE]; - int len; - try { - while ((len = inputStream.read(currentBytes)) > 0) { - bytes.write(currentBytes, 0, len); - } - } catch (IOException e) { - throw new CarrierException(e, bytes.toByteArray()); - } - return bytes.toByteArray(); - } - - /** - * Reads all bytes in the stream and converts them to a char[] - * @return {@link Character} array (native) - * @throws IOException Inherited from {@link StreamReader#readAllAsBytes()} - */ - public char[] readAllAsChars() throws IOException { - return new String(readAllAsBytes()).toCharArray(); - } - - /** - * Reads all bytes in the stream and converts them to a char[] - * @param encoding The encoding to use for conversion - * @return {@link Character} array (native) - * @throws IOException Inherited from {@link StreamReader#readAllAsBytes()} - */ - public char[] readAllAsChars(String encoding) throws IOException { - return new String(readAllAsBytes(), encoding).toCharArray(); - } - - /** - * Same as {@link StreamReader#readAllAsChars()}, but returns a string instead. - * @return The string - * @throws IOException Inherited from {@link StreamReader#readAllAsBytes()} - */ - public String readAllAsString() throws IOException { - return new String(readAllAsBytes()); - } - - /** - * Returns all lines in the file. All line ending are supported (\r\n, \n, \r). - * @return The lines - * @throws IOException Inherited from {@link StreamReader#readAllAsBytes()} - */ - public String[] readAllAsLines() throws IOException { - return new String(readAllAsBytes()).replaceAll("\r\n", "\n").replaceAll("\r", "\n").split("\n"); - } - - /** - * Same as {@link StreamReader#readAllAsChars()}, but returns a string instead. - * @param encoding The encoding to use - * @return The string - * @throws IOException Inherited from {@link StreamReader#readAllAsBytes()} - */ - public String readAllAsString(String encoding) throws IOException { - return new String(readAllAsBytes(), encoding); - } - - /** - * Returns all lines in the file. All line ending are supported (\r\n, \n, \r). - * @param encoding The encoding to use - * @return The lines - * @throws IOException Inherited from {@link StreamReader#readAllAsBytes()} - */ - public String[] readAllAsLines(String encoding) throws IOException { - return new String(readAllAsBytes(), encoding).replaceAll("\r\n", "\n").replaceAll("\r", "\n").split("\n"); - } - -} diff --git a/Loader/src/main/java/de/tudbut/obj/CarrierException.java b/Loader/src/main/java/de/tudbut/obj/CarrierException.java deleted file mode 100644 index 9df3050..0000000 --- a/Loader/src/main/java/de/tudbut/obj/CarrierException.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.obj; - -public class CarrierException extends RuntimeException { - - public final Object carried; - - public CarrierException(Exception e, Object o) { - super(e); - carried = o; - } -} diff --git a/Loader/src/main/java/de/tudbut/obj/DoubleTypedObject.java b/Loader/src/main/java/de/tudbut/obj/DoubleTypedObject.java deleted file mode 100644 index 21509cc..0000000 --- a/Loader/src/main/java/de/tudbut/obj/DoubleTypedObject.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.obj; - -import de.tudbut.tools.ReflectUtil; - -import java.util.Objects; - -public class DoubleTypedObject implements Cloneable { - - public O o; - public T t; - - public DoubleTypedObject(O o, T t) { - this.o = o; - this.t = t; - } - public DoubleTypedObject() { - } - - @Override - public boolean equals(Object o1) { - if (this == o1) return true; - if (!(o1 instanceof DoubleTypedObject)) return false; - DoubleTypedObject that = (DoubleTypedObject) o1; - return Objects.equals(o, that.o) && Objects.equals(t, that.t); - } - - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public DoubleTypedObject clone() { - return new DoubleTypedObject<>(ReflectUtil.forceClone(o), ReflectUtil.forceClone(t)); - } -} diff --git a/Loader/src/main/java/de/tudbut/obj/TLMap.java b/Loader/src/main/java/de/tudbut/obj/TLMap.java deleted file mode 100644 index 7f99cff..0000000 --- a/Loader/src/main/java/de/tudbut/obj/TLMap.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.obj; - -import de.tudbut.tools.Retriever; - -import java.util.*; - -public class TLMap { - protected Binding binding = new Binding<>(); - - public static TLMap stringToMap(String mapStringParsable) { - TLMap map = new TLMap<>(); - - String[] splitTiles = mapStringParsable.split(";"); - for (int i = 0; i < splitTiles.length; i++) { - String tile = splitTiles[i]; - String[] splitTile = tile.split(":"); - if (tile.contains(":")) { - if (splitTile.length == 2) - map.set( - splitTile[0].replaceAll("%I", ":").replaceAll("%B", ";").replaceAll("%P", "%"), - splitTile[1].equals("%N") ? null : splitTile[1].replaceAll("%I", ":").replaceAll("%B", ";").replaceAll("%P", "%") - ); - else - map.set(splitTile[0].replaceAll("%I", ":").replaceAll("%B", ";").replaceAll("%P", "%"), ""); - } - } - - return map; - } - - public static String mapToString(TLMap map) { - StringBuilder r = new StringBuilder(); - - for (String key : map.keys().toArray(new String[0])) { - - r - .append(key.replaceAll("%", "%P").replaceAll(";", "%B").replaceAll(":", "%I")) - .append(":") - .append(map.get(key) == null ? "%N" : map.get(key).replaceAll("%", "%P").replaceAll(";", "%B").replaceAll(":", "%I")) - .append(";") - ; - } - - return r.toString(); - } - - public void set(K key, V value) { - binding.set(key, value); - } - - public void setIfNull(K key, V value) { - if(binding.get(key) == null) { - binding.set(key, value); - } - } - - public V get(K key) { - return binding.get(key); - } - - public V get(K key, V def) { - V v = binding.get(key); - return v == null ? def : v; - } - public V get(K key, Retriever def) { - V v = binding.get(key); - return v == null ? def.retrieve() : v; - } - - public Set keys() { - return binding.keys(); - } - - public int size() { - return binding.size(); - } - - public Set values() { - return binding.values(); - } - - public ArrayList> entries() { - return binding.entries(); - } - - public TLMap flip() { - TLMap map = new TLMap<>(); - map.binding = binding.flip(); - return map; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - TLMap tlMap = (TLMap) o; - return tlMap.binding.entries.equals(binding.entries); - } - - protected static class Binding { - protected ArrayList> entries = new ArrayList<>(); - - protected void set(K key, V value) { - boolean exists = false; - for (int i = 0; i < entries.size(); i++) { - Entry entry = entries.get(i); - if (key == entry.key || entry.key.equals(key)) { - exists = true; - if(value == null) { - entries.remove(i); - break; - } - entry.val = value; - } - } - if(!exists && value != null && key != null) { - this.entries.add(new Entry<>(key, value)); - } - } - - protected V get(K key) { - ArrayList> entries = (ArrayList>) this.entries.clone(); - for (Entry entry : entries) { - if (key == entry.key || entry.key.equals(key)) - return entry.val; - } - return null; - } - - protected Set keys() { - Set keys = new LinkedHashSet<>(); - for (int i = 0; i < entries.size(); i++) { - keys.add(entries.get(i).key); - } - return keys; - } - - protected Set values() { - Set vals = new LinkedHashSet<>(); - for (int i = 0; i < entries.size(); i++) { - vals.add(entries.get(i).val); - } - return vals; - } - - protected ArrayList> entries() { - ArrayList> vals = new ArrayList<>(); - vals.addAll(entries); - return vals; - } - - protected Binding flip() { - Binding binding = new Binding<>(); - for (int i = 0 ; i < entries.size() ; i++) { - Entry entry = entries.get(i); - binding.entries.add(new Entry<>(entry.val, entry.key)); - } - return binding; - } - - public int size() { - return entries.size(); - } - } - - public static class Entry { - public K key; - public V val; - - protected Entry() { - } - - protected Entry(K key, V val) { - this.key = key; - this.val = val; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Entry entry = (Entry) o; - if (!Objects.equals(key, entry.key)) return false; - return Objects.equals(val, entry.val); - } - } - - @Override - public TLMap clone() { - TLMap n = new TLMap<>(); - Object[] keys = keys().toArray(); - Object[] vals = values().toArray(); - for (int i = 0, arrayLength = keys.length ; i < arrayLength ; i++) { - Object key = keys[i]; - n.set((K)key, (V)vals[i]); - } - return n; - } -} diff --git a/Loader/src/main/java/de/tudbut/parsing/JSON.java b/Loader/src/main/java/de/tudbut/parsing/JSON.java deleted file mode 100644 index 6969ace..0000000 --- a/Loader/src/main/java/de/tudbut/parsing/JSON.java +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.parsing; - -import de.tudbut.tools.Stack; -import de.tudbut.tools.StringTools; - -import java.util.ArrayList; - -/** - * Interconverting JSON and TCN - */ -public class JSON { - - /** - * Converts a JSON string to a TCN object - * @param string The JSON string, supports most compact and readable formats - * @return The parsed TCN object - * @throws JSONFormatException If a format error is found - */ - public static TCN read(String string) throws JSONFormatException { - while (string.startsWith(" ")) { - string = string.substring(1); - } - if(!string.startsWith("{") && !string.startsWith("[")) { - throw new JSONFormatException("Expected: { or [ at 0 (String is '" + string + "')"); - } - boolean array = string.startsWith("["); - TCN tcn = new TCN("JSON", array); - boolean escape = false; - int pos = 1; - char[] a = string.toCharArray(); - char c = a[pos]; - int arrayPos = 0; - boolean inString = false; - boolean startString = false; - StringBuilder theString = new StringBuilder(); - boolean kv = false; - String key = ""; - boolean inStringKV = false; - boolean inObjectKV = false; - TCN sub = null; - - try { - while (inString || (c != '}' && c != ']')) { - if(array) { - kv = true; - } - - if (startString) { - inString = true; - startString = false; - } - if (c == '\\') { - escape = !escape; - } - if (!escape && c == '"') { - startString = !inString; - if (startString) { - if (kv) - inStringKV = true; - theString = new StringBuilder(); - } - else { - inString = false; - if (!kv) { // Key - key = theString.toString(); - } - } - } - if (inString) { - if (!escape) - theString.append(c); - else { - a: - { - // Make escapes work - if (c == 'n') - theString.append('\n'); - if (c == 'r') - theString.append('\r'); - if (c == 'u') { - String e = ""; - e += c = a[++pos]; - e += c = a[++pos]; - e += c = a[++pos]; - e += c = a[++pos]; - theString.append((char) Integer.parseInt(e, 16)); - break a; - } - if (c == '0') { - String e = ""; - e += c = a[pos]; - e += c = a[++pos]; - e += c = a[++pos]; - theString.append((char) Integer.parseInt(e, 8)); - break a; - } - if (c == '1') { - String e = ""; - e += c = a[pos]; - e += c = a[++pos]; - e += c = a[++pos]; - theString.append((char) Integer.parseInt(e, 8)); - break a; - } - if (c == '2') { - String e = ""; - e += c = a[pos]; - e += c = a[++pos]; - e += c = a[++pos]; - theString.append((char) Integer.parseInt(e, 8)); - break a; - } - if (c == '3') { - String e = ""; - e += c = a[pos]; - e += c = a[++pos]; - e += c = a[++pos]; - theString.append((char) Integer.parseInt(e, 8)); - break a; - } - if (c == 'x') { - String e = ""; - e += c = a[++pos]; - e += c = a[++pos]; - theString.append((char) Integer.parseInt(e, 16)); - break a; - } - if (c == '"') { - theString.append("\""); - } - } - } - } - - // Booleans, ints, etc - else if (kv && !startString && !inStringKV && c != ',' && (Character.isLetterOrDigit(c) || c == '.' || c == '-')) { - theString.append(c); - } - - // SubObjects - if (!inString && c == '{') { - inObjectKV = true; - escape = false; - theString = new StringBuilder("{"); - int layer = 1; - while (layer > 0) { - c = a[++pos]; - theString.append(c); - if(c == '{' && !inString) { - layer++; - } - if(c == '}' && !inString) { - layer--; - } - - if (c == '\\') { - escape = !escape; - } - if (c == '\"' && !escape) { - inString = !inString; - } - if (c != '\\') { - escape = false; - } - } - theString.append("}"); - sub = read(theString.toString()); - theString = new StringBuilder(); - } - // Arrays - if (!inString && c == '[') { - inObjectKV = true; - escape = false; - theString = new StringBuilder("["); - int layer = 1; - while (layer != 0) { - c = a[++pos]; - theString.append(c); - if(c == '[' && !inString) { - layer++; - } - if(c == ']' && !inString) { - layer--; - } - - if (c == '\\') { - escape = !escape; - } - if (c == '\"' && !escape) { - inString = !inString; - } - if (c != '\\') { - escape = false; - } - } - theString.append(']'); - sub = read(theString.toString()); - theString = new StringBuilder(); - } - - - if(array) { - kv = true; - } - // Key vs Value parsing - if (!inString && c == ':') { - theString = new StringBuilder(); - if (!kv) - kv = true; - else - throw new JSONFormatException("Unexpected: '" + c + "' at " + pos + " - Should be ','"); - } - if (!inString && c == ',') { - if(array) - key = String.valueOf(arrayPos++); - - if (inObjectKV) { - tcn.set(key, sub); - } else if(inStringKV || !theString.toString().equals("null")) { - tcn.set(key, theString.toString()); - } - inObjectKV = false; - inStringKV = false; - theString = new StringBuilder(); - if (kv) - kv = false; - else - throw new JSONFormatException("Unexpected: '" + c + "' at " + pos + " - Should be ':'"); - - } - - if (c != '\\') { - escape = false; - } - - c = a[++pos]; - } - if(kv) { - if (array) - key = String.valueOf(arrayPos); - if (inObjectKV) - tcn.set(key, sub); - else if(inStringKV || !theString.toString().equals("null")) - tcn.set(key, theString.toString()); - } - - - for (String theKey : tcn.map.keys()) { - TCN.deepConvert(theKey, tcn.get(theKey), tcn); - } - return tcn; - } catch (JSONFormatException e) { - throw e; - } catch (Throwable e) { - throw new JSONFormatException("At " + pos + " in " + string + " (Debug: " + inString + " " + kv + " " + theString + " " + key + " " + array + ")", e); - } - } - - private static String indent(boolean b, int i, int il) { - if(b) - return StringTools.multiply(StringTools.multiply(" ", il), i); - else - return ""; - } - - /** - * Converts a TCN object to a JSON string, uses the most compact form - * @param tcn The TCN to write to JSON - * @return The JSON string - */ - public static String write(TCN tcn) { - return write(tcn, false, false, 0); - } - - /** - * Converts a TCN object to a JSON string - * @param tcn The TCN to write to JSON - * @param spaces If the JSON string should have spaces after : and , - * @return The JSON string - */ - public static String write(TCN tcn, boolean spaces) { - return write(tcn, false, spaces, 0); - } - - /** - * Converts a TCN object to a JSON string, uses newlines with selected indent and without spaces - * @param tcn The TCN to write to JSON - * @param indent The indent to use - * @return The JSON string - */ - public static String write(TCN tcn, int indent) { - return write(tcn, true, false, indent); - } - - /** - * Converts a TCN object to a JSON string, uses newlines with an indent of 2 and spaces - * @param tcn The TCN to write to JSON - * @return The JSON string - */ - public static String writeReadable(TCN tcn) { - return write(tcn, true, true, 2); - } - - /** - * Converts a TCN object to a JSON string, uses newlines with selected indent and spaces - * @param tcn The TCN to write to JSON - * @param indent The indent to use - * @return The JSON string - */ - public static String writeReadable(TCN tcn, int indent) { - return write(tcn, true, true, indent); - } - - /** - * Converts a TCN object to a JSON string - * @param tcn The TCN to write to JSON - * @param newlines If the JSON string should have newlines and indents - * @param spaces If the JSON string should have spaces after : and , - * @param indentLength The indent to use - * @return The JSON string - */ - public static String write(TCN tcn, boolean newlines, boolean spaces, int indentLength) { - - StringBuilder s = new StringBuilder(); - s.append(tcn.isArray ? "[" : "{").append(newlines ? "\n" : ""); - int i = 1; - - ArrayList> paths = new ArrayList<>(); - Stack tcnStack = new Stack<>(); - Stack path = new Stack<>(); - tcnStack.add(tcn); - path.add(""); - while (tcnStack.size() > 0) { - boolean b = false; - for(String key : tcnStack.peek().map.keys()) { - Object o = tcnStack.peek().map.get(key); - - if(o == null) - continue; - - String k = key.replaceAll("\\\\", "\\\\\\\\").replaceAll("\n", "\\\\n").replaceAll("\"", "\\\\\""); - if(o.getClass() == TCN.class) { - path.add(key); - if(!paths.contains(path)) { - paths.add(path.clone()); - TCN theTCN = tcnStack.peek(); - tcnStack.add((TCN) o); - if(theTCN.isArray) { - s.append(indent(newlines, i, indentLength)).append("{").append(newlines ? "\n" : ""); - } - else - s.append(indent(newlines, i, indentLength)).append("\"").append(k).append("\":").append(spaces ? " " : "").append("{").append(newlines ? "\n" : ""); - b = true; - i++; - } else - path.next(); - } else if(o.getClass() == TCNArray.class) { - path.add(key); - if(!paths.contains(path)) { - paths.add(path.clone()); - TCN theTCN = tcnStack.peek(); - tcnStack.add(((TCNArray) o).toTCN()); - if(theTCN.isArray) { - s.append(indent(newlines, i, indentLength)).append("[").append(newlines ? "\n" : ""); - } - else - s.append(indent(newlines, i, indentLength)).append("\"").append(k).append("\":").append(spaces ? " " : "").append("[").append(newlines ? "\n" : ""); - i++; - b = true; - } else - path.next(); - } else if (o instanceof String) { - path.add(key); - if(!paths.contains(path)) { - paths.add(path.clone()); - String val = o.toString().replaceAll("\\\\", "\\\\\\\\").replaceAll("\n", "\\\\n").replaceAll("\r", "\\\\r").replaceAll("\"", "\\\\\""); - if(tcnStack.peek().isArray) { - s.append(indent(newlines, i, indentLength)).append("\"").append(val).append("\",").append(spaces ? " " : "").append(newlines ? "\n" : ""); - } - else - s.append(indent(newlines, i, indentLength)).append("\"").append(k).append("\":").append(spaces ? " \"" : "\"").append(val).append("\",").append(spaces ? " " : "").append(newlines ? "\n" : ""); - b = true; - } - path.next(); - } - else { - path.add(key); - if(!paths.contains(path)) { - paths.add(path.clone()); - String val = o.toString(); - if(tcnStack.peek().isArray) { - s.append(indent(newlines, i, indentLength)).append(val).append(",").append(spaces ? " " : "").append(newlines ? "\n" : ""); - } - else - s.append(indent(newlines, i, indentLength)).append("\"").append(k).append("\":").append(spaces ? " " : "").append(val).append(",").append(spaces ? " " : "").append(newlines ? "\n" : ""); - b = true; - } - path.next(); - } - } - if(!b) { - TCN theTCN = tcnStack.next(); - path.next(); - i--; - if(theTCN.map.keys().isEmpty()) { - s.append(",").append(spaces ? " " : ""); - } - s.delete(s.length() - ((newlines ? 2 : 1) + (spaces ? 1 : 0)), s.length()); - s.append(newlines ? "\n" : "").append(indent(newlines, i, indentLength)).append(theTCN.isArray ? "]" : "}").append(",").append(spaces ? " " : "").append(newlines ? "\n" : ""); - } - } - s.delete(s.length() - ((newlines ? 2 : 1) + (spaces ? 1 : 0)), s.length()); - return s.toString(); - } - - public static class JSONFormatException extends Exception { - public JSONFormatException(String s, Throwable e) { - super(s, e); - } - public JSONFormatException(String s) { - super(s); - } - } -} diff --git a/Loader/src/main/java/de/tudbut/parsing/TCN.java b/Loader/src/main/java/de/tudbut/parsing/TCN.java deleted file mode 100644 index 26ea4a6..0000000 --- a/Loader/src/main/java/de/tudbut/parsing/TCN.java +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.parsing; - - -import de.tudbut.tools.Tools; -import de.tudbut.obj.DoubleTypedObject; -import de.tudbut.obj.TLMap; -import de.tudbut.tools.Stack; -import de.tudbut.tools.StringTools; - -import java.util.*; - -/** - * T udbuT
- * C onfig
- * N otation
- */ -public class TCN { - - /** - * The map - */ - public TLMap map = new TLMap<>(); - public final boolean isArray; - public String type; - - /** - * Creates a new, empty TCN - */ - public TCN() { - isArray = false; - this.type = "TCN"; - } - - TCN(boolean array) { - isArray = array; - this.type = "TCN"; - } - - public TCN(String type) { - isArray = false; - this.type = type; - } - - TCN(String type, boolean array) { - isArray = array; - this.type = type; - } - - - /** - * Sets something in the map - * @param key Key - * @param o Object, can be a native type, string, or another TCN (or TCNArray) - */ - public void set(String key, Object o) { - /*TLMap map = this.map; - ArrayList path = new ArrayList<>(Arrays.asList(key.split("#"))); - - while (path.size() > 1) { - map = ((TCN) map.get(path.remove(0))).map; - } - */ - map.set(key, o); - } - - public String getString(String key) { - Object o = map.get(key); - if(o != null) - return get(key).toString(); - else - return null; - } - - public Short getShort(String key) { - Object o = get(key); - if(o != null) - return Short.valueOf(String.valueOf(o)); - else - return null; - } - - public Integer getInteger(String key) { - Object o = get(key); - if(o != null) - return Integer.valueOf(String.valueOf(o)); - else - return null; - } - - public Boolean getBoolean(String key) { - Object o = get(key); - if(o != null) - return Boolean.valueOf(String.valueOf(o)); - else - return null; - } - - public Float getFloat(String key) { - Object o = get(key); - if(o != null) - return Float.valueOf(String.valueOf(o)); - else - return null; - } - - public Long getLong(String key) { - Object o = get(key); - if(o != null) - return Long.valueOf(String.valueOf(o)); - else - return null; - } - - public Double getDouble(String key) { - Object o = get(key); - if(o != null) - return Double.valueOf(String.valueOf(o)); - else - return null; - } - - public TCN getSub(String key) { - Object o = get(key); - if(o != null && o.getClass() == TCN.class) - return (TCN) map.get(key); - else - return null; - } - - public TCNArray getArray(String key) { - Object o = get(key); - if(o != null && o.getClass() == TCNArray.class) - return (TCNArray) map.get(key); - else - return null; - } - - public Object get(String key) { - TLMap map = this.map; - ArrayList path = new ArrayList<>(Collections.singletonList(key)); - - while (path.size() > 1) { - map = ((TCN) map.get(path.remove(0))).map; - } - - return map.get(path.get(0)); - } - - /** - * Converts a Map to a TCN - * @param map The map to convert - * @return The converted TCN - */ - public static TCN readMap(Map map) { - TCN tcn = new TCN(map.containsKey("TCN%isArray") && Boolean.parseBoolean(map.get("TCN%isArray"))); - - map.remove("TCN%isArray"); - - String[] array = map.keySet().toArray(new String[0]); - for (int i = 0, arrayLength = array.length; i < arrayLength; i++) { - String key = array[i]; - String s = map.get(key); - - if(s.contains(":")) { - tcn.map.set(key, TCN.readMap(Tools.stringToMap(s))); - } - else { - tcn.map.set(key, s.replaceAll("%C", ":").replaceAll("%P", "%")); - } - } - - for (String key : tcn.map.keys()) { - deepConvert(key, tcn.get(key), tcn); - } - - return tcn; - } - - /** - * Converts this TCN object to a Map - * {@link #readMap} - * @return The converted Map - */ - public Map toMap() { - Map r = new LinkedHashMap<>(); - - if(isArray) - r.put("TCN%isArray", "true"); - - String[] array = map.keys().toArray(new String[0]); - for (int i = 0, arrayLength = array.length; i < arrayLength; i++) { - String key = array[i]; - Object o = map.get(key); - - if(o == null) - continue; - - if(o.getClass() == TCN.class) { - r.put(key, Tools.mapToString(((TCN) o).toMap())); - } - else if(o.getClass() == TCNArray.class) { - r.put(key, Tools.mapToString(((TCNArray) o).toMap())); - } - else - r.put(key, o.toString().replaceAll("%", "%P").replaceAll(":", "%C")); - } - - return r; - } - - /** - * Converts this TCN to a reversible string - * @return The converted string - */ - public String toString() { - if(type.equalsIgnoreCase("TCN")) { - StringBuilder s = new StringBuilder(); - int i = 0; - - ArrayList> paths = new ArrayList<>(); - Stack tcnStack = new Stack<>(); - Stack path = new Stack<>(); - tcnStack.add(this); - path.add(""); - while (tcnStack.size() > 0) { - boolean b = false; - for (String key : tcnStack.peek().map.keys()) { - Object o = tcnStack.peek().map.get(key); - - if (o == null) - continue; - - String k = key.replaceAll("%", "%P").replaceAll(":", "%C").replaceAll("\n", "%N"); - if (k.startsWith(" ")) { - if (!k.equals(" ")) { - k = "%S" + k.substring(1); - } else - k = "%S"; - } - if (k.startsWith("#")) { - if (!k.equals("#")) { - k = "%H" + k.substring(1); - } else - k = "%H"; - } - if (o.getClass() == TCN.class) { - path.add(key); - if (!paths.contains(path)) { - paths.add(path.clone()); - TCN tcn = tcnStack.peek(); - tcnStack.add((TCN) o); - String indent = StringTools.multiply(" ", i); - if (tcn.isArray) { - s.append("\n").append(indent).append(";").append(((TCN) o).isArray ? " [\n" : " {\n"); - } else - s.append("\n").append(indent).append(k).append(((TCN) o).isArray ? " [\n" : " {\n"); - i++; - b = true; - break; - } else - path.next(); - } else if (o.getClass() == TCNArray.class) { - path.add(key); - if (!paths.contains(path)) { - paths.add(path.clone()); - TCN tcn = tcnStack.peek(); - tcnStack.add(((TCNArray) o).toTCN()); - String indent = StringTools.multiply(" ", i); - if (tcn.isArray) { - s.append("\n").append(indent).append(";").append(" [\n"); - } else - s.append("\n").append(indent).append(k).append(" [\n"); - i++; - b = true; - break; - } else - path.next(); - } else { - path.add(key); - if (!paths.contains(path)) { - paths.add(path.clone()); - String indent = StringTools.multiply(" ", i); - String val = o.toString().replaceAll("%", "%P").replaceAll("\n", "%N"); - if (tcnStack.peek().isArray) { - s.append(indent).append("; ").append(val).append("\n"); - } else - s.append(indent).append(k).append(": ").append(val).append("\n"); - b = true; - } - path.next(); - } - } - if (!b) { - TCN tcn = tcnStack.next(); - path.next(); - i--; - String indent = StringTools.multiply(" ", i); - s.append(indent).append(tcn.isArray ? "]\n\n" : "}\n\n"); - } - } - try { - s.setLength(s.length() - "\n#\n\n".length()); - s.trimToSize(); - } catch (Exception ignored) { - } - - return s.toString(); - } - else if(type.equalsIgnoreCase("JSON")) { - return JSON.write(this); - } - return ""; - } - - /** - * Converts a string {@link #toString()} to a TCN object - * @param s The string - * @return The converted TCN - * @throws TCNException If a format error occurs - */ - public static TCN read(String s) throws TCNException { - TCN tcn = new TCN(); - - Map, Stack>, String> scanned = deepScan(s); - Set, Stack>> keys = scanned.keySet(); - for (DoubleTypedObject, Stack> path : keys) { - deepPut(path.clone(), tcn, scanned.get(path)); - } - for (String key : tcn.map.keys()) { - deepConvert(key, tcn.get(key), tcn); - } - - return tcn; - } - - /** - * Converts stray arrays to TCNArray objects, recursive.
- *
Example:{@code
-     *     for (String key : tcn.map.keys()) {
-     *         deepConvert(key, tcn.get(key), tcn);
-     *     }
-     * }
- * @param key The key of o - * @param o Any value in a TCN - * @param top The TCN that o is embedded in - */ - public static void deepConvert(String key, Object o, TCN top) { - if(!(o instanceof TCN) && !(o instanceof TCNArray)) - return; - TCN tcn; - if(o instanceof TCN) { - tcn = (TCN) o; - } - else - tcn = ((TCNArray) o).toTCN(); - - for (String theKey : tcn.map.keys()) { - deepConvert(theKey, tcn.get(theKey), tcn); - } - - if (tcn.isArray) { - top.set(key, TCNArray.fromTCN(tcn)); - } - } - - private static void deepPut(DoubleTypedObject, Stack> path, TCN tcn, String value) throws TCNException { - try { - if (path.o.size() == 1) { - tcn.map.set(path.o.next(), value); - } - else { - int arrayPos = path.t.popBottom(); - TCN toPut = (TCN) tcn.map.get(path.o.getBottom(), () -> new TCN(arrayPos != -1)); - tcn.map.set(path.o.popBottom(), toPut); - deepPut(path, toPut, value); - } - } catch (Exception e) { - throw new TCNException(null, pathToString(path.o) + ": " + value, e); - } - } - - private static Map, Stack>, String> deepScan(String s) throws TCNException { - String[] lines = s.split("\n"); - Map, Stack>, String> map = new LinkedHashMap<>(); - - Stack array = new Stack<>(); - array.add(false); - Stack arrayPos = new Stack<>(); - Stack path = new Stack<>(); - for (int i = 0; i < lines.length; i++) { - try { - String line = removePrefixSpaces(lines[i]); - if (!line.isEmpty() && !line.startsWith("#")) { - if (line.equals("}") || line.equals("]")) { - path.next(); - array.next(); - arrayPos.next(); - } - else if (line.endsWith(" {") && !line.contains(": ")) { - String k = line.split(" \\{")[0].replaceAll("%C", ":").replaceAll("%N", "\n"); - if (k.startsWith("%S")) { - if (!k.equals("%S")) - k = " " + k.substring(2); - else - k = " "; - } - if (k.startsWith("%H")) { - if (!k.equals("%H")) - k = "#" + k.substring(2); - else - k = "#"; - } - if(!array.peek()) - path.add(k.replaceAll("%P", "%")); - else { - path.add(arrayPos.peek() + ""); - arrayPos.add(arrayPos.next() + 1); - } - array.add(false); - arrayPos.add(-1); - } - else if (line.endsWith(" [") && !line.contains(": ")) { - String k = line.split(" \\[")[0].replaceAll("%C", ":").replaceAll("%N", "\n"); - if (k.startsWith("%S")) { - if (!k.equals("%S")) - k = " " + k.substring(2); - else - k = " "; - } - if (k.startsWith("%H")) { - if (!k.equals("%H")) - k = "#" + k.substring(2); - else - k = "#"; - } - if(!array.peek()) - path.add(k.replaceAll("%P", "%")); - else { - path.add(arrayPos.peek() + ""); - arrayPos.add(arrayPos.next() + 1); - } - array.add(true); - arrayPos.add(0); - } - else { - Stack p = path.clone(); - if(array.peek()) { - p.add(String.valueOf(arrayPos.peek())); - if(line.equals(";")) - line = "; "; - map.put(new DoubleTypedObject<>(p, arrayPos.clone()), line.substring(2).replaceAll("%N", "\n").replaceAll("%P", "%")); - arrayPos.add(arrayPos.next() + 1); - } - else { - String rawk = line.split(": ")[0].replaceAll("%C", ":").replaceAll("%N", "\n"); - String k = rawk; - if (k.startsWith("%S")) { - if (!k.equals("%S")) - k = " " + k.substring(2); - else - k = " "; - } - if (k.startsWith("%H")) { - if (!k.equals("%H")) - k = "#" + k.substring(2); - else - k = "#"; - } - p.add(k.replaceAll("%P", "%")); - map.put(new DoubleTypedObject<>(p, arrayPos.clone()), line.substring(rawk.length() + 2).replaceAll("%N", "\n").replaceAll("%P", "%")); - } - } - } - } catch (Exception e) { - throw new TCNException(i, lines[i], e); - } - } - - return map; - } - - static String pathToString(Stack path) { - StringBuilder s = new StringBuilder("/"); - path = path.clone(); - while (path.hasNext()) { - s.append(path.popBottom()).append("/"); - } - return s.toString(); - } - - private static String removePrefixSpaces(String s) { - while (s.startsWith(" ")) - s = s.substring(1); - return s; - } - - /** - * Creates a new, empty TCN object - * @deprecated Use {@code new} {@link #TCN()} - * @return The new TCN - */ - @Deprecated - public static TCN getEmpty() { - return new TCN(); - } - - public static class TCNException extends Exception { - - public TCNException(Integer line, String lineString, Exception e) { - super("Error in line " + line + " (" + lineString + ")", e); - } - } -} diff --git a/Loader/src/main/java/de/tudbut/parsing/TCNArray.java b/Loader/src/main/java/de/tudbut/parsing/TCNArray.java deleted file mode 100644 index 96684d1..0000000 --- a/Loader/src/main/java/de/tudbut/parsing/TCNArray.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.parsing; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Map; - -/** - * TCN-Compatible Arrays - */ -public class TCNArray extends ArrayList { - - /** - * Creates a new, empty TCNArray - */ - public TCNArray() { } - /** - * Creates a new TCNArray from a collection - */ - public TCNArray(Collection collection) { - addAll(collection); - } - - public String getString(int key) { - Object o = get(key); - if(o != null) - return o.toString(); - else - return null; - } - - public Short getShort(int key) { - Object o = get(key); - if(o != null) - return Short.valueOf(String.valueOf(o)); - else - return null; - } - - public Integer getInteger(int key) { - Object o = get(key); - if(o != null) - return Integer.valueOf(String.valueOf(o)); - else - return null; - } - - public Boolean getBoolean(int key) { - Object o = get(key); - if(o != null) - return Boolean.valueOf(String.valueOf(o)); - else - return null; - } - - public Float getFloat(int key) { - Object o = get(key); - if(o != null) - return Float.valueOf(String.valueOf(o)); - else - return null; - } - - public Long getLong(int key) { - Object o = get(key); - if(o != null) - return Long.valueOf(String.valueOf(o)); - else - return null; - } - - public Double getDouble(int key) { - Object o = get(key); - if(o != null) - return Double.valueOf(String.valueOf(o)); - else - return null; - } - - public TCN getSub(int key) { - Object o = get(key); - if(o != null && o.getClass() == TCN.class) - return (TCN) o; - else - return null; - } - - public TCNArray getArray(int key) { - Object o = get(key); - if(o != null && o.getClass() == TCNArray.class) - return (TCNArray) o; - else - return null; - } - - /** - * - * @return a TCN object from this TCNArray, this is the only way to get a TCN with {@link TCN#isArray} true - */ - public TCN toTCN() { - TCN tcn = new TCN(true); - for (int i = 0 ; i < this.size() ; i++) { - tcn.set(String.valueOf(i), get(i)); - } - return tcn; - } - - /** - * Converts a TCN to a TCNArray - * @param tcn The TCN to convert from - * @return The created TCNArray - */ - public static TCNArray fromTCN(TCN tcn) { - TCNArray array = new TCNArray(); - for (String key : tcn.map.keys()) { - array.add(tcn.get(key)); - } - return array; - } - - /** - * Converts the TCNArray to a TCN, then maps it - * @return the created map - */ - public Map toMap() { - return toTCN().toMap(); - } -} diff --git a/Loader/src/main/java/de/tudbut/security/AccessKiller.java b/Loader/src/main/java/de/tudbut/security/AccessKiller.java deleted file mode 100644 index ced12ef..0000000 --- a/Loader/src/main/java/de/tudbut/security/AccessKiller.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security; - -import de.tudbut.tools.ReflectUtil; - -import java.lang.ref.SoftReference; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class AccessKiller { - - private static final Field reflectionData; - - static { - try { - reflectionData = getField(Class.class.getDeclaredField("reflectionData")); - } catch (NoSuchFieldException e) { - throw new InternalError(e); - } - } - - private static Field getField(Field f) { - ReflectUtil.forceAccessible(f); - return f; - } - - private static Object getReflectionData(Class clazz) throws ReflectiveOperationException { - // make sure ReflectionData is populated - clazz.getDeclaredMethods(); - clazz.getDeclaredFields(); - clazz.getDeclaredConstructors(); - clazz.getInterfaces(); - - SoftReference data = (SoftReference) reflectionData.get(clazz); - Object reflectionData = data.get(); - assert reflectionData != null; - return reflectionData; - } - - /** - * WARNING!!! Can only erase private fields!! - * @param clazz Class to kill fields of - * @param fieldsToKill Field names to kill, or empty to kill all. - */ - public static void killFieldAccess(Class clazz, String... fieldsToKill) { - List toKill = Arrays.asList(fieldsToKill); - try { - Object reflectionData = getReflectionData(clazz); - Field data = getField(reflectionData.getClass().getDeclaredField("declaredFields")); - List fields = new ArrayList<>(Arrays.asList((Field[]) data.get(reflectionData))); - if(!toKill.isEmpty()) { - for (int i = 0; i < fields.size(); i++) { - if (toKill.contains(fields.get(i).getName())) - fields.remove(i--); - } - } - else { - fields.clear(); - } - data.set(reflectionData, fields.toArray(new Field[0])); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * WARNING!!! Can only erase private methods!! - * @param clazz Class to kill methods of - * @param methodsToKill Method names to kill, or empty to kill all. - */ - public static void killMethodAccess(Class clazz, String... methodsToKill) { - List toKill = Arrays.asList(methodsToKill); - try { - Object reflectionData = getReflectionData(clazz); - Field data = getField(reflectionData.getClass().getDeclaredField("declaredMethods")); - List methods = new ArrayList<>(Arrays.asList((Method[]) data.get(reflectionData))); - if(!toKill.isEmpty()) { - for (int i = 0; i < methods.size(); i++) { - if (toKill.contains(methods.get(i).getName())) - methods.remove(i--); - } - } - else { - methods.clear(); - } - data.set(reflectionData, methods.toArray(new Method[0])); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * WARNING!!! Can only erase private constructors!! - * @param clazz Class to kill constructors of - */ - public static void killConstructorAccess(Class clazz) { - try { - Object reflectionData = getReflectionData(clazz); - Field data = getField(reflectionData.getClass().getDeclaredField("declaredConstructors")); - data.set(reflectionData, new Constructor[0]); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - public static void killReflectionFor(Class... classes) { - for (Class clazz : classes) { - killConstructorAccess(clazz); - killMethodAccess(clazz); - killFieldAccess(clazz); - } - } - - /** - * Stops any code from making further changes to reflectionData. - * This also stops any further AccessKiller calls.
- * Use with EXTREME caution!! - */ - public static void killClassReflection() { - killReflectionFor(Class.class); - } - - /** - * Kills access to possible ways to restore reflective access after it has been removed. - * This should prevent all other ways of accessing fields, but other ways may exist. - */ - public static void ensureKills() { - killMethodAccess(Class.class, "getDeclaredFields0", "getDeclaredMethods0", "getDeclaredConstructors0"); - } -} diff --git a/Loader/src/main/java/de/tudbut/security/DataKeeper.java b/Loader/src/main/java/de/tudbut/security/DataKeeper.java deleted file mode 100644 index 4b3fe2e..0000000 --- a/Loader/src/main/java/de/tudbut/security/DataKeeper.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security; - -import de.tudbut.obj.DoubleTypedObject; -import de.tudbut.tools.Lock; - -import java.util.LinkedList; -import java.util.Queue; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; -import java.util.function.Supplier; - -// Keeps some data as safe as possible, unable to be accessed even by reflection -public class DataKeeper { - public static boolean forgetAll = false; - - - public Lock forget = new Lock(true); - private final PermissionManager permissionManager; - private Supplier dataInsertion; - private final Strictness strictness; - private final Lock lock = new Lock(true); - private final Queue>, Lock>> nextFunctionToRun = new LinkedList<>(); - private final Thread keeper = new Thread(this::keep, "DataKeeper"); { keeper.start(); } - - static { initSecurity(); } - - private static void initSecurity() { - // this should prevent any reflection, but is not a 100% guarantee! - AccessKiller.killReflectionFor(DataKeeper.class, Accessor.class); - } - - public DataKeeper(PermissionManager permissionManager, Strictness strictness, T toKeep) { - // make sure reflection is killed for it - permissionManager.killReflection(); - - this.permissionManager = permissionManager; - dataInsertion = () -> toKeep; - this.strictness = strictness; - lock.unlock(); - } - - public Strictness getStrictness() { - return strictness.clone(); - } - - public void access(Consumer> accessor) { - if(!forget.isLocked()) { - throw new IllegalStateException("This DataKeeper has already forgotten its value."); - } - if(!permissionManager.checkCaller(strictness)) { - if(permissionManager.showErrors()) - throw new IllegalAccessError("The active PermissionManager does not allow you to access this DataKeeper."); - else - return; - } - Lock waitLock = new Lock(true); - nextFunctionToRun.add(new DoubleTypedObject<>(accessor, waitLock)); - lock.unlock(); - waitLock.waitHere(500); - } - - public void forget() { - forget.unlock(); - } - - public DataKeeper forgetIn(int ms) { - if(forget.timeLeft() > ms) - return this; - forget.lock(ms); - return this; - } - - private void keep() { - lock.waitHere(); - lock.lock(); - PermissionManager permissionManager = this.permissionManager.clone(); - AtomicReference data = new AtomicReference<>(dataInsertion.get()); - Strictness strictness = this.strictness.clone(); - dataInsertion = null; - while(!forgetAll && forget.isLocked()) { - lock.waitHere(); - lock.lock(500); - - DoubleTypedObject>, Lock> itm = nextFunctionToRun.poll(); - if(itm == null) - continue; - Consumer> toRun = itm.o; - Lock lock = itm.t; - // second layer of protection, crashes this time. - if(!permissionManager.checkLambda(strictness, toRun)) - permissionManager.crash(strictness); - - toRun.accept(new Accessor<>(permissionManager, strictness, data)); - lock.unlock(); - } - } - - // A very last, third layer of protection, not actually that necessary. - public static class Accessor { - // The accessor will only ever be in local variables, so it does - // not have to be reflection-safe. But it is anyway due to AccessKiller. - private final PermissionManager permissionManager; - private final AtomicReference value; - private final Strictness strictness; - - public Accessor(PermissionManager permissionManager, Strictness strictness, AtomicReference data) { - this.permissionManager = permissionManager; - this.strictness = strictness; - value = data; - } - - public T getValue() { - if(permissionManager.checkCaller(strictness)) - return value.get(); - else { - // crash soon - new Thread(() -> { - try { - Thread.sleep(5000); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - permissionManager.crash(strictness); - }).start(); - // generate a weird error - return (T) value.get().getClass().cast(new Object()); - } - } - - public T setValue(T newValue) { - // check is in getValue - T old = getValue(); - value.set(newValue); - return old; - } - } -} diff --git a/Loader/src/main/java/de/tudbut/security/ExtendedStrictness.java b/Loader/src/main/java/de/tudbut/security/ExtendedStrictness.java deleted file mode 100644 index 147e46a..0000000 --- a/Loader/src/main/java/de/tudbut/security/ExtendedStrictness.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security; - -public class ExtendedStrictness implements Strictness { - static { - AccessKiller.killReflectionFor(ExtendedStrictness.class); - } - private final Strictness primary, secondary; - - public ExtendedStrictness(Strictness primary, Strictness secondary) { - this.primary = primary; - this.secondary = secondary; - } - - @Override - public Object getRawProperty(String name) { - if(primary.hasProperty(name)) - return primary.getRawProperty(name); - return secondary.getRawProperty(name); - } - - @Override - public Strictness clone() { - return new ExtendedStrictness(primary.clone(), secondary.clone()); - } -} diff --git a/Loader/src/main/java/de/tudbut/security/PermissionManager.java b/Loader/src/main/java/de/tudbut/security/PermissionManager.java deleted file mode 100644 index b5c12f1..0000000 --- a/Loader/src/main/java/de/tudbut/security/PermissionManager.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security; - -import de.tudbut.tools.ReflectUtil; - -import java.lang.reflect.Method; -import java.util.Arrays; - -public interface PermissionManager extends Cloneable { - boolean checkCaller(Strictness strictnessLevel); - - boolean checkLambda(Strictness strictnessLevel, T lambda); - - default void crash(Strictness strictnessLevel) { - DataKeeper.forgetAll = true; - try { - Class shutdownClass = Class.forName("java.lang.Shutdown"); - Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class); - ReflectUtil.forceAccessible(exitMethod); - exitMethod.invoke(null, 1); - } catch (Exception ignored) {} - System.exit(1); - throw new Error(); - } - - default boolean showErrors() { - return true; - } - - default void killReflection() { - Class clazz = getClass(); - while(Arrays.stream(clazz.getInterfaces()).anyMatch(x -> x == PermissionManager.class)) { - AccessKiller.killReflectionFor(clazz); - clazz = clazz.getSuperclass(); - } - } - - PermissionManager clone(); -} diff --git a/Loader/src/main/java/de/tudbut/security/Strictness.java b/Loader/src/main/java/de/tudbut/security/Strictness.java deleted file mode 100644 index c8f3795..0000000 --- a/Loader/src/main/java/de/tudbut/security/Strictness.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security; - -public interface Strictness extends Cloneable { - - Object getRawProperty(String name); - - default T getProperty(String name) { - return (T) getRawProperty(name); - } - default boolean getBoolProperty(String name) { - Boolean b = getProperty(name); - if(b == null) - return false; - return b; - } - default String getStringProperty(String name) { - return getProperty(name); - } - default int getIntProperty(String name) { - return getProperty(name); - } - default boolean hasProperty(String name) { - return getRawProperty(name) != null; - } - default Strictness extend(Strictness newPrimary) { - return new ExtendedStrictness(newPrimary, this); - } - - Strictness clone(); -} diff --git a/Loader/src/main/java/de/tudbut/security/StrictnessBuilder.java b/Loader/src/main/java/de/tudbut/security/StrictnessBuilder.java deleted file mode 100644 index 88b27e5..0000000 --- a/Loader/src/main/java/de/tudbut/security/StrictnessBuilder.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security; - -import de.tudbut.parsing.TCN; - -import java.util.HashMap; - -public class StrictnessBuilder { - static { - AccessKiller.killReflectionFor(StrictnessBuilder.class); - } - - private final HashMap properties = new HashMap<>(); - - public static StrictnessBuilder create() { - return new StrictnessBuilder(); - } - - public static Strictness empty() { - return new StrictnessBuilder().build(); - } - - public StrictnessBuilder property(String s, Object o) { - properties.put(s, o); - return this; - } - - public StrictnessBuilder fromTCN(TCN tcn) { - properties.putAll(tcn.toMap()); - return this; - } - - public StrictnessBuilder tryFromStrictness(Strictness strictness) { - if(strictness instanceof StrictnessImpl) { - properties.putAll((((StrictnessImpl) strictness).properties)); - return this; - } - // error - return null; - } - - public Strictness build() { - return new StrictnessImpl((HashMap) properties.clone()); - } - - private static class StrictnessImpl implements Strictness { - static { - AccessKiller.killReflectionFor(StrictnessImpl.class); - } - - private final HashMap properties; - - public StrictnessImpl(HashMap properties) { - this.properties = properties; - } - - @Override - public Object getRawProperty(String name) { - return properties.get(name); - } - - @Override - public Strictness clone() { - return new StrictnessImpl((HashMap) properties.clone()); - } - } -} diff --git a/Loader/src/main/java/de/tudbut/security/permissionmanager/AllowAllRestriction.java b/Loader/src/main/java/de/tudbut/security/permissionmanager/AllowAllRestriction.java deleted file mode 100644 index 9f8dc2e..0000000 --- a/Loader/src/main/java/de/tudbut/security/permissionmanager/AllowAllRestriction.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security.permissionmanager; - -import de.tudbut.security.PermissionManager; -import de.tudbut.security.Strictness; - -public class AllowAllRestriction implements PermissionManager { - @Override - public boolean checkCaller(Strictness strictnessLevel) { - return true; - } - - @Override - public boolean checkLambda(Strictness strictnessLevel, T lambda) { - return true; - } - - @Override - public PermissionManager clone() { - return this; - } -} diff --git a/Loader/src/main/java/de/tudbut/security/permissionmanager/CallClassRestriction.java b/Loader/src/main/java/de/tudbut/security/permissionmanager/CallClassRestriction.java deleted file mode 100644 index e9944b9..0000000 --- a/Loader/src/main/java/de/tudbut/security/permissionmanager/CallClassRestriction.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security.permissionmanager; - -import de.tudbut.security.PermissionManager; -import de.tudbut.security.Strictness; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; - -/** - * Supported strictness properties: - * - Restriction.CallClass.MaxDistance (int): How far down the stack trace should the restriction look until it fails - * - Restriction.CallClass.RestrictLambda (bool): If the restriction should apply to lambdas. If true, ONLY classes in the - * allowlist pass, instead of allowing the allowed classes to call "through" others. - */ -public class CallClassRestriction extends Restriction { - - private final Set allow; - - public CallClassRestriction(PermissionManager parent, Class... allowFromClasses) { - super(parent); - allow = Collections.unmodifiableSet(Arrays.stream(allowFromClasses).map(Class::getName).collect(Collectors.toSet())); - } - public CallClassRestriction(Class... allowFromClasses) { - this(null, allowFromClasses); - } - - @Override - public boolean checkCaller(Strictness strictnessLevel) { - StackTraceElement[] st = Thread.currentThread().getStackTrace(); - - if(strictnessLevel.hasProperty("Restriction.CallClass.MaxDistance")) { - int maxDist = strictnessLevel.getIntProperty("Restriction.CallClass.MaxDistance"); - if(st.length > maxDist) { - StackTraceElement[] elements = new StackTraceElement[maxDist]; - System.arraycopy(st, 0, elements, 0, maxDist); - st = elements; - } - } - - boolean isCalledByAllowed = false; - for (StackTraceElement element : st) { - if (allow.contains(element.getClassName())) { - isCalledByAllowed = true; - break; - } - } - return isCalledByAllowed && super.checkCaller(strictnessLevel); - } - - @Override - public boolean checkLambda(Strictness strictnessLevel, T lambda) { - boolean b = true; - if(strictnessLevel.getBoolProperty("Restriction.CallClass.RestrictLambda")) { - // might get more complex soon. - // is class, inner class of it, loaded by it, or lambda in it? - Class enclosingClass = lambda.getClass().getEnclosingClass(); - b = allow.contains(lambda.getClass().getName()) - || allow.contains(lambda.getClass().getName().replaceAll("\\$\\$Lambda.*$", "")); - if (enclosingClass != null) - b = b || allow.contains(enclosingClass.getName()); - } - return b && super.checkLambda(strictnessLevel, lambda); - } -} diff --git a/Loader/src/main/java/de/tudbut/security/permissionmanager/ClassLoaderRestriction.java b/Loader/src/main/java/de/tudbut/security/permissionmanager/ClassLoaderRestriction.java deleted file mode 100644 index 0803df5..0000000 --- a/Loader/src/main/java/de/tudbut/security/permissionmanager/ClassLoaderRestriction.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security.permissionmanager; - -import de.tudbut.security.PermissionManager; -import de.tudbut.security.Strictness; -import de.tudbut.tools.ReflectUtil; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -/** - * Only allows classes loaded by a certain class loader, and the classloader itself. - * - * Supported strictness properties: - * - Restriction.ClassLoader.MaxDistance (int): How far down the stack trace should the restriction look until it fails - * - Restriction.ClassLoader.RestrictLambda (bool): If the restriction should apply to lambdas. If true, ONLY classes in the - * allowlist pass, instead of allowing the allowed classes to call "through" others. - */ -public class ClassLoaderRestriction extends Restriction { - private final Set allow; - - public ClassLoaderRestriction(PermissionManager parent, ClassLoader... allowFromClassLoaders) { - super(parent); - this.allow = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(allowFromClassLoaders))); - } - - public ClassLoaderRestriction(ClassLoader... allowFromClassLoaders) { - this(null, allowFromClassLoaders); - } - - @Override - public boolean checkCaller(Strictness strictnessLevel) { - StackTraceElement[] st = Thread.currentThread().getStackTrace(); - - if(strictnessLevel.hasProperty("Restriction.ClassLoader.MaxDistance")) { - int maxDist = strictnessLevel.getIntProperty("Restriction.ClassLoader.MaxDistance"); - if(st.length > maxDist) { - StackTraceElement[] elements = new StackTraceElement[maxDist]; - System.arraycopy(st, 0, elements, 0, maxDist); - st = elements; - } - } - - boolean isCalledByAllowed = false; - for (StackTraceElement element : st) { - try { - Class cls = getClassObject(element.getClassName()); - // is the classloader or loaded by it? - if(allow.stream().anyMatch(x -> x.getClass() == cls) || allow.contains(cls.getClassLoader())) { - isCalledByAllowed = true; - break; - } - } catch (Exception e) { - // it'll just stay false - } - } - return isCalledByAllowed && super.checkCaller(strictnessLevel); - } - - private Class getClassObject(String className) throws ClassNotFoundException { - try { - Method findLoadedClass = ClassLoader.class.getDeclaredMethod("findLoadedClass", String.class); - ReflectUtil.forceAccessible(findLoadedClass); - for (ClassLoader allowed : allow) { - Class clazz = (Class) findLoadedClass.invoke(allowed, className); - if(clazz != null) { - return clazz; - } - } - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - throw new RuntimeException(e); - } - return Class.forName(className); - } - - @Override - public boolean checkLambda(Strictness strictnessLevel, T lambda) { - boolean b = true; - if(strictnessLevel.getBoolProperty("Restriction.ClassLoader.RestrictLambda")) { - // might get more complex soon. - // is classloader, inner class of it, or loaded by it? - - - //noinspection SuspiciousMethodCalls - b = allow.contains(lambda) - || allow.contains(lambda.getClass().getClassLoader()); - - // is enclosed class (e.g. anonymous class) - Class enclosingClass = lambda.getClass().getEnclosingClass(); - if (enclosingClass != null) - b = b || allow.stream().anyMatch(x -> x.getClass() == enclosingClass); - - // is lambda in allowed class? - String name = lambda.getClass().getName().replaceAll("\\$\\$Lambda.*$", ""); - b = b || allow.stream().anyMatch(x -> x.getClass().getName().equals(name)); // is lambda in classloader - try { - b = b || allow.contains(getClassObject(name).getClassLoader()); // is lambda in classloader-loaded class - } catch (Exception e) { - // it'll just stay false - } - } - return b && super.checkLambda(strictnessLevel, lambda); - } -} diff --git a/Loader/src/main/java/de/tudbut/security/permissionmanager/HideErrorRestriction.java b/Loader/src/main/java/de/tudbut/security/permissionmanager/HideErrorRestriction.java deleted file mode 100644 index 7c0d73f..0000000 --- a/Loader/src/main/java/de/tudbut/security/permissionmanager/HideErrorRestriction.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security.permissionmanager; - -import de.tudbut.security.PermissionManager; - -public class HideErrorRestriction extends Restriction { - public HideErrorRestriction(PermissionManager parent) { - super(parent); - } - - @Override - public boolean showErrors() { - return false; - } -} diff --git a/Loader/src/main/java/de/tudbut/security/permissionmanager/PermissionOR.java b/Loader/src/main/java/de/tudbut/security/permissionmanager/PermissionOR.java deleted file mode 100644 index 37f9788..0000000 --- a/Loader/src/main/java/de/tudbut/security/permissionmanager/PermissionOR.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security.permissionmanager; - -import de.tudbut.security.PermissionManager; -import de.tudbut.security.Strictness; - -public class PermissionOR implements PermissionManager { - - private final PermissionManager primary, secondary; - - public PermissionOR(PermissionManager primary, PermissionManager secondary) { - this.primary = primary; - this.secondary = secondary; - } - - @Override - public boolean checkCaller(Strictness strictnessLevel) { - return primary.checkCaller(strictnessLevel) || secondary.checkCaller(strictnessLevel); - } - - @Override - public boolean checkLambda(Strictness strictnessLevel, T lambda) { - return primary.checkLambda(strictnessLevel, lambda) || secondary.checkLambda(strictnessLevel, lambda); - } - - @Override - public void crash(Strictness strictnessLevel) { - primary.crash(strictnessLevel); - secondary.crash(strictnessLevel); - } - - @Override - public boolean showErrors() { - return primary.showErrors() || secondary.showErrors(); - } - - @Override - public void killReflection() { - PermissionManager.super.killReflection(); - primary.killReflection(); - secondary.killReflection(); - } - - @Override - public PermissionManager clone() { - return new PermissionOR(primary.clone(), secondary.clone()); - } -} diff --git a/Loader/src/main/java/de/tudbut/security/permissionmanager/Restriction.java b/Loader/src/main/java/de/tudbut/security/permissionmanager/Restriction.java deleted file mode 100644 index fbcbc20..0000000 --- a/Loader/src/main/java/de/tudbut/security/permissionmanager/Restriction.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.security.permissionmanager; - -import de.tudbut.security.PermissionManager; -import de.tudbut.security.Strictness; - -public abstract class Restriction implements PermissionManager { - - protected PermissionManager parent; - - public Restriction(PermissionManager parent) { - if(parent == null) - parent = new AllowAllRestriction(); - this.parent = parent; - } - - @Override - public boolean checkCaller(Strictness strictnessLevel) { - return parent.checkCaller(strictnessLevel); - } - - @Override - public boolean checkLambda(Strictness strictnessLevel, T lambda) { - return parent.checkLambda(strictnessLevel, lambda); - } - - @Override - public void crash(Strictness strictnessLevel) { - parent.crash(strictnessLevel); - } - - @Override - public void killReflection() { - parent.killReflection(); - PermissionManager.super.killReflection(); - } - - @Override - public PermissionManager clone() { - try { - Restriction cloned = (Restriction) super.clone(); - cloned.parent = parent.clone(); - return cloned; - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e); - } - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/ExtendedMath.java b/Loader/src/main/java/de/tudbut/tools/ExtendedMath.java deleted file mode 100644 index c50331c..0000000 --- a/Loader/src/main/java/de/tudbut/tools/ExtendedMath.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -import java.security.SecureRandom; - -public class ExtendedMath { - - static SecureRandom RANDOM = new SecureRandom(); - - - public static int random(int lower, int upper) { - return (int) randomLong(lower, upper); - } - - public static long randomLong(long lower, long upper) { - upper ++; - return (long) (Math.floor(RANDOM.nextFloat() * (upper - lower)) + lower); - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/Lock.java b/Loader/src/main/java/de/tudbut/tools/Lock.java deleted file mode 100644 index e60adb4..0000000 --- a/Loader/src/main/java/de/tudbut/tools/Lock.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -import java.util.Date; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Helper for synchronization and timing - */ -public class Lock { - - private final Locker locker = new Locker(); - private boolean locked = false; - private int t = 0; - private long ts = 0; - private final AtomicInteger waiting = new AtomicInteger(); - private volatile boolean[] waiterLocker = null; - - /** - * Object to handle thread locking - */ - private static class Locker { - - /** - * Make the thread wait until {@link Locker#unlock()} is called - * @throws InterruptedException Inherited from {@link Object#wait} - */ - public synchronized void lockHere() throws InterruptedException { - wait(); - } - - /** - * Make the thread wait until {@link Locker#unlock()} is called or the timeout runs out - * @throws InterruptedException Inherited from {@link Object#wait} - * @param timeout Maximal wait time - */ - public synchronized void lockHere(long timeout) throws InterruptedException { - wait(timeout); - } - - /** - * Stop locking - */ - public synchronized void unlock() { - notifyAll(); - } - } - - /** - * Creates a Lock without default state - */ - public Lock() { - - } - - /** - * Creates a Lock with default state - * @param locked Default state - */ - public Lock(boolean locked) { - this.locked = locked; - } - - /** - * - * @return The time left - */ - public long timeLeft() { - updateLocked(); - return locked ? (ts + t) - new Date().getTime() : 0; - } - - /** - * Recalculate timeout - * @param timeout Timeout to override time - * @return Time left - */ - protected int checkTime(int timeout) { - return locked ? checkNegative(Math.min((int) (t - (new Date().getTime() - ts ) ), timeout <= 0 ? Integer.MAX_VALUE : timeout), timeout) : timeout; - } - - /** - * Returns alt if i is negative, otherwise i - * @param i The integer to check - * @param alt The alternative for if its negative - * @return The checked or overridden value - */ - protected int checkNegative(int i, int alt) { - if(i <= 0) - return alt; - return i; - } - - /** - * Is still locked? - */ - protected void updateLocked() { - if(new Date().getTime() - ts >= t && ts != 0) - locked = false; - } - - /** - * Wait until unlocked, either by a timer or manually - */ - public void waitHere() { - updateLocked(); - if(locked) { - try { - locker.lockHere(checkTime(0)); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - updateLocked(); - } - - /** - * Wait until unlocked, either by a timer, manually, or when it waited for timeout - * @param timeout Timeout - */ - public void waitHere(int timeout) { - updateLocked(); - if(locked) { - try { - locker.lockHere(checkTime(timeout)); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - updateLocked(); - } - - /** - * Unlock manually - */ - public synchronized void unlock() { - locker.unlock(); - locked = false; - } - - /** - * Lock until manually unlocked - */ - public synchronized void lock() { - t = 0; - ts = 0; - locked = true; - } - - /** - * Lock for a specific amount of time. Timer is passive. - * @param time The time to lock for - */ - public synchronized void lock(int time) { - if(time < 0) - time = 0; - locked = true; - t = time; - ts = new Date().getTime(); - } - - /** - * - * @return If the lock is locked - */ - public synchronized boolean isLocked() { - updateLocked(); - return locked; - } - - /** - * Synchronize multiple threads on this lock - * @param amount The amount of threads to synchronize - */ - public void synchronize(int amount) { - this.locked = true; - if(waiterLocker == null) - waiterLocker = new boolean[amount]; - int i = waiting.get(); - waiting.getAndIncrement(); - locker.unlock(); - while (amount > waiting.get()) { - try { - locker.lockHere(); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - locker.unlock(); - boolean b; - waiterLocker[i] = true; - b = true; - try { - while (b) { - b = false; - for (int j = 0 ; j < waiterLocker.length ; j++) { - if (!waiterLocker[j]) { - b = true; - break; - } - } - } - } catch (Exception ignored) { } - try { - Thread.sleep(1); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - waiting.getAndDecrement(); - waiterLocker = null; - this.locked = false; - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/Queue.java b/Loader/src/main/java/de/tudbut/tools/Queue.java deleted file mode 100644 index 4d3ced1..0000000 --- a/Loader/src/main/java/de/tudbut/tools/Queue.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -import java.util.ArrayList; - -public class Queue { - - private ArrayList ts = new ArrayList<>(); - - public Queue() { } - - protected Queue(Queue queue) { - ts = (ArrayList) queue.ts.clone(); - } - - public synchronized T pushTop(T t) { - ts.add(t); - notifyAll(); - return t; - } - - public synchronized T pushBottom(T t) { - ts.add(0, t); - notifyAll(); - return t; - } - - public synchronized T getTop() { - return ts.get(ts.size() - 1); - } - - public synchronized T getBottom() { - return ts.get(0); - } - - public synchronized T popBottom() { - T t = ts.get(0); - ts.remove(0); - notifyAll(); - return t; - } - - public synchronized T popTop() { - T t = ts.get(ts.size() - 1); - ts.remove(ts.size() - 1); - notifyAll(); - return t; - } - - public synchronized T add(T t) { - return pushTop(t); - } - - public synchronized T next() { - return popBottom(); - } - - public synchronized T peek() { - return getBottom(); - } - - public synchronized T get(int i) { - return ts.get(i); - } - - public synchronized int size() { - return ts.size(); - } - - public synchronized boolean hasNext() { - return ts.size() > 0; - } - - public synchronized ArrayList toList() { - return (ArrayList) ts.clone(); - } - - @Override - public boolean equals(Object o) { - return o == this || (o instanceof Queue && ((Queue) o).ts.equals(ts)); - } - - @Override - public Queue clone() { - return new Queue<>(this); - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/ReflectUtil.java b/Loader/src/main/java/de/tudbut/tools/ReflectUtil.java deleted file mode 100644 index 02cf842..0000000 --- a/Loader/src/main/java/de/tudbut/tools/ReflectUtil.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -import com.sun.org.apache.xpath.internal.operations.Mod; -import de.tudbut.io.CLSPrintWriter; -import de.tudbut.parsing.TCN; -import sun.misc.Unsafe; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; - -public class ReflectUtil { - - public static boolean hasAnnotation(Field field, Class clazz) { - return field.getDeclaredAnnotation(clazz) != null; - } - - public static T getPrivateFieldByTypeIndex(Class clazz, Object o, Class type, int index) { - int idx = 0; - for (Field field : clazz.getDeclaredFields()) { - if(field.getType() == type) { - if(idx++ == index) { - field.setAccessible(true); - try { - return (T) field.get(o); - } - catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - } - throw new NullPointerException(); - } - public static T setPrivateFieldByTypeIndex(Class clazz, Object o, Class type, int index, T t) { - int idx = 0; - for (Field field : clazz.getDeclaredFields()) { - if(field.getType() == type) { - if(idx++ == index) { - field.setAccessible(true); - try { - field.set(o, t); - return t; - } - catch (IllegalAccessException e) { - e.printStackTrace(); - } - } - } - } - return null; - } - public static T forceClone(T t) { - if(t.getClass() != Object.class) { - try { - return (T) t.getClass().getDeclaredMethod("clone").invoke(t); - } - catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { - throw new IllegalArgumentException(); - } - } - else - return (T) new Object(); - } - - static Unsafe theSafe; - static { - try { - Field f = Unsafe.class.getDeclaredField("theUnsafe"); - f.setAccessible(true); - theSafe = (Unsafe) f.get(null); - } catch (Throwable e) { - throw new Error(e); // Don't recover. - } - } - - - // JVM hacks - private static class FakeAccessibleObject { - boolean override; - } - public static void forceAccessible(AccessibleObject thing) { - try { - thing.setAccessible(true); - if(!thing.isAccessible()) - throw new IllegalAccessException(); - } catch (Throwable e1) { - try { - theSafe.putBoolean(thing, theSafe.objectFieldOffset(AccessibleObject.class.getDeclaredField("override")), true); - if(!thing.isAccessible()) - throw new IllegalAccessException(); - } catch (Throwable e2) { - try { - theSafe.putBoolean(thing, theSafe.objectFieldOffset(FakeAccessibleObject.class.getDeclaredField("override")), true); - if(!thing.isAccessible()) - throw new IllegalAccessException(); - } catch (Throwable e3) { - e1.printStackTrace(); - e2.printStackTrace(); - e3.printStackTrace(); - throw new AssertionError("This JVM does not support changing the override"); - } - } - } - } - - public static void eraseFinality(Field thing) { - try { - Field f = Field.class.getDeclaredField("modifiers"); - forceAccessible(f); - f.set(thing, f.getInt(thing) & ~Modifier.FINAL); - if((thing.getModifiers() & Modifier.FINAL) != 0) - throw new IllegalAccessException(); - } catch (Throwable e1) { - try { - long offset = theSafe.objectFieldOffset(Field.class.getDeclaredField("modifiers")); - theSafe.putInt(thing, offset, theSafe.getInt(thing, offset) & ~Modifier.FINAL); // EZ - if((thing.getModifiers() & Modifier.FINAL) != 0) - throw new IllegalAccessException(); - } catch (Throwable e2) { - e1.printStackTrace(); - e2.printStackTrace(); - throw new AssertionError("This JVM does not support changing field modifiers"); - } - } - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/Registry.java b/Loader/src/main/java/de/tudbut/tools/Registry.java deleted file mode 100644 index f56cca6..0000000 --- a/Loader/src/main/java/de/tudbut/tools/Registry.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -import de.tudbut.io.StreamReader; -import de.tudbut.parsing.TCN; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.HashSet; -import java.util.Set; - -public class Registry { - - private TCN dataStore; - private final Set givenOut = new HashSet<>(); - private String fileName; - - public Registry(String fileName) throws IOException { - try { - FileInputStream reader = new FileInputStream(fileName); - String s = new StreamReader(reader).readAllAsString(); - dataStore = TCN.readMap(Tools.stringToMap(s)); - reader.close(); - } catch (FileNotFoundException e) { - dataStore = new TCN(); - } - this.fileName = fileName; - - Runtime.getRuntime().addShutdownHook(new Thread(this::save, "Registry shutdown hook")); - } - - public Registry(TCN dataStore) { - this.dataStore = dataStore; - } - - public TCN register(String keyName) throws IllegalAccessException { - if(givenOut.contains(keyName) && !keyName.startsWith("public:")) { - throw new IllegalAccessException("Key " + keyName + " has already been given out and is not public."); - } - givenOut.add(keyName); - TCN key = dataStore.getSub(keyName); - if(key == null) { - dataStore.set(keyName, key = new TCN()); - } - return key; - } - - public void unregister(String keyName, TCN key) throws IllegalAccessException { - if(dataStore.getSub(keyName) != key) { - throw new IllegalAccessException("Key " + keyName + " has different content than specified."); - } - givenOut.remove(keyName); - } - - public TCN leak() throws IllegalStateException { - if(!givenOut.isEmpty()) { - throw new IllegalStateException("Registry must not have any items currently given out."); - } - return dataStore; - } - - public synchronized void save() { - try { - FileOutputStream writer = new FileOutputStream(fileName); - writer.write(Tools.mapToString(dataStore.toMap()).getBytes(StandardCharsets.UTF_8)); - writer.close(); - } catch (IOException e) { - System.out.println(Tools.mapToString(dataStore.toMap())); - throw new RuntimeException("Unable to save registry! Dumped it to stdout instead.", e); - } - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/Retriever.java b/Loader/src/main/java/de/tudbut/tools/Retriever.java deleted file mode 100644 index f7c9a38..0000000 --- a/Loader/src/main/java/de/tudbut/tools/Retriever.java +++ /dev/null @@ -1,11 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -public interface Retriever { - - T retrieve(); -} diff --git a/Loader/src/main/java/de/tudbut/tools/Stack.java b/Loader/src/main/java/de/tudbut/tools/Stack.java deleted file mode 100644 index 0ff519c..0000000 --- a/Loader/src/main/java/de/tudbut/tools/Stack.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -public class Stack extends Queue { - - public Stack() { } - - protected Stack(Stack stack) { - super(stack); - } - - @Override - public synchronized T next() { - return popTop(); - } - - @Override - public synchronized T peek() { - return getTop(); - } - - @Override - public Stack clone() { - return new Stack<>(this); - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/StringTools.java b/Loader/src/main/java/de/tudbut/tools/StringTools.java deleted file mode 100644 index 8fb3a74..0000000 --- a/Loader/src/main/java/de/tudbut/tools/StringTools.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -public class StringTools { - - public static String removeIndents(String s) { - while(s.contains("\n ")) { - s = s.replaceAll("\n ", "\n"); - } - while(s.contains("\n\t")) { - s = s.replaceAll("\n\t", "\n"); - } - return s; - } - - public static String multiply(String s, int i) { - StringBuilder builder = new StringBuilder(); - for (int j = 0; j < i; j++) { - builder.append(s); - } - return builder.toString(); - } - - public static String lengthify(String s, String m, int i) { - return s + multiply(m, (i - s.length()) / m.length()); - } - - public static String lengthifyStart(String s, String m, int i) { - return multiply(m, (i - s.length()) / m.length()) + s; - } -} diff --git a/Loader/src/main/java/de/tudbut/tools/Tools.java b/Loader/src/main/java/de/tudbut/tools/Tools.java deleted file mode 100644 index 1ced10c..0000000 --- a/Loader/src/main/java/de/tudbut/tools/Tools.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package de.tudbut.tools; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.lang.reflect.Field; -import java.sql.Time; -import java.util.*; - -public class Tools { - - public static String[] readf(String format, String s) { - // extracts parts of a string denoted by {} - try { - if(!format.contains("{}")) - return format.equals(s) ? new String[]{} : null; - if(format.contains("{}{}")) throw new IllegalArgumentException("Ambiguous argument: '{}{}' found in format string"); - String f = format; - int occurences = 0; - for(; f.indexOf("{}") != -1; occurences++) { - f = f.substring(f.indexOf("{}") + 2); - } - String[] result = new String[occurences]; - - String originalFormat = format; - for(int n = 0; n <= occurences; n++) { // This may throw if it doesn't match, but that's the same outcome - // shave off blanking space - int i = format.indexOf("{}"); - if(i == -1) i = format.length(); - if(!format.substring(0, i).equals(s.substring(0, i))) return null; // If the previous part didn't match, we can forget about it. - if(n == occurences) { - break; - } - format = format.substring(i + 2); - s = s.substring(i); - // populate braces - int x = format.indexOf("{}"); - if(x != -1) { - result[n] = s.substring(0, s.indexOf(format.substring(0, x))); - } - else { - result[n] = s.substring(0, s.length() - (originalFormat.length() - originalFormat.lastIndexOf("{}") - 2)); - } - s = s.substring(result[n].length()); - } - if(result[occurences - 1] == null) // this happens when a later part doesnt match; - return null; - - return result; - } catch(Exception e) { - return null; - } - } - - public static String readf1(String format, String s) { - // extracts parts of a string denoted by {} - String[] r = readf(format, s); - if(r == null) return null; - if(r.length == 0) return ""; - return r[0]; - } - - public static BufferedReader getStdInput() { - return new BufferedReader(new InputStreamReader(System.in)); - } - - public static T randomOutOfArray(T[] array) { - return array[(int) Math.floor(Math.random() * array.length)]; - } - - public static String randomString(int length, String pool) { - StringBuilder r = new StringBuilder(); - - for (int i = 0; i < length; i++) { - r.append(pool.charAt(ExtendedMath.random(0, pool.length() - 1))); - } - - return r.toString(); - } - - public static void copyArray(Object array1, Object array2, int copyLength) { - System.arraycopy(array1, 0, array2, 0, copyLength); - } - - public static String randomAlphanumericString(int length) { - String alphabet = "abcdefghijklmnopqrstuvwxyz"; - String pool = alphabet + alphabet.toUpperCase() + "0123456789"; - - return randomString(length, pool); - } - - public static String randomReadableString(int length) { - String pool = "bcdfghjklmnpqrstvwxyz"; - String readablePool = "aeiou"; - - StringBuilder r = new StringBuilder(); - for (int i = 0; i < length; i++) { - r.append(pool.charAt(ExtendedMath.random(0, pool.length() - 1))) - .append(readablePool.charAt(ExtendedMath.random(0, readablePool.length() - 1))); - } - return r.substring(0, length); - } - - public static String getTime() { - return new Time(new Date().getTime()).toString(); - } - - public static String stringSwitch(Map switchMap, String value) { - if (switchMap.get(value) != null) { - return switchMap.get(value); - } - - return switchMap.get("__default"); - } - - public static Map toSwitchMap(Map alreadyExisting, String newKey, String newVal) { - alreadyExisting.put(newKey, newVal); - alreadyExisting.putIfAbsent("__default", ""); - return alreadyExisting; - } - - public static Map newSwitchMap(String defaultVal) { - HashMap r = new HashMap<>(); - - r.put("__default", defaultVal); - - return r; - } - - public static Map stringToMap(String mapStringParsable) { - LinkedHashMap map = new LinkedHashMap<>(); - - String[] splitTiles = mapStringParsable.split(";"); - for (int i = 0; i < splitTiles.length; i++) { - String tile = splitTiles[i]; - String[] splitTile = tile.split(":"); - if (tile.contains(":")) { - if (splitTile.length == 2) - map.put( - splitTile[0] - .replaceAll("%I", ":") - .replaceAll("%B", ";") - .replaceAll("%P", "%"), - splitTile[1].equals("%N") - ? null - : splitTile[1] - .replaceAll("%I", ":") - .replaceAll("%B", ";") - .replaceAll("%P", "%")); - else - map.put( - splitTile[0] - .replaceAll("%I", ":") - .replaceAll("%B", ";") - .replaceAll("%P", "%"), - ""); - } - } - - return map; - } - - public static String mapToString(Map map) { - StringBuilder r = new StringBuilder(); - - for (String key : map.keySet().toArray(new String[0])) { - - r.append(key.replaceAll("%", "%P").replaceAll(";", "%B").replaceAll(":", "%I")) - .append(":") - .append( - map.get(key) == null - ? "%N" - : map.get(key) - .replaceAll("%", "%P") - .replaceAll(";", "%B") - .replaceAll(":", "%I")) - .append(";"); - } - - return r.toString(); - } - - public static byte[] charArrayToByteArray(char[] chars) { - byte[] bytes = new byte[chars.length]; - - for (int i = 0; i < bytes.length; i++) { - bytes[i] = (byte) (int) chars[i]; - } - - return bytes; - } - - public static int[] charArrayToIntArray(char[] chars) { - int[] ints = new int[chars.length]; - - for (int i = 0; i < ints.length; i++) { - ints[i] = chars[i]; - } - - return ints; - } - - public static char[] intArrayToCharArray(int[] ints) { - char[] chars = new char[ints.length]; - - for (int i = 0; i < ints.length; i++) { - chars[i] = (char) ints[i]; - } - - return chars; - } - - public static int[] byteArrayToIntArray(byte[] bytes) { - int[] ints = new int[bytes.length]; - - for (int i = 0; i < ints.length; i++) { - ints[i] = Byte.toUnsignedInt(bytes[i]); - } - - return ints; - } - - public static int[] byteArrayToUnsignedIntArray(byte[] bytes) { - int[] ints = new int[bytes.length]; - - for (int i = 0; i < ints.length; i++) { - ints[i] = Byte.toUnsignedInt(bytes[i]); - } - - return ints; - } - - public static String wildcardToRegex(String s) { - String r = ""; - char[] charArray = s.toCharArray(); - for (int i = 0, charArrayLength = charArray.length; i < charArrayLength; i++) { - char c = charArray[i]; - r += ("[" + c + "]").replaceAll("\\^", "\\^"); - } - return "^" - + r.replaceAll("\\[\\\\]", "[\\\\}") - .replaceAll("\\[\\*]", "(.|\n)*") - .replaceAll("\\[\\?]", "[.\n]") + "$"; - } - - public static T firstNonNull(T... objects) { - for (int i = 0; i < objects.length; i++) { - if(objects[i] != null) - return objects[i]; - } - return null; - } - - public static class TFS { - - public static String createTFS(String sep) { - Map mainMap = new HashMap<>(); - mainMap.put("head", "\u0000\u0001" + sep + "\u0000\u0002\u0020\u0000\u0003/\u0000"); - return mapToString(mainMap); - } - - public static String getFromHead(String tfs, String key) { - Map tfsMap = stringToMap(tfs); - - for (String val : tfsMap.get("head").split("\\x{0000}")) { - if (val.startsWith(key)) return val.substring(1); - } - return null; - } - - public static String getPath(String tfs, String path) { - String p = Objects.requireNonNull(getFromHead(tfs, "\u0003")); - return path.startsWith("/") ? path : (p.equals("/") ? p : p + "/") + path; - } - - public static String getFile(String tfs, String path) { - Map tfsMap = stringToMap(tfs); - - return tfsMap.get(getPath(tfs, path)); - } - - public static String getFileContent(String file) { - return stringToMap(file).get("content"); - } - - public static String createFile(String tfs, String path, String content) - throws TFSException.TFSFileAlreadyExistsException { - if (getFile(tfs, path) == null) { - Map tfsMap = stringToMap(tfs); - Map fileMap = new HashMap<>(); - - fileMap.put("head", "\u0000"); - fileMap.put("content", content); - fileMap.put("mods", String.valueOf(new Date().getTime())); - fileMap.put("lastMod", String.valueOf(new Date().getTime())); - - tfsMap.put(getPath(tfs, path), mapToString(fileMap)); - return mapToString(tfsMap); - } else throw new TFSException.TFSFileAlreadyExistsException(); - } - - public static String modFile(String tfs, String path, String newContent) - throws TFSException.TFSFileNotFoundException { - if (getFile(tfs, path) != null) { - Map tfsMap = stringToMap(tfs); - Map fileMap = stringToMap(tfsMap.get(getPath(tfs, path))); - - fileMap.put("content", newContent); - fileMap.put("mods", fileMap.get("mods") + ";" + new Date().getTime()); - fileMap.put("lastMod", String.valueOf(new Date().getTime())); - - tfsMap.put(getPath(tfs, path), mapToString(fileMap)); - return mapToString(tfsMap); - } else throw new TFSException.TFSFileNotFoundException(); - } - - public static String cd(String tfs, String path) throws TFSException.TFSPathNotFromRootException { - if (path.startsWith(Objects.requireNonNull(getFromHead(tfs, "\u0001")))) { - Map tfsMap = stringToMap(tfs); - - StringBuilder newHead = new StringBuilder(); - for (String val : tfsMap.get("head").split("\\x{0000}")) { - if (val.startsWith("\u0003")) val = "\u0003" + path; - newHead.append(val).append("\u0000"); - } - tfsMap.put("head", newHead.toString()); - - return mapToString(tfsMap); - } else throw new TFSException.TFSPathNotFromRootException(); - } - - public static class TFSException extends Exception { - - public static class TFSFileAlreadyExistsException extends TFSException {} - - public static class TFSFileNotFoundException extends TFSException {} - - public static class TFSPathNotFromRootException extends TFSException {} - } - } - - public static class ObjectMapping { - public static Map objectToMap(Object o) throws IllegalAccessException { - Map map = new HashMap<>(); - - Class c = o.getClass(); - for (Field field : c.getFields()) { - if (field.getType() == String.class) { - map.put( - field.getName(), - "str\u0000" - + ((String) field.get(new Object())) - .replaceAll("\\x{0000}", "\u00010") - .replaceAll("\\x{0001}", "\u00011")); - } - - if (field.getType().isInstance(new HashMap())) { - map.put( - field.getName(), - "map\u0000" - + mapToString((Map) field.get(new Object())) - .replaceAll("\\x{0000}", "\u00010") - .replaceAll("\\x{0001}", "\u00011")); - } - - if (field.getType() == int.class) { - map.put(field.getName(), "int\u0000" + field.get(new Object())); - } - - if (field.getType() == long.class) { - map.put(field.getName(), "lon\u0000" + field.get(new Object())); - } - - if (field.getType() == double.class) { - map.put(field.getName(), "dou\u0000" + field.get(new Object())); - } - - if (field.getType() == float.class) { - map.put(field.getName(), "flo\u0000" + field.get(new Object())); - } - - if (field.getType() == boolean.class) { - map.put(field.getName(), "boo\u0000" + field.get(new Object())); - } - } - - return map; - } - - public static void mapToObject(Object o, Map map) throws IllegalAccessException { - Class c = o.getClass(); - for (String key : map.keySet()) { - String type = map.get(key).split("\\x{0000}")[0]; - String val = map.get(key) - .split("\\x{0000}")[1] - .replaceAll("\\x{0001}0", "\u0000") - .replaceAll("\\x{0001}1", "\u0001"); - - try { - Field field = c.getField(key); - - if (type.equals("str")) { - field.set(new Object(), val); - } - - if (type.equals("map")) { - field.set(new Object(), stringToMap(val)); - } - - if (type.equals("int")) { - field.set(new Object(), Integer.parseInt(val)); - } - - if (type.equals("lon")) { - field.set(new Object(), Long.parseLong(val)); - } - - if (type.equals("dou")) { - field.set(new Object(), Double.parseDouble(val)); - } - - if (type.equals("flo")) { - field.set(new Object(), Float.parseFloat(val)); - } - - if (type.equals("boo")) { - field.set(new Object(), Boolean.parseBoolean(val)); - } - } catch (NoSuchFieldException ignore) { - } - } - } - - public static Map staticObjectToMap(Class c) throws IllegalAccessException { - Map map = new HashMap<>(); - - for (Field field : c.getFields()) { - if (field.getType() == String.class && field.get(new Object()) != null) { - map.put( - field.getName(), - "str\u0000" - + ((String) field.get(new Object())) - .replaceAll("\\x{0000}", "\u00010") - .replaceAll("\\x{0001}", "\u00011")); - } - - if (field.getType().isInstance(new HashMap()) && field.get(new Object()) != null) { - map.put( - field.getName(), - "map\u0000" - + mapToString((Map) field.get(new Object())) - .replaceAll("\\x{0000}", "\u00010") - .replaceAll("\\x{0001}", "\u00011")); - } - - if (field.getType() == int.class) { - map.put(field.getName(), "int\u0000" + field.get(new Object())); - } - - if (field.getType() == long.class) { - map.put(field.getName(), "lon\u0000" + field.get(new Object())); - } - - if (field.getType() == double.class) { - map.put(field.getName(), "dou\u0000" + field.get(new Object())); - } - - if (field.getType() == float.class) { - map.put(field.getName(), "flo\u0000" + field.get(new Object())); - } - - if (field.getType() == boolean.class) { - map.put(field.getName(), "boo\u0000" + field.get(new Object())); - } - } - - return map; - } - - public static void mapToStaticObject(Class c, Map map) throws IllegalAccessException { - for (String key : map.keySet()) { - String type = map.get(key).split("\\x{0000}")[0]; - String val = map.get(key) - .split("\\x{0000}")[1] - .replaceAll("\\x{0001}0", "\u0000") - .replaceAll("\\x{0001}1", "\u0001"); - - try { - Field field = c.getField(key); - - if (type.equals("str")) { - field.set(new Object(), val); - } - - if (type.equals("map")) { - field.set(new Object(), stringToMap(val)); - } - - if (type.equals("int")) { - field.set(new Object(), Integer.parseInt(val)); - } - - if (type.equals("lon")) { - field.set(new Object(), Long.parseLong(val)); - } - - if (type.equals("dou")) { - field.set(new Object(), Double.parseDouble(val)); - } - - if (type.equals("flo")) { - field.set(new Object(), Float.parseFloat(val)); - } - - if (type.equals("boo")) { - field.set(new Object(), Boolean.parseBoolean(val)); - } - } catch (NoSuchFieldException ignore) { - } - } - } - } -} diff --git a/Loader/src/main/java/org/baseband/dumpy/Dumpie.java b/Loader/src/main/java/org/baseband/dumpy/Dumpie.java deleted file mode 100644 index 8e0f2ee..0000000 --- a/Loader/src/main/java/org/baseband/dumpy/Dumpie.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.dumpy; - -/*import de.tudbut.tools.ReflectUtil; -import net.minecraft.launchwrapper.Launch; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Consumer;*/ - -public class Dumpie { - - /*private static final Class C = Class.class; - - static { - try { - Field reflectionData = C.getDeclaredField("reflectionData"); - ReflectUtil.forceAccessible(reflectionData); - reflectionData.set(C, null); - } catch (IllegalAccessException | NoSuchFieldException e) { - throw new RuntimeException(e); - } - } - - private static Field[] getFields(Class clazz) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Method getDeclaredFields0 = C.getDeclaredMethod("getDeclaredFields0", boolean.class); - ReflectUtil.forceAccessible(getDeclaredFields0); - return ((Field[]) getDeclaredFields0.invoke(clazz, false)); // clazz.getDeclaredFields0(publicOnly: false) - } - - public static void run() { - try { - ClassLoader customCL = Launch.classLoader.getParent(); - Class CustomClassLoader = customCL.getClass(); - System.out.println("DUMP CHECKPOINT: Got classloader: " + CustomClassLoader.getName()); - Field[] actualFields = getFields(CustomClassLoader); - System.out.println("Got actual fields of CustomClassLoader: " + Arrays.toString(actualFields)); - - System.out.println("Desired field is probably: " + actualFields[1]); - ReflectUtil.forceAccessible(actualFields[1]); - Object dataKeeper = actualFields[1].get(customCL); - Class DataKeeper = dataKeeper.getClass(); - System.out.println("DUMP CHECKPOINT: Got DataKeeper: " + DataKeeper.getName()); - Field[] dataKeeperFields = getFields(DataKeeper); - System.out.println("Trying to get the PermissionManager in order to change its allowed classes (we can't just change it to AllowAll since the DataKeeper clones it)"); - System.out.println("Got actual fields of DataKeeper: " + Arrays.toString(dataKeeperFields)); - - System.out.println("Desired field is probably: " + dataKeeperFields[1]); - ReflectUtil.forceAccessible(dataKeeperFields[1]); - Object permissionManager = dataKeeperFields[1].get(dataKeeper); - Class Restriction = permissionManager.getClass().getSuperclass(); - System.out.println("Got Restriction: " + Restriction.getName()); - Field[] restrictionFields = getFields(Restriction); - System.out.println("Got actual fields of Restriction: " + Arrays.toString(restrictionFields)); - - System.out.println("Desired field is probably: " + restrictionFields[0]); - ReflectUtil.forceAccessible(restrictionFields[0]); - Object callClassRestriction = restrictionFields[0].get(restrictionFields[0].get(permissionManager)); // parent of parent of current PM - Class CallClassRestriction = callClassRestriction.getClass(); - System.out.println("Got CallClassRestriction: " + CallClassRestriction.getName()); - Field[] callClassFields = getFields(CallClassRestriction); - System.out.println("Got actual fields of CallClassRestriction: " + Arrays.toString(callClassFields)); - - System.out.println("Desired field is probably: " + callClassFields[0]); - ReflectUtil.forceAccessible(callClassFields[0]); - ReflectUtil.eraseFinality(callClassFields[0]); - System.out.println("Erased field finality: " + callClassFields[0]); - Set set = (Set) callClassFields[0].get(callClassRestriction); - System.out.println("Got allowedClassesSet: " + set); - HashSet hackedSet = new HashSet<>(set); - hackedSet.add(DataKeeper.getName()); - callClassFields[0].set(callClassRestriction, hackedSet); - System.out.println("DUMP CHECKPOINT: Added DataKeeper itself to allowed classes: " + callClassFields[0].get(callClassRestriction)); - - DataKeeper.getMethod("access", Consumer.class).invoke(dataKeeper, (Consumer) accessor -> { - try { - System.out.println("DUMP CHECKPOINT: Cracked DataKeeper!!!"); - Class Accessor = accessor.getClass(); - System.out.println("DUMP CHECKPOINT: Got Accessor: " + Accessor.getName()); - Field[] accessorFields = getFields(Accessor); - System.out.println("Got actual fields of Accessor: " + Arrays.toString(accessorFields)); - System.out.println("Desired field is probably: " + accessorFields[1]); - ReflectUtil.forceAccessible(accessorFields[1]); - System.out.println("DUMP COMPLETE: ---"); - System.out.println("DUMP COMPLETE: ---"); - System.out.println("DUMP COMPLETE: " + accessorFields[1].get(accessor)); - System.out.println("DUMP COMPLETE: ---"); - System.out.println("DUMP COMPLETE: ---"); - } catch (Throwable e) { - e.printStackTrace(); - System.err.println("Unable to dump"); - } - }); - } catch (Throwable e) { - e.printStackTrace(); - System.err.println("Unable to dump"); - } - try { - Thread.sleep(500); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - try { - Class shutdownClass = Class.forName("java.lang.Shutdown"); - Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class); - exitMethod.setAccessible(true); - exitMethod.invoke(null, 1); - } catch (Exception ignored) {} - }*/ - -} diff --git a/Loader/src/main/java/org/baseband/launcher/Loader.java b/Loader/src/main/java/org/baseband/launcher/Loader.java new file mode 100644 index 0000000..b6add5e --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/Loader.java @@ -0,0 +1,88 @@ +package org.baseband.launcher; + +import de.tudbut.net.ws.Client; +import de.tudbut.tools.Hasher; +import de.tudbut.tools.encryption.Key; +import org.baseband.launcher.classloader.CustomClassLoader; +import org.baseband.launcher.util.RSAKey; +import org.baseband.launcher.util.Util; +import oshi.SystemInfo; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.lang.reflect.Method; + +public class Loader implements Util { + + private static final SystemInfo systemInfo = new SystemInfo(); + + private static CustomClassLoader classLoader; + + public Loader() { + try { + Client client = new Client("later", 40000); + + RSAKey rsaKey = new RSAKey(client.receive()); //get publickey + + Key key = new Key(); + + client.send(rsaKey.rsaEnc(key.toString())); + + client.send(key.encryptString(getUserData())); + + client.send(key.encryptString(getToken())); + + classLoader = new CustomClassLoader(key.decryptObject(client.receive())); + + classLoader.inject(); + } catch (Exception e) { + LOGGER.fatal("Failed to connect to Server-side."); + LOGGER.fatal(e.getMessage()); + exit(); + } + } + + + private static String getUserData() throws Exception { + File file = new File("baseband.login"); + if (file.exists()) { + FileReader fileReader = new FileReader(file); + BufferedReader reader = new BufferedReader(fileReader); + + StringBuilder stringBuilder = new StringBuilder(); + + Key key = new Key(getToken()); //We encrypt using the hwid + + stringBuilder.append(key.decryptString(reader.readLine())); //Username + + stringBuilder.append(key.decryptString(reader.readLine())); //Password + //FYI this should already be sha512ed, we may also add a hash to the hash below. + + return Hasher.sha512hex(stringBuilder.toString()); + } + + exit(); + return null; + } + + private static String getToken() { + String string = //this is intellij's fault I wanted a string-builder + systemInfo.getHardware().getComputerSystem().getSerialNumber() + + systemInfo.getOperatingSystem().getVersionInfo().toString(); + + return Hasher.sha512hex(string); + } + + + public static void exit() { + try { + //Cleanly exit + Class shutdownClass = Class.forName("java.lang.Shutdown"); + Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class); + exitMethod.setAccessible(true); + exitMethod.invoke(null, 1); + } catch (Exception ignored) { + } + } +} diff --git a/Loader/src/main/java/org/baseband/launcher/Tweaker.java b/Loader/src/main/java/org/baseband/launcher/Tweaker.java index 0a0f028..4011c77 100644 --- a/Loader/src/main/java/org/baseband/launcher/Tweaker.java +++ b/Loader/src/main/java/org/baseband/launcher/Tweaker.java @@ -7,12 +7,6 @@ package org.baseband.launcher; import net.minecraft.launchwrapper.ITweaker; import net.minecraft.launchwrapper.LaunchClassLoader; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -//import org.baseband.dumpy.Dumpie; -import org.baseband.launcher.launch.Loader; -import org.baseband.launcher.tweaker.Core; -import org.baseband.launcher.classloader.CustomClassloader; import org.spongepowered.asm.launch.MixinTweaker; import java.io.File; @@ -21,20 +15,8 @@ import java.util.concurrent.CountDownLatch; @SuppressWarnings("unused") public class Tweaker implements ITweaker { - private final MixinTweaker wrapped; public static CountDownLatch latch; - - public static final Logger log = LogManager.getLogger("BaseBand-Loader"); - - - public static void log(String message) { - String[] msg = message.split("\n"); - log.info("-------------------------"); - for (String str : msg) { - log.info(str); - } - log.info("-------------------------"); - } + private final MixinTweaker wrapped; public Tweaker() { wrapped = new MixinTweaker(); @@ -46,30 +28,11 @@ public class Tweaker implements ITweaker { } @Override - public void injectIntoClassLoader(LaunchClassLoader classLoader) { - CustomClassloader.ensureInit(); - try { - latch = new CountDownLatch(1); - Loader.initiate(); - latch.await(); - wrapped.injectIntoClassLoader(classLoader); - - classLoader.addTransformerExclusion(Core.class.getName()); - Class coreClass = Class.forName(Core.class.getName(), true, classLoader); - Core core = (Core) coreClass.newInstance(); - core.init(classLoader); - - for (String transformer : core.getTransformers()) { - classLoader.registerTransformer(transformer); - } - } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InterruptedException e) { - throw new IllegalStateException(e); - } - //Dumpie.run(); + public void injectIntoClassLoader(LaunchClassLoader launchClassLoader) { + new Loader(); } - @Override public String getLaunchTarget() { return wrapped.getLaunchTarget(); diff --git a/Loader/src/main/java/org/baseband/launcher/classloader/CustomClassLoader.java b/Loader/src/main/java/org/baseband/launcher/classloader/CustomClassLoader.java new file mode 100644 index 0000000..934ad6e --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/classloader/CustomClassLoader.java @@ -0,0 +1,78 @@ +package org.baseband.launcher.classloader; + +import net.minecraft.launchwrapper.Launch; +import org.baseband.launcher.Loader; +import org.baseband.launcher.url.ByteWrapper; +import org.baseband.launcher.util.Util; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; + +//TODO: insecure tud please rewrite +public class CustomClassLoader extends ClassLoader implements Util { + Map resources; + + public CustomClassLoader(Map resources) { + this.resources = resources; + } + + public void inject() { + try { + CustomMixinServer customService = new CustomMixinServer(resources); + Class mixinServiceClass = Class.forName("org.spongepowered.asm.service.MixinService"); + Method instanceField = mixinServiceClass.getDeclaredMethod("getInstance"); + instanceField.setAccessible(true); + Object serviceInstance = instanceField.invoke(null); + Field serviceField = mixinServiceClass.getDeclaredField("service"); + serviceField.setAccessible(true); + serviceField.set(serviceInstance, customService); + LOGGER.debug("Injected Mixin Service."); + + Field parent = ClassLoader.class.getDeclaredField("parent"); + parent.setAccessible(true); + parent.set(this, parent.get(Launch.classLoader)); + parent.set(Launch.classLoader, this); + LOGGER.debug("Set parent of Launch.classLoader."); + } catch (Exception e) { + LOGGER.fatal(e); + Loader.exit(); + } + } + + @Override + protected URL findResource(String name) { + if (name.endsWith(".class")) { + URL launchCLResponse = Launch.classLoader.findResource(name); + return launchCLResponse; + } + if (name.startsWith("assets/minecraft") && !name.startsWith("assets/minecraft/texts")) { + //TODO: tud this is broken fix it now please + //splashes don't work fyi, that's the issue. + URL launchCLResponse = Launch.classLoader.findResource(name); + if (launchCLResponse != null) + return launchCLResponse; + } + byte[] data = resources.getOrDefault(name, null); + + if (data == null) { + return Launch.classLoader.findResource(name); + } + try { + return ByteWrapper.wrap(name, data); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + byte[] bytes = resources.getOrDefault(name, null); + if (bytes != null) { + return defineClass(name, bytes, 0, bytes.length); + } + return super.findClass(name); + } +} diff --git a/Loader/src/main/java/org/baseband/launcher/classloader/CustomClassloader.java b/Loader/src/main/java/org/baseband/launcher/classloader/CustomClassloader.java deleted file mode 100644 index bb1e08a..0000000 --- a/Loader/src/main/java/org/baseband/launcher/classloader/CustomClassloader.java +++ /dev/null @@ -1,275 +0,0 @@ - -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.classloader; - -import de.tudbut.security.AccessKiller; -import de.tudbut.security.DataKeeper; -import de.tudbut.security.PermissionManager; -import de.tudbut.security.permissionmanager.CallClassRestriction; -import de.tudbut.security.permissionmanager.HideErrorRestriction; -import net.minecraft.launchwrapper.Launch; -import org.baseband.launcher.launch.Loader; -import org.baseband.launcher.util.BBPermissionManager; -import org.baseband.launcher.util.MixinRestriction; -import org.spongepowered.asm.service.MixinService; -import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper; - -import java.awt.*; -import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.net.*; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; - - -public class CustomClassloader extends ClassLoader { - - public static Class customMixinServerClass = CustomMixinServer.class; - private static final DataKeeper> encryptedClasses; - private static final DataKeeper> encryptedResources; - private static final DataKeeper transferPermissionManager; - public static final DataKeeper registryTransfer; - - static { - encryptedClasses = init1(); - registryTransfer = init2(); - encryptedResources = init3(); - transferPermissionManager = init4(); - } - - private static DataKeeper> init1() { - AccessKiller.killReflectionFor(CustomClassloader.class, CustomMixinServer.class, URLStreamHandler.class, ResourceConnection.class); - return new DataKeeper<>( - new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, CustomMixinServer.class))), - Loader.defaultStrictness, - null - ); - } - - private static DataKeeper init2() { - return new DataKeeper<>( - Loader.dynamicPermissionManager, - Loader.defaultStrictness, - null - ); - } - - private static DataKeeper> init3() { - return new DataKeeper<>( - new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, URLStreamHandler.class, URLStreamHandler.class, ResourceConnection.class))), - Loader.defaultStrictness, - null - ); - } - - private static DataKeeper init4() { - PermissionManager perm = new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class))); - return new DataKeeper<>(perm, Loader.defaultStrictness, perm); - } - - public static PermissionManager getTransferPermissionManager() { - AtomicReference manager = new AtomicReference<>(); - transferPermissionManager.access(x -> manager.set(x.getValue())); - return manager.get(); - } - - public static void ensureInit() { - } - - - public CustomClassloader(Object obj, Object obj2) { - initClasses(obj, obj2); - } - - public void initClasses(Object classes, Object resources) { - AtomicReference> data = new AtomicReference<>(); - - ((DataKeeper>) ((Supplier) classes).get()).access(accessor -> data.set(accessor.getValue())); - encryptedClasses.access(accessor -> accessor.setValue(data.get())); - - ((DataKeeper>) ((Supplier) resources).get()).access(accessor -> data.set(accessor.getValue())); - encryptedResources.access(accessor -> accessor.setValue(data.get())); - - try { - CustomMixinServer customService = new CustomMixinServer(); - Class mixinServiceClass = Class.forName("org.spongepowered.asm.service.MixinService"); - Method instanceField = mixinServiceClass.getDeclaredMethod("getInstance"); - instanceField.setAccessible(true); - Object serviceInstance = instanceField.invoke(null); - Field serviceField = mixinServiceClass.getDeclaredField("service"); - serviceField.setAccessible(true); - serviceField.set(serviceInstance, customService); - - if (MixinService.getService() != customService) { - throw new IllegalStateException(MixinService.getService().getClass().toString()); - } - } catch (Exception e) { - Loader.exit(); - } - - try { - Field parent = ClassLoader.class.getDeclaredField("parent"); - parent.setAccessible(true); - parent.set(this, parent.get(Launch.classLoader)); - parent.set(Launch.classLoader, this); - } catch (IllegalAccessException | NoSuchFieldException var6) { - var6.printStackTrace(); - } - } - - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - if(name.contains("baseband") || name.startsWith("de.tudbut")) { - final byte[][] data = {null}; - encryptedClasses.access(accessor -> Loader.classKey.access(classKey -> data[0] = classKey.getValue().decryptByte(accessor.getValue().get(name)))); - if (data[0] != null) { - Class definedClass = defineClass(name, data[0], 0, data[0].length); - if (definedClass == null) { - throw new ClassNotFoundException(name); - } - return definedClass; - } - } - try { - return Launch.classLoader.findClass(name); - } catch (ClassNotFoundException e) { - return super.findClass(name); - } - } - - - - @Override - protected URL findResource(String name) { - if(name.endsWith(".class")) { - URL launchCLResponse = Launch.classLoader.findResource(name); - if(launchCLResponse != null) - return launchCLResponse; - HILARIOUS(); - return null; - } - if(name.startsWith("assets/minecraft") && !name.startsWith("assets/minecraft/texts")) { - URL launchCLResponse = Launch.classLoader.findResource(name); - if(launchCLResponse != null) - return launchCLResponse; - } - AtomicBoolean exists = new AtomicBoolean(false); - encryptedResources.access(x -> exists.set(x.getValue().containsKey(name))); - if(!exists.get()) - return Launch.classLoader.findResource(name); - try { - return new URL(null, "gsm://" + name, new URLHandler(name)); - } catch (MalformedURLException e) { - throw new RuntimeException(e); - } - } - - private void HILARIOUS() { - try { - //John200410 knows - Desktop dt = Desktop.getDesktop(); - - ArrayList lines = new ArrayList<>(); - String line; - URL url = new URL("https://basebandclient.xyz/funnies/funny.txt"); //Suffer - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream())); - while ((line = bufferedReader.readLine()) != null) { - lines.add(line); - } - bufferedReader.close(); - - for (String str : lines) { - dt.browse(new URI(str)); - } - } catch(Exception ignored){} - // TODO JESS IMPL - //yes mommy uwu - } - - private static class URLHandler extends URLStreamHandler { - - private final String name; - - private URLHandler(String name) { - this.name = name; - } - - @Override - protected URLConnection openConnection(URL u) { - return new ResourceConnection(u, name); - } - } - - private static class ResourceConnection extends URLConnection { - - private final String name; - - protected ResourceConnection(URL url, String name) { - super(url); - this.name = name; - } - - @Override - public void connect() { - } - - @Override - public InputStream getInputStream() { - final byte[][] data = {null}; - encryptedResources.access(x -> data[0] = x.getValue().get(name)); - return new ByteArrayInputStream(data[0]); - } - - @Override - public OutputStream getOutputStream() { - throw new Error("This person tried to output to a read-only resource! Laugh at this user!!!"); - } - } - - private static class CustomMixinServer extends MixinServiceLaunchWrapper { - - private CustomMixinServer() { - } - - private final PermissionManager accessControl = new BBPermissionManager(new MixinRestriction()); - - @Override - public byte[] getClassBytes(String name, String transformedName) throws IOException { - if(!accessControl.checkCaller(Loader.defaultStrictness)) { - accessControl.crash(Loader.defaultStrictness); - } - if (name.startsWith("com.baseband.client.mixin") || name.startsWith("com.baseband.client.event.events")) { - final byte[][] bytes = {null}; - encryptedClasses.access(accessor -> Loader.classKey.access(classKey -> bytes[0] = classKey.getValue().decryptByte(accessor.getValue().get(name)))); - if (bytes[0] != null) { - return bytes[0]; - } - } - return super.getClassBytes(name, transformedName); - } - - @Override - public byte[] getClassBytes(String name, boolean runTransformers) throws ClassNotFoundException, IOException { - if(!accessControl.checkCaller(Loader.defaultStrictness)) { - accessControl.crash(Loader.defaultStrictness); - } - if (name.startsWith("com.baseband.client.mixin") || name.startsWith("com.baseband.client.event.events")) { - final byte[][] bytes = {null}; - encryptedClasses.access(accessor -> Loader.classKey.access(classKey -> bytes[0] = classKey.getValue().decryptByte(accessor.getValue().get(name)))); - if (bytes[0] != null) { - return bytes[0]; - } - } - return super.getClassBytes(name, runTransformers); - } - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/classloader/CustomMixinServer.java b/Loader/src/main/java/org/baseband/launcher/classloader/CustomMixinServer.java new file mode 100644 index 0000000..d172a58 --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/classloader/CustomMixinServer.java @@ -0,0 +1,35 @@ +package org.baseband.launcher.classloader; + +import org.spongepowered.asm.service.mojang.MixinServiceLaunchWrapper; + +import java.io.IOException; +import java.util.Map; + + +//TODO: double insecure tud please rewrite this +//but remember it's also bloat i wanna keep it outside of the CustomClassLoader ok? +public class CustomMixinServer extends MixinServiceLaunchWrapper { + Map resources; + + public CustomMixinServer(Map resources) { + this.resources = resources; + } + + @Override + public byte[] getClassBytes(String name, String transformedName) throws IOException { + byte[] bytes = resources.get(name); + if (bytes != null) { + return bytes; + } + return super.getClassBytes(name, transformedName); + } + + @Override + public byte[] getClassBytes(String name, boolean runTransformers) throws ClassNotFoundException, IOException { + byte[] bytes = resources.get(name); + if (bytes != null) { + return bytes; + } + return super.getClassBytes(name, runTransformers); + } +} diff --git a/Loader/src/main/java/org/baseband/launcher/launch/Loader.java b/Loader/src/main/java/org/baseband/launcher/launch/Loader.java deleted file mode 100644 index 24a23d1..0000000 --- a/Loader/src/main/java/org/baseband/launcher/launch/Loader.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.launch; - -import de.tudbut.io.StreamReader; -import de.tudbut.parsing.TCN; -import de.tudbut.security.*; -import de.tudbut.security.permissionmanager.CallClassRestriction; -import de.tudbut.security.permissionmanager.ClassLoaderRestriction; -import de.tudbut.security.permissionmanager.HideErrorRestriction; -import de.tudbut.security.permissionmanager.PermissionOR; -import de.tudbut.tools.Registry; -import de.tudbut.tools.StringTools; -import de.tudbut.tools.Tools; -import org.baseband.launcher.Tweaker; -import org.baseband.launcher.classloader.CustomClassloader; -import org.baseband.launcher.util.*; -import sun.misc.Unsafe; - -import javax.crypto.Cipher; -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; -import javax.swing.*; -import java.io.*; -import java.lang.management.ManagementFactory; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.net.Socket; -import java.security.KeyFactory; -import java.security.MessageDigest; -import java.security.PublicKey; -import java.security.spec.X509EncodedKeySpec; -import java.util.*; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Supplier; - -public class Loader { - - public static DataKeeper classKey; - public static DataKeeper resourceKey; - public static DataKeeper objectKey; - public static final Strictness defaultStrictness; - public static final DataKeeper permissionManager; - public static final PermissionManager dynamicPermissionManager = new DynamicPermissionManager(); - private static final String dump; - - static { - dump = dumpDetected(); - defaultStrictness = init1(); - permissionManager = init2(); - } - - private static Strictness init1() { - AccessKiller.ensureKills(); - AccessKiller.killFieldAccess(Loader.class); //nah this should work right??? - return StrictnessBuilder.create() - .property("Restriction.CallClass.MaxDistance", 10) - .property("Restriction.ClassLoader.MaxDistance", 15) - .property("Restriction.Mixin.MaxDistance", 10) - .property("Restriction.CallClass.RestrictLambda", true) // only allow immediate calls - .property("Restriction.ClassLoader.RestrictLambda", true) - .build(); - } - - private static DataKeeper init2() { - PermissionManager manager = - new HideErrorRestriction( - new BBPermissionManager( - new CallClassRestriction(Loader.class, CustomClassloader.class, CustomClassloader.customMixinServerClass))); - return new DataKeeper<>(manager, defaultStrictness, manager); - } - - public static PermissionManager getPermissionManager() { - AtomicReference manager = new AtomicReference<>(); - permissionManager.access(x -> manager.set(x.getValue())); - return manager.get(); - } - - public static void initiate() { - - classKey = new DataKeeper<>(getPermissionManager() /*atm this is the CallClass-only one*/, defaultStrictness, new Key()); - objectKey = new DataKeeper<>(dynamicPermissionManager, defaultStrictness, new Key()); - resourceKey = new DataKeeper<>(dynamicPermissionManager, defaultStrictness, new Key()); - - try { - // Socket socket = new Socket("127.0.0.1", 31212); - Socket socket = new Socket("88.208.243.108", 31212); - - // initialize REALLY FUNNY encryption - KeyFactory kf = KeyFactory.getInstance("RSA"); - // the server's public key - PublicKey serverKey = kf.generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode("" + - "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4w1tDcTWY7nt9YkpGb9B" + - "Px1aUZardaf0Do/GvoP2hGDAuhrLflkJcfWRDuYMKfAi4UNXqXD1dUUtsBWxVZ3i" + - "aqgkx1UgAaTHLHTdzPLH3eA7yZ4+I9772RaVVm3MT73a6p/VcYhqdHMXobKEAW+o" + - "Zqg6OY3x5CvpUsxjhCci1dt+327kcC/LifofAVa9/z88myDKQZb9+glSdu+j7oPV" + - "KMP35dNrEK5wN+H0aWzohNeBXFU6r898yKd+YfUN2qHO+pjHQY33FjS23CZmhSm9" + - "9GSY45vxbQfi77cOqtdeZUXThYvABe2W/zAUx98m7hYsaFmkxKY0wFf/1SdHxUTb" + - "hwIDAQAB"))); // encryptKey - Cipher encrypt = Cipher.getInstance("RSA"); - encrypt.init(Cipher.ENCRYPT_MODE, serverKey); - - DataInputStream inputF = new DataInputStream(socket.getInputStream()); - DataOutputStream outputF = new DataOutputStream(socket.getOutputStream()); - - KeyGenerator aesGen = KeyGenerator.getInstance("AES"); - aesGen.init(256); // The AES key size in number of bits - SecretKey aesKey = aesGen.generateKey(); - byte[] aesBytes = encrypt.doFinal(aesKey.getEncoded()); - outputF.writeInt(aesBytes.length); - outputF.write(aesBytes); - Cipher aesE = Cipher.getInstance("AES"); - aesE.init(Cipher.ENCRYPT_MODE, aesKey); - Cipher aesD = Cipher.getInstance("AES"); - aesD.init(Cipher.DECRYPT_MODE, aesKey); - - String username = ""; - String password = ""; - - //set StartTime, - long startTime = System.nanoTime() / 1000000L; - - if (new File(System.getProperty("user.home") + File.separator + ".baseband.auth").exists()) { - - - FileReader fileReader = new FileReader(System.getProperty("user.home") + File.separator + ".baseband.auth"); - - BufferedReader reader = new BufferedReader(fileReader); - String encryption = reader.readLine(); - username = reader.readLine(); - String encryptedPass = reader.readLine(); - password = new Key(Base64.getDecoder().decode(encryption.getBytes())).decryptString(encryptedPass); - - if (username.length() > 20 || password.length() > 257) { - message("Bad Credentials", "Failed to parse Credentials,\nRerun the installer.", JOptionPane.ERROR_MESSAGE, true); - } - Tweaker.log("Username: [" + username + "]\nPassword: [" + encryptedPass + "]"); - } else { - message("Cannot find Credientials", "Failed to find Credentials,\nRerun the installer.\nIf rerunning the installer does not fix this,\nPlease contact support.", JOptionPane.ERROR_MESSAGE, true); - } - - - //We need this to make sure we're not being poked at - String ticket = getRandomTicket(); - byte[] encryptedTicket = aesE.doFinal(ticket.getBytes()); - outputF.writeInt(encryptedTicket.length); - outputF.write(encryptedTicket); - byte[] receivedTicket = new byte[inputF.readInt()]; - inputF.readFully(receivedTicket); - String compare = new String(aesD.doFinal(receivedTicket)); - if (!compare.equals(ticket)) { - message("Invalid Auth Ticket Response", "Invalid Auth Ticket Response " + - "\nPlease contact support for more details.", JOptionPane.ERROR_MESSAGE, true); - } - - //Set Communication key instance based on our previous key. - Key communicationKey = new Key(ticket); - - - outputF.writeUTF("loader"); - outputF.writeUTF(communicationKey.encryptString(username)); - outputF.writeUTF(communicationKey.encryptString(password)); - outputF.writeUTF(communicationKey.encryptString(generate())); - - - outputF.writeBoolean(!(dump == null)); - outputF.writeUTF(communicationKey.encryptString(dump != null ? dump : "")); - String file = Loader.class.getProtectionDomain().getCodeSource().getLocation().getFile(); - String filePM = BBPermissionManager.class.getProtectionDomain().getCodeSource().getLocation().getFile(); - if(!file.endsWith(".jar") || !file.equals(filePM)) { - message("An unexpected issue occurred.", "An unexpected issue occurred, " + - "\nPlease contact support. ", JOptionPane.ERROR_MESSAGE, true); - getPermissionManager().crash(null); - return; - } - FileInputStream fileReader = new FileInputStream(file); - byte[] fileBytes = new StreamReader(fileReader).readAllAsBytes(); - fileReader.close(); - byte[] jarHashBytes = MessageDigest.getInstance("SHA-512").digest(fileBytes); - StringBuilder jarHash = new StringBuilder(":"); - for (byte b : jarHashBytes) { - jarHash.append(StringTools.lengthifyStart(Integer.toHexString(Byte.toUnsignedInt(b)), "0", 2)).append(":"); - } - outputF.writeUTF(communicationKey.encryptString(jarHash.toString())); - - - int responseCode = inputF.readInt(); - - switch (responseCode) { - case -1: { - message("Invalid username/password", "Invalid username/password " + - "\nPlease contact support for more details.", JOptionPane.ERROR_MESSAGE, true); - break; - } - - case -3: { - message("Auth Server Down.", "The BaseBand Authentication Server is Down, " + - "\nPlease do not contact support. " + - "\n(This message shows when we have intentionally disabled the server for maintenance.)", JOptionPane.ERROR_MESSAGE, true); - break; - } - - case -4: { - message("Invalid HWID", "Invalid HWID, " + - "\nPlease contact support for more details.", JOptionPane.ERROR_MESSAGE, true); - break; - } - - case -5: { - message("Banned Account", "Your BaseBand account has been banned," + - "\nContact support for more details." + - "\n(This may be because you attempted to dump BaseBand.)", JOptionPane.ERROR_MESSAGE, true); - break; - } - - case -6: { - message("Rerun the installer", "Your password has been reset, " + - "\nPlease Rerun the installer.", JOptionPane.ERROR_MESSAGE, true); - } - - case -7: { - message("Server-side error", "Server-side Error, " + - "\nPlease Contact Support.", JOptionPane.ERROR_MESSAGE, true); - } - - case -8: { - Tweaker.log("Debug info: " + new Key("\u0005").encryptString(jarHash.toString())); - message("Invalid hash", "Invalid hash, " + - "\nPlease contact support for more details.", JOptionPane.ERROR_MESSAGE, true); - break; - } - - case -9: { - new File(Loader.class.getProtectionDomain().getCodeSource().getLocation().getFile()).delete(); - message("Update", "Re-run the installer. " + - "\nPlease re-run the installer.", JOptionPane.ERROR_MESSAGE, true); - break; - } - - default: { - Tweaker.log("Authenticated."); - } - } - - String key = getRandomTicket(); - - try { - Registry Registry = new Registry("BaseBand.registry"); - TCN tcn = Registry.register("*"); - tcn.set("LoaderPresent", true); - tcn.set("Key", key); - TCN data = new TCN(); - data.set("level", responseCode); - data.set("username", username); - tcn.set("Data", new Key(key).encryptString(Tools.mapToString(data.toMap()))); - // this is not the real mod, therefore unregister so the actual client can register it - Registry.unregister("*", tcn); - CustomClassloader.registryTransfer.access(x -> x.setValue(Registry)); - } catch (Exception e) { - throw new RuntimeException(e); - } - - - Map classCache = new HashMap<>(); - Map resources = new HashMap<>(); - - - - int amountOfData = inputF.readInt(); - - for (int i = 0; i < amountOfData; i++) { - Tweaker.log(i + "datapart"); - - String name = new String(aesD.doFinal(communicationKey.decryptByteKey(Base64.getDecoder().decode(inputF.readUTF())))); - Tweaker.log("1"); - - byte[] data = communicationKey.decryptByteKey(Base64.getDecoder().decode(inputF.readUTF())); - Tweaker.log("2"); - - byte[] dataKey = aesD.doFinal(communicationKey.decryptByteKey(Base64.getDecoder().decode(inputF.readUTF()))); - Tweaker.log("3"); - - if (name.endsWith(".class")) { - classKey.access(x -> classCache.put(name.replace(".class", "").replace('/', '.'), x.getValue().encryptByte(new Key(dataKey).decryptByte(data)))); - } else { - resources.put(name, new Key(dataKey).decryptByte(data)); - } - } - - Tweaker.log("loaded classes?"); - - - CustomClassloader customCL = new CustomClassloader( - (Supplier) (() -> new DataKeeper<>(CustomClassloader.getTransferPermissionManager(), defaultStrictness, classCache).forgetIn(2000)), - (Supplier) (() -> new DataKeeper<>(CustomClassloader.getTransferPermissionManager(), defaultStrictness, resources).forgetIn(2000)) - ); - permissionManager.access(x -> x.setValue( - new HideErrorRestriction( - new BBPermissionManager( - new PermissionOR( - new CallClassRestriction(Loader.class, CustomClassloader.class, CustomClassloader.customMixinServerClass), - new ClassLoaderRestriction(customCL) - ) - ) - ) - )); - - - Tweaker.log(String.format("Loaded. (Took %s milliseconds.)", System.nanoTime() / 1000000L - startTime)); - Tweaker.latch.countDown(); - } catch (Exception e) { - e.printStackTrace(); - exit(); - } - } - - - private static String generate() { - try { - return bytesToHex(MessageDigest.getInstance("SHA-512").digest((System.getenv("PROCESSOR_IDENTIFIER") + System.getenv("COMPUTERNAME") + System.getProperty("user.name")).getBytes())); - } catch (Exception e) { - return "######################"; - } - } - - private static String bytesToHex(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = "0123456789ABCDEF".toCharArray()[v >>> 4]; - hexChars[j * 2 + 1] = "0123456789ABCDEF".toCharArray()[v & 0x0F]; - } - return new String(hexChars); - } - - - private static String getRandomTicket() { - return Tools.randomAlphanumericString(4096); - } - - - private static String dumpDetected() { - //Begin section, Anti JavaAgent - byte[] EMPTY_CLASS_BYTES = - { - -54, -2, -70, -66, 0, 0, 0, 49, 0, 5, 1, 0, 34, 115, 117, 110, - 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 47, 73, - 110, 115, 116, 114, 117, 109, 101, 110, 116, 97, 116, 105, 111, - 110, 73, 109, 112, 108, 7, 0, 1, 1, 0, 16, 106, 97, 118, 97, 47, - 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 7, 0, 3, 0, 1, - 0, 2, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0 - }; - - try { - Objects.requireNonNull(getUnsafe()).defineClass("sun.instrument.InstrumentationImpl", EMPTY_CLASS_BYTES, 0, EMPTY_CLASS_BYTES.length, null, null); - } catch (Throwable e) { - return "JavaAgent?"; - } - - List BAD_INPUT_FLAGS = Arrays.asList( - "-XBootclasspath", - "-javaagent", - "-Xdebug", - "-agentlib", - "-Xrunjdwp", - "-Xnoagent", - "-verbose", - "-DproxySet", - "-DproxyHost", - "-DproxyPort", - "-Djavax.net.ssl.trustStore", - "-Djavax.net.ssl.trustStorePassword", - "-Dmixin.debug=true", - "-Dmixin.debug.export=true" - ); - - Optional inputFlag = ManagementFactory.getRuntimeMXBean().getInputArguments().stream() - .filter(input -> BAD_INPUT_FLAGS.stream().anyMatch(input::contains)) - .findFirst(); - - - Optional hasDisableFlag = ManagementFactory.getRuntimeMXBean().getInputArguments().stream() - .filter(input -> input.equals("-XX:+DisableAttachMechanism")) - .findFirst(); - - if(!hasDisableFlag.isPresent()) { - Tweaker.log.fatal("JVM does not have disable attach mechanism argument"); - Tweaker.log.fatal("Please add -XX:+DisableAttachMechanism to your JVM args"); - Loader.exit(); - } - - - if (inputFlag.isPresent()) { - return "Bad JVM flag "+Base64.getEncoder().encodeToString(ManagementFactory.getRuntimeMXBean().getInputArguments().toString().getBytes()); - } - - // this is for testing purposes to make sure it's actually loaded - try { - Class.forName("sun.instrument.InstrumentationImpl"); - } catch (ClassNotFoundException e) { - return "What. PING JESS."; - } - - if(!(System.getSecurityManager() instanceof BaseBandSecurityManager)) { - try { - SecurityManager currentSecurityManager = System.getSecurityManager(); - - if (currentSecurityManager != null) { - Field b = Unsafe.class.getDeclaredField("theUnsafe"); - boolean a = b.isAccessible(); - b.setAccessible(true); - Unsafe unsafe = (Unsafe) b.get(null); - b.setAccessible(a); - Object base = null; - Field[] fields = System.class.getDeclaredFields(); - for (Field field : fields) { - if (Modifier.isStatic(field.getModifiers())) { - base = unsafe.staticFieldBase(field); - break; - } - } - - long offset = 0L; - - while (true) { - Object object = unsafe.getObject(base, offset); - if (object == currentSecurityManager) { - unsafe.putObject(base, offset, new BaseBandSecurityManager()); - break; - } - - offset += 4L; - } - } else { - System.setSecurityManager(new BaseBandSecurityManager()); - } - } catch (Exception e) { - return e.getLocalizedMessage(); - } - } - - return null; - - //return null if it's fine, return StringReason if it broke - } - - - public static Unsafe getUnsafe() { - try { - Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe"); - - unsafeField.setAccessible(true); - - return (Unsafe) unsafeField.get(null); - } catch (NoSuchFieldException | IllegalAccessException e) { - e.printStackTrace(); - return null; - } - } - - - public static void message(String title, String message, int b, boolean exit) { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - } catch (Exception ignored) { - } - JFrame jFrame = new JFrame(); - jFrame.setAlwaysOnTop(true); - jFrame.setFocusable(false); - JOptionPane.showMessageDialog(jFrame, message, "[BaseBand] " + title, b); - jFrame.dispose(); - if (exit) { - exit(); - } - } - - public static void exit() { - try { - DataKeeper.forgetAll=true; //REAL - Class shutdownClass = Class.forName("java.lang.Shutdown"); - Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class); - exitMethod.setAccessible(true); - exitMethod.invoke(null, 1); - } catch (Exception ignored) { - } - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/security/SecurityImpl.java b/Loader/src/main/java/org/baseband/launcher/security/SecurityImpl.java new file mode 100644 index 0000000..bc78ef5 --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/security/SecurityImpl.java @@ -0,0 +1,7 @@ +package org.baseband.launcher.security; + +import org.baseband.launcher.util.Util; + +public interface SecurityImpl extends Util { + void run(); +} diff --git a/Loader/src/main/java/org/baseband/launcher/security/impl/TestImpl.java b/Loader/src/main/java/org/baseband/launcher/security/impl/TestImpl.java new file mode 100644 index 0000000..931109a --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/security/impl/TestImpl.java @@ -0,0 +1,10 @@ +package org.baseband.launcher.security.impl; + +import org.baseband.launcher.security.SecurityImpl; + +public class TestImpl implements SecurityImpl { + @Override + public void run() { + LOGGER.info("TestImpl"); + } +} diff --git a/Loader/src/main/java/org/baseband/launcher/tweaker/CfgAccessTransformer.java b/Loader/src/main/java/org/baseband/launcher/tweaker/CfgAccessTransformer.java deleted file mode 100644 index 395420f..0000000 --- a/Loader/src/main/java/org/baseband/launcher/tweaker/CfgAccessTransformer.java +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.tweaker; - -import net.minecraftforge.fml.common.asm.transformers.AccessTransformer; - -import java.io.IOException; - -public final class CfgAccessTransformer extends AccessTransformer { - public CfgAccessTransformer() throws IOException { - super("client_at.cfg"); - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/tweaker/Core.java b/Loader/src/main/java/org/baseband/launcher/tweaker/Core.java deleted file mode 100644 index aa7954d..0000000 --- a/Loader/src/main/java/org/baseband/launcher/tweaker/Core.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.tweaker; - -import org.spongepowered.asm.launch.MixinBootstrap; -import org.spongepowered.asm.mixin.MixinEnvironment; -import org.spongepowered.asm.mixin.Mixins; - -@SuppressWarnings("unused") -public class Core { - public void init(ClassLoader classLoader) { - MixinBootstrap.init(); - - MixinEnvironment.getEnvironment(MixinEnvironment.Phase.DEFAULT).setSide(MixinEnvironment.Side.CLIENT); - MixinEnvironment.getEnvironment(MixinEnvironment.Phase.PREINIT).setSide(MixinEnvironment.Side.CLIENT); - MixinEnvironment.getEnvironment(MixinEnvironment.Phase.INIT).setSide(MixinEnvironment.Side.CLIENT); - MixinEnvironment.getEnvironment(MixinEnvironment.Phase.DEFAULT).setSide(MixinEnvironment.Side.CLIENT); - - Mixins.addConfiguration("mixins.baseband.json"); - MixinEnvironment.getDefaultEnvironment().setObfuscationContext("searge"); - } - - public String[] getTransformers() { - return new String[]{ - //CfgAccessTransformer.class.getName() - }; - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/url/ByteWrapper.java b/Loader/src/main/java/org/baseband/launcher/url/ByteWrapper.java new file mode 100644 index 0000000..1ec7725 --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/url/ByteWrapper.java @@ -0,0 +1,12 @@ +package org.baseband.launcher.url; + +import java.net.MalformedURLException; +import java.net.URL; + +//TODO: tud wrap it all in a datakeeper :trollerolley: +public class ByteWrapper { + //Stub, i love oop + public static URL wrap(String name, byte[] data) throws MalformedURLException { + return new URL(null, "bb://" + name, new URLHandler(data)); + } +} diff --git a/Loader/src/main/java/org/baseband/launcher/url/ResourceConnection.java b/Loader/src/main/java/org/baseband/launcher/url/ResourceConnection.java new file mode 100644 index 0000000..b3ea7c5 --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/url/ResourceConnection.java @@ -0,0 +1,31 @@ +package org.baseband.launcher.url; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLConnection; + + +public class ResourceConnection extends URLConnection { + private final byte[] data; + + protected ResourceConnection(URL url, byte[] data) { + super(url); + this.data = data; + } + + @Override + public void connect() { + } + + @Override + public InputStream getInputStream() { + return new ByteArrayInputStream(data); + } + + @Override + public OutputStream getOutputStream() { + throw new Error("This person tried to output to a read-only resource! Laugh at this user!!!"); + } +} \ No newline at end of file diff --git a/Loader/src/main/java/org/baseband/launcher/url/URLHandler.java b/Loader/src/main/java/org/baseband/launcher/url/URLHandler.java new file mode 100644 index 0000000..1ec52b7 --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/url/URLHandler.java @@ -0,0 +1,19 @@ +package org.baseband.launcher.url; + +import java.net.URL; +import java.net.URLConnection; +import java.net.URLStreamHandler; + +public class URLHandler extends URLStreamHandler { + + private final byte[] data; + + public URLHandler(byte[] data) { + this.data = data; + } + + @Override + protected URLConnection openConnection(URL u) { + return new ResourceConnection(u, data); + } +} diff --git a/Loader/src/main/java/org/baseband/launcher/util/BBPermissionManager.java b/Loader/src/main/java/org/baseband/launcher/util/BBPermissionManager.java deleted file mode 100644 index 7c1b0c5..0000000 --- a/Loader/src/main/java/org/baseband/launcher/util/BBPermissionManager.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.util; - -import de.tudbut.security.DataKeeper; -import de.tudbut.security.PermissionManager; -import de.tudbut.security.Strictness; -import de.tudbut.security.permissionmanager.Restriction; - -import java.io.File; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Objects; -import java.util.Set; -import java.util.Vector; -import java.util.stream.Collectors; - -public class BBPermissionManager extends Restriction { - public BBPermissionManager(PermissionManager parent) { - super(parent); - } - - @Override - public void crash(Strictness strictnessLevel) { - DataKeeper.forgetAll = true; - new Throwable().printStackTrace(); - new File(BBPermissionManager.class.getProtectionDomain().getCodeSource().getLocation().getFile()).delete(); - try { - Class shutdownClass = Class.forName("java.lang.Shutdown"); - Method exitMethod = shutdownClass.getDeclaredMethod("exit", int.class); - exitMethod.setAccessible(true); - exitMethod.invoke(null, 1); - } catch (Exception ignored) {} - } - - @Override - public boolean checkCaller(Strictness strictnessLevel) { - if(!(System.getSecurityManager() instanceof BaseBandSecurityManager)) { - System.out.println("No security?"); - return false; - } - - //// TudbuT // Are you sure this is this a good idea? it will be called a LOT. - - Set uniqueClassLoaders = Thread.getAllStackTraces().keySet().stream() - .map(thread -> thread.getContextClassLoader()) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - for (ClassLoader classLoader : uniqueClassLoaders) { - try { - Field librariesField = ClassLoader.class.getDeclaredField("loadedLibraryNames"); - librariesField.setAccessible(true); - Vector libraries = (Vector) librariesField.get(classLoader); - - for(String s : libraries) { - // TODO: add more protection - if(s.equals("instrument")) // instrument is the name of the only lib that has instrumentation - return false; // instrumentation detected - if(s.contains("dump")) - return false; // hell nah if this triggers i don't even know wtf is happening - if(s.contains("hook")) //Maybe? - return false; - } - - } catch (Exception e) { - return false; - } - } - - return super.checkCaller(strictnessLevel); - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/util/BaseBandSecurityManager.java b/Loader/src/main/java/org/baseband/launcher/util/BaseBandSecurityManager.java deleted file mode 100644 index 9a8eb03..0000000 --- a/Loader/src/main/java/org/baseband/launcher/util/BaseBandSecurityManager.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.util; - -import org.baseband.launcher.Tweaker; -import org.baseband.launcher.launch.Loader; - -import java.security.Permission; - -public class BaseBandSecurityManager extends SecurityManager { - - @Override - public void checkPermission(Permission permission) { - String permissionName = (permission.getName() != null) ? permission.getName() : "null"; - - //noinspection DuplicateCondition - if (permissionName.equals("setSecurityManager")) { - //Loader.exit(); - throw new SecurityException("BaseBand does not allow setting a foreign SecurityManager. Please contact basebandsec@mail.tudbut.de or @tudbut on Discord."); - } - // noinspection ConstantValue - if (permissionName.equals("setSecurityManager")) { - Loader.exit(); - } - - if (permissionName.startsWith("accessClassInPackage.com.baseband")) { - Class[] classContext = this.getClassContext(); - String callerClassName = (classContext.length > 4) ? classContext[4].getName() : null; - String parentClassName = (classContext.length > 5) ? classContext[5].getName() : null; - Tweaker.log.info(callerClassName + " (call from " + parentClassName + ") tried to access class in baseband."); - - if (callerClassName != null && !callerClassName.startsWith("com.baseband.")) { - if (parentClassName == null || !parentClassName.startsWith("com.baseband.")) { - Loader.exit(); - } - } - } - } - - @Override - public void checkPermission(Permission b, Object a) { - checkPermission(b); - } -} \ No newline at end of file diff --git a/Loader/src/main/java/org/baseband/launcher/util/DynamicPermissionManager.java b/Loader/src/main/java/org/baseband/launcher/util/DynamicPermissionManager.java deleted file mode 100644 index f4b383f..0000000 --- a/Loader/src/main/java/org/baseband/launcher/util/DynamicPermissionManager.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.util; - -import de.tudbut.security.PermissionManager; -import de.tudbut.security.Strictness; -import org.baseband.launcher.launch.Loader; - -public class DynamicPermissionManager implements PermissionManager { - @Override - public boolean checkCaller(Strictness strictnessLevel) { - return Loader.getPermissionManager().checkCaller(strictnessLevel); - } - - @Override - public boolean checkLambda(Strictness strictnessLevel, T lambda) { - return Loader.getPermissionManager().checkLambda(strictnessLevel, lambda); - } - - @Override - public void crash(Strictness strictnessLevel) { - Loader.getPermissionManager().crash(strictnessLevel); - } - - @Override - public boolean showErrors() { - return Loader.getPermissionManager().showErrors(); - } - - @Override - public void killReflection() { - Loader.getPermissionManager().killReflection(); - } - - @Override - public PermissionManager clone() { - return this; // holds no state - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/util/Key.java b/Loader/src/main/java/org/baseband/launcher/util/Key.java deleted file mode 100644 index eb1f352..0000000 --- a/Loader/src/main/java/org/baseband/launcher/util/Key.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.util; - -import java.nio.charset.StandardCharsets; -import java.util.UUID; - -import de.tudbut.tools.Tools; - -public class Key { - - private final String string; - - public Key() { - string = Tools.randomAlphanumericString(4096); - } - - public Key(String key) { - string = key; - } - - public Key(byte[] key) { - string = new String(key, StandardCharsets.ISO_8859_1); - } - - - public byte[] encryptByte(byte[] bytes) { - if(bytes == null) { - return null; - } - bytes = bytes.clone(); - byte[] eb = string.getBytes(StandardCharsets.ISO_8859_1); - int len = bytes.length; - int p = eb.length; - for (int i = 0 ; i < len ; i+=p) { - for (int j = 0 ; j < p && i + j < len ; j++) { - int idx = i + j; - bytes[idx] = (byte) ((int) bytes[idx] + (int) eb[j]); - } - } - return bytes; - } - - public byte[] decryptByte(byte[] bytes) { - if(bytes == null) { - return null; - } - bytes = bytes.clone(); - byte[] eb = string.getBytes(StandardCharsets.ISO_8859_1); - int len = bytes.length; - int p = eb.length; - for (int i = 0 ; i < len ; i+=p) { - for (int j = 0 ; j < p && i + j < len ; j++) { - int idx = i + j; - bytes[idx] = (byte) ((int) bytes[idx] - (int) eb[j]); - } - } - return bytes; - } - - public byte[] decryptByteKey(byte[] bytes) { - if(bytes == null) { - return null; - } - byte[] eb = string.getBytes(StandardCharsets.ISO_8859_1); - int len = bytes.length; - int p = eb.length; - for (int i = 0 ; i < len ; i+=p) { - for (int j = 0 ; j < p && i + j < len ; j++) { - int idx = i + j; - bytes[idx] = (byte) ((int) bytes[idx] - (int) eb[j]); - } - } - return bytes; - } - - /** - * Encrypts a string - * @param s string to encrypt - * @return encrypted string - */ - public String encryptString(String s) { - byte[] bytes = s.getBytes(StandardCharsets.ISO_8859_1); - byte[] eb = string.getBytes(StandardCharsets.ISO_8859_1); - int len = bytes.length; - int p = eb.length; - for (int i = 0 ; i < len ; i+=p) { - for (int j = 0 ; j < p && i + j < len ; j++) { - int idx = i + j; - bytes[idx] = (byte) ((int) bytes[idx] + (int) eb[j]); - } - } - return new String(bytes, StandardCharsets.ISO_8859_1); - } - - /** - * Decrypts a string - * @param s string to decrypt - * @return decrypted string - */ - public String decryptString(String s) { - byte[] bytes = s.getBytes(StandardCharsets.ISO_8859_1); - byte[] eb = string.getBytes(StandardCharsets.ISO_8859_1); - int len = bytes.length; - int p = eb.length; - for (int i = 0 ; i < len ; i+=p) { - for (int j = 0 ; j < p && i + j < len ; j++) { - int idx = i + j; - bytes[idx] = (byte) ((int) bytes[idx] - (int) eb[j]); - } - } - return new String(bytes, StandardCharsets.ISO_8859_1); - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/util/MixinRestriction.java b/Loader/src/main/java/org/baseband/launcher/util/MixinRestriction.java deleted file mode 100644 index 1671c7e..0000000 --- a/Loader/src/main/java/org/baseband/launcher/util/MixinRestriction.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023 Jess H & Daniella H. All Rights Reserved. - * Unauthorized copying of this file via any medium is Strictly Prohibited. - */ - -package org.baseband.launcher.util; - -import de.tudbut.security.Strictness; -import de.tudbut.security.permissionmanager.Restriction; -import de.tudbut.security.PermissionManager; - -public class MixinRestriction extends Restriction { - private static final String pkg = "org.spongepowered.asm.mixin.transformer"; - - // restrictions should always have this in order to be able to chain them - public MixinRestriction(PermissionManager parent) { - super(parent); - } - public MixinRestriction() { - super(null); - } - - @Override - public boolean checkCaller(Strictness strictnessLevel) { - StackTraceElement[] st = Thread.currentThread().getStackTrace(); - StackTraceElement[] elements; - if (strictnessLevel.hasProperty("Restriction.Mixin.MaxDistance")) { - int maxDist = strictnessLevel.getIntProperty("Restriction.Mixin.MaxDistance"); - if (st.length > maxDist) { - elements = new StackTraceElement[maxDist]; - System.arraycopy(st, 0, elements, 0, maxDist); - st = elements; - } - } - - boolean isCalledByAllowed = false; - elements = st; - int var5 = st.length; - - for(int var6 = 0; var6 < var5; ++var6) { - StackTraceElement element = elements[var6]; - if (element.getClassName().startsWith(pkg)) { - isCalledByAllowed = true; - break; - } - } - - return isCalledByAllowed && super.checkCaller(strictnessLevel); - } -} diff --git a/Loader/src/main/java/org/baseband/launcher/util/RSAKey.java b/Loader/src/main/java/org/baseband/launcher/util/RSAKey.java new file mode 100644 index 0000000..05acd25 --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/util/RSAKey.java @@ -0,0 +1,76 @@ +package org.baseband.launcher.util; + +import javax.crypto.Cipher; +import java.security.*; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; + +public class RSAKey implements Util { + + PublicKey publicKey; + + PrivateKey privateKey; + + public RSAKey(String publicKey) throws Exception { + this.publicKey = decodeBase64ToPublicKey(publicKey); + } + + + + public RSAKey() { + KeyPair keyPair = generateKeyPair(); + this.publicKey = keyPair.getPublic(); + this.privateKey = keyPair.getPrivate(); + } + + private KeyPair generateKeyPair() { + try { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(4096); + return keyPairGenerator.generateKeyPair(); + } catch (Exception e) { + LOGGER.fatal(e); + return null; + } + } + + public String rsaEnc(String plainText) { + try { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + return Base64.getEncoder().encodeToString(cipher.doFinal(plainText.getBytes())); + } catch (Exception e) { + LOGGER.fatal(e); + return null; + } + } + + public String rsaDec(String encryptedBytesInBase64) { + try { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedBytesInBase64)); + return new String(decryptedBytes); + } catch (Exception e) { + LOGGER.fatal(e); + return null; + } + } + + public PublicKey decodeBase64ToPublicKey(String base64PublicKey) { + try { + byte[] publicKeyBytes = Base64.getDecoder().decode(base64PublicKey); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes); + return keyFactory.generatePublic(keySpec); + } catch (Exception e) { + LOGGER.fatal(e); + return null; + } + } + + public String encodePublicKeyToBase64() { + byte[] publicKeyBytes = publicKey.getEncoded(); + return Base64.getEncoder().encodeToString(publicKeyBytes); + } +} diff --git a/Loader/src/main/java/org/baseband/launcher/util/Util.java b/Loader/src/main/java/org/baseband/launcher/util/Util.java new file mode 100644 index 0000000..964f116 --- /dev/null +++ b/Loader/src/main/java/org/baseband/launcher/util/Util.java @@ -0,0 +1,11 @@ +package org.baseband.launcher.util; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.security.SecureRandom; + +public interface Util { + Logger LOGGER = LogManager.getLogger("BaseBand Loader"); + SecureRandom RANDOM = new SecureRandom(); +} diff --git a/Loader/src/main/resources/mcmod.info b/Loader/src/main/resources/mcmod.info index e51c167..0e3237b 100644 --- a/Loader/src/main/resources/mcmod.info +++ b/Loader/src/main/resources/mcmod.info @@ -1,15 +1,15 @@ [ { "modid": "baseband", - "name": "BaseBand Loader", - "description": "Copyright JessSystemV (2023) All Rights Reserved.", + "name": "BaseBand Rewrite Loader", + "description": "Copyright JessSystemV (2024) All Rights Reserved.", "version": "1.0", "mcversion": "[1.12.2]", "authorList": [ "JessSystemV", "TudbuT" ], - "credits": "John200410 for the ClassLoader hierarchy", + "credits": "Caitlynn for emotional support.", "screenshots": [], "dependencies": [] }