- Converting to new repo
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
164
src/main/java/dev/unlegitdqrk/unlegitlibrary/file/FileUtils.java
Normal file
164
src/main/java/dev/unlegitdqrk/unlegitlibrary/file/FileUtils.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 + ")";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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 + ")";
|
||||
}
|
||||
}
|
||||
@@ -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 + ")";
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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(" ");
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
213
src/main/java/dev/unlegitdqrk/unlegitlibrary/utils/Logger.java
Normal file
213
src/main/java/dev/unlegitdqrk/unlegitlibrary/utils/Logger.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user