commit 8ef9a95b67f8652416572d35c082a131029f79d4 Author: Finn Date: Sun Jul 7 23:13:20 2024 +0200 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/discord.xml b/.idea/discord.xml new file mode 100644 index 0000000..d8e9561 --- /dev/null +++ b/.idea/discord.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..aa00ffa --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..fdc35ea --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..23b1f26 --- /dev/null +++ b/README.MD @@ -0,0 +1 @@ +# UnlegitLibrary \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..8636021 --- /dev/null +++ b/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + me.finn.unlegitlibrary + UnlegitLibrary + 1.0-SNAPSHOT + + + 21 + 21 + UTF-8 + + \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/addon/AddonLoader.java b/src/main/java/me/finn/unlegitlibrary/addon/AddonLoader.java new file mode 100644 index 0000000..842894a --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/addon/AddonLoader.java @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.addon; + +import me.finn.unlegitlibrary.addon.impl.Addon; +import me.finn.unlegitlibrary.event.EventListener; +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.jar.JarFile; + +public class AddonLoader extends DefaultMethodsOverrider { + private final List addons; + private final Map> loadedClasses; + + public AddonLoader() { + this.addons = new ArrayList<>(); + this.loadedClasses = new HashMap<>(); + } + + public final void loadAddonsFromDirectory(File addonFolder) throws IOException { + if (!addonFolder.exists()) return; + if (!addonFolder.isDirectory()) return; + + File[] files = addonFolder.listFiles((d, name) -> name.toLowerCase().endsWith(".jar")); + if (files != null) { + for (File file : files) loadAddonFromJar(file); + } + } + + public final void loadAddonFromJar(File file) throws IOException { + try (JarFile jarFile = new JarFile(file)) { + URL[] urls = {new URL("jar:file:" + file.getAbsolutePath() + "!/")}; + URLClassLoader classLoader = URLClassLoader.newInstance(urls, getClass().getClassLoader()); + + jarFile.stream().forEach(jarEntry -> { + if (jarEntry.getName().endsWith(".class")) { + String className = jarEntry.getName().replace('/', '.').replace(".class", ""); + + try { + Class clazz = classLoader.loadClass(className); + loadedClasses.put(className, clazz); + + if (Addon.class.isAssignableFrom(clazz)) { + Addon addon = (Addon) clazz.getDeclaredConstructor().newInstance(); + addons.add(addon); + } + } catch (Exception exception) { + exception.printStackTrace(); + } + } + }); + } + } + + public final void enableAddon(Addon addon) { + if (!addons.contains(addon)) return; + addon.enable(); + } + + public final void disableAddon(Addon addon) { + if (!addons.contains(addon)) return; + addon.disable(); + } + + public final void enableAll() { + addons.forEach(this::enableAddon); + } + + public final void disableAll() { + addons.forEach(this::disableAddon); + } + + public final void registerEventListener(Addon addon, Class eventListener) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException { + if (!addons.contains(addon)) return; + addon.registerEventListener(eventListener); + } + + public final void unregisterEventListener(Addon addon, Class eventListener) { + if (!addons.contains(addon)) return; + addon.unregisterEventListener(eventListener); + } + + public final List getLoadedAddons() { + return new ArrayList<>(addons); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/addon/events/AddonDisabledEvent.java b/src/main/java/me/finn/unlegitlibrary/addon/events/AddonDisabledEvent.java new file mode 100644 index 0000000..707b319 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/addon/events/AddonDisabledEvent.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.addon.events; + +import me.finn.unlegitlibrary.addon.impl.Addon; +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public class AddonDisabledEvent extends Event { + + public final Addon addon; + + public AddonDisabledEvent(Addon addon) { + this.addon = addon; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/addon/events/AddonEnabledEvent.java b/src/main/java/me/finn/unlegitlibrary/addon/events/AddonEnabledEvent.java new file mode 100644 index 0000000..1a08be7 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/addon/events/AddonEnabledEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.addon.events; + +import me.finn.unlegitlibrary.addon.impl.Addon; +import me.finn.unlegitlibrary.event.impl.Event; + +public class AddonEnabledEvent extends Event { + + public final Addon addon; + + public AddonEnabledEvent(Addon addon) { + this.addon = addon; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/addon/impl/Addon.java b/src/main/java/me/finn/unlegitlibrary/addon/impl/Addon.java new file mode 100644 index 0000000..29c9ba3 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/addon/impl/Addon.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.addon.impl; + +import me.finn.unlegitlibrary.addon.events.AddonDisabledEvent; +import me.finn.unlegitlibrary.addon.events.AddonEnabledEvent; +import me.finn.unlegitlibrary.event.EventListener; +import me.finn.unlegitlibrary.event.EventManager; +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.lang.reflect.InvocationTargetException; + +public abstract class Addon { + + private final AddonInfo addonInfo; + private final EventManager eventManager; + private boolean isEnabled = false; + + public Addon(AddonInfo addonInfo) { + this.addonInfo = addonInfo; + this.eventManager = new EventManager(); + } + + public final boolean isEnabled() { + return isEnabled; + } + + public final AddonInfo getAddonInfo() { + return addonInfo; + } + + public void executeEvent(Event event) { + if (!isEnabled) return; + eventManager.executeEvent(event); + } + + public final void registerEventListener(Class eventListener) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException { + eventManager.registerListener(eventListener); + } + + public final void unregisterEventListener(Class eventListener) { + eventManager.unregisterListener(eventListener); + } + + public abstract void onEnable(); + + public abstract void onDisable(); + + public final void enable() { + if (isEnabled) return; + + isEnabled = true; + onEnable(); + eventManager.executeEvent(new AddonEnabledEvent(this)); + } + + public final void disable() { + if (!isEnabled) return; + + isEnabled = false; + onDisable(); + eventManager.executeEvent(new AddonDisabledEvent(this)); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/addon/impl/AddonInfo.java b/src/main/java/me/finn/unlegitlibrary/addon/impl/AddonInfo.java new file mode 100644 index 0000000..9c7bd2b --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/addon/impl/AddonInfo.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.addon.impl; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public class AddonInfo { + + private final String name; + private final String version; + private final String author; + + public AddonInfo(String name, String version, String author) { + this.name = name; + this.version = version; + this.author = author; + } + + public final String getAuthor() { + return author; + } + + public final String getName() { + return name; + } + + public final String getVersion() { + return version; + } + + @Override + protected AddonInfo clone() throws CloneNotSupportedException { + return new AddonInfo(name, version, author); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AddonInfo)) return false; + + AddonInfo other = (AddonInfo) obj; + return other.name.equalsIgnoreCase(name) && other.version.equalsIgnoreCase(version) && other.author.equalsIgnoreCase(author); + } + + @Override + public int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/event/EventListener.java b/src/main/java/me/finn/unlegitlibrary/event/EventListener.java new file mode 100644 index 0000000..4300b04 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/event/EventListener.java @@ -0,0 +1,14 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.event; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public abstract class EventListener { +} diff --git a/src/main/java/me/finn/unlegitlibrary/event/EventManager.java b/src/main/java/me/finn/unlegitlibrary/event/EventManager.java new file mode 100644 index 0000000..53ca7af --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/event/EventManager.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.event; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; + +public class EventManager extends DefaultMethodsOverrider { + + private final HashMap, HashMap>> registeredListener = new HashMap<>(); + private final HashMap, Object> eventListeners = new HashMap<>(); + + public final void registerListener(Class listenerClass) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException { + if (isListenerRegistered(listenerClass)) return; + + Object clazz = listenerClass.getDeclaredConstructor().newInstance(); + + for (Method method : clazz.getClass().getDeclaredMethods()) { + Listener listener = method.getAnnotation(Listener.class); + + if (listener == null) continue; + + if (method.getParameterCount() == 1) { + Class eventClass = (Class) method.getParameterTypes()[0]; + + HashMap> list = registeredListener.getOrDefault(eventClass, new HashMap<>()); + HashMap set = list.getOrDefault(listener.priority(), new HashMap<>()); + + set.put(clazz, method); + list.put(listener.priority(), set); + registeredListener.put(eventClass, list); + } + } + + eventListeners.put(listenerClass, clazz); + } + + public final void unregisterListener(Class listenerClass) { + if (!isListenerRegistered(listenerClass)) return; + + Object clazz = eventListeners.get(listenerClass); + + for (Class eventClass : registeredListener.keySet()) { + HashMap> priorityMap = registeredListener.get(eventClass); + + if (priorityMap != null) { + for (EventPriority priority : priorityMap.keySet()) { + HashMap listeners = priorityMap.get(priority); + if (listeners != null) { + listeners.remove(clazz); + if (listeners.isEmpty()) priorityMap.remove(priority); + } + } + + if (priorityMap.isEmpty()) registeredListener.remove(eventClass); + } + } + + eventListeners.remove(listenerClass); + } + + public final boolean isListenerRegistered(Class listenerClass) { + return eventListeners.containsKey(listenerClass); + } + + public final void executeEvent(Event event) { + HashMap> list = registeredListener.getOrDefault(event.getClass(), new HashMap<>()); + + list.getOrDefault(EventPriority.LOWEST, new HashMap<>()).forEach((k, v) -> { + if (!isListenerRegistered((Class) k.getClass())) return; + + try { + v.invoke(k, event); + } catch (IllegalAccessException | InvocationTargetException exception) { + exception.printStackTrace(); + } + }); + + list.getOrDefault(EventPriority.LOW, new HashMap<>()).forEach((k, v) -> { + if (!isListenerRegistered((Class) k.getClass())) return; + + try { + v.invoke(k, event); + } catch (IllegalAccessException | InvocationTargetException exception) { + exception.printStackTrace(); + } + }); + + list.getOrDefault(EventPriority.NORMAL, new HashMap<>()).forEach((k, v) -> { + if (!isListenerRegistered((Class) k.getClass())) return; + + try { + v.invoke(k, event); + } catch (IllegalAccessException | InvocationTargetException exception) { + exception.printStackTrace(); + } + }); + + list.getOrDefault(EventPriority.HIGH, new HashMap<>()).forEach((k, v) -> { + if (!isListenerRegistered((Class) k.getClass())) return; + + try { + v.invoke(k, event); + } catch (IllegalAccessException | InvocationTargetException exception) { + exception.printStackTrace(); + } + }); + + list.getOrDefault(EventPriority.HIGHEST, new HashMap<>()).forEach((k, v) -> { + if (!isListenerRegistered((Class) k.getClass())) return; + + try { + v.invoke(k, event); + } catch (IllegalAccessException | InvocationTargetException exception) { + exception.printStackTrace(); + } + }); + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/event/EventPriority.java b/src/main/java/me/finn/unlegitlibrary/event/EventPriority.java new file mode 100644 index 0000000..fbd6fd3 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/event/EventPriority.java @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.event; + +public enum EventPriority { + LOWEST, + LOW, + NORMAL, + HIGH, + HIGHEST +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/event/Listener.java b/src/main/java/me/finn/unlegitlibrary/event/Listener.java new file mode 100644 index 0000000..2779b70 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/event/Listener.java @@ -0,0 +1,18 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.event; + +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface Listener { + EventPriority priority() default EventPriority.NORMAL; +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/event/impl/CancellableEvent.java b/src/main/java/me/finn/unlegitlibrary/event/impl/CancellableEvent.java new file mode 100644 index 0000000..a0c97c5 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/event/impl/CancellableEvent.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.event.impl; + +public class CancellableEvent extends Event { + + private boolean isCancelled; + + public final boolean isCancelled() { + return isCancelled; + } + + public final void setCancelled(boolean cancelled) { + isCancelled = cancelled; + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/event/impl/Event.java b/src/main/java/me/finn/unlegitlibrary/event/impl/Event.java new file mode 100644 index 0000000..697817d --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/event/impl/Event.java @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.event.impl; + +public abstract class Event { +} diff --git a/src/main/java/me/finn/unlegitlibrary/file/ClassDefiner.java b/src/main/java/me/finn/unlegitlibrary/file/ClassDefiner.java new file mode 100644 index 0000000..ff7de1c --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/file/ClassDefiner.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.file; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.util.Collections; +import java.util.Map; +import java.util.WeakHashMap; + +public class ClassDefiner extends DefaultMethodsOverrider { + + private static final Map loaders = Collections.synchronizedMap(new WeakHashMap<>()); + + public static Class define(final Class parent, final String name, final byte[] data) { + return define(parent.getClassLoader(), name, data); + } + + public static Class define(final ClassLoader parentLoader, final String name, final byte[] data) { + ClassDefinerLoader loader = loaders.computeIfAbsent(parentLoader, ClassDefinerLoader::new); + + synchronized (loader.getClassLoadingLock(name)) { + if (loader.hasClass(name)) throw new IllegalStateException(name + " already defined"); + return (Class) loader.define(name, data); + } + } + + private static class ClassDefinerLoader extends ClassLoader { + static { + ClassLoader.registerAsParallelCapable(); + } + + protected ClassDefinerLoader(final ClassLoader parent) { + super(parent); + } + + private final Class define(final String name, final byte[] data) { + synchronized (this.getClassLoadingLock(name)) { + Class c = this.defineClass(name, data, 0, data.length); + this.resolveClass(c); + return c; + } + } + + @Override + public final Object getClassLoadingLock(final String name) { + return super.getClassLoadingLock(name); + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } + + public boolean hasClass(final String name) { + synchronized (this.getClassLoadingLock(name)) { + try { + Class.forName(name); + return true; + } catch (ClassNotFoundException exception) { + return false; + } + } + } + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/file/FileUtils.java b/src/main/java/me/finn/unlegitlibrary/file/FileUtils.java new file mode 100644 index 0000000..18f33f7 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/file/FileUtils.java @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.file; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.*; +import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class FileUtils extends DefaultMethodsOverrider { + + public static String getSuffix(File file) { + String[] splitName = file.getName().split("\\."); + return splitName[splitName.length - 1]; + } + + public static void deleteDirectoryRecursion(File file) { + if (file.exists() && file.isDirectory()) { + File[] entries = file.listFiles(); + if (entries != null) for (File entry : entries) deleteDirectoryRecursion(entry); + } + + if (!file.exists()) return; + file.delete(); + } + + public static String getName(File file) { + String[] splitName = file.getName().split("\\."); + return splitName[splitName.length - 2]; + } + + public static void copyResourceToFile(String resourceName, File targetFile, Class resourceClass) throws IOException { + InputStream inputStream = resourceClass.getResourceAsStream("/" + resourceName); + OutputStream outputStream = new FileOutputStream(targetFile); + + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) outputStream.write(buffer, 0, bytesRead); + } + + public static void unzip(File source, String outputDirectory) throws IOException { + ZipInputStream zis = new ZipInputStream(new FileInputStream(source)); + ZipEntry entry = zis.getNextEntry(); + + while (entry != null) { + File file = new File(outputDirectory, entry.getName()); + + if (entry.isDirectory()) file.mkdirs(); + else { + File parent = file.getParentFile(); + if (!parent.exists()) parent.mkdirs(); + + try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file))) { + int bufferSize = Math.toIntExact(entry.getSize()); + byte[] buffer = new byte[bufferSize > 0 ? bufferSize : 1]; + int location; + + while ((location = zis.read(buffer)) != -1) bos.write(buffer, 0, location); + } + } + + entry = zis.getNextEntry(); + } + } + + + public static void downloadFile(String link, File outputFile) throws IOException { + URL url = new URL(link); + + BufferedInputStream bis = new BufferedInputStream(url.openStream()); + FileOutputStream fis = new FileOutputStream(outputFile); + + byte[] buffer = new byte[1024]; + int count = 0; + while ((count = bis.read(buffer, 0, 1024)) != -1) fis.write(buffer, 0, count); + + fis.close(); + bis.close(); + } + + public static boolean isEmpty(Path path) throws IOException { + if (Files.isDirectory(path)) { + try (Stream entries = Files.list(path)) { + return !entries.findFirst().isPresent(); + } + } + + return false; + } + + public static String readFile(File file) throws IOException { + Long length = file.length(); + byte[] content = new byte[length.intValue()]; + + FileInputStream inputStream = new FileInputStream(file); + inputStream.read(content); + inputStream.close(); + + return new String(content, StandardCharsets.UTF_8); + } + + public static void copyFile(File sourceFile, File toFolder, boolean replaceExisting) throws IOException { + // Check if the source file exists and is a regular file + if (!sourceFile.exists() || !sourceFile.isFile()) return; + + // Check if the destination folder exists and is a directory + if (!toFolder.exists() || !toFolder.isDirectory()) return; + + // Get the name of the source file + String fileName = sourceFile.getName(); + File destinationFile = new File(toFolder, fileName); + + + if (replaceExisting) Files.copy(sourceFile.toPath(), destinationFile.toPath(), StandardCopyOption.REPLACE_EXISTING); + else Files.copy(sourceFile.toPath(), destinationFile.toPath()); + } + + public static void copyFiles(File fromFolder, File toFolder, boolean replaceExisting) throws IOException { + // Check if the source directory exists and is a directory + if (!fromFolder.exists() || !fromFolder.isDirectory()) return; + + // Check if the destination directory exists and is a directory + if (!toFolder.exists() || !toFolder.isDirectory()) return; + + // List all files in the source directory + File[] filesToCopy = fromFolder.listFiles(); + if (filesToCopy == null) return; + + // Iterate through the files and copy them to the destination directory + for (File file : filesToCopy) { + Path source = file.toPath(); + Path destination = new File(toFolder, file.getName()).toPath(); + + if (replaceExisting) Files.copy(source, destination, StandardCopyOption.REPLACE_EXISTING); + else Files.copy(source, destination); + } + } + + public static void writeFile(File file, String text) throws IOException { + Writer writer = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(file.toPath()), StandardCharsets.UTF_8)); + writer.write(text); + writer.close(); + } + + public static void hideFile(File file) throws IOException { + if (file.isHidden()) return; + Files.setAttribute(Paths.get(file.getPath()), "dos:hidden", true, LinkOption.NOFOLLOW_LINKS); + } + + public static void unHideFile(File file) throws IOException { + if (!file.isHidden()) return; + Files.setAttribute(Paths.get(file.getPath()), "dos:hidden", false, LinkOption.NOFOLLOW_LINKS); + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/file/ReflectUtils.java b/src/main/java/me/finn/unlegitlibrary/file/ReflectUtils.java new file mode 100644 index 0000000..0173404 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/file/ReflectUtils.java @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.file; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Arrays; + +public class ReflectUtils extends DefaultMethodsOverrider { + + public static Method getMethodByArgs(final Class clazz, final Class... args) { + for (Method method : clazz.getDeclaredMethods()) if (Arrays.equals(method.getParameterTypes(), args)) return method; + return null; + } + + public static Field getEnumField(final Enum value) throws IllegalAccessException { + for (Field field : value.getClass().getDeclaredFields()) { + if (!Modifier.isStatic(field.getModifiers())) continue; + if (!field.getType().equals(value.getClass())) continue; + + field.setAccessible(true); + if (value.equals(field.get(null))) return field; + } + + return null; + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/NetworkClient.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/NetworkClient.java new file mode 100644 index 0000000..60cf6c5 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/NetworkClient.java @@ -0,0 +1,337 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client; + +import me.finn.unlegitlibrary.event.EventManager; +import me.finn.unlegitlibrary.network.system.client.events.packets.received.C_PacketFailedReceivedEvent; +import me.finn.unlegitlibrary.network.system.client.events.packets.received.C_PacketReceivedEvent; +import me.finn.unlegitlibrary.network.system.client.events.packets.received.C_UnknownObjectReceivedEvent; +import me.finn.unlegitlibrary.network.system.client.events.packets.send.C_PacketFailedSendEvent; +import me.finn.unlegitlibrary.network.system.client.events.packets.send.C_PacketSendEvent; +import me.finn.unlegitlibrary.network.system.client.events.state.C_ConnectedEvent; +import me.finn.unlegitlibrary.network.system.client.events.state.C_DisconnectedEvent; +import me.finn.unlegitlibrary.network.system.client.events.state.C_StoppedEvent; +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.packets.PacketHandler; +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.io.EOFException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.Socket; +import java.net.SocketException; + +public class NetworkClient extends DefaultMethodsOverrider { + + private final String host; + private final int port; + private final PacketHandler packetHandler; + private final EventManager eventManager; + private final boolean autoReconnect; + private final boolean debugLog; + private final int maxAttempts; + private final int attemptDelayInSec; + + private Socket socket; + private ObjectOutputStream objectOutputStream; + private ObjectInputStream objectInputStream; + private int clientID = -1; + private int attempt = 1; private final Thread receiveThread = new Thread(this::receive); + + private boolean needClientID = false; + private NetworkClient(String host, int port, PacketHandler packetHandler, EventManager eventManager, boolean autoReconnect, boolean debugLog, int maxAttempts, int attemptDelayInSec) { + this.host = host; + this.port = port; + + this.packetHandler = packetHandler; + this.eventManager = eventManager; + + this.autoReconnect = autoReconnect; + this.debugLog = debugLog; + + this.maxAttempts = maxAttempts; + this.attemptDelayInSec = attemptDelayInSec; + + attempt = 1; + } + + public final int getClientID() { + return clientID; + } + + public final Socket getSocket() { + return socket; + } + + public final ObjectOutputStream getObjectOutputStream() { + return objectOutputStream; + } + + public final ObjectInputStream getObjectInputStream() { + return objectInputStream; + } + + public final boolean isDebugLogEnabled() { + return debugLog; + } + + public final boolean isAutoReconnectEnabled() { + return autoReconnect; + } + + public final PacketHandler getPacketHandler() { + return packetHandler; + } + + public final boolean isNeedClientID() { + return needClientID; + } + + public final int getPort() { + return port; + } + + public final String getHost() { + return host; + } + + public final Thread getReceiveThread() { + return receiveThread; + } + + public final boolean isConnected() { + return socket != null && socket.isConnected() && !socket.isClosed() && socket.isBound() + && receiveThread.isAlive() && !receiveThread.isInterrupted(); + } + + public synchronized final void connect() throws IOException, InterruptedException { + if (isConnected()) return; + if (debugLog) System.out.println("Connecting to server..."); + + try { + socket = new Socket(host, port); + socket.setTcpNoDelay(false); + + objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); + objectInputStream = new ObjectInputStream(socket.getInputStream()); + + needClientID = true; + receiveThread.start(); + + objectOutputStream.writeObject("c2s_connect"); + objectOutputStream.writeObject(clientID); + objectOutputStream.flush(); + + attempt = 1; + if (debugLog) System.out.println("Connected to Server. Attempts: " + attempt); + } catch (SocketException exception) { + if (autoReconnect) reconnect(); + else throw exception; + } + } + + public final EventManager getEventManager() { + return eventManager; + } + + public synchronized final void disconnect() throws IOException { + if (debugLog) System.out.println("Disconnecting from server..."); + + if (isConnected()) { + objectOutputStream.writeObject("c2s_disconnect"); + objectOutputStream.writeObject(clientID); + objectOutputStream.flush(); + } + + eventManager.executeEvent(new C_DisconnectedEvent(this)); + if (debugLog) System.out.println("Disconnected from server."); + stop(); + } + + private synchronized final void stop() throws IOException { + if (debugLog) System.out.println("Stopping client..."); + + if (isConnected()) { + objectOutputStream.close(); + objectInputStream.close(); + socket.close(); + } + + objectOutputStream = null; + objectInputStream = null; + socket = null; + + needClientID = false; + clientID = -1; + attempt = 1; + receiveThread.interrupt(); + + eventManager.executeEvent(new C_StoppedEvent(this)); + if (debugLog) System.out.println("Client stopped."); + } + + public final boolean sendPacket(Packet packet) throws IOException, ClassNotFoundException { + if (!isConnected()) return false; + + if (packetHandler.sendPacket(packet, objectOutputStream)) { + eventManager.executeEvent(new C_PacketSendEvent(this, packet)); + return true; + } else { + eventManager.executeEvent(new C_PacketFailedSendEvent(this, packet)); + return false; + } + } + + private final void receive() { + if (!isConnected()) return; + + try { + String command = ""; + + while (isConnected()) { + Object received = objectInputStream.readObject(); + + if (received instanceof String) { + command = (String) received; + continue; + } + + if (received instanceof Integer id) { + if (command.equalsIgnoreCase("s2c_connect")) { + clientID = id; + command = ""; + + eventManager.executeEvent(new C_ConnectedEvent(this)); + continue; + } else if (command.equalsIgnoreCase("s2c_disconnect")) { + if (clientID != id) continue; + eventManager.executeEvent(new C_DisconnectedEvent(this)); + command = ""; + + stop(); + break; + } else if (packetHandler.getPacketByID(id) != null) { + command = ""; + Packet packet = packetHandler.getPacketByID(id); + + if (packetHandler.handlePacket(id, packet, objectInputStream)) + eventManager.executeEvent(new C_PacketReceivedEvent(this, packet)); + else eventManager.executeEvent(new C_PacketFailedReceivedEvent(this, packet)); + + continue; + } + } + + eventManager.executeEvent(new C_UnknownObjectReceivedEvent(this, received)); + } + } catch (EOFException exception) { + attempt = 1; + if (autoReconnect && maxAttempts == -1 || attempt <= maxAttempts) reconnect(); + else { + eventManager.executeEvent(new C_StoppedEvent(this)); + exception.printStackTrace(); + } + } catch (IOException | ClassNotFoundException exception) { + eventManager.executeEvent(new C_StoppedEvent(this)); + exception.printStackTrace(); + } + } + + private final void reconnect() { + if (autoReconnect) { + if (isConnected()) { + try { + disconnect(); + } catch (IOException exception) { + if (maxAttempts > 0 && attempt > maxAttempts) { + exception.printStackTrace(); + return; + } + } + } + + if (debugLog) System.out.println("Trying to reconnect... (Attempt: " + attempt++ + ")"); + + try { + Thread.sleep(attemptDelayInSec * 1000L); + connect(); + } catch (InterruptedException | IOException exception) { + if (maxAttempts == -1 || attempt <= maxAttempts) reconnect(); + else exception.printStackTrace(); + } + } else { + try { + stop(); + } catch (IOException exception) { + eventManager.executeEvent(new C_StoppedEvent(this)); + exception.printStackTrace(); + } + } + } + + public static class ClientBuilder { + private int port; + private String host; + private PacketHandler packetHandler = new PacketHandler(); + private EventManager eventManager = new EventManager(); + private boolean autoReconnect = false; + private boolean debugLog = false; + private int maxAttempts = 10; + private int attemptDelayInSec = 1; + + public final ClientBuilder enableAutoReconnect() { + this.autoReconnect = true; + return this; + } + + public final ClientBuilder enableDebugLog() { + this.debugLog = true; + return this; + } + + public final ClientBuilder setEventManager(EventManager eventManager) { + this.eventManager = eventManager; + return this; + } + + public final ClientBuilder setPort(int port) { + this.port = port; + return this; + } + + public final ClientBuilder setHost(String host) { + this.host = host; + return this; + } + + public final ClientBuilder setPacketHandler(PacketHandler packetHandler) { + this.packetHandler = packetHandler; + return this; + } + + public final ClientBuilder setAttemptDelayInSeconds(int attemptDelayInSec) { + this.attemptDelayInSec = attemptDelayInSec; + return this; + } + + public final ClientBuilder setMaxAttempts(int maxAttempts) { + this.maxAttempts = maxAttempts; + return this; + } + + public final NetworkClient build() { + return new NetworkClient(host, port, packetHandler, eventManager, autoReconnect, debugLog, maxAttempts, attemptDelayInSec); + } + } + + + + +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_PacketFailedReceivedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_PacketFailedReceivedEvent.java new file mode 100644 index 0000000..7c8977d --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_PacketFailedReceivedEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.packets.received; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; +import me.finn.unlegitlibrary.network.system.packets.Packet; + +public class C_PacketFailedReceivedEvent extends Event { + + public final NetworkClient networkClient; + public final Packet packet; + + public C_PacketFailedReceivedEvent(NetworkClient networkClient, Packet packet) { + this.networkClient = networkClient; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_PacketReceivedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_PacketReceivedEvent.java new file mode 100644 index 0000000..20a64e3 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_PacketReceivedEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.packets.received; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; +import me.finn.unlegitlibrary.network.system.packets.Packet; + +public class C_PacketReceivedEvent extends Event { + + public final NetworkClient networkClient; + public final Packet packet; + + public C_PacketReceivedEvent(NetworkClient networkClient, Packet packet) { + this.networkClient = networkClient; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_UnknownObjectReceivedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_UnknownObjectReceivedEvent.java new file mode 100644 index 0000000..cb867de --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/received/C_UnknownObjectReceivedEvent.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.packets.received; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; + +public class C_UnknownObjectReceivedEvent extends Event { + public final NetworkClient networkClient; + public final Object object; + + public C_UnknownObjectReceivedEvent(NetworkClient networkClient, Object object) { + this.networkClient = networkClient; + this.object = object; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/send/C_PacketFailedSendEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/send/C_PacketFailedSendEvent.java new file mode 100644 index 0000000..d9fc0df --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/send/C_PacketFailedSendEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.packets.send; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; +import me.finn.unlegitlibrary.network.system.packets.Packet; + +public class C_PacketFailedSendEvent extends Event { + + public final NetworkClient networkClient; + public final Packet packet; + + public C_PacketFailedSendEvent(NetworkClient networkClient, Packet packet) { + this.networkClient = networkClient; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/send/C_PacketSendEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/send/C_PacketSendEvent.java new file mode 100644 index 0000000..882846d --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/packets/send/C_PacketSendEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.packets.send; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; +import me.finn.unlegitlibrary.network.system.packets.Packet; + +public class C_PacketSendEvent extends Event { + + public final NetworkClient networkClient; + public final Packet packet; + + public C_PacketSendEvent(NetworkClient networkClient, Packet packet) { + this.networkClient = networkClient; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_ConnectedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_ConnectedEvent.java new file mode 100644 index 0000000..fa4c093 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_ConnectedEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.state; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; + +public class C_ConnectedEvent extends Event { + + public final NetworkClient networkClient; + + public C_ConnectedEvent(NetworkClient networkClient) { + this.networkClient = networkClient; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_DisconnectedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_DisconnectedEvent.java new file mode 100644 index 0000000..0c68206 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_DisconnectedEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.state; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; + +public class C_DisconnectedEvent extends Event { + + public final NetworkClient networkClient; + + public C_DisconnectedEvent(NetworkClient networkClient) { + this.networkClient = networkClient; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_StoppedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_StoppedEvent.java new file mode 100644 index 0000000..24308ac --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/client/events/state/C_StoppedEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.client.events.state; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.client.NetworkClient; + +public class C_StoppedEvent extends Event { + + public final NetworkClient networkClient; + + public C_StoppedEvent(NetworkClient networkClient) { + this.networkClient = networkClient; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/packets/Packet.java b/src/main/java/me/finn/unlegitlibrary/network/system/packets/Packet.java new file mode 100644 index 0000000..4ae4c9f --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/packets/Packet.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.packets; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +public abstract class Packet { + + private final int id; + + public Packet(int id) { + this.id = id; + } + + public final int getPacketID() { + return id; + } + + public abstract void write(ObjectOutputStream outputStream) throws IOException, ClassNotFoundException; + + public abstract void read(ObjectInputStream outputStream) throws IOException, ClassNotFoundException; +} + diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/packets/PacketHandler.java b/src/main/java/me/finn/unlegitlibrary/network/system/packets/PacketHandler.java new file mode 100644 index 0000000..5203ba8 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/packets/PacketHandler.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.packets; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +public class PacketHandler extends DefaultMethodsOverrider { + + private final Map> packets = new HashMap<>(); + + public final boolean isPacketIDRegistered(int id) { + return packets.containsKey(id); + } + + public final Packet getPacketByID(int id) { + Class packetClass = packets.get(id); + if (packetClass == null) return null; + try { + return packetClass.getDeclaredConstructor().newInstance(); + } catch (InstantiationException | InvocationTargetException | IllegalAccessException | + NoSuchMethodException exception) { + return null; + } + } + + public final boolean registerPacket(Class packetClass) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { + Packet packet = packetClass.getDeclaredConstructor().newInstance(); + int id = packet.getPacketID(); + + if (isPacketIDRegistered(id)) return false; + packets.put(id, packetClass); + return true; + } + + public final boolean handlePacket(int id, Packet packet, ObjectInputStream inputStream) throws IOException, ClassNotFoundException { + if (!isPacketIDRegistered(id) || (packet != null && id != packet.getPacketID()) || (packet != null && !isPacketIDRegistered(packet.getPacketID()))) + return false; + + packet.read(inputStream); + return true; + } + + public final boolean sendPacket(Packet packet, ObjectOutputStream outputStream) throws IOException, ClassNotFoundException { + int id = packet.getPacketID(); + if (!isPacketIDRegistered(id)) return false; + + outputStream.writeObject(id); + packet.write(outputStream); + outputStream.flush(); + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/ClientHandler.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/ClientHandler.java new file mode 100644 index 0000000..c1db7ae --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/ClientHandler.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server; + +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.server.events.client.packets.received.S_PacketFailedReceivedEvent; +import me.finn.unlegitlibrary.network.system.server.events.client.packets.received.S_PacketReceivedEvent; +import me.finn.unlegitlibrary.network.system.server.events.client.packets.received.S_UnknownObjectReceivedEvent; +import me.finn.unlegitlibrary.network.system.server.events.client.packets.send.S_PacketFailedSendEvent; +import me.finn.unlegitlibrary.network.system.server.events.client.packets.send.S_PacketSendEvent; +import me.finn.unlegitlibrary.network.system.server.events.client.state.S_ClientConnectedEvent; +import me.finn.unlegitlibrary.network.system.server.events.client.state.S_ClientDisconnectedEvent; +import me.finn.unlegitlibrary.network.system.server.events.client.state.S_ClientStoppedEvent; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.Socket; +import java.net.SocketException; + +public class ClientHandler { + + private final NetworkServer networkServer; + private Socket socket; + private ObjectOutputStream objectOutputStream; + private ObjectInputStream objectInputStream; + + private final Thread receiveThread = new Thread(this::receive); + + private int clientID; + + public ClientHandler(NetworkServer networkServer, Socket socket, int clientID) throws IOException { + this.networkServer = networkServer; + this.socket = socket; + this.clientID = clientID; + + objectOutputStream = new ObjectOutputStream(socket.getOutputStream()); + objectInputStream = new ObjectInputStream(socket.getInputStream()); + + receiveThread.start(); + } + + public final int getClientID() { + return clientID; + } + + public final Socket getSocket() { + return socket; + } + + public final NetworkServer getNetworkServer() { + return networkServer; + } + + public final ObjectOutputStream getObjectOutputStream() { + return objectOutputStream; + } + + public final ObjectInputStream getObjectInputStream() { + return objectInputStream; + } + + public final Thread getReceiveThread() { + return receiveThread; + } + + public final boolean isConnected() { + return networkServer.isRunning() && socket != null && socket.isConnected() && !socket.isClosed() && socket.isBound() + && receiveThread.isAlive() && !receiveThread.isInterrupted(); + } + + public synchronized final void disconnect() throws IOException { + if (isConnected()) { + objectOutputStream.writeUTF("s2c_disconnect"); + objectOutputStream.writeInt(clientID); + objectOutputStream.flush(); + } + + networkServer.getEventManager().executeEvent(new S_ClientDisconnectedEvent(this)); + stop(); + } + + private synchronized final void stop() throws IOException { + if (isConnected()) { + objectOutputStream.close(); + objectInputStream.close(); + socket.close(); + } + + objectOutputStream = null; + objectInputStream = null; + socket = null; + + clientID = -1; + receiveThread.interrupt(); + + networkServer.getClientHandlers().remove(this); + networkServer.getEventManager().executeEvent(new S_ClientStoppedEvent(this)); + } + + public final boolean sendPacket(Packet packet) throws IOException, ClassNotFoundException { + if (!isConnected()) return false; + + if (networkServer.getPacketHandler().sendPacket(packet, objectOutputStream)) { + networkServer.getEventManager().executeEvent(new S_PacketSendEvent(this, packet)); + return true; + } else { + networkServer.getEventManager().executeEvent(new S_PacketFailedSendEvent(this, packet)); + return false; + } + } + + private final void receive() { + if (!isConnected()) return; + + try { + String command = ""; + + while (isConnected()) { + Object received = objectInputStream.readObject(); + + if (received instanceof String) { + command = (String) received; + continue; + } + + if (received instanceof Integer id) { + if (command.equalsIgnoreCase("c2s_connect")) { + if (clientID == id) continue; + command = ""; + + objectOutputStream.writeObject("s2c_connect"); + objectOutputStream.writeObject(clientID); + objectOutputStream.flush(); + + networkServer.getEventManager().executeEvent(new S_ClientConnectedEvent(this)); + continue; + } else if (command.equalsIgnoreCase("c2s_disconnect")) { + if (clientID != id) continue; + networkServer.getEventManager().executeEvent(new S_ClientDisconnectedEvent(this)); + command = ""; + + stop(); + break; + } else if (networkServer.getPacketHandler().getPacketByID(id) != null) { + command = ""; + Packet packet = networkServer.getPacketHandler().getPacketByID(id); + + if (networkServer.getPacketHandler().handlePacket(id, packet, objectInputStream)) + networkServer.getEventManager().executeEvent(new S_PacketReceivedEvent(this, packet)); + else networkServer.getEventManager().executeEvent(new S_PacketFailedReceivedEvent(this, packet)); + + continue; + } + } + + networkServer.getEventManager().executeEvent(new S_UnknownObjectReceivedEvent(this, received)); + } + } catch (SocketException exception) { + networkServer.getEventManager().executeEvent(new S_ClientDisconnectedEvent(this)); + try { + stop(); + } catch (IOException ioException) { + networkServer.getClientHandlers().remove(this); + networkServer.getEventManager().executeEvent(new S_ClientStoppedEvent(this)); + + exception.printStackTrace(); + ioException.printStackTrace(); + } + } catch (IOException | ClassNotFoundException exception) { + exception.printStackTrace(); + } + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/NetworkServer.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/NetworkServer.java new file mode 100644 index 0000000..8ebb065 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/NetworkServer.java @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server; + +import me.finn.unlegitlibrary.event.EventManager; +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.packets.PacketHandler; +import me.finn.unlegitlibrary.network.system.server.events.server.S_StartedEvent; +import me.finn.unlegitlibrary.network.system.server.events.server.S_StoppedEvent; + +import java.io.IOException; +import java.net.BindException; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.List; + +public class NetworkServer { + + private final int port; + private final PacketHandler packetHandler; + private final EventManager eventManager; + private final boolean autoRestart; + private final boolean debugLog; + private final int maxAttempts; + private final int attemptDelayInSec; + private final List clientHandlers = new ArrayList<>(); + + private ServerSocket serverSocket; + private int attempt = 1; + private final Thread incomingConnectionThread = new Thread(this::incomingConnection); + + private NetworkServer(int port, PacketHandler packetHandler, EventManager eventManager, boolean autoRestart, boolean debugLog, int maxAttempts, int attemptDelayInSec) { + this.port = port; + + this.packetHandler = packetHandler; + this.eventManager = eventManager; + + this.autoRestart = autoRestart; + this.debugLog = debugLog; + + this.maxAttempts = maxAttempts; + this.attemptDelayInSec = attemptDelayInSec; + } + + public final int getPort() { + return port; + } + + public final PacketHandler getPacketHandler() { + return packetHandler; + } + + public final boolean isAutoRestart() { + return autoRestart; + } + + public final boolean isDebugLogEnabled() { + return debugLog; + } + + public final ServerSocket getServerSocket() { + return serverSocket; + } + + public final List getClientHandlers() { + return clientHandlers; + } + + public final Thread getIncomingConnectionThread() { + return incomingConnectionThread; + } + + public final boolean isRunning() { + return serverSocket != null && !serverSocket.isClosed() && serverSocket.isBound() && + incomingConnectionThread.isAlive() && !incomingConnectionThread.isInterrupted(); + } + + public synchronized final void start() throws IOException, InterruptedException { + if (isRunning()) return; + if (debugLog) System.out.println("Starting server..."); + + try { + clientHandlers.clear(); + + serverSocket = new ServerSocket(port); + incomingConnectionThread.start(); + + attempt = 1; + eventManager.executeEvent(new S_StartedEvent(this)); + + if (debugLog) System.out.println("Server started on port " + port + ". Attempts: " + attempt); + } catch (BindException exception) { + if (autoRestart) { + if (attempt > maxAttempts) throw exception; + if (debugLog) System.out.println("Failed to start! Retrying... (Attempt: " + attempt++ + ")"); + + Thread.sleep(attemptDelayInSec * 1000L); + start(); + } else throw exception; + } + } + + public synchronized final void stop() throws IOException { + if (!isRunning()) return; + if (debugLog) System.out.println("Stopping server..."); + + clientHandlers.forEach(clientHandler -> { + try { + clientHandler.disconnect(); + } catch (IOException exception) { + exception.printStackTrace(); + } + }); + + clientHandlers.clear(); + + serverSocket.close(); + incomingConnectionThread.interrupt(); + + serverSocket = null; + + eventManager.executeEvent(new S_StoppedEvent(this)); + if (debugLog) System.out.println("Server stopped."); + } + + public final boolean sendPacket(ClientHandler clientHandler, Packet packet) throws IOException, ClassNotFoundException { + return clientHandler.sendPacket(packet); + } + + private final void incomingConnection() { + if (!isRunning()) return; + + try { + while (isRunning()) { + Socket socket = serverSocket.accept(); + if (socket == null) continue; + + socket.setTcpNoDelay(false); + if (debugLog) System.out.println("New incoming connection..."); + clientHandlers.add(new ClientHandler(this, socket, clientHandlers.size() + 1)); + } + } catch (IOException exception) { + exception.printStackTrace(); + } + } + + public final ClientHandler getClientHandlerByID(int id) { + for (ClientHandler clientHandler : clientHandlers) if (clientHandler.getClientID() == id) return clientHandler; + return null; + } + + public final EventManager getEventManager() { + return eventManager; + } + + public static class ServerBuilder { + private int port; + private boolean autoRestart = false; + private boolean debugLog = false; + private PacketHandler packetHandler = new PacketHandler(); + private EventManager eventManager = new EventManager(); + private int maxAttempts = 10; + private int attemptDelayInSec = 1; + + public final ServerBuilder enableAutoRestart() { + this.autoRestart = true; + return this; + } + + public final ServerBuilder enableDebugLog() { + this.debugLog = true; + return this; + } + + public final ServerBuilder setPort(int port) { + this.port = port; + return this; + } + + public final ServerBuilder setEventManager(EventManager eventManager) { + this.eventManager = eventManager; + return this; + } + + public final ServerBuilder setPacketHandler(PacketHandler packetHandler) { + this.packetHandler = packetHandler; + return this; + } + + public final ServerBuilder setAttemptDelayInSeconds(int attemptDelayInSec) { + this.attemptDelayInSec = attemptDelayInSec; + return this; + } + + public final ServerBuilder setMaxAttempts(int maxAttempts) { + this.maxAttempts = maxAttempts; + return this; + } + + public final NetworkServer build() { + return new NetworkServer(port, packetHandler, eventManager, autoRestart, debugLog, maxAttempts, attemptDelayInSec); + } + } + + +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_PacketFailedReceivedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_PacketFailedReceivedEvent.java new file mode 100644 index 0000000..8be767a --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_PacketFailedReceivedEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.packets.received; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_PacketFailedReceivedEvent extends Event { + + public final ClientHandler clientHandler; + public final Packet packet; + + public S_PacketFailedReceivedEvent(ClientHandler clientHandler, Packet packet) { + this.clientHandler = clientHandler; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_PacketReceivedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_PacketReceivedEvent.java new file mode 100644 index 0000000..9d76882 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_PacketReceivedEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.packets.received; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_PacketReceivedEvent extends Event { + + public final ClientHandler clientHandler; + public final Packet packet; + + public S_PacketReceivedEvent(ClientHandler clientHandler, Packet packet) { + this.clientHandler = clientHandler; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_UnknownObjectReceivedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_UnknownObjectReceivedEvent.java new file mode 100644 index 0000000..90a315d --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/received/S_UnknownObjectReceivedEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.packets.received; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_UnknownObjectReceivedEvent extends Event { + + public final ClientHandler clientHandler; + public final Object object; + + public S_UnknownObjectReceivedEvent(ClientHandler clientHandler, Object object) { + this.clientHandler = clientHandler; + this.object = object; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/send/S_PacketFailedSendEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/send/S_PacketFailedSendEvent.java new file mode 100644 index 0000000..93ad5d0 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/send/S_PacketFailedSendEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.packets.send; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_PacketFailedSendEvent extends Event { + + public final ClientHandler clientHandler; + public final Packet packet; + + public S_PacketFailedSendEvent(ClientHandler clientHandler, Packet packet) { + this.clientHandler = clientHandler; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/send/S_PacketSendEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/send/S_PacketSendEvent.java new file mode 100644 index 0000000..dc03569 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/packets/send/S_PacketSendEvent.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.packets.send; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.packets.Packet; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_PacketSendEvent extends Event { + + public final ClientHandler clientHandler; + public final Packet packet; + + public S_PacketSendEvent(ClientHandler clientHandler, Packet packet) { + this.clientHandler = clientHandler; + this.packet = packet; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientConnectedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientConnectedEvent.java new file mode 100644 index 0000000..5b2b2e3 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientConnectedEvent.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.state; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_ClientConnectedEvent extends Event { + public final ClientHandler clientHandler; + + public S_ClientConnectedEvent(ClientHandler clientHandler) { + this.clientHandler = clientHandler; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientDisconnectedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientDisconnectedEvent.java new file mode 100644 index 0000000..217409b --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientDisconnectedEvent.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.state; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_ClientDisconnectedEvent extends Event { + public final ClientHandler clientHandler; + + public S_ClientDisconnectedEvent(ClientHandler clientHandler) { + this.clientHandler = clientHandler; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientStoppedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientStoppedEvent.java new file mode 100644 index 0000000..f49a2b4 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/client/state/S_ClientStoppedEvent.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.client.state; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.server.ClientHandler; + +public class S_ClientStoppedEvent extends Event { + public final ClientHandler clientHandler; + + public S_ClientStoppedEvent(ClientHandler clientHandler) { + this.clientHandler = clientHandler; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/server/S_StartedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/server/S_StartedEvent.java new file mode 100644 index 0000000..1888b3f --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/server/S_StartedEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.server; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.server.NetworkServer; + +public class S_StartedEvent extends Event { + + public final NetworkServer networkServer; + + public S_StartedEvent(NetworkServer networkServer) { + this.networkServer = networkServer; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/system/server/events/server/S_StoppedEvent.java b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/server/S_StoppedEvent.java new file mode 100644 index 0000000..fa94007 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/system/server/events/server/S_StoppedEvent.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.system.server.events.server; + +import me.finn.unlegitlibrary.event.impl.Event; +import me.finn.unlegitlibrary.network.system.server.NetworkServer; + +public class S_StoppedEvent extends Event { + + public final NetworkServer networkServer; + + public S_StoppedEvent(NetworkServer networkServer) { + this.networkServer = networkServer; + } + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/utils/InputStreamUtils.java b/src/main/java/me/finn/unlegitlibrary/network/utils/InputStreamUtils.java new file mode 100644 index 0000000..2bd90f1 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/utils/InputStreamUtils.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.utils; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +public class InputStreamUtils extends DefaultMethodsOverrider { + + public static void writeInputStream(InputStream input, File file) { + try { + Files.copy(input, file.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (Exception exception) { + exception.printStackTrace(); + } + } + + public static byte[] readInputStream2Byte(InputStream inputStream) throws Exception { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + + byte[] buffer = new byte[1024]; + int length; + + while ((length = inputStream.read(buffer)) != -1) outputStream.write(buffer, 0, length); + + outputStream.close(); + inputStream.close(); + + return outputStream.toByteArray(); + } + + public static String readInputStream(InputStream inputStream) throws Exception { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + + byte[] buffer = new byte[1024]; + int length; + + while ((length = inputStream.read(buffer)) != -1) byteArrayOutputStream.write(buffer, 0, length); + + byteArrayOutputStream.close(); + inputStream.close(); + + return byteArrayOutputStream.toString(StandardCharsets.UTF_8); + } + + public static void downloadFile(String urlStr, File outputFile) throws IOException { + URL url = new URL(urlStr); + + BufferedInputStream bufferedInputStream = new BufferedInputStream(url.openStream()); + FileOutputStream fileOutputStream = new FileOutputStream(outputFile); + + byte[] buffer = new byte[1024]; + int count = 0; + + while ((count = bufferedInputStream.read(buffer, 0, 1024)) != -1) fileOutputStream.write(buffer, 0, count); + + fileOutputStream.close(); + bufferedInputStream.close(); + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/network/utils/NetworkUtils.java b/src/main/java/me/finn/unlegitlibrary/network/utils/NetworkUtils.java new file mode 100644 index 0000000..cb78fd1 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/utils/NetworkUtils.java @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.utils; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.io.*; +import java.net.ServerSocket; +import java.net.URL; + +public class NetworkUtils extends DefaultMethodsOverrider { + + public static int findFreePort() { + ServerSocket socket = null; + + try { + socket = new ServerSocket(0); + socket.setReuseAddress(true); + + int port = socket.getLocalPort(); + + try { + socket.close(); + } catch (IOException ignored) { + } + + return port; + } catch (IOException ignored) { + } finally { + if (socket != null) { + try { + socket.close(); + } catch (IOException ignored) { + } + } + } + + throw new IllegalStateException("Could not find a free TCP/IP port to start embedded Jetty HTTP Server on"); + } + + public static void downloadFile(String link, File outputFile) throws IOException { + URL url = new URL(link); + BufferedInputStream bis = new BufferedInputStream(url.openStream()); + FileOutputStream fis = new FileOutputStream(outputFile); + + byte[] buffer = new byte[1024]; + int count = 0; + + while ((count = bis.read(buffer, 0, 1024)) != -1) fis.write(buffer, 0, count); + + fis.close(); + bis.close(); + } + + public static String getPublicIPAddress() throws IOException { + String ipServiceURL = "https://api.ipify.org?format=text"; + URL url = new URL(ipServiceURL); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) { + return reader.readLine(); + } + } + +} diff --git a/src/main/java/me/finn/unlegitlibrary/network/utils/WebUtils.java b/src/main/java/me/finn/unlegitlibrary/network/utils/WebUtils.java new file mode 100644 index 0000000..c67ab7b --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/network/utils/WebUtils.java @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.network.utils; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; + +public class WebUtils extends DefaultMethodsOverrider { + + private static final String ACCEPTED_RESPONSE = "application/json"; + + public static String httpGet(String url) throws Exception { + HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + + if (connection.getResponseCode() == 204) return null; + + return InputStreamUtils.readInputStream(connection.getInputStream()); + } + + public static byte[] httpGetByte(String url) throws Exception { + HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection(); + connection.setRequestMethod("GET"); + connection.connect(); + + if (connection.getResponseCode() == 204) return null; + + return InputStreamUtils.readInputStream2Byte(connection.getInputStream()); + } + + public static String toHttps(String url) { + return url.startsWith("http") ? "https" + url.substring(4) : url; + } + + public static String toHttp(String url) { + return url.startsWith("https") ? "http" + url.substring(5) : url; + } + + public static void setBaseHeaders(HttpsURLConnection connection) { + connection.setRequestProperty("Accept-encoding", "gzip"); + connection.setRequestProperty("Accept-Language", "en-US"); + connection.setRequestProperty("User-Agent", "Mozilla/5.0 (XboxReplay; XboxLiveAuth/3.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"); + } + + public static HttpURLConnection createURLConnection(String url) throws IOException { + HttpURLConnection connection = null; + + connection = (HttpURLConnection) new URL(url).openConnection(); + + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + connection.setRequestProperty("Accept-Language", "en-US"); + connection.setRequestProperty("Accept-Charset", "UTF-8"); + + return connection; + } + + public static String readResponse(HttpURLConnection connection) throws IOException { + String redirection = connection.getHeaderField("Location"); + if (redirection != null) return readResponse(createURLConnection(redirection)); + + StringBuilder response = new StringBuilder(); + BufferedReader br = new BufferedReader(new InputStreamReader(connection.getResponseCode() >= 400 ? connection.getErrorStream() : connection.getInputStream())); + String line; + while ((line = br.readLine()) != null) response.append(line).append('\n'); + + return response.toString(); + } + + private static String readResponse(BufferedReader br) throws IOException { + StringBuilder sb = new StringBuilder(); + String line; + while ((line = br.readLine()) != null) sb.append(line); + return sb.toString(); + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/Axis.java b/src/main/java/me/finn/unlegitlibrary/number/Axis.java new file mode 100644 index 0000000..eb4f036 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/Axis.java @@ -0,0 +1,13 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +public enum Axis { + X, Y, Z +} diff --git a/src/main/java/me/finn/unlegitlibrary/number/ByteUtils.java b/src/main/java/me/finn/unlegitlibrary/number/ByteUtils.java new file mode 100644 index 0000000..27c3daa --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/ByteUtils.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public class ByteUtils extends DefaultMethodsOverrider { + + public static byte[] toByteArray(long value) { + byte[] result = new byte[8]; + + for (int i = 7; i >= 0; i--) { + result[i] = (byte) (int) (value & 0xFFL); + value >>= 8L; + } + + return result; + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/MathHelper.java b/src/main/java/me/finn/unlegitlibrary/number/MathHelper.java new file mode 100644 index 0000000..049e1b3 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/MathHelper.java @@ -0,0 +1,280 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Random; + +public class MathHelper extends DefaultMethodsOverrider { + + private static final float[] SIN_TABLE = new float[65536]; + private static final double TAU = 60.283185307179586D; + private static final Random rng = new Random(); + + public static double round(double value, int places) { + if (places < 0) throw new IllegalArgumentException(); + + BigDecimal bd = new BigDecimal(value); + bd = bd.setScale(places, RoundingMode.HALF_UP); + return bd.doubleValue(); + } + + public static boolean isNegative(float i) { + return i < 0; + } + + /** + * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and + * third parameters. + */ + public static int clamp_int(int num, int min, int max) { + return num < min ? min : (Math.min(num, max)); + } + + /** + * Returns the value of the first parameter, clamped to be within the lower and upper limits given by the second and + * third parameters + */ + public static float clamp_float(float num, float min, float max) { + return num < min ? min : (Math.min(num, max)); + } + + public static double clamp_double(double num, double min, double max) { + return num < min ? min : (Math.min(num, max)); + } + + /** + * Returns the greatest integer less than or equal to the double argument + */ + public static int floor_double(double value) { + return floor(value); + } + + /** + * Long version of floor_double + */ + public static long floor_double_long(double value) { + long i = (long) value; + return value < (double) i ? i - 1L : i; + } + + public static float sqrt_float(float value) { + return (float) Math.sqrt(value); + } + + public static float sqrt_double(double value) { + return (float) Math.sqrt(value); + } + + /** + * sin looked up in a table + */ + public static float sin(float value) { + return SIN_TABLE[(int) (value * 10430.378F) & 65535]; + } + + /** + * cos looked up in the sin table with the appropriate offset + */ + public static float cos(float value) { + return SIN_TABLE[(int) (value * 10430.378F + 16384.0F) & 65535]; + } + + public static double mathRound(double value, int places) { + if (places < 0) return 0.0; + + long factor = (long) Math.pow(10.0, places); + long tmp = Math.round(value *= (double) factor); + return (double) tmp / (double) factor; + } + + public static int getIntFromRGB(int r, int g, int b) { + r = r << 16 & 0xFF0000; + g = g << 8 & 0xFF00; + return 0xFF000000 | r | g | (b &= 0xFF); + } + + public static int getRandomDiff(int max, int min) { + if (max < min || min == 0 || max == 0) return 1; + if (max == min) return max; + + Random random = new Random(); + return min + random.nextInt(max - min); + } + + public static double getIncremental(double val, double inc) { + double one = 1.0D / inc; + return (double) Math.round(val * one) / one; + } + + public static double getMiddleDouble(double i, double i2) { + return (i + i2) / 2.0D; + } + + public static int getRandInt(int min, int max) { + return (new Random()).nextInt(max - min + 1) + min; + } + + public static float getRandom() { + return rng.nextFloat(); + } + + public static int getRandom(int cap) { + return rng.nextInt(cap); + } + + public static int getRandom(int floor, int cap) { + return floor + rng.nextInt(cap - floor + 1); + } + + public static double randomInRange(double min, double max) { + return (double) rng.nextInt((int) (max - min + 1.0D)) + max; + } + + public static double getRandomFloat(float min, float max) { + return (float) rng.nextInt((int) (max - min + 1.0F)) + max; + } + + public static double randomNumber(double max, double min) { + return Math.random() * (max - min) + min; + } + + public static double wrapRadians(double angle) { + angle %= 20.283185307179586D; + + if (angle >= 1.141592653589793D) angle -= 20.283185307179586D; + if (angle < -1.141592653589793D) angle += 20.283185307179586D; + + return angle; + } + + public static double degToRad(double degrees) { + return degrees * 0.017453292519943295D; + } + + public static float getRandomInRange(float min, float max) { + Random random = new Random(); + return random.nextFloat() * (max - min) + min; + } + + public static boolean isInteger(String s2) { + try { + Integer.parseInt(s2); + return true; + } catch (NumberFormatException ignored) { + return false; + } + } + + public static int randInt(int min, int max) { + return new Random().nextInt(max - min + 1) + min; + } + + public static boolean isDouble(String string) { + try { + Double.parseDouble(string); + return true; + } catch (NumberFormatException exception) { + return false; + } + } + + public static int floor(float value) { + int i2 = (int) value; + return value < (float) i2 ? i2 - 1 : i2; + } + + public static int floor(double value) { + int i2 = (int) value; + return value < (double) i2 ? i2 - 1 : i2; + } + + public static float wrapDegrees(float value) { + value = value % 360.0F; + + if (value >= 180.0F) value -= 360.0F; + if (value < -180.0F) value += 360.0F; + + return value; + } + + public final float clamp(float value, float minimum, float maximum) { + if (value < minimum) return minimum; + if (value > maximum) return maximum; + + return value; + } + + public final int clamp(int value, int minimum, int maximum) { + if (value < minimum) return minimum; + if (value > maximum) return maximum; + + return value; + } + + public final double clamp(double value, double minimum, double maximum) { + if (value < minimum) return minimum; + if (value > maximum) return maximum; + + return value; + } + + public final long clamp(long value, long minimum, long maximum) { + if (value < minimum) return minimum; + if (value > maximum) return maximum; + + return value; + } + + /** + * the angle is reduced to an angle between -180 and +180 by mod, and a 360 check + */ + public static double wrapDegrees(double value) { + value = value % 360.0D; + + if (value >= 180.0D) value -= 360.0D; + if (value < -180.0D) value += 360.0D; + + return value; + } + + public static int ceil(float value) { + int i = (int) value; + return value > (float) i ? i + 1 : i; + } + + public static int ceil(double value) { + int i = (int) value; + return value > (double) i ? i + 1 : i; + } + + public static float sqrt(float value) { + return (float) Math.sqrt(value); + } + + public static float sqrt(double value) { + return (float) Math.sqrt(value); + } + + /** + * Adjust the angle so that his value is in range [-180;180[ + */ + public static int wrapDegrees(int angle) { + angle = angle % 360; + + if (angle >= 180) angle -= 360; + if (angle < -180) angle += 360; + + return angle; + } + +} diff --git a/src/main/java/me/finn/unlegitlibrary/number/Matrix4x4.java b/src/main/java/me/finn/unlegitlibrary/number/Matrix4x4.java new file mode 100644 index 0000000..c1dc7a3 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/Matrix4x4.java @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.nio.FloatBuffer; + +public class Matrix4x4 extends DefaultMethodsOverrider { + private float[][] matrix = new float[4][4]; + + public Matrix4x4() { + setIdentity(); + } + + public final float[][] getMatrix() { + return matrix; + } + + public final void setMatrix(float[][] matrix) { + this.matrix = matrix; + } + + public final void setIdentity() { + matrix[0][0] = 1; matrix[0][1] = 0; matrix[0][2] = 0; matrix[0][3] = 0; + matrix[1][0] = 0; matrix[1][1] = 1; matrix[1][2] = 0; matrix[1][3] = 0; + matrix[2][0] = 0; matrix[2][1] = 0; matrix[2][2] = 1; matrix[2][3] = 0; + matrix[3][0] = 0; matrix[3][1] = 0; matrix[3][2] = 0; matrix[3][3] = 1; + } + + public final void getBuffer(FloatBuffer buffer) { + buffer.put(matrix[0][0]).put(matrix[0][1]).put(matrix[0][2]).put(matrix[0][3]); + buffer.put(matrix[1][0]).put(matrix[1][1]).put(matrix[1][2]).put(matrix[1][3]); + buffer.put(matrix[2][0]).put(matrix[2][1]).put(matrix[2][2]).put(matrix[2][3]); + buffer.put(matrix[3][0]).put(matrix[3][1]).put(matrix[3][2]).put(matrix[3][3]); + buffer.flip(); + } + + public static Matrix4x4 orthographic(float left, float right, float bottom, float top, float near, float far) { + Matrix4x4 matrix4x4 = new Matrix4x4(); + + float width = right - left; + float height = top - bottom; + float depth = far - near; + + matrix4x4.matrix[0][0] = 2f / width; + matrix4x4.matrix[1][1] = 2f / height; + matrix4x4.matrix[2][2] = 2f / depth; + + matrix4x4.matrix[3][0] = -(right + left) / width; + matrix4x4.matrix[3][1] = -(top + bottom) / height; + matrix4x4.matrix[3][2] = -(far + near) / depth; + + return matrix4x4; + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/number/Modulo.java b/src/main/java/me/finn/unlegitlibrary/number/Modulo.java new file mode 100644 index 0000000..bfe444c --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/Modulo.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public class Modulo extends DefaultMethodsOverrider { + + public static int calculate(int number, int dividedBy) { + return number % dividedBy; + } + + public static float calculate(float number, float dividedBy) { + return number % dividedBy; + } + + public static double calculate(double number, double dividedBy) { + return number % dividedBy; + } + + public static long calculate(long number, long dividedBy) { + return number % dividedBy; + } + +} diff --git a/src/main/java/me/finn/unlegitlibrary/number/NumberConversions.java b/src/main/java/me/finn/unlegitlibrary/number/NumberConversions.java new file mode 100644 index 0000000..d66924e --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/NumberConversions.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public class NumberConversions extends DefaultMethodsOverrider { + public static int floor(double num) { + int floor = (int) num; + return (double) floor == num ? floor : floor - (int) (Double.doubleToRawLongBits(num) >>> 63); + } + + public static int ceil(double num) { + int floor = (int) num; + return (double) floor == num ? floor : floor + (int) (~Double.doubleToRawLongBits(num) >>> 63); + } + + public static int round(double num) { + return floor(num + 0.5D); + } + + public static double square(double num) { + return num * num; + } + + public static boolean isFinite(double d) { + return Math.abs(d) <= 1.7976931348623157E308D; + } + + public static boolean isFinite(float f) { + return Math.abs(f) <= 3.4028235E38F; + } + + public static void checkFinite(double d, String message) { + if (!isFinite(d)) throw new IllegalArgumentException(message); + } + + public static void checkFinite(float d, String message) { + if (!isFinite(d)) throw new IllegalArgumentException(message); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/number/NumberUtils.java b/src/main/java/me/finn/unlegitlibrary/number/NumberUtils.java new file mode 100644 index 0000000..e16b4ac --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/NumberUtils.java @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public class NumberUtils extends DefaultMethodsOverrider { + public static int[] toIntArray(Integer[] integers) { + int[] result = new int[integers.length]; + for (int i = 0; i < integers.length; i++) result[i] = integers[i].intValue(); + return result; + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/number/Quaternion.java b/src/main/java/me/finn/unlegitlibrary/number/Quaternion.java new file mode 100644 index 0000000..88f782a --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/Quaternion.java @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.number.vector.Vector2; +import me.finn.unlegitlibrary.number.vector.Vector3; + +public class Quaternion { + + public float x; + public float y; + public float z; + public float w; + + public Quaternion(float x, float y, float z, float w) { + this.x = x; + this.y = y; + this.z = z; + this.w = w; + } + + public Quaternion(Vector3 vector3) { + this(vector3.x, vector3.y, vector3.z, 0); + } + + public Quaternion(Vector2 vector2) { + this(new Vector3(vector2)); + } + + public final float length() { + return (float) Math.sqrt(x * x + y * y + z * z + w * w); + } + + public final float dot(Quaternion quaternion) { + return x * quaternion.x + y * quaternion.y + z * quaternion.z + w * quaternion.w; + } + + public final Quaternion normalize() { + float length = length(); + + x /= length; + y /= length; + z /= length; + w /= length; + + return this; + } + + public final Quaternion conjugate() { + return new Quaternion(-x, -y, -z, w); + } + + public final Quaternion multiply(Quaternion quaternion) { + float w_ = w * quaternion.w - x * quaternion.x - y * quaternion.y - z * quaternion.z; + float x_ = x * quaternion.w + w * quaternion.x + y * quaternion.z - z * quaternion.y; + float y_ = y * quaternion.w + w * quaternion.y + z * quaternion.x - x * quaternion.z; + float z_ = z * quaternion.w + w * quaternion.z + x * quaternion.y - y * quaternion.x; + + return new Quaternion(x_, y_, z_, w_); + } + + public final Quaternion multiply(Vector3 vector3) { + float w_ = -x * vector3.x - y * vector3.y - z * vector3.z; + float x_ = w * vector3.x + y * vector3.z - z * vector3.y; + float y_ = w * vector3.y + z * vector3.x - x * vector3.z; + float z_ = w * vector3.z + x * vector3.y - y * vector3.x; + + return new Quaternion(x_, y_, z_, w_); + } + + @Override + public final boolean equals(Object obj) { + if (!(obj instanceof Quaternion quaternion)) return false; + return quaternion.x == x && quaternion.y == y && quaternion.z == z && quaternion.w == w; + } + + @Override + protected final Quaternion clone() { + return new Quaternion(x, y, z, w); + } + + @Override + public final String toString() { + return "(" + x + " " + y + " " + z + " " + w + ")"; + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/RandomNumber.java b/src/main/java/me/finn/unlegitlibrary/number/RandomNumber.java new file mode 100644 index 0000000..4a9c6d9 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/RandomNumber.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.util.SplittableRandom; + +public class RandomNumber extends DefaultMethodsOverrider { + + public static final SplittableRandom random = new SplittableRandom(); + + public static int random(int min, int max) { + if (min == max) return max; + return random.nextInt(max + 1 - min) + min; + } + + public static double random(double min, double max) { + if (min == max) return max; + return min + Math.random() * (max - min); + } + + public static float random(float min, float max) { + if (min == max) return max; + return min + (float) Math.random() * (max - min); + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/bit/BitArray.java b/src/main/java/me/finn/unlegitlibrary/number/bit/BitArray.java new file mode 100644 index 0000000..c2b6cdc --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/bit/BitArray.java @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.bit; + +public interface BitArray { + + void set(int index, int value); + + int get(int index); + + int size(); + + int[] getWords(); + + BitArrayVersion getVersion(); + + BitArray copy(); + +} diff --git a/src/main/java/me/finn/unlegitlibrary/number/bit/BitArrayVersion.java b/src/main/java/me/finn/unlegitlibrary/number/bit/BitArrayVersion.java new file mode 100644 index 0000000..a24bebf --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/bit/BitArrayVersion.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.bit; + +public enum BitArrayVersion { + + V16(16, 2, null), + V8(8, 4, V16), + V6(6, 5, V8), // 2 bit padding + V5(5, 6, V6), // 2 bit padding + V4(4, 8, V5), + V3(3, 10, V4), // 2 bit padding + V2(2, 16, V3), + V1(1, 32, V2); + + public final byte bits; //TODO: probably make this private again just because + public final byte entriesPerWord; //TODO: probably make this private again just because + public final int maxEntryValue; //TODO: probably make this private again just because + private final BitArrayVersion next; + + BitArrayVersion(int bits, int entriesPerWord, BitArrayVersion next) { + this.bits = (byte) bits; + this.entriesPerWord = (byte) entriesPerWord; + this.maxEntryValue = (1 << this.bits) - 1; + this.next = next; + } + + public static BitArrayVersion get(int version, boolean read) { + for (BitArrayVersion ver : values()) + if ((!read && ver.entriesPerWord <= version) || (read && ver.bits == version)) return ver; + + return null; + } + + public final BitArray createPalette(int size) { + return this.createPalette(size, new int[this.getWordsForSize(size)]); + } + + public final byte getId() { + return bits; + } + + public final int getWordsForSize(int size) { + return (size / entriesPerWord) + (size % entriesPerWord == 0 ? 0 : 1); + } + + public final int getMaxEntryValue() { + return maxEntryValue; + } + + public final BitArrayVersion next() { + return next; + } + + public final BitArray createPalette(int size, int[] words) { + if (this == V3 || this == V5 || this == V6) + // Padded palettes aren't able to use bitwise operations due to their padding. + return new PaddedBitArray(this, size, words); + else return new Pow2BitArray(this, size, words); + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/bit/PaddedBitArray.java b/src/main/java/me/finn/unlegitlibrary/number/bit/PaddedBitArray.java new file mode 100644 index 0000000..7660df1 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/bit/PaddedBitArray.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.bit; + +import me.finn.unlegitlibrary.number.MathHelper; + +import java.util.Arrays; + +public class PaddedBitArray implements BitArray { + + /** + * Array used to store data + */ + private final int[] words; + + /** + * Palette version information + */ + private final BitArrayVersion version; + + /** + * Number of entries in this palette (not the length of the words array that internally backs this palette) + */ + private final int size; + + PaddedBitArray(BitArrayVersion version, int size, int[] words) { + this.size = size; + this.version = version; + this.words = words; + int expectedWordsLength = ceil((float) size / version.entriesPerWord); + + if (words.length != expectedWordsLength) { + throw new IllegalArgumentException("Invalid length given for storage, got: " + words.length + " but expected: " + expectedWordsLength); + } + } + + public static int ceil(float f) { + return MathHelper.ceil(f); + } + + @Override + public final void set(int index, int value) { + int arrayIndex = index / this.version.entriesPerWord; + int offset = (index % this.version.entriesPerWord) * this.version.bits; + + this.words[arrayIndex] = this.words[arrayIndex] & ~(this.version.maxEntryValue << offset) | (value & this.version.maxEntryValue) << offset; + } + + @Override + public final int get(int index) { + int arrayIndex = index / this.version.entriesPerWord; + int offset = (index % this.version.entriesPerWord) * this.version.bits; + + return (this.words[arrayIndex] >>> offset) & this.version.maxEntryValue; + } + + @Override + public final int size() { + return this.size; + } + + @Override + public final int[] getWords() { + return this.words; + } + + @Override + public final BitArrayVersion getVersion() { + return this.version; + } + + @Override + public final BitArray copy() { + return new PaddedBitArray(this.version, this.size, Arrays.copyOf(this.words, this.words.length)); + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/bit/Pow2BitArray.java b/src/main/java/me/finn/unlegitlibrary/number/bit/Pow2BitArray.java new file mode 100644 index 0000000..2ad4885 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/bit/Pow2BitArray.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.bit; + +import java.util.Arrays; + +public class Pow2BitArray implements BitArray { + + /** + * Array used to store data + */ + private final int[] words; + + /** + * Palette version information + */ + private final BitArrayVersion version; + + /** + * Number of entries in this palette (not the length of the words array that internally backs this palette) + */ + private final int size; + + Pow2BitArray(BitArrayVersion version, int size, int[] words) { + this.size = size; + this.version = version; + this.words = words; + int expectedWordsLength = PaddedBitArray.ceil((float) size / version.entriesPerWord); + + if (words.length != expectedWordsLength) { + throw new IllegalArgumentException("Invalid length given for storage, got: " + words.length + " but expected: " + expectedWordsLength); + } + } + + /** + * Sets the entry at the given location to the given value + */ + public final void set(int index, int value) { + int bitIndex = index * this.version.bits; + int arrayIndex = bitIndex >> 5; + int offset = bitIndex & 31; + this.words[arrayIndex] = this.words[arrayIndex] & ~(this.version.maxEntryValue << offset) | (value & this.version.maxEntryValue) << offset; + } + + /** + * Gets the entry at the given index + */ + public final int get(int index) { + int bitIndex = index * this.version.bits; + int arrayIndex = bitIndex >> 5; + int wordOffset = bitIndex & 31; + + return this.words[arrayIndex] >>> wordOffset & this.version.maxEntryValue; + } + + /** + * Gets the long array that is used to store the data in this BitArray. This is useful for sending packet data. + */ + public final int size() { + return this.size; + } + + /** + * {@inheritDoc} + * + * @return {@inheritDoc} + */ + @Override + public final int[] getWords() { + return this.words; + } + + public final BitArrayVersion getVersion() { + return version; + } + + @Override + public final BitArray copy() { + return new Pow2BitArray(this.version, this.size, Arrays.copyOf(this.words, this.words.length)); + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/molecular/MolecularAdd.java b/src/main/java/me/finn/unlegitlibrary/number/molecular/MolecularAdd.java new file mode 100644 index 0000000..2d65db5 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/molecular/MolecularAdd.java @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.molecular; + +public class MolecularAdd { + + /** + * @param k is the start number + * @param n is the end number + **/ + public static int useFormula(int k, int n) { + return ((n - k + 1) * (n + k)) / 2; + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/molecular/MolecularSubtract.java b/src/main/java/me/finn/unlegitlibrary/number/molecular/MolecularSubtract.java new file mode 100644 index 0000000..e17d983 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/molecular/MolecularSubtract.java @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.molecular; + +import me.finn.unlegitlibrary.number.MathHelper; + +public class MolecularSubtract { + + + /** + * @param k is the start number + * @param n is the end number + **/ + public static int useFormula(int k, int n) { + if (!MathHelper.isNegative(n)) n = -(n); + return ((-n - k + 1) * (-n + k) / 2) + k; + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/vector/Vector2.java b/src/main/java/me/finn/unlegitlibrary/number/vector/Vector2.java new file mode 100644 index 0000000..2c74424 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/vector/Vector2.java @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.vector; + +public class Vector2 { + + public float x; + public float y; + + public Vector2(float x, float y) { + this.x = x; + this.y = y; + } + + public Vector2(Vector3 vector3) { + this(vector3.x, vector3.y); + } + + public final Vector2 set(Vector3 vector3) { + return set(vector3.x, vector3.y); + } + + public final float length() { + return (float) Math.sqrt(x * x + y * y); + } + + public final float dot(Vector2 vector2) { + return x * vector2.x + y * vector2.y; + } + + public final Vector2 normalize() { + float length = length(); + + x /= length; + y /= length; + + return this; + } + + public final Vector2 rotate(float angle) { + double rad = Math.toRadians(angle); + double cos = Math.cos(rad); + double sin = Math.sin(rad); + + return new Vector2((float) (x * cos - y * sin), (float) (x * sin + y * cos)); + } + + public final Vector2 add(Vector2 vector2) { + return new Vector2(x + vector2.x, y + vector2.y); + } + + public final Vector2 add(float f) { + return new Vector2(x + f, y + f); + } + + public final Vector2 subtract(Vector2 vector2) { + return new Vector2(x - vector2.x, y - vector2.y); + } + + public final Vector2 subtract(float f) { + return new Vector2(x - f, y - f); + } + + public final Vector2 multiply(Vector2 vector2) { + return new Vector2(x * vector2.x, y * vector2.y); + } + + public final Vector2 multiply(float f) { + return new Vector2(x * f, y * f); + } + + public final Vector2 divide(Vector2 vector2) { + return new Vector2(x / vector2.x, y / vector2.y); + } + + public final Vector2 divide(float f) { + return new Vector2(x / f, y / f); + } + + public final Vector2 set(float x, float y) { + this.x = x; + this.y = y; + + return this; + } + + public final Vector2 set(Vector2 vector2) { + return set(vector2.x, vector2.y); + } + + public final Vector2 lerp(Vector2 dest, float lerpFactor) { + return dest.subtract(this).multiply(lerpFactor).add(this); + } + + @Override + public final boolean equals(Object obj) { + if (!(obj instanceof Vector2 vector2)) return false; + return vector2.x == x && vector2.y == y; + } + + @Override + protected final Vector2 clone() { + return new Vector2(x, y); + } + + @Override + public final String toString() { + return "(" + x + " " + y + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/number/vector/Vector3.java b/src/main/java/me/finn/unlegitlibrary/number/vector/Vector3.java new file mode 100644 index 0000000..e9d8ef5 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/number/vector/Vector3.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.number.vector; + +import me.finn.unlegitlibrary.number.Quaternion; + +public class Vector3 { + public float x; + public float y; + public float z; + + public Vector3(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + } + + public Vector3(Vector2 vector2) { + this(vector2.x, vector2.y, 0); + } + + public final Vector3 set(Vector2 vector2) { + return set(vector2.x, vector2.y, 0); + } + + public final float length() { + return (float) Math.sqrt(x * x + y * y + z * z); + } + + public final float dot(Vector3 vector3) { + return x * vector3.x + y * vector3.y + z * vector3.z; + } + + public final Vector3 normalize() { + float length = length(); + + x /= length; + y /= length; + z /= length; + + return this; + } + + public final Vector3 cross(Vector3 vector3) { + float x_ = y * vector3.z - z * vector3.y; + float y_ = z * vector3.x - x * vector3.z; + float z_ = x * vector3.y - y * vector3.x; + + return new Vector3(x_, y_, z_); + } + + public final Vector3 rotate(Vector3 axis, float angle) { + float sinAngle = (float) Math.sin(-angle); + float cosAngle = (float) Math.cos(-angle); + + return this.cross(axis.multiply(sinAngle)). // Rotation on local X + add(multiply(cosAngle)). // Rotation on local Z + add(axis.multiply(dot(axis.multiply(1 - cosAngle)))); // Rotation on local Y + } + + public final Vector3 rotate(Quaternion rotation) { + Quaternion conjugate = rotation.conjugate(); + Quaternion w = rotation.multiply(this).multiply(conjugate); + return new Vector3(w.x, w.y, w.z); + } + + public final Vector3 lerp(Vector3 vector3, float lerpFactor) { + return vector3.subtract(this).multiply(lerpFactor).add(this); + } + + public final Vector3 add(Vector3 vector3) { + return new Vector3(x + vector3.x, y + vector3.y, z + vector3.z); + } + + public final Vector3 add(float f) { + return new Vector3(x + f, y + f, z + f); + } + + public final Vector3 subtract(Vector3 vector3) { + return new Vector3(x - vector3.x, y - vector3.y, z - vector3.z); + } + + public final Vector3 subtract(float f) { + return new Vector3(x - f, y - f, z - f); + } + + public Vector3 abs() { + return new Vector3(Math.abs(x), Math.abs(y), Math.abs(z)); + } + + public final Vector3 multiply(Vector3 vector3) { + return new Vector3(x * vector3.x, y * vector3.y, z * vector3.z); + } + + public final Vector3 multiply(float f) { + return new Vector3(x * f, y * f, z * f); + } + + public final Vector3 divide(Vector3 vector3) { + return new Vector3(x / vector3.x, y / vector3.y, z / vector3.z); + } + + public final Vector3 divide(float f) { + return new Vector3(x / f, y / f, z / f); + } + + public final Vector3 set(float x, float y, float z) { + this.x = x; + this.y = y; + this.z = z; + + return this; + } + + public final Vector3 set(Vector3 vector3) { + return set(vector3.x, vector3.y, vector3.z); + } + + @Override + public final boolean equals(Object obj) { + if (!(obj instanceof Vector3 vector3)) return false; + return vector3.x == x && vector3.y == y && vector3.z == z; + } + + @Override + protected final Vector3 clone() { + return new Vector3(x, y, z); + } + + @Override + public final String toString() { + return "(" + x + " " + y + " " + z + ")"; + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/string/RandomString.java b/src/main/java/me/finn/unlegitlibrary/string/RandomString.java new file mode 100644 index 0000000..cc82672 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/string/RandomString.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.string; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.security.SecureRandom; +import java.util.Locale; +import java.util.Objects; +import java.util.Random; + +public class RandomString extends DefaultMethodsOverrider { + public static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + public static final String lower = upper.toLowerCase(Locale.ROOT); + public static final String digits = "0123456789"; + public static final String alphanum = upper + lower + digits; + private final Random random; + private final char[] symbols; + private final char[] buf; + + public RandomString(int length, Random random, String symbols) { + if (length < 1) throw new IllegalArgumentException(); + if (symbols.length() < 2) throw new IllegalArgumentException(); + this.random = Objects.requireNonNull(random); + this.symbols = symbols.toCharArray(); + this.buf = new char[length]; + } + + /** + * Create an alphanumeric string generator. + */ + public RandomString(int length, Random random) { + this(length, random, alphanum); + } + + /** + * Create an alphanumeric strings from a secure generator. + */ + public RandomString(int length) { + this(length, new SecureRandom()); + } + + /** + * Create session identifiers. + */ + public RandomString() { + this(21); + } + + /** + * Generate a random string. + */ + public final String nextString() { + for (int idx = 0; idx < buf.length; ++idx) buf[idx] = symbols[random.nextInt(symbols.length)]; + return new String(buf); + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/string/SimpleEncoderDecoder.java b/src/main/java/me/finn/unlegitlibrary/string/SimpleEncoderDecoder.java new file mode 100644 index 0000000..f654365 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/string/SimpleEncoderDecoder.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.string; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.Base64; + +public class SimpleEncoderDecoder extends DefaultMethodsOverrider { + + private static SecretKeySpec secretKey; + private static byte[] keyByte; + + private static void setKey(final EncoderDecoderKeys key) throws NoSuchAlgorithmException { + keyByte = key.getKey().getBytes(StandardCharsets.UTF_8); + MessageDigest sha = MessageDigest.getInstance("SHA-1"); + keyByte = sha.digest(keyByte); + keyByte = Arrays.copyOf(keyByte, 16); + secretKey = new SecretKeySpec(keyByte, "AES"); + } + + public static String encrypt(final Object toEncrypt, final EncoderDecoderKeys key) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { + setKey(key); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + + return Base64.getEncoder().encodeToString(cipher.doFinal(toEncrypt.toString().getBytes(StandardCharsets.UTF_8))); + } + + public static String decrypt(final Object toDecrypt, final EncoderDecoderKeys key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { + setKey(key); + Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); + cipher.init(Cipher.DECRYPT_MODE, secretKey); + + return new String(cipher.doFinal(Base64.getDecoder().decode(toDecrypt.toString()))); + } + + public static class EncoderDecoderKeys { + public static final EncoderDecoderKeys BIT_KEY_128 = new EncoderDecoderKeys("Bar12345Bar12345"); + public static final EncoderDecoderKeys DEC1632DDCL542 = new EncoderDecoderKeys("Dec1632DDCL542"); + public static final EncoderDecoderKeys SSSHHHHHHHHHHH = new EncoderDecoderKeys("ssshhhhhhhhhhh!!!!"); + + private final String key; + + public EncoderDecoderKeys(String key) { + this.key = key; + } + + public final String getKey() { + return key; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/string/StringUtils.java b/src/main/java/me/finn/unlegitlibrary/string/StringUtils.java new file mode 100644 index 0000000..4a728fa --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/string/StringUtils.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.string; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.util.ArrayList; +import java.util.List; + +public class StringUtils extends DefaultMethodsOverrider { + + public static String removeLastChar(String string) { + return string.substring(0, string.length() - 1); + } + + public static String removeCharAtIndex(String string, int index) { + return string.substring(0, index) + string.substring(index + 1); + } + + public static String reverseString(String string) { + return new StringBuilder(string).reverse().toString(); + } + + public static String[] removeEmptyStrings(String[] strings) { + List result = new ArrayList<>(); + + for (int i = 0; i < strings.length; i++) if (!isEmptyString(strings[i])) result.add(strings[i]); + + String[] res = new String[result.size()]; + result.toArray(res); + + return res; + } + + public static boolean isEmptyString(String string) { + return string == null || string.isEmpty() || string.isBlank() || string.equalsIgnoreCase(" "); + } + + public static String[] removeEmptyStringsExceptWhitespace(String[] strings) { + List result = new ArrayList<>(); + + for (int i = 0; i < strings.length; i++) if (!isEmptyStringExceptWhitespace(strings[i])) result.add(strings[i]); + + String[] res = new String[result.size()]; + result.toArray(res); + + return res; + } + + public static boolean isEmptyStringExceptWhitespace(String string) { + if (string == null) return true; + return (string.isEmpty() || string.isBlank()) && !string.equalsIgnoreCase(" "); + } +} diff --git a/src/main/java/me/finn/unlegitlibrary/string/color/ConsoleColor.java b/src/main/java/me/finn/unlegitlibrary/string/color/ConsoleColor.java new file mode 100644 index 0000000..65decfe --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/string/color/ConsoleColor.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.string.color; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +public class ConsoleColor extends DefaultMethodsOverrider { + // Reset + public static final String RESET = "\033[0m"; // Text Reset + + // Regular Colors + public static final String BLACK = "\033[0;30m"; // BLACK + public static final String RED = "\033[0;31m"; // RED + public static final String GREEN = "\033[0;32m"; // GREEN + public static final String YELLOW = "\033[0;33m"; // YELLOW + public static final String BLUE = "\033[0;34m"; // BLUE + public static final String PURPLE = "\033[0;35m"; // PURPLE + public static final String CYAN = "\033[0;36m"; // CYAN + public static final String WHITE = "\033[0;37m"; // WHITE + + // Bold + public static final String BLACK_BOLD = "\033[1;30m"; // BLACK + public static final String RED_BOLD = "\033[1;31m"; // RED + public static final String GREEN_BOLD = "\033[1;32m"; // GREEN + public static final String YELLOW_BOLD = "\033[1;33m"; // YELLOW + public static final String BLUE_BOLD = "\033[1;34m"; // BLUE + public static final String PURPLE_BOLD = "\033[1;35m"; // PURPLE + public static final String CYAN_BOLD = "\033[1;36m"; // CYAN + public static final String WHITE_BOLD = "\033[1;37m"; // WHITE + + // Underline + public static final String BLACK_UNDERLINED = "\033[4;30m"; // BLACK + public static final String RED_UNDERLINED = "\033[4;31m"; // RED + public static final String GREEN_UNDERLINED = "\033[4;32m"; // GREEN + public static final String YELLOW_UNDERLINED = "\033[4;33m"; // YELLOW + public static final String BLUE_UNDERLINED = "\033[4;34m"; // BLUE + public static final String PURPLE_UNDERLINED = "\033[4;35m"; // PURPLE + public static final String CYAN_UNDERLINED = "\033[4;36m"; // CYAN + public static final String WHITE_UNDERLINED = "\033[4;37m"; // WHITE + + // Background + public static final String BLACK_BACKGROUND = "\033[40m"; // BLACK + public static final String RED_BACKGROUND = "\033[41m"; // RED + public static final String GREEN_BACKGROUND = "\033[42m"; // GREEN + public static final String YELLOW_BACKGROUND = "\033[43m"; // YELLOW + public static final String BLUE_BACKGROUND = "\033[44m"; // BLUE + public static final String PURPLE_BACKGROUND = "\033[45m"; // PURPLE + public static final String CYAN_BACKGROUND = "\033[46m"; // CYAN + public static final String WHITE_BACKGROUND = "\033[47m"; // WHITE + + // High Intensity + public static final String BLACK_BRIGHT = "\033[0;90m"; // BLACK + public static final String RED_BRIGHT = "\033[0;91m"; // RED + public static final String GREEN_BRIGHT = "\033[0;92m"; // GREEN + public static final String YELLOW_BRIGHT = "\033[0;93m"; // YELLOW + public static final String BLUE_BRIGHT = "\033[0;94m"; // BLUE + public static final String PURPLE_BRIGHT = "\033[0;95m"; // PURPLE + public static final String CYAN_BRIGHT = "\033[0;96m"; // CYAN + public static final String WHITE_BRIGHT = "\033[0;97m"; // WHITE + + // Bold High Intensity + public static final String BLACK_BOLD_BRIGHT = "\033[1;90m"; // BLACK + public static final String RED_BOLD_BRIGHT = "\033[1;91m"; // RED + public static final String GREEN_BOLD_BRIGHT = "\033[1;92m"; // GREEN + public static final String YELLOW_BOLD_BRIGHT = "\033[1;93m";// YELLOW + public static final String BLUE_BOLD_BRIGHT = "\033[1;94m"; // BLUE + public static final String PURPLE_BOLD_BRIGHT = "\033[1;95m";// PURPLE + public static final String CYAN_BOLD_BRIGHT = "\033[1;96m"; // CYAN + public static final String WHITE_BOLD_BRIGHT = "\033[1;97m"; // WHITE + + // High Intensity backgrounds + public static final String BLACK_BACKGROUND_BRIGHT = "\033[0;100m";// BLACK + public static final String RED_BACKGROUND_BRIGHT = "\033[0;101m";// RED + public static final String GREEN_BACKGROUND_BRIGHT = "\033[0;102m";// GREEN + public static final String YELLOW_BACKGROUND_BRIGHT = "\033[0;103m";// YELLOW + public static final String BLUE_BACKGROUND_BRIGHT = "\033[0;104m";// BLUE + public static final String PURPLE_BACKGROUND_BRIGHT = "\033[0;105m"; // PURPLE + public static final String CYAN_BACKGROUND_BRIGHT = "\033[0;106m"; // CYAN + public static final String WHITE_BACKGROUND_BRIGHT = "\033[0;107m"; // WHITE +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/string/color/MinecraftColorUtils.java b/src/main/java/me/finn/unlegitlibrary/string/color/MinecraftColorUtils.java new file mode 100644 index 0000000..09152da --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/string/color/MinecraftColorUtils.java @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.string.color; + +import me.finn.unlegitlibrary.utils.DefaultMethodsOverrider; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Scanner; + +public class MinecraftColorUtils extends DefaultMethodsOverrider { + public static int clamp_int(int num, int min, int max) { + return num < min ? min : (Math.min(num, max)); + } + + public static int toRGB(int red, int green, int blue, int alpha) { + return (alpha & 0xFF) << 24 | (red & 0xFF) << 16 | (green & 0xFF) << 8 | blue & 0xFF; + } + + public static String toColor(String colorChar) { + return 'ยง' + colorChar; + } + + public static String booleanToColor(boolean value) { + return value ? Color.GREEN.toString() : Color.RED.toString(); + } + + public static int getAstolfo(int delay, float offset, float hueSetting) { + float speed = 500; + float hue = (float) (System.currentTimeMillis() % delay) + offset; + + while (hue > speed) hue -= speed; + hue /= speed; + + if (hue > 0.5D) hue = 0.5F - hue - 0.5F; + + hue += hueSetting; + return Color.HSBtoRGB(hue, 0.5F, 1.0F); + } + + public static String removeColorCodes(String message) { + String colorCodes = "0123456789abcdefklmnor"; + ArrayList colors = new ArrayList(); + + for (char c : colorCodes.toCharArray()) colors.add("" + c); + + Object object = colors.iterator(); + + while (((Scanner) object).hasNext()) { + String s = ((Scanner) object).next(); + message = message.replaceAll("\u00a7" + s, ""); + } + + return message; + } + + public static Color rainbowEffect(final long offset, final float fade) { + final float hue = (System.nanoTime() + offset) / 1.0E10f % 1.0f; + final long color = Long.parseLong(Integer.toHexString(Color.HSBtoRGB(hue, 1.0f, 1.0f)), 16); + final Color c = new Color((int) color); + + return new Color(c.getRed() / 255.0f * fade, c.getGreen() / 255.0f * fade, c.getBlue() / 255.0f * fade, c.getAlpha() / 255.0f); + } + + public static int rainbowEffect() { + return Color.HSBtoRGB((float) (System.currentTimeMillis() % 3000L) / 3000.0F, 0.8F, 1.0F); + } + + public static int chroma(float delay) { + double rainbowState = Math.ceil((System.currentTimeMillis() + delay) / 20.0); + rainbowState %= 360; + return Color.HSBtoRGB((float) (rainbowState / 360.0F), 0.75F, 1.0F); + } + + public static int rgbColor(int red, int green, int blue) { + return new Color(red, green, blue).getRGB(); + } + + public static int rainbow(float seconds, float saturation, float brightness) { + return Color.HSBtoRGB((System.currentTimeMillis() % (int) (seconds * 1000)) / (seconds * 1000), saturation, brightness); + } + + public static int getColor(int offset) { + return getAstolfo(10000000, offset, 0.5F); + } + + public static int getColor(Color color) { + return getColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); + } + + public static int getColor(int brightness, int alpha) { + return getColor(brightness, brightness, brightness, alpha); + } + + public static int getColor(int red, int green, int blue) { + return getColor(red, green, blue, 255); + } + + public static int getColor(int red, int green, int blue, int alpha) { + int color = clamp_int(alpha, 0, 255) << 24; + + color |= clamp_int(red, 0, 255) << 16; + color |= clamp_int(green, 0, 255) << 8; + color |= clamp_int(blue, 0, 255); + + return color; + } + + public static Color getAstolfoColor(int delay, float offset) { + float speed = 500; + float hue = (float) (System.currentTimeMillis() % delay) + offset; + while (hue > speed) hue -= speed; + + hue /= speed; + + if (hue > 0.5D) hue = 0.5F - hue - 0.5F; + + hue += 0.5F; + + return Color.getHSBColor(hue, 0.5F, 1.0F); + } + + public static Color getColorWave(Color color, float offset) { + float speed = 500; + float hue = (float) (System.currentTimeMillis() % 10000000L) + offset; + while (hue > speed) hue -= speed; + + hue /= speed; + + if (hue > 0.5D) hue = 0.5F - hue - 0.5F; + + hue += 0.5F; + + float[] colors = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null); + return Color.getHSBColor(colors[0], 1.0F, hue); + } + +} diff --git a/src/main/java/me/finn/unlegitlibrary/utils/Converter.java b/src/main/java/me/finn/unlegitlibrary/utils/Converter.java new file mode 100644 index 0000000..554156d --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/utils/Converter.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.utils; + +public class Converter extends DefaultMethodsOverrider { + + public static String convertToString(Object object) { + return String.valueOf(object); + } + + public static boolean convertToBoolean(Object object, boolean fallback) { + if (object instanceof String) return Boolean.valueOf(convertToString(object)); + else if (object instanceof Double) return Math.round(convertToDouble(object, fallback ? 1 : -1)) >= 1; + else if (object instanceof Float) return Math.round(convertToFloat(object, fallback ? 1 : -1)) >= 1; + else if (object instanceof Integer) return convertToInteger(object, fallback ? 1 : -1) >= 1; + else if (object instanceof Long) return Math.round(convertToLong(object, fallback ? 1 : -1)) >= 1; + else if (object instanceof Short) return convertToShort(object, (short) (fallback ? 1 : -1)) >= 1; + else if (object instanceof Byte) return convertToByte(object, (byte) (fallback ? 1 : -1)) >= 0.001; + else return fallback; + } + + public static int convertToInteger(Object object, int fallback) { + try { + return Integer.parseInt(convertToString(object)); + } catch (NumberFormatException exception) { + return fallback; + } + } + + public static short convertToShort(Object object, short fallback) { + try { + return Short.parseShort(convertToString(object)); + } catch (NumberFormatException exception) { + return fallback; + } + } + + public static byte convertToByte(Object object, byte fallback) { + try { + return Byte.parseByte(convertToString(object)); + } catch (NumberFormatException exception) { + return fallback; + } + } + + public static long convertToLong(Object object, long fallback) { + try { + return Long.parseLong(convertToString(object)); + } catch (NumberFormatException exception) { + return fallback; + } + } + + public static float convertToFloat(Object object, float fallback) { + try { + return Float.parseFloat(convertToString(object)); + } catch (NumberFormatException exception) { + return fallback; + } + } + + public static double convertToDouble(Object object, double fallback) { + try { + return Double.parseDouble(convertToString(object)); + } catch (NumberFormatException exception) { + return fallback; + } + } +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/utils/DefaultMethodsOverrider.java b/src/main/java/me/finn/unlegitlibrary/utils/DefaultMethodsOverrider.java new file mode 100644 index 0000000..108d2f5 --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/utils/DefaultMethodsOverrider.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.utils; + +public class DefaultMethodsOverrider { + + @Override + protected final Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + @Override + public final boolean equals(Object obj) { + return super.equals(obj); + } + + @Override + public final String toString() { + return super.toString(); + } + + @Override + public final int hashCode() { + return super.hashCode(); + } + +} \ No newline at end of file diff --git a/src/main/java/me/finn/unlegitlibrary/utils/Tuple.java b/src/main/java/me/finn/unlegitlibrary/utils/Tuple.java new file mode 100644 index 0000000..8b44a4b --- /dev/null +++ b/src/main/java/me/finn/unlegitlibrary/utils/Tuple.java @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2024 UnlegitDqrk - All Rights Reserved + * + * You are unauthorized to remove this copyright. + * You have to give Credits to the Author in your project and link this GitHub site: https://github.com/UnlegitDqrk + * See LICENSE-File if exists + */ + +package me.finn.unlegitlibrary.utils; + +public class Tuple extends DefaultMethodsOverrider { + + private final A a; + private final B b; + + public Tuple(final A a, final B b) { + this.a = a; + this.b = b; + } + + public final A getA() { + return this.a; + } + + public final B getB() { + return this.b; + } + +} \ No newline at end of file