- Converting to new repo

This commit is contained in:
Finn
2025-09-24 21:20:00 +02:00
parent d94e8dd8b9
commit f7c3654f02
87 changed files with 905 additions and 279 deletions

View File

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.addon;
import dev.unlegitdqrk.unlegitlibrary.addon.impl.Addon;
import dev.unlegitdqrk.unlegitlibrary.event.EventListener;
import dev.unlegitdqrk.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<Addon> addons;
private final Map<String, Class<?>> 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, EventListener eventListener) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
if (!addons.contains(addon)) return;
addon.registerEventListener(eventListener);
}
public final void unregisterEventListener(Addon addon, EventListener eventListener) {
if (!addons.contains(addon)) return;
addon.unregisterEventListener(eventListener);
}
public final List<Addon> getLoadedAddons() {
return new ArrayList<>(addons);
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.addon.events;
import dev.unlegitdqrk.unlegitlibrary.addon.impl.Addon;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
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();
}
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.addon.events;
import dev.unlegitdqrk.unlegitlibrary.addon.impl.Addon;
import dev.unlegitdqrk.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();
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.addon.impl;
import dev.unlegitdqrk.unlegitlibrary.addon.events.AddonDisabledEvent;
import dev.unlegitdqrk.unlegitlibrary.addon.events.AddonEnabledEvent;
import dev.unlegitdqrk.unlegitlibrary.event.EventListener;
import dev.unlegitdqrk.unlegitlibrary.event.EventManager;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
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(EventListener eventListener) throws InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchMethodException {
eventManager.registerListener(eventListener);
}
public final void unregisterEventListener(EventListener 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));
}
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.addon.impl;
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();
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command;
import javax.management.InstanceAlreadyExistsException;
import java.util.ArrayList;
import java.util.List;
public abstract class Command {
public final CommandManager commandManager;
public final String name;
public final String description;
public final String usage;
private final List<CommandPermission> permissions;
private final List<String> aliases;
public Command(CommandManager commandManager, String name, String description, String usage, List<CommandPermission> permissions, List<String> aliases) throws InstanceAlreadyExistsException {
this.commandManager = commandManager;
this.name = name;
this.description = description;
this.usage = usage;
this.permissions = permissions;
this.aliases = aliases;
boolean exists = commandManager.getCommand(name) != null;
if (!exists) for (String alias : aliases) exists = commandManager.getCommand(alias) != null;
if (exists) throw new InstanceAlreadyExistsException("Command with this name or some alias alreadx exists!");
}
public final List<CommandPermission> getPermissions() {
return new ArrayList<>(permissions);
}
public final List<String> getAliases() {
return new ArrayList<>(aliases);
}
public abstract void execute(CommandExecutor commandExecutor, String label, String[] args);
}

View File

@@ -0,0 +1,49 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public abstract class CommandExecutor {
public final String name;
private final List<CommandPermission> permissions;
public CommandExecutor(String name, CommandPermission... permissions) {
this.name = name;
this.permissions = new ArrayList<>();
this.permissions.addAll(Arrays.asList(permissions));
}
public List<CommandPermission> getPermissions() {
return new ArrayList<>(permissions);
}
public boolean hasPermission(CommandPermission permission) {
return permissions.contains(permission);
}
public boolean hasPermissions(List<CommandPermission> permissions) {
return new HashSet<>(this.permissions).containsAll(permissions);
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command;
import dev.unlegitdqrk.unlegitlibrary.command.events.*;
import me.finn.unlegitlibrary.command.events.*;
import dev.unlegitdqrk.unlegitlibrary.event.EventManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CommandManager {
private final List<Command> commands;
private final EventManager eventManager;
public CommandManager(EventManager eventManager) {
this.commands = new ArrayList<>();
this.eventManager = eventManager;
}
public final void registerCommand(Command command) {
if (this.commands.contains(command)) return;
this.commands.add(command);
}
public final void unregisterCommand(Command command) {
if (!this.commands.contains(command)) return;
this.commands.remove(command);
}
public List<Command> getCommands() {
return new ArrayList<>(commands);
}
public Command getCommandByName(String name) {
for (Command command : commands) if (command.name.equals(name)) return command;
return null;
}
public Command getCommandByAliases(List<String> aliases) {
for (String alias : aliases) {
for (Command command : commands) {
List<String> aliasesCommand = new ArrayList<>();
for (String registeredAlias : command.getAliases()) aliasesCommand.add(registeredAlias.toLowerCase());
if (aliasesCommand.contains(alias.toLowerCase())) return command;
}
}
return null;
}
public Command getCommandByAlias(String alias) {
for (Command command : commands) {
List<String> aliasesCommand = new ArrayList<>();
for (String registeredAlias : command.getAliases()) aliasesCommand.add(registeredAlias.toLowerCase());
if (aliasesCommand.contains(alias.toLowerCase())) return command;
}
return null;
}
public Command getCommand(String input) {
if (getCommandByName(input) != null) return getCommandByName(input);
if (getCommandByAlias(input) != null) return getCommandByAlias(input);
return null;
}
public void execute(CommandExecutor commandExecutor, String line) {
String[] split = line.split(" ");
String command = split[0];
String[] args = Arrays.copyOfRange(split, 1, split.length);
if (getCommand(command) != null) {
Command cmd = getCommand(command);
PreCommandExecuteEvent preEvent = new PreCommandExecuteEvent(this, commandExecutor, cmd);
eventManager.executeEvent(preEvent);
if (preEvent.isCancelled()) return;
if (commandExecutor.hasPermissions(cmd.getPermissions())) {
CommandExecuteEvent event = new CommandExecuteEvent(this, commandExecutor, cmd);
eventManager.executeEvent(event);
if (event.isCancelled()) return;
cmd.execute(commandExecutor, command, args);
eventManager.executeEvent(new CommandExecutedEvent(this, commandExecutor, cmd));
} else eventManager.executeEvent(new CommandExecutorMissingPermissionEvent(this, commandExecutor, cmd));
} else eventManager.executeEvent(new CommandNotFoundEvent(this, commandExecutor, command, args));
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command;
public class CommandPermission {
public final String name;
public final int level;
public CommandPermission(String name, int level) {
this.name = name;
this.level = level;
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command.events;
import dev.unlegitdqrk.unlegitlibrary.command.Command;
import dev.unlegitdqrk.unlegitlibrary.command.CommandExecutor;
import dev.unlegitdqrk.unlegitlibrary.command.CommandManager;
import dev.unlegitdqrk.unlegitlibrary.event.impl.CancellableEvent;
public class CommandExecuteEvent extends CancellableEvent {
public final CommandManager commandManager;
public final CommandExecutor commandExecutor;
public final Command command;
public CommandExecuteEvent(CommandManager commandManager, CommandExecutor commandExecutor, Command command) {
this.commandManager = commandManager;
this.commandExecutor = commandExecutor;
this.command = command;
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command.events;
import dev.unlegitdqrk.unlegitlibrary.command.Command;
import dev.unlegitdqrk.unlegitlibrary.command.CommandExecutor;
import dev.unlegitdqrk.unlegitlibrary.command.CommandManager;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
public class CommandExecutedEvent extends Event {
public final CommandManager commandManager;
public final CommandExecutor commandExecutor;
public final Command command;
public CommandExecutedEvent(CommandManager commandManager, CommandExecutor commandExecutor, Command command) {
this.commandManager = commandManager;
this.commandExecutor = commandExecutor;
this.command = command;
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command.events;
import dev.unlegitdqrk.unlegitlibrary.command.Command;
import dev.unlegitdqrk.unlegitlibrary.command.CommandExecutor;
import dev.unlegitdqrk.unlegitlibrary.command.CommandManager;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
public class CommandExecutorMissingPermissionEvent extends Event {
public final CommandManager commandManager;
public final CommandExecutor commandExecutor;
public final Command command;
public CommandExecutorMissingPermissionEvent(CommandManager commandManager, CommandExecutor commandExecutor, Command command) {
this.commandManager = commandManager;
this.commandExecutor = commandExecutor;
this.command = command;
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command.events;
import dev.unlegitdqrk.unlegitlibrary.command.CommandExecutor;
import dev.unlegitdqrk.unlegitlibrary.command.CommandManager;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
public class CommandNotFoundEvent extends Event {
public final CommandManager commandManager;
public final CommandExecutor commandExecutor;
public final String name;
public final String[] args;
public CommandNotFoundEvent(CommandManager commandManager, CommandExecutor commandExecutor, String name, String[] args) {
this.commandManager = commandManager;
this.commandExecutor = commandExecutor;
this.name = name;
this.args = args;
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.command.events;
import dev.unlegitdqrk.unlegitlibrary.command.Command;
import dev.unlegitdqrk.unlegitlibrary.command.CommandExecutor;
import dev.unlegitdqrk.unlegitlibrary.command.CommandManager;
import dev.unlegitdqrk.unlegitlibrary.event.impl.CancellableEvent;
public class PreCommandExecuteEvent extends CancellableEvent {
public final CommandManager commandManager;
public final CommandExecutor commandExecutor;
public final Command command;
public PreCommandExecuteEvent(CommandManager commandManager, CommandExecutor commandExecutor, Command command) {
this.commandManager = commandManager;
this.commandExecutor = commandExecutor;
this.command = command;
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.event;
public abstract class EventListener {
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.event;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class EventManager extends DefaultMethodsOverrider {
private final HashMap<Class<? extends Event>, HashMap<EventPriority, HashMap<Object, Method>>> registeredListener = new HashMap<>();
private final HashMap<EventListener, Object> eventListeners = new HashMap<>();
public final void registerListener(EventListener listenerClass) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
if (isListenerRegistered(listenerClass)) return;
for (Method method : listenerClass.getClass().getDeclaredMethods()) {
Listener listener = method.getAnnotation(Listener.class);
if (listener == null) continue;
if (method.getParameterCount() == 1) {
Class<? extends Event> eventClass = (Class<? extends Event>) method.getParameterTypes()[0];
HashMap<EventPriority, HashMap<Object, Method>> list = registeredListener.getOrDefault(eventClass, new HashMap<>());
HashMap<Object, Method> set = list.getOrDefault(listener.priority(), new HashMap<>());
set.put(listenerClass, method);
list.put(listener.priority(), set);
registeredListener.put(eventClass, list);
}
}
eventListeners.put(listenerClass, listenerClass);
}
public synchronized final void unregisterListener(EventListener listenerClass) {
if (!isListenerRegistered(listenerClass)) return;
Object clazz = eventListeners.get(listenerClass);
synchronized (registeredListener) {
List<Class<? extends Event>> eventsToRemove = new ArrayList<>();
for (Map.Entry<Class<? extends Event>, HashMap<EventPriority, HashMap<Object, Method>>> entry : registeredListener.entrySet()) {
Class<? extends Event> eventClass = entry.getKey();
HashMap<EventPriority, HashMap<Object, Method>> priorityMap = entry.getValue();
if (priorityMap != null) {
synchronized (priorityMap) {
List<EventPriority> prioritiesToRemove = new ArrayList<>();
for (Map.Entry<EventPriority, HashMap<Object, Method>> priorityEntry : priorityMap.entrySet()) {
EventPriority priority = priorityEntry.getKey();
HashMap<Object, Method> listeners = priorityEntry.getValue();
if (listeners != null) {
listeners.remove(clazz);
if (listeners.isEmpty()) {
prioritiesToRemove.add(priority);
}
}
}
for (EventPriority priority : prioritiesToRemove) {
priorityMap.remove(priority);
}
if (priorityMap.isEmpty()) {
eventsToRemove.add(eventClass);
}
}
}
}
for (Class<? extends Event> eventClass : eventsToRemove) {
registeredListener.remove(eventClass);
}
}
eventListeners.remove(listenerClass);
}
public final boolean isListenerRegistered(EventListener listenerClass) {
return eventListeners.containsKey(listenerClass);
}
public final void executeEvent(Event event) {
HashMap<EventPriority, HashMap<Object, Method>> list = registeredListener.getOrDefault(event.getClass(), new HashMap<>());
list.getOrDefault(EventPriority.LOWEST, new HashMap<>()).forEach((k, v) -> {
if (!isListenerRegistered((EventListener) k)) return;
try {
v.invoke(k, event);
} catch (IllegalAccessException | InvocationTargetException exception) {
exception.printStackTrace();
}
});
list.getOrDefault(EventPriority.LOW, new HashMap<>()).forEach((k, v) -> {
if (!isListenerRegistered((EventListener) k)) return;
try {
v.invoke(k, event);
} catch (IllegalAccessException | InvocationTargetException exception) {
exception.printStackTrace();
}
});
list.getOrDefault(EventPriority.NORMAL, new HashMap<>()).forEach((k, v) -> {
if (!isListenerRegistered((EventListener) k)) return;
try {
v.invoke(k, event);
} catch (IllegalAccessException | InvocationTargetException exception) {
exception.printStackTrace();
}
});
list.getOrDefault(EventPriority.HIGH, new HashMap<>()).forEach((k, v) -> {
if (!isListenerRegistered((EventListener) k)) return;
try {
v.invoke(k, event);
} catch (IllegalAccessException | InvocationTargetException exception) {
exception.printStackTrace();
}
});
list.getOrDefault(EventPriority.HIGHEST, new HashMap<>()).forEach((k, v) -> {
if (!isListenerRegistered((EventListener) k)) return;
try {
v.invoke(k, event);
} catch (IllegalAccessException | InvocationTargetException exception) {
exception.printStackTrace();
}
});
}
}

View File

@@ -0,0 +1,25 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.event;
public enum EventPriority {
LOWEST,
LOW,
NORMAL,
HIGH,
HIGHEST
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.event;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Listener {
EventPriority priority() default EventPriority.NORMAL;
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.event.impl;
public abstract class Event {
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.file;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
public class ClassDefiner extends DefaultMethodsOverrider {
private static final Map<ClassLoader, ClassDefinerLoader> loaders = Collections.synchronizedMap(new WeakHashMap<>());
public static <T> Class<T> define(final Class<?> parent, final String name, final byte[] data) {
return define(parent.getClassLoader(), name, data);
}
public static <T> Class<T> 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<T>) 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;
}
}
}
}
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.file;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
public class ConfigurationManager extends DefaultMethodsOverrider {
private final Properties properties = new Properties();
private final File configFile;
public ConfigurationManager(File configFile) {
this.configFile = configFile;
}
public final boolean isSet(String key) {
return properties.containsKey(key);
}
public final void loadProperties() throws IOException {
try (FileInputStream in = new FileInputStream(configFile)) {
properties.load(in);
}
}
public final void saveProperties() throws IOException {
try (FileOutputStream out = new FileOutputStream(configFile)) {
properties.store(out, null);
}
}
public final long getLong(String key) {
return Long.parseLong(properties.getProperty(key));
}
public final double getDouble(String key) {
return Double.parseDouble(properties.getProperty(key));
}
public final float getFloat(String key) {
return Float.parseFloat(properties.getProperty(key));
}
public final int getInt(String key) {
return Integer.parseInt(properties.getProperty(key));
}
public final Object getObject(String key) {
return properties.getProperty(key);
}
public Map<String, String> getMap(String key) {
String value = properties.getProperty(key);
Map<String, String> map = new HashMap<>();
if (value != null) {
String[] entries = value.split(",");
for (String entry : entries) {
String[] pair = entry.split("=");
if (pair.length == 2) map.put(pair[0], pair[1]);
}
}
return map;
}
public final String getString(String key) {
return properties.getProperty(key);
}
public final List<String> getList(String key) {
String value = properties.getProperty(key);
if (value != null) return Arrays.asList(value.split(","));
else return new ArrayList<>();
}
public final void set(String key, long value) {
properties.setProperty(key, String.valueOf(value));
}
public final void set(String key, int value) {
properties.setProperty(key, String.valueOf(value));
}
public final void set(String key, double value) {
properties.setProperty(key, String.valueOf(value));
}
public final void set(String key, float value) {
properties.setProperty(key, String.valueOf(value));
}
public final void set(String key, Object value) {
properties.setProperty(key, String.valueOf(value));
}
public final void set(String key, String value) {
properties.setProperty(key, value);
}
public final void set(String key, Map<String, String> map) {
String value = map.entrySet().stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining(","));
properties.setProperty(key, value);
}
public final void set(String key, List<String> list) {
String value = list.stream().collect(Collectors.joining(","));
properties.setProperty(key, value);
}
}

View File

@@ -0,0 +1,164 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.file;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
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 String readFileFromResource(String filePath) throws IOException {
StringBuilder content = new StringBuilder();
InputStream inputStream = FileUtils.class.getClassLoader().getResourceAsStream(filePath);
if (inputStream == null) throw new FileNotFoundException("Can not load resource: " + filePath);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
String line;
while ((line = reader.readLine()) != null) content.append(line).append("\n");
}
inputStream.close();
return content.toString();
}
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];
}
@Deprecated
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(File file) throws IOException {
if (file.isDirectory()) {
try (Stream<Path> entries = Files.list(file.toPath())) {
return !entries.findFirst().isPresent();
}
} else if (file.isFile()) return file.length() == 0;
return false;
}
public static String readFileFull(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 List<String> readFileLines(File file) throws IOException {
List<String> lines = new ArrayList<>();
BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
String str;
while ((str = in.readLine()) != null) lines.add(str);
return lines;
}
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);
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.file;
import dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,290 @@
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client;
import dev.unlegitdqrk.unlegitlibrary.event.EventManager;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.events.*;
import me.finn.unlegitlibrary.network.system.client.events.*;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.PacketHandler;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.impl.ClientIDPacket;
import dev.unlegitdqrk.unlegitlibrary.network.utils.PemUtils;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import dev.unlegitdqrk.unlegitlibrary.utils.Logger;
import javax.net.ssl.*;
import java.io.*;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
public final class NetworkClient {
private final String host;
private final int port;
private final PacketHandler packetHandler;
private final EventManager eventManager;
private final Logger logger;
private final int timeout;
private SSLSocket socket;
private ObjectOutputStream outputStream;
private ObjectInputStream inputStream;
private final SSLSocketFactory sslSocketFactory;
private final SSLParameters sslParameters;
private int clientID = -1;
private final Proxy proxy;
public Proxy getProxy() {
return proxy;
}
public int getClientID() {
return clientID;
}
public void setClientID(int clientID) {
if (this.clientID == -1) this.clientID = clientID;
}
private final Thread receiveThread = new Thread(this::receive);
public PacketHandler getPacketHandler() {
return packetHandler;
}
public EventManager getEventManager() {
return eventManager;
}
public ObjectInputStream getInputStream() {
return inputStream;
}
public SSLSocket getSocket() {
return socket;
}
public ObjectOutputStream getOutputStream() {
return outputStream;
}
public Logger getLogger() {
return logger;
}
public int getPort() {
return port;
}
public String getHost() {
return host;
}
private NetworkClient(String host, int port, PacketHandler packetHandler,
EventManager eventManager, Logger logger,
int timeout, SSLSocketFactory sslSocketFactory,
SSLParameters sslParameters, Proxy proxy) {
this.host = host;
this.port = port;
this.packetHandler = packetHandler;
this.eventManager = eventManager;
this.logger = logger;
this.timeout = timeout;
this.sslSocketFactory = sslSocketFactory;
this.sslParameters = sslParameters;
this.packetHandler.setClientInstance(this);
this.packetHandler.registerPacket(new ClientIDPacket());
this.proxy = proxy;
}
public boolean isConnected() {
return socket != null && socket.isConnected() && !socket.isClosed()
&& receiveThread.isAlive() && !receiveThread.isInterrupted();
}
public synchronized boolean connect() throws ConnectException {
if (isConnected()) return false;
if (logger != null) logger.info("Trying to connect to " + host + ":" + port + "...");
else System.out.println("Trying to connect to " + host + ":" + port + "...");
try {
if (sslSocketFactory == null) throw new ConnectException("SSL socket factory not set. Client certificate required!");
if (proxy != null) {
Socket rawSocket = new Socket(proxy);
rawSocket.connect(new InetSocketAddress(host, port), timeout);
socket = (SSLSocket) sslSocketFactory.createSocket(rawSocket, host, port, true);
} else socket = (SSLSocket) sslSocketFactory.createSocket(host, port);
if (sslParameters != null) socket.setSSLParameters(sslParameters);
else {
SSLParameters defaultParams = socket.getSSLParameters();
defaultParams.setProtocols(new String[]{"TLSv1.3"});
socket.setSSLParameters(defaultParams);
}
socket.setTcpNoDelay(true);
socket.setSoTimeout(timeout);
try {
socket.startHandshake();
} catch (Exception handshakeEx) {
throw new ConnectException("Handshake failed: " + handshakeEx.getMessage());
}
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
receiveThread.start();
eventManager.executeEvent(new ClientConnectedEvent(this));
if (logger != null) logger.info("Connected to " + host + ":" + port);
else System.out.println("Connected to " + host + ":" + port);
return true;
} catch (Exception e) {
throw new ConnectException("Failed to connect: " + e.getMessage());
}
}
private void receive() {
try {
while (isConnected()) {
Object received = inputStream.readObject();
handleReceived(received);
}
} catch (Exception e) { disconnect(); }
}
private void handleReceived(Object received) throws IOException, ClassNotFoundException {
if (received instanceof Integer id) {
if (packetHandler.isPacketIDRegistered(id)) {
Packet packet = packetHandler.getPacketByID(id);
boolean handled = packetHandler.handlePacket(id, packet, inputStream);
if (handled) eventManager.executeEvent(new C_PacketReceivedEvent(this, packet));
else eventManager.executeEvent(new C_PacketReceivedFailedEvent(this, packet));
} else eventManager.executeEvent(new C_UnknownObjectReceivedEvent(this, received));
} else eventManager.executeEvent(new C_UnknownObjectReceivedEvent(this, received));
}
public synchronized boolean disconnect() {
if (!isConnected()) return false;
try {
receiveThread.interrupt();
if (outputStream != null) outputStream.close();
if (inputStream != null) inputStream.close();
if (socket != null) socket.close();
} catch (IOException e) {
if (logger != null) logger.exception("Error closing connection", e);
else System.err.println("Error closing connection: " + e.getMessage());
} finally {
socket = null;
outputStream = null;
inputStream = null;
clientID = -1;
eventManager.executeEvent(new ClientDisconnectedEvent(this));
}
return true;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NetworkClient target)) return false;
return target.getClientID() == clientID;
}
public boolean sendPacket(Packet packet) throws IOException, ClassNotFoundException {
if (!isConnected()) return false;
boolean sent = packetHandler.sendPacket(packet, outputStream);
if (sent) eventManager.executeEvent(new C_PacketSendEvent(this, packet));
else eventManager.executeEvent(new C_PacketSendFailedEvent(this, packet));
return sent;
}
// --- Builder ---
public static class ClientBuilder extends DefaultMethodsOverrider {
private String host;
private int port;
private PacketHandler packetHandler;
private EventManager eventManager;
private Logger logger;
private int timeout = 5000;
private SSLSocketFactory sslSocketFactory;
private SSLParameters sslParameters;
private File caFolder;
private File clientFolder;
private File keyFolder;
private Proxy proxy;
public ClientBuilder setHost(String host) { this.host = host; return this; }
public ClientBuilder setPort(int port) { this.port = port; return this; }
public ClientBuilder setPacketHandler(PacketHandler handler) { this.packetHandler = handler; return this; }
public ClientBuilder setEventManager(EventManager manager) { this.eventManager = manager; return this; }
public ClientBuilder setLogger(Logger logger) { this.logger = logger; return this; }
public ClientBuilder setTimeout(int timeout) { this.timeout = timeout; return this; }
public ClientBuilder setSSLSocketFactory(SSLSocketFactory factory) { this.sslSocketFactory = factory; return this; }
public ClientBuilder setSSLParameters(SSLParameters params) { this.sslParameters = params; return this; }
public ClientBuilder setRootCAFolder(File folder) { this.caFolder = folder; return this; }
public ClientBuilder setClientCertificatesFolder(File clientFolder, File keyFolder) { this.clientFolder = clientFolder; this.keyFolder = keyFolder; return this; }
public ClientBuilder setProxy(Proxy proxy) { this.proxy = proxy; return this; }
public NetworkClient build() {
if (sslSocketFactory == null && caFolder != null) {
try { sslSocketFactory = createSSLSocketFactory(caFolder, clientFolder, keyFolder); }
catch (Exception e) { throw new RuntimeException("Failed to create SSLFactory", e); }
}
return new NetworkClient(host, port, packetHandler, eventManager, logger,
timeout, sslSocketFactory, sslParameters, proxy);
}
public static SSLSocketFactory createSSLSocketFactory(File caFolder, File clientCertFolder, File clientKeyFolder) throws Exception {
// TrustStore (Root-CAs)
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
int caIndex = 1;
for (File caFile : caFolder.listFiles((f) -> f.getName().endsWith(".pem"))) {
try (FileInputStream fis = new FileInputStream(caFile)) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
java.security.cert.Certificate caCert = cf.generateCertificate(fis);
trustStore.setCertificateEntry("ca" + (caIndex++), caCert);
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, null); // Kein Passwort nötig
int clientIndex = 1;
for (File certFile : clientCertFolder.listFiles((f) -> f.getName().endsWith(".crt"))) {
String baseName = certFile.getName().replace(".crt", "");
File keyFile = new File(clientKeyFolder, baseName + ".key");
if (!keyFile.exists()) continue;
java.security.PrivateKey key = PemUtils.loadPrivateKey(keyFile);
java.security.cert.Certificate cert = PemUtils.loadCertificate(certFile);
keyStore.setKeyEntry("client" + (clientIndex++), key, null, new java.security.cert.Certificate[]{cert});
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, null);
// SSLContext
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
}
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
import dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
public class C_PacketReceivedFailedEvent extends Event {
public final NetworkClient networkClient;
public final Packet packet;
public C_PacketReceivedFailedEvent(NetworkClient networkClient, Packet packet) {
this.networkClient = networkClient;
this.packet = packet;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
import dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
public class C_PacketSendFailedEvent extends Event {
public final NetworkClient networkClient;
public final Packet packet;
public C_PacketSendFailedEvent(NetworkClient networkClient, Packet packet) {
this.networkClient = networkClient;
this.packet = packet;
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
public class C_UnknownObjectReceivedEvent extends Event {
public final NetworkClient networkClient;
public final Object received;
public C_UnknownObjectReceivedEvent(NetworkClient networkClient, Object received) {
this.networkClient = networkClient;
this.received = received;
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
public class ClientConnectedEvent extends Event {
public final NetworkClient client;
public ClientConnectedEvent(NetworkClient client) {
this.client = client;
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.client.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
public class ClientDisconnectedEvent extends Event {
public final NetworkClient client;
public ClientDisconnectedEvent(NetworkClient client) {
this.client = client;
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.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(PacketHandler packetHandler, ObjectOutputStream outputStream) throws IOException, ClassNotFoundException;
public abstract void read(PacketHandler packetHandler, ObjectInputStream outputStream) throws IOException, ClassNotFoundException;
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.packets;
import dev.unlegitdqrk.unlegitlibrary.network.system.client.NetworkClient;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.NetworkServer;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.Map;
public final class PacketHandler extends DefaultMethodsOverrider {
private final Map<Integer, Packet> packets = new HashMap<>();
private NetworkClient clientInstance;
private NetworkServer serverInstance;
public NetworkClient getClientInstance() {
return clientInstance;
}
public void setClientInstance(NetworkClient clientInstance) {
if (this.clientInstance == null) this.clientInstance = clientInstance;
}
public NetworkServer getServerInstance() {
return serverInstance;
}
public void setServerInstance(NetworkServer serverInstance) {
if (this.serverInstance == null) this.serverInstance = serverInstance;
}
public boolean isPacketIDRegistered(int id) {
return packets.containsKey(id);
}
public Packet getPacketByID(int id) {
return packets.get(id);
}
public boolean registerPacket(Packet packet) {
int id = packet.getPacketID();
if (isPacketIDRegistered(id)) return false;
packets.put(id, packet);
return true;
}
public 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(this, inputStream);
return true;
}
public boolean sendPacket(Packet packet, ObjectOutputStream outputStream) throws IOException, ClassNotFoundException {
int id = packet.getPacketID();
if (!isPacketIDRegistered(id)) return false;
outputStream.writeObject(id);
packet.write(this, outputStream);
outputStream.flush();
return true;
}
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.packets.impl;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.PacketHandler;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class ClientIDPacket extends Packet {
private int clientID;
public ClientIDPacket() {
super(0);
}
public ClientIDPacket(int clientID) {
this();
this.clientID = clientID;
}
@Override
public void write(PacketHandler packetHandler, ObjectOutputStream outputStream) throws IOException, ClassNotFoundException {
outputStream.writeInt(clientID);
}
@Override
public void read(PacketHandler packetHandler, ObjectInputStream outputStream) throws IOException, ClassNotFoundException {
packetHandler.getClientInstance().setClientID(clientID);
}
}

View File

@@ -0,0 +1,113 @@
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.impl.ClientIDPacket;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.events.*;
import me.finn.unlegitlibrary.network.system.server.events.*;
import javax.net.ssl.SSLSocket;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.SocketException;
public class ConnectionHandler {
private SSLSocket socket;
private int clientID;
private ObjectOutputStream outputStream;
private ObjectInputStream inputStream;
private final NetworkServer server;
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ConnectionHandler target)) return false;
return target.getClientID() == clientID;
}
public SSLSocket getSocket() {
return socket;
}
public ObjectOutputStream getOutputStream() {
return outputStream;
}
public ObjectInputStream getInputStream() {
return inputStream;
}
public NetworkServer getServer() {
return server;
}
public ConnectionHandler(NetworkServer server, SSLSocket socket, int clientID) throws IOException, ClassNotFoundException {
this.server = server; this.socket = socket; this.clientID = clientID;
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
receiveThread.start();
sendPacket(new ClientIDPacket());
server.getEventManager().executeEvent(new ConnectionHandlerConnectedEvent(this));
}
public final Thread receiveThread = new Thread(this::receive);
public int getClientID() { return clientID; }
public boolean isConnected() { return socket != null && socket.isConnected() && !socket.isClosed() && receiveThread.isAlive(); }
public synchronized boolean disconnect() {
if (!isConnected()) return false;
if (receiveThread.isAlive()) receiveThread.interrupt();
try { outputStream.close(); inputStream.close(); socket.close(); } catch (IOException ignored) {}
socket = null; outputStream = null; inputStream = null; clientID = -1;
server.getConnectionHandlers().remove(this);
server.getEventManager().executeEvent(new ConnectionHandlerDisconnectedEvent(this));
return true;
}
public boolean sendPacket(Packet packet) throws IOException, ClassNotFoundException {
if (!isConnected()) return false;
boolean sent = server.getPacketHandler().sendPacket(packet, outputStream);
if (sent) server.getEventManager().executeEvent(new S_PacketSendEvent(packet, this));
else server.getEventManager().executeEvent(new S_PacketSendFailedEvent(packet, this));
return sent;
}
private void receive() {
while (isConnected()) {
try {
Object received = inputStream.readObject();
if (received instanceof Integer) {
int id = (Integer) received;
if (server.getPacketHandler().isPacketIDRegistered(id)) {
Packet packet = server.getPacketHandler().getPacketByID(id);
if (server.getPacketHandler().handlePacket(id, packet, inputStream)) server.getEventManager().executeEvent(new S_PacketReceivedEvent(this, packet));
else server.getEventManager().executeEvent(new S_PacketReceivedFailedEvent(this, packet));
} else server.getEventManager().executeEvent(new S_UnknownObjectReceivedEvent(received, this));
} else server.getEventManager().executeEvent(new S_UnknownObjectReceivedEvent(received, this));
} catch (SocketException se) { disconnect(); }
catch (Exception ex) {
if (server.getLogger() != null) server.getLogger().exception("Receive thread exception for client " + clientID, ex);
else System.err.println("Receive thread exception for client " + clientID + ": " + ex.getMessage());
disconnect();
}
}
}
}

View File

@@ -0,0 +1,191 @@
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server;
import dev.unlegitdqrk.unlegitlibrary.event.EventManager;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.PacketHandler;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.impl.ClientIDPacket;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.events.IncomingConnectionEvent;
import dev.unlegitdqrk.unlegitlibrary.network.utils.PemUtils;
import dev.unlegitdqrk.unlegitlibrary.utils.DefaultMethodsOverrider;
import dev.unlegitdqrk.unlegitlibrary.utils.Logger;
import javax.net.ssl.*;
import java.io.File;
import java.io.FileInputStream;
import java.net.Socket;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.List;
public final class NetworkServer {
private final int port;
private final PacketHandler packetHandler;
private final EventManager eventManager;
private final Logger logger;
private final int timeout;
private SSLServerSocket serverSocket;
private final SSLServerSocketFactory sslServerSocketFactory;
private final List<ConnectionHandler> connectionHandlers = new ArrayList<>();
private final Thread incomingThread = new Thread(this::incomingConnections);
public List<ConnectionHandler> getConnectionHandlers() {
return connectionHandlers;
}
public ConnectionHandler getConnectionHandlerByID(int clientID) {
for (ConnectionHandler connectionHandler : connectionHandlers) if (connectionHandler.getClientID() == clientID) return connectionHandler;
return null;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NetworkServer target)) return false;
return super.equals(obj);
}
public int getPort() {
return port;
}
public PacketHandler getPacketHandler() {
return packetHandler;
}
public Logger getLogger() {
return logger;
}
public SSLServerSocket getServerSocket() {
return serverSocket;
}
public EventManager getEventManager() {
return eventManager;
}
private final boolean requireClientCert;
private NetworkServer(int port, PacketHandler packetHandler, EventManager eventManager,
Logger logger, int timeout, SSLServerSocketFactory factory, boolean requireClientCert) {
this.port = port; this.packetHandler = packetHandler; this.eventManager = eventManager;
this.logger = logger; this.timeout = timeout; this.sslServerSocketFactory = factory;
this.packetHandler.setServerInstance(this);
this.packetHandler.registerPacket(new ClientIDPacket());
this.requireClientCert = requireClientCert;
}
public boolean start() {
try {
serverSocket = (SSLServerSocket) sslServerSocketFactory.createServerSocket(port);
serverSocket.setNeedClientAuth(requireClientCert);
serverSocket.setSoTimeout(timeout);
serverSocket.setEnabledProtocols(new String[]{"TLSv1.3"});
incomingThread.start();
if (logger != null) logger.log("Server started on port " + port);
else System.out.println("Server started on port " + port);
return true;
} catch (Exception e) {if (logger != null) logger.exception("Failed to start", e);
else System.err.println("Failed to start: " + e.getMessage()); return false; }
}
private void incomingConnections() {
try {
while (!serverSocket.isClosed()) {
Socket socket = serverSocket.accept();
if (!(socket instanceof SSLSocket ssl)) { socket.close(); continue; }
ssl.setTcpNoDelay(true);
ssl.setSoTimeout(timeout);
try { ssl.startHandshake(); }
catch (Exception handshakeEx) {
if (logger != null) logger.exception("Handshake failed", handshakeEx);
else System.err.println("Handshake failed: " + handshakeEx.getMessage());
ssl.close();
continue;
}
IncomingConnectionEvent event = new IncomingConnectionEvent(this, ssl);
eventManager.executeEvent(event);
if (event.isCancelled()) { ssl.close(); continue; }
try {
ConnectionHandler connectionHandler = new ConnectionHandler(this, ssl, connectionHandlers.size() + 1);
connectionHandlers.add(connectionHandler);
} catch (Exception exception) {
ssl.close();
continue;
}
}
} catch (Exception e) { e.printStackTrace(); }
}
// --- Builder ---
public static class ServerBuilder extends DefaultMethodsOverrider {
private int port;
private PacketHandler packetHandler;
private EventManager eventManager;
private Logger logger;
private int timeout = 5000;
private SSLServerSocketFactory factory;
private boolean requireClientCert;
private File caFolder;
private File serverCertFile;
private File serverKeyFile;
public ServerBuilder setPort(int port) { this.port = port; return this; }
public ServerBuilder setPacketHandler(PacketHandler handler) { this.packetHandler = handler; return this; }
public ServerBuilder setEventManager(EventManager manager) { this.eventManager = manager; return this; }
public ServerBuilder setLogger(Logger logger) { this.logger = logger; return this; }
public ServerBuilder setTimeout(int timeout) { this.timeout = timeout; return this; }
public ServerBuilder setSSLServerSocketFactory(SSLServerSocketFactory factory) { this.factory = factory; return this; }
public ServerBuilder setRequireClientCertificate(boolean requireClientCertificate) { this.requireClientCert = requireClientCertificate; return this; }
public ServerBuilder setRootCAFolder(File folder) { this.caFolder = folder; return this; }
public ServerBuilder setServerCertificate(File certFile, File keyFile) { this.serverCertFile = certFile; this.serverKeyFile = keyFile; return this; }
public NetworkServer build() {
if (factory == null && caFolder != null && serverCertFile != null && serverKeyFile != null) {
try { factory = createSSLServerSocketFactory(caFolder, serverCertFile, serverKeyFile); }
catch (Exception e) { throw new RuntimeException("Failed to create SSLServerSocketFactory", e); }
}
return new NetworkServer(port, packetHandler, eventManager, logger, timeout, factory, requireClientCert);
}
public static SSLServerSocketFactory createSSLServerSocketFactory(File caFolder, File serverCert, File serverKey) throws Exception {
// TrustStore (Root-CAs)
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
int caIndex = 1;
for (File caFile : caFolder.listFiles((f) -> f.getName().endsWith(".pem"))) {
try (FileInputStream fis = new FileInputStream(caFile)) {
java.security.cert.Certificate cert = PemUtils.loadCertificate(caFile);
trustStore.setCertificateEntry("ca" + (caIndex++), cert);
}
}
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(null, null);
java.security.PrivateKey key = PemUtils.loadPrivateKey(serverKey);
java.security.cert.Certificate cert = PemUtils.loadCertificate(serverCert);
keyStore.setKeyEntry("server", key, null, new java.security.cert.Certificate[]{cert});
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, null);
SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return sslContext.getServerSocketFactory();
}
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
public final class ConnectionHandlerConnectedEvent extends Event {
public final ConnectionHandler connectionHandler;
public ConnectionHandlerConnectedEvent(ConnectionHandler connectionHandler) {
this.connectionHandler = connectionHandler;
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
public final class ConnectionHandlerDisconnectedEvent extends Event {
public final ConnectionHandler connectionHandler;
public ConnectionHandlerDisconnectedEvent(ConnectionHandler connectionHandler) {
this.connectionHandler = connectionHandler;
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.CancellableEvent;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.NetworkServer;
import javax.net.ssl.SSLSocket;
public class IncomingConnectionEvent extends CancellableEvent {
public final NetworkServer server;
public final SSLSocket socket;
public IncomingConnectionEvent(NetworkServer server, SSLSocket socket) {
this.server = server;
this.socket = socket;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
public class S_PacketReceivedEvent extends Event {
public final ConnectionHandler connectionHandler;
public final Packet packet;
public S_PacketReceivedEvent(ConnectionHandler connectionHandler, Packet packet) {
this.connectionHandler = connectionHandler;
this.packet = packet;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
public class S_PacketReceivedFailedEvent extends Event {
public final ConnectionHandler connectionHandler;
public final Packet packet;
public S_PacketReceivedFailedEvent(ConnectionHandler connectionHandler, Packet packet) {
this.connectionHandler = connectionHandler;
this.packet = packet;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
public class S_PacketSendEvent extends Event {
public final Packet packet;
public final ConnectionHandler connectionHandler;
public S_PacketSendEvent(Packet packet, ConnectionHandler connectionHandler) {
this.packet = packet;
this.connectionHandler = connectionHandler;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.packets.Packet;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
public class S_PacketSendFailedEvent extends Event {
public final Packet packet;
public final ConnectionHandler connectionHandler;
public S_PacketSendFailedEvent(Packet packet, ConnectionHandler connectionHandler) {
this.packet = packet;
this.connectionHandler = connectionHandler;
}
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.system.server.events;
import dev.unlegitdqrk.unlegitlibrary.event.impl.Event;
import dev.unlegitdqrk.unlegitlibrary.network.system.server.ConnectionHandler;
public class S_UnknownObjectReceivedEvent extends Event {
public final Object received;
public final ConnectionHandler connectionHandler;
public S_UnknownObjectReceivedEvent(Object received, ConnectionHandler connectionHandler) {
this.received = received;
this.connectionHandler = connectionHandler;
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.network.utils;
import dev.unlegitdqrk.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 new String(byteArrayOutputStream.toByteArray(), 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();
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.network.utils;
import dev.unlegitdqrk.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();
}
}
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2025 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
*/
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.network.utils;
import java.io.*;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Base64;
public class PemUtils {
public static PrivateKey loadPrivateKey(File keyFile) throws Exception {
String keyPem = new String(Files.readAllBytes(keyFile.toPath()))
.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s", "");
byte[] keyBytes = Base64.getDecoder().decode(keyPem);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA"); // oder "EC" je nach Key
return kf.generatePrivate(spec);
}
public static X509Certificate loadCertificate(File certFile) throws Exception {
try (FileInputStream fis = new FileInputStream(certFile)) {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
return (X509Certificate) cf.generateCertificate(fis);
}
}
}

View File

@@ -0,0 +1,97 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.network.utils;
import dev.unlegitdqrk.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.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();
}
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
public enum Axis {
X, Y, Z
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
import dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,288 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
import dev.unlegitdqrk.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;
}
/**
* 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;
}
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;
}
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
import dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
import dev.unlegitdqrk.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);
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
import dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
import dev.unlegitdqrk.unlegitlibrary.number.vector.Vector2;
import dev.unlegitdqrk.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 Quaternion conjugate(Quaternion dest) {
dest.x = -this.x;
dest.y = -this.y;
dest.z = -this.z;
dest.w = this.w;
return dest;
}
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)) return false;
Quaternion quaternion = (Quaternion) obj;
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 + ")";
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number;
import dev.unlegitdqrk.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);
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number.bit;
public interface BitArray {
void set(int index, int value);
int get(int index);
int size();
int[] getWords();
BitArrayVersion getVersion();
BitArray copy();
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.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);
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number.bit;
import dev.unlegitdqrk.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 (<b>not</b> 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));
}
}

View File

@@ -0,0 +1,95 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.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 (<b>not</b> 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));
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number.molecular;
import dev.unlegitdqrk.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;
}
}

View File

@@ -0,0 +1,125 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.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)) return false;
Vector2 vector2 = (Vector2) obj;
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 + ")";
}
}

View File

@@ -0,0 +1,149 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.number.vector;
import dev.unlegitdqrk.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)) return false;
Vector3 vector3 = (Vector3) obj;
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 + ")";
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.string;
import dev.unlegitdqrk.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);
}
}

View File

@@ -0,0 +1,77 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.string;
import dev.unlegitdqrk.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;
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.string;
import dev.unlegitdqrk.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<String> 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.trim().isEmpty() || string.equalsIgnoreCase(" ");
}
public static String[] removeEmptyStringsExceptWhitespace(String[] strings) {
List<String> 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.trim().isEmpty()) && !string.equalsIgnoreCase(" ");
}
}

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.string.color;
import dev.unlegitdqrk.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
}

View File

@@ -0,0 +1,152 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.string.color;
import dev.unlegitdqrk.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<String> colors = new ArrayList<String>();
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);
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.utils;
import dev.unlegitdqrk.unlegitlibrary.number.MathHelper;
public class Color {
public static final Color COLOR_BLACK = new Color(0, 0, 0);
public static final Color COLOR_WHITE = new Color(1, 1, 1);
public static final Color COLOR_RED = new Color(1, 0, 0);
public static final Color COLOR_GREEN = new Color(0, 1, 0);
public static final Color COLOR_BLUE = new Color(0, 0, 1);
public static final Color COLOR_YELLOW = new Color(1, 1, 0);
public static final Color COLOR_ORANGE = new Color(1, 0, 1);
public static final Color COLOR_MAGENTA = new Color(1, 0, 1);
public static final Color COLOR_CYAN = new Color(0, 1, 0);
public static final Color COLOR_WINE = new Color(0.5f, 0.5f, 0.5f);
public static final Color COLOR_FORREST = new Color(0, 0.5f, 0);
public static final Color COLOR_MARINE = new Color(0, 0, 0.5f);
public float red = 1;
public float green = 1;
public float blue = 1;
public float alpha = 1;
public Color(float red, float green, float blue, float alpha) {
this.red = MathHelper.clamp_float(red, 0f, 1f);
this.green = MathHelper.clamp_float(green, 0f, 1f);
this.blue = MathHelper.clamp_float(blue, 0f, 1f);
this.alpha = MathHelper.clamp_float(alpha, 0f, 1f);
}
public Color(float red, float green, float blue) {
this(red, green, blue, 1);
}
public static Color fromAwtColor(java.awt.Color awtColor) {
return new Color(awtColor.getRed(), awtColor.getGreen(), awtColor.getBlue(), awtColor.getAlpha());
}
@Override
public String toString() {
return "(" + red + "," + green + "," + blue + "," + alpha + ")";
}
@Override
protected final Color clone() throws CloneNotSupportedException {
return new Color(red, green, blue, alpha);
}
public final java.awt.Color toAwtColor() {
return new java.awt.Color(red, green, blue, alpha);
}
@Override
public final boolean equals(Object obj) {
if (!(obj instanceof Color)) return false;
Color equalTo = (Color) obj;
return equalTo.alpha == alpha && equalTo.red == red && equalTo.green == green && equalTo.blue == blue;
}
@Override
public final int hashCode() {
return super.hashCode();
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.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;
}
}
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.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();
}
}

View File

@@ -0,0 +1,213 @@
/*
* Copyright (C) 2025 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 dev.unlegitdqrk.unlegitlibrary.utils;
import dev.unlegitdqrk.unlegitlibrary.file.FileUtils;
import dev.unlegitdqrk.unlegitlibrary.string.color.ConsoleColor;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Logger by shock9 Interactive
*/
public final class Logger {
private final File logFolder;
private final File latestLogFile;
private boolean isInitialized = false;
public Logger(File logFolder, boolean changeCharset, boolean addShutdownHook) throws IOException, NoSuchFieldException, IllegalAccessException {
if (changeCharset) {
try {
Field field = Charset.class.getDeclaredField("defaultCharset");
field.setAccessible(true);
field.set(null, StandardCharsets.UTF_8);
} catch (IllegalAccessException exception) {
exception.printStackTrace();
}
}
System.setProperty("client.encoding.override", "UTF-8");
System.setProperty("file.encoding", "UTF-8");
// Basic setup for log folder and latest log file
this.logFolder = logFolder;
latestLogFile = new File(logFolder, "log-latest.txt");
logFolder.mkdir();
if (latestLogFile.exists()) latestLogFile.delete();
latestLogFile.createNewFile();
if (addShutdownHook) {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
shutdown();
} catch (IOException exception) {
exception("Failed to shutdown logger", exception);
}
}));
}
isInitialized = true;
}
// Renaming latest log to current date and yeah
public void shutdown() throws IOException {
if (!isInitialized) return;
// Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("dd.MM.yyyy_HH.mm.ss");
Date date = new Date();
String timeStamp = formatter.format(date);
// Backup latest log file to current date and time
File backupLogFile = new File(logFolder, "log-" + timeStamp + ".txt");
backupLogFile.createNewFile();
Files.copy(latestLogFile.toPath(), backupLogFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
FileUtils.writeFile(backupLogFile, FileUtils.readFileFull(latestLogFile));
isInitialized = false;
}
private void writeToLog(String log) throws IOException {
if (isInitialized)
FileUtils.writeFile(latestLogFile, FileUtils.readFileFull(latestLogFile) + System.lineSeparator() + log);
}
public void log(String string) {
// Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
String timeStamp = formatter.format(date);
// Writing log
String log = timeStamp + " [LOG] " + string;
try {
writeToLog(log);
} catch (IOException ignored) {
}
}
public void info(String info) {
// Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
String timeStamp = formatter.format(date);
// Writing log
String log = timeStamp + " [INFO] " + info;
System.out.println(ConsoleColor.WHITE + log + ConsoleColor.RESET);
try {
writeToLog(log);
} catch (IOException exception) {
exception.printStackTrace();
}
}
public void warn(String warn) {
// Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
String timeStamp = formatter.format(date);
// Writing log
String log = timeStamp + " [WARN] " + warn;
System.out.println(ConsoleColor.YELLOW + log + ConsoleColor.RESET);
try {
writeToLog(log);
} catch (IOException exception) {
exception.printStackTrace();
}
}
public void error(String error) {
// Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
String timeStamp = formatter.format(date);
// Writing log
String log = timeStamp + " [ERROR] " + error;
System.out.println(ConsoleColor.RED + log + ConsoleColor.RESET);
try {
writeToLog(log);
} catch (IOException exception) {
exception.printStackTrace();
}
}
public void exception(String infoLine, Exception exception) {
// Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
String timeStamp = formatter.format(date);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
exception.printStackTrace(pw);
String stackTrace = sw.toString();
// Writing log
String log =
timeStamp + " [EXCEPTION-INFO] " + infoLine + System.lineSeparator() +
timeStamp + " [EXCEPTION-MESSAGE] " + exception.getMessage() + System.lineSeparator() +
timeStamp + " [EXCEPTION-STACKTRACE] " + stackTrace;
System.out.println(ConsoleColor.RED + log + ConsoleColor.RESET);
try {
writeToLog(log);
} catch (IOException exception1) {
exception1.printStackTrace();
}
}
public void debug(String debug) {
// Get current date and time
SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date date = new Date();
String timeStamp = formatter.format(date);
// Writing log
String log = timeStamp + " [DEBUG] " + debug;
System.out.println(ConsoleColor.BLUE + log + ConsoleColor.RESET);
try {
writeToLog(log);
} catch (IOException exception) {
exception.printStackTrace();
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2025 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
*/
/*
* 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 dev.unlegitdqrk.unlegitlibrary.utils;
public class Tuple<A, B> 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;
}
}