Overall refactor and add reflection.
This commit is contained in:
parent
134eb44f74
commit
dbd8c6a83e
21 changed files with 716 additions and 250 deletions
121
build.gradle.kts
121
build.gradle.kts
|
|
@ -1,10 +1,121 @@
|
|||
group = "io.github.adrianvic"
|
||||
version = "1.2"
|
||||
|
||||
plugins {
|
||||
`java-library`
|
||||
java
|
||||
id("xyz.jpenilla.run-paper") version "2.3.1"
|
||||
}
|
||||
|
||||
group = "org.adrianvictor"
|
||||
version = System.getenv("VERSION") ?: "unknown"
|
||||
val buildEnv = System.getenv("BUILD_CHANNEL")
|
||||
?: if (System.getenv("JITPACK") != null) "jitpack" else "local"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.papermc.io/repository/maven-public/")
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* SUPPORTED VERSIONS */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
val mcVersions = listOf(
|
||||
"b1_7_3",
|
||||
"r1_21"
|
||||
)
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* CREATE SOURCE SET PER VERSION */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
//tasks.withType<ProcessResources> {
|
||||
// inputs.property("version", project.version)
|
||||
//
|
||||
// filesMatching("plugin.yml") {
|
||||
// expand("version" to project.version)
|
||||
// }
|
||||
//}
|
||||
|
||||
mcVersions.forEach { ver ->
|
||||
val ss = sourceSets.create(ver) {
|
||||
java.srcDir("src/$ver/java")
|
||||
|
||||
resources.setSrcDirs(
|
||||
listOf(
|
||||
"src/$ver/resources",
|
||||
"src/main/resources"
|
||||
)
|
||||
)
|
||||
|
||||
compileClasspath += sourceSets["main"].output
|
||||
runtimeClasspath += output + compileClasspath
|
||||
}
|
||||
|
||||
if (ver == "r1_21") {
|
||||
configurations[ss.compileOnlyConfigurationName]
|
||||
.extendsFrom(configurations["compileOnly"])
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* DEPENDENCIES */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
dependencies {
|
||||
compileOnly(files("libs/craftbukkit-1060.jar"))
|
||||
add("compileOnly", "io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
|
||||
add("r1_21CompileOnly", "io.papermc.paper:paper-api:1.21.10-R0.1-SNAPSHOT")
|
||||
add("b1_7_3CompileOnly", files("libs/craftbukkit-1060.jar"))
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* BUILD TASKS */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
mcVersions.forEach { ver ->
|
||||
tasks.register<Jar>("jar${ver.replace(".", "_").replace("-", "_").replace("/", "_").capitalize()}") {
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
from(sourceSets["main"].output)
|
||||
from(sourceSets[ver].output)
|
||||
archiveClassifier.set(ver)
|
||||
|
||||
manifest {
|
||||
attributes(
|
||||
"TLib-Impl-Version" to ver,
|
||||
"TLib-Environment" to buildEnv
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("buildAll") {
|
||||
dependsOn(tasks.withType<Jar>())
|
||||
}
|
||||
|
||||
tasks.register<Jar>("bundleAll") {
|
||||
from(sourceSets["main"].output)
|
||||
mcVersions.forEach { ver ->
|
||||
from(sourceSets[ver].output)
|
||||
}
|
||||
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
|
||||
archiveClassifier.set("all-implementations")
|
||||
archiveVersion.set(project.version.toString())
|
||||
|
||||
manifest {
|
||||
attributes(
|
||||
"Implemented-Versions" to mcVersions.joinToString(",")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/* ----------------------------------------- */
|
||||
/* JAVA SETTINGS */
|
||||
/* ----------------------------------------- */
|
||||
|
||||
java {
|
||||
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package org.adrianvictor.lib.configuration;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Configuration implements org.adrianvictor.lib.configuration.provider.ConfigurationProvider {
|
||||
org.bukkit.util.config.Configuration config;
|
||||
|
||||
@Override
|
||||
public void load(File file) {
|
||||
config = new org.bukkit.util.config.Configuration(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String contents) throws IOException {
|
||||
String timestamp = LocalDateTime.now()
|
||||
.format(DateTimeFormatter.ofPattern("HH-mm-dd-MM-yyyy"));
|
||||
Path temp = Files.createTempFile("tlib-configprovider-tmp-%s".formatted(timestamp), ".yml");
|
||||
Files.writeString(temp, contents);
|
||||
File file = temp.toFile();
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Reader reader) throws IOException {
|
||||
String timestamp = LocalDateTime.now()
|
||||
.format(DateTimeFormatter.ofPattern("HH-mm-dd-MM-yyyy"));
|
||||
Path temp = Files.createTempFile("tlib-configprovider-tmp-%s".formatted(timestamp), ".yml");
|
||||
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(temp)) {
|
||||
reader.transferTo(writer);
|
||||
}
|
||||
|
||||
File file = temp.toFile();
|
||||
load(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(File file) {
|
||||
return config.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save() {
|
||||
return config.save();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveToString() {
|
||||
return config.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String path) {
|
||||
return config.getProperty(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String path, Object value) {
|
||||
config.setProperty(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAll() {
|
||||
return config.getAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String path, boolean def) {
|
||||
return config.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Boolean> getBooleanList(String path, List<Boolean> def) {
|
||||
return config.getBooleanList(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(String path, double def) {
|
||||
return config.getDouble(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Double> getDoubleList(String path, List<Double> def) {
|
||||
return config.getDoubleList(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String path, int def) {
|
||||
return config.getInt(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String path) {
|
||||
return config.getString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String path, String def) {
|
||||
return config.getString(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStringList(String path, List<String> def) {
|
||||
return config.getStringList(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getIntList(String path, List<Integer> def) {
|
||||
return config.getIntList(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getKeys(String path) {
|
||||
return config.getKeys(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getKeys() {
|
||||
return config.getKeys();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getList(String path) {
|
||||
return config.getList(path);
|
||||
}
|
||||
}
|
||||
10
src/b1_7_3/java/org/adrianvictor/lib/text/TextColor.java
Normal file
10
src/b1_7_3/java/org/adrianvictor/lib/text/TextColor.java
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package org.adrianvictor.lib.text;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class TextColor implements org.adrianvictor.lib.text.provider.TextColorProvider {
|
||||
@Override
|
||||
public String colorize(String colorCode) {
|
||||
return ChatColor.valueOf(colorCode).toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
package gd.rf.adrianvictor.lib;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class Color {
|
||||
public static String formatColors(String message) {
|
||||
return message.replaceAll("&", "§");
|
||||
}
|
||||
|
||||
public static Object[] ignoreColors(String message) {
|
||||
String parsed = message.replaceAll("&([0-9a-fk-or])", "");
|
||||
Boolean changed = parsed.equals(message);
|
||||
return new Object[] {parsed, changed};
|
||||
}
|
||||
|
||||
public static String rainbow(String message) {
|
||||
ChatColor[] rainbowColors = { ChatColor.RED, ChatColor.GOLD, ChatColor.YELLOW, ChatColor.GREEN, ChatColor.AQUA, ChatColor.BLUE, ChatColor.LIGHT_PURPLE };
|
||||
int colorIndex = 0;
|
||||
String coloredMessage = "";
|
||||
|
||||
for (char c : message.toCharArray()) {
|
||||
ChatColor currentColor = rainbowColors[colorIndex];
|
||||
coloredMessage += currentColor + String.valueOf(c);
|
||||
colorIndex++;
|
||||
if (colorIndex >= rainbowColors.length) {
|
||||
colorIndex = 0;
|
||||
}
|
||||
}
|
||||
return coloredMessage;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
package gd.rf.adrianvictor.lib;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.config.Configuration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
/**
|
||||
* Utility class for managing plugin configuration files.
|
||||
* <p>
|
||||
* This class extends {@link ConfigurationEx} to provide custom methods for loading, saving, and managing
|
||||
* configuration files. It automatically handles the creation of parent directories and copies default configuration
|
||||
* files from the plugin's resources if they do not exist.
|
||||
* <p>
|
||||
* <b>Note:</b> This class allows for flexible management of multiple configuration files, specified by their file name.
|
||||
*/
|
||||
public class ConfigurationEx extends Configuration {
|
||||
|
||||
private final File configFile;
|
||||
private Log logger;
|
||||
JavaPlugin plugin;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code ConfigUtil}.
|
||||
*
|
||||
* @param _plugin the plugin instance using this configuration utility
|
||||
* @param fileName the name of the configuration file to manage (e.g., "config.yml", "settings.yml")
|
||||
*/
|
||||
public ConfigurationEx(JavaPlugin _plugin, String fileName, Log _logger) {
|
||||
super(new File(_plugin.getDataFolder(), fileName));
|
||||
plugin = _plugin;
|
||||
logger = _logger;
|
||||
this.configFile = new File(plugin.getDataFolder(), fileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration file.
|
||||
* <ul>
|
||||
* <li>Creates parent directories if they do not exist.</li>
|
||||
* <li>Copies the default configuration file from the plugin's resources if the configuration file does not exist.</li>
|
||||
* <li>Attempts to load the configuration by calling the superclass' {@code load()} method.</li>
|
||||
* <li>Logs errors if the configuration file cannot be loaded.</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public void load() {
|
||||
createParentDirectories();
|
||||
|
||||
if (!configFile.exists()) {
|
||||
copyDefaultConfig();
|
||||
}
|
||||
|
||||
try {
|
||||
super.load();
|
||||
} catch (Exception e) {
|
||||
logger.severe(String.format("Failed to load config '%s': %s", configFile.getName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the parent directories for the configuration file if they do not exist.
|
||||
* <p>
|
||||
* Logs an error if the directories cannot be created.
|
||||
*/
|
||||
private void createParentDirectories() {
|
||||
try {
|
||||
Files.createDirectories(configFile.getParentFile().toPath());
|
||||
} catch (IOException e) {
|
||||
logger.severe(String.format("Failed to generate default config directory: %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies the default configuration file from the plugin's resources to the target location.
|
||||
* <p>
|
||||
* This method looks for a file in the plugin's resources with the same name as the configuration file being managed.
|
||||
* If found, it copies this file to the plugin's data folder.
|
||||
* <p>
|
||||
* Logs an error if the default configuration file cannot be found or copied.
|
||||
*/
|
||||
private void copyDefaultConfig() {
|
||||
// Load the config from the JAR directly (it is located at the root level)
|
||||
String resourcePath = "/" + configFile.getName(); // Root path of JAR
|
||||
|
||||
try (InputStream input = plugin.getClass().getResourceAsStream(resourcePath)) {
|
||||
if (input == null) {
|
||||
logger.severe(String.format("Default config '%s' wasn't found in the JAR.", configFile.getName()));
|
||||
return;
|
||||
}
|
||||
|
||||
Files.copy(input, configFile.toPath());
|
||||
if (Files.exists(configFile.toPath())) {
|
||||
logger.info(String.format("Default config '%s' generated successfully.", configFile.getName()));
|
||||
} else {
|
||||
logger.warning("We tried to generate the default config file, but it was not found even after the creation. Maybe your permissions are broken?");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.severe(String.format("Failed to generate default config '%s': %s", configFile.getName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the configuration file and logs the result.
|
||||
* <p>
|
||||
* Logs a message indicating whether the configuration was loaded successfully.
|
||||
*/
|
||||
public void loadConfig() {
|
||||
try {
|
||||
this.load();
|
||||
logger.info(String.format("Config '%s' loaded successfully.", configFile.getName()));
|
||||
} catch (Exception e) {
|
||||
logger.severe(String.format("Failed to load config '%s': %s", configFile.getName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the configuration file and logs the result.
|
||||
* <p>
|
||||
* Logs a message indicating whether the configuration was saved successfully.
|
||||
*/
|
||||
public void saveConfig() {
|
||||
try {
|
||||
this.save();
|
||||
logger.info(String.format("Config '%s' saved successfully.", configFile.getName()));
|
||||
} catch (Exception e) {
|
||||
logger.severe(String.format("Failed to save config '%s': %s", configFile.getName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the configuration file managed by this utility.
|
||||
*
|
||||
* @return the configuration file
|
||||
*/
|
||||
public File getConfig() {
|
||||
return configFile;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
package gd.rf.adrianvictor.lib;
|
||||
import static org.bukkit.Bukkit.getServer;
|
||||
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Log {
|
||||
JavaPlugin plugin;
|
||||
PluginDescriptionFile pdf;
|
||||
|
||||
public Log(JavaPlugin _plugin) {
|
||||
plugin = _plugin;
|
||||
pdf = plugin.getDescription();
|
||||
}
|
||||
|
||||
public void info(String message) {
|
||||
getServer().getLogger().info("[" + pdf.getName() + "] " + message);
|
||||
}
|
||||
|
||||
public void infoc(String message) {
|
||||
getServer().getLogger().info("[" + pdf.getName() + "] " + Color.formatColors(message));
|
||||
}
|
||||
|
||||
public void warning(String message) {
|
||||
getServer().getLogger().warning("[" + pdf.getName() + "] " + message);
|
||||
}
|
||||
|
||||
public void warningc(String message) {
|
||||
getServer().getLogger().warning("[" + pdf.getName() + "] " + Color.formatColors(message));
|
||||
}
|
||||
|
||||
public void severe(String message) {
|
||||
getServer().getLogger().severe("[" + pdf.getName() + "] " + message);
|
||||
}
|
||||
|
||||
public void severec(String message) {
|
||||
getServer().getLogger().severe("[" + pdf.getName() + "] " + Color.formatColors(message));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
package gd.rf.adrianvictor.lib;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Main extends JavaPlugin {
|
||||
|
||||
Log logger;
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
logger.info("is being disabled.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
logger = new Log(this);
|
||||
logger.info("is loading.");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package gd.rf.adrianvictor.lib;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PlayerEx {
|
||||
public static void strikeLightning(Player player) {
|
||||
player.getWorld().strikeLightning(player.getLocation());
|
||||
}
|
||||
}
|
||||
45
src/main/java/org/adrianvictor/lib/Main.java
Normal file
45
src/main/java/org/adrianvictor/lib/Main.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
package org.adrianvictor.lib;
|
||||
import org.adrianvictor.lib.reflection.ImplementationRegistry;
|
||||
import org.adrianvictor.lib.reflection.VersionMatcher;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Main extends JavaPlugin {
|
||||
VersionMatcher matcher;
|
||||
String serverVersion;
|
||||
ImplementationRegistry registry;
|
||||
private static Main instance;
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
getLogger().info("is being disabled.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
getLogger().info("is loading.");
|
||||
|
||||
instance = this;
|
||||
matcher = new VersionMatcher();
|
||||
serverVersion = matcher.getServerVersion();
|
||||
|
||||
String classSuffix = matcher.getClassSuffix("release", serverVersion);
|
||||
|
||||
if (classSuffix == null) {
|
||||
classSuffix = matcher.getClassSuffix("beta", serverVersion);
|
||||
}
|
||||
|
||||
if (classSuffix == null) {
|
||||
throw new IllegalStateException("No suitable implementation found for version " + serverVersion);
|
||||
}
|
||||
|
||||
registry = new ImplementationRegistry(classSuffix);
|
||||
}
|
||||
|
||||
public static Main getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public ImplementationRegistry getRegistry() {
|
||||
return registry;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package org.adrianvictor.lib.configuration;
|
||||
|
||||
import org.adrianvictor.lib.Main;
|
||||
import org.adrianvictor.lib.configuration.provider.ConfigurationProvider;
|
||||
|
||||
public class Configuration {
|
||||
public static ConfigurationProvider create() {
|
||||
return Main.getInstance().getRegistry().getInstance(ConfigurationProvider.class, "org.adrianvictor.lib.configuraion");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.adrianvictor.lib.configuration.exception;
|
||||
|
||||
public class InvalidConfigurationException extends Exception {
|
||||
public InvalidConfigurationException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public InvalidConfigurationException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package org.adrianvictor.lib.configuration.provider;
|
||||
|
||||
import org.adrianvictor.lib.configuration.exception.InvalidConfigurationException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface ConfigurationProvider {
|
||||
void load(File file) throws IOException, InvalidConfigurationException;
|
||||
void load(String contents) throws IOException, InvalidConfigurationException;
|
||||
void load(Reader reader) throws IOException, InvalidConfigurationException;
|
||||
boolean save(File file);
|
||||
boolean save();
|
||||
String saveToString();
|
||||
Object getProperty(String path);
|
||||
void setProperty(String path, Object value);
|
||||
Map<String, Object> getAll();
|
||||
boolean getBoolean(String path, boolean def);
|
||||
List<Boolean> getBooleanList(String path, List<Boolean> def);
|
||||
double getDouble(String path, double def);
|
||||
List<Double> getDoubleList(String path, List<Double> def);
|
||||
int getInt(String path, int def);
|
||||
String getString(String path);
|
||||
String getString(String path, String def);
|
||||
List<String> getStringList(String path, List<String> def);
|
||||
List<Integer> getIntList(String path, List<Integer> def);
|
||||
List<String> getKeys(String path);
|
||||
List<String> getKeys();
|
||||
List<Object> getList(String path);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.adrianvictor.lib.reflection;
|
||||
|
||||
public class ImplementationRegistry {
|
||||
|
||||
private final String classSuffix;
|
||||
|
||||
public ImplementationRegistry(String classSuffix) {
|
||||
this.classSuffix = classSuffix;
|
||||
}
|
||||
|
||||
public <T> T getInstance(Class<T> interfaceClass, String packagePath) {
|
||||
String implClassName = packagePath.replace(
|
||||
"org.adrianvictor.lib",
|
||||
"org.adrianvictor.lib.impl." + classSuffix
|
||||
);
|
||||
|
||||
try {
|
||||
Class<?> implClass = Class.forName(implClassName);
|
||||
return interfaceClass.cast(implClass.getDeclaredConstructor().newInstance());
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw new IllegalStateException("Cannot load " + implClassName, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
package org.adrianvictor.lib.reflection;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class VersionMatcher {
|
||||
|
||||
public VersionMatcher() {}
|
||||
|
||||
private record Entry(String pattern, String classSuffix) {}
|
||||
|
||||
public String getClassSuffix(String type, String serverVersion) {
|
||||
if (type == null || serverVersion == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, List<Entry>> map = populateMap();
|
||||
List<Entry> entries = map.get(type.toLowerCase());
|
||||
if (entries == null || entries.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Exact match
|
||||
for (Entry e : entries) {
|
||||
if (safeMatches(e.pattern, serverVersion)) {
|
||||
return e.classSuffix;
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback to closest version
|
||||
List<Entry> sorted = new ArrayList<>(entries);
|
||||
Collections.sort(sorted, (a, b) -> compareVersions(a.pattern, b.pattern));
|
||||
|
||||
Entry oldest = sorted.get(0);
|
||||
Entry newest = sorted.get(sorted.size() - 1);
|
||||
|
||||
int cmpOldest = compareVersions(serverVersion, oldest.pattern);
|
||||
int cmpNewest = compareVersions(serverVersion, newest.pattern);
|
||||
|
||||
if (cmpOldest < 0) {
|
||||
return oldest.classSuffix;
|
||||
} else if (cmpNewest > 0) {
|
||||
return newest.classSuffix;
|
||||
}
|
||||
|
||||
return newest.classSuffix;
|
||||
}
|
||||
|
||||
public String getServerVersion() {
|
||||
String rawVersion = null;
|
||||
try {
|
||||
rawVersion = Bukkit.getMinecraftVersion();
|
||||
} catch (NoSuchMethodError ignored) {}
|
||||
|
||||
if (rawVersion == null || rawVersion.isEmpty()) {
|
||||
String v = Bukkit.getVersion();
|
||||
int start = v.lastIndexOf("MC: ");
|
||||
if (start != -1) {
|
||||
rawVersion = v.substring(start + 4, v.length() - 1);
|
||||
} else {
|
||||
rawVersion = "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
return rawVersion;
|
||||
}
|
||||
|
||||
private Map<String, List<Entry>> populateMap() {
|
||||
Map<String, List<Entry>> map = new HashMap<>();
|
||||
map.put("release", List.of(
|
||||
new Entry("^1\\.21\\..*$", "r1_21")
|
||||
));
|
||||
map.put("beta", List.of(
|
||||
new Entry("^1\\.7\\.3$", "b1_7_3")
|
||||
));
|
||||
return map;
|
||||
}
|
||||
|
||||
private int compareVersions(String v1, String v2) {
|
||||
String clean1 = v1.replaceAll("[^0-9.]", "");
|
||||
String clean2 = v2.replaceAll("[^0-9.]", "");
|
||||
|
||||
String[] a1 = clean1.split("\\.");
|
||||
String[] a2 = clean2.split("\\.");
|
||||
|
||||
int len = Math.max(a1.length, a2.length);
|
||||
for (int i = 0; i < len; i++) {
|
||||
int n1 = i < a1.length ? parseInt(a1[i]) : 0;
|
||||
int n2 = i < a2.length ? parseInt(a2[i]) : 0;
|
||||
if (n1 != n2) {
|
||||
return n1 - n2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int parseInt(String s) {
|
||||
try {
|
||||
return Integer.parseInt(s);
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean safeMatches(String expression, String against) {
|
||||
String cleanPattern = expression.trim();
|
||||
Pattern pattern = Pattern.compile(cleanPattern, Pattern.CASE_INSENSITIVE);
|
||||
return pattern.matcher(against).matches();
|
||||
}
|
||||
}
|
||||
10
src/main/java/org/adrianvictor/lib/text/TextColor.java
Normal file
10
src/main/java/org/adrianvictor/lib/text/TextColor.java
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package org.adrianvictor.lib.text;
|
||||
|
||||
import org.adrianvictor.lib.Main;
|
||||
import org.adrianvictor.lib.text.provider.TextColorProvider;
|
||||
|
||||
public class TextColor {
|
||||
public static TextColorProvider create() {
|
||||
return Main.getInstance().getRegistry().getInstance(TextColorProvider.class, "org.adrianvictor.lib.text");
|
||||
}
|
||||
}
|
||||
31
src/main/java/org/adrianvictor/lib/text/TextColorUtils.java
Normal file
31
src/main/java/org/adrianvictor/lib/text/TextColorUtils.java
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
package org.adrianvictor.lib.text;
|
||||
|
||||
import org.adrianvictor.lib.text.provider.TextColorProvider;
|
||||
|
||||
public class TextColorUtils {
|
||||
private static final TextColorProvider provider = TextColor.create();
|
||||
|
||||
public static String formatColors(String message) {
|
||||
return message.replace("&", "§");
|
||||
}
|
||||
|
||||
public static String ignoreColors(String message) {
|
||||
return message.replaceAll("&([0-9a-fk-or])", "");
|
||||
}
|
||||
|
||||
public static String rainbow(String message) {
|
||||
String[] colorNames = {"RED", "GOLD", "YELLOW", "GREEN", "AQUA", "BLUE", "LIGHT_PURPLE"};
|
||||
int colorIndex = 0;
|
||||
String coloredMessage = "";
|
||||
|
||||
for (char c : message.toCharArray()) {
|
||||
String currentColor = provider.colorize(colorNames[colorIndex]);
|
||||
coloredMessage += currentColor + c;
|
||||
colorIndex++;
|
||||
if (colorIndex >= colorNames.length) {
|
||||
colorIndex = 0;
|
||||
}
|
||||
}
|
||||
return coloredMessage;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
package gd.rf.adrianvictor.lib;
|
||||
package org.adrianvictor.lib.text;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.bukkit.ChatColor;
|
||||
|
||||
public class Text {
|
||||
public class TextUtils {
|
||||
public static String generateRandomString(int length) {
|
||||
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
Random random = new Random();
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package org.adrianvictor.lib.text.provider;
|
||||
|
||||
public interface TextColorProvider {
|
||||
String colorize(String colorCode);
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
name: tenkumaLib
|
||||
author: tenkuma
|
||||
database: false
|
||||
main: gd.rf.adrianvictor.lib.Main
|
||||
name: tenkumaLib
|
||||
main: org.adrianvictor.lib.Main
|
||||
startup: startup
|
||||
url: https://adrianvictor.rf.gd
|
||||
version: '1.0'
|
||||
url: https://adrianvic.github.io
|
||||
version: '2.0'
|
||||
api-version: '1.13'
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
package org.adrianvictor.lib.configuration;
|
||||
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.util.*;
|
||||
|
||||
public class Configuration implements org.adrianvictor.lib.configuration.provider.ConfigurationProvider {
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
File configFile;
|
||||
|
||||
@Override
|
||||
public void load(File file) throws IOException, org.adrianvictor.lib.configuration.exception.InvalidConfigurationException {
|
||||
try {
|
||||
config.load(file);
|
||||
configFile = file;
|
||||
} catch (InvalidConfigurationException e) {
|
||||
throw new org.adrianvictor.lib.configuration.exception.InvalidConfigurationException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(String contents) throws IOException, org.adrianvictor.lib.configuration.exception.InvalidConfigurationException {
|
||||
try {
|
||||
config.load(contents);
|
||||
} catch (InvalidConfigurationException e) {
|
||||
throw new org.adrianvictor.lib.configuration.exception.InvalidConfigurationException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Reader reader) throws IOException, org.adrianvictor.lib.configuration.exception.InvalidConfigurationException {
|
||||
try {
|
||||
config.load(reader);
|
||||
} catch (InvalidConfigurationException e) {
|
||||
throw new org.adrianvictor.lib.configuration.exception.InvalidConfigurationException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save(File file) {
|
||||
try {
|
||||
config.save(file);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean save() {
|
||||
try {
|
||||
config.save(configFile);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String saveToString() {
|
||||
return config.saveToString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String path) {
|
||||
return config.get(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProperty(String path, Object value) {
|
||||
config.set(path, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getAll() {
|
||||
assert config.getRoot() != null;
|
||||
return config.getRoot().getValues(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(String path, boolean def) {
|
||||
return config.getBoolean(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Boolean> getBooleanList(String path, List<Boolean> def) {
|
||||
List<Boolean> result = config.getBooleanList(path);
|
||||
if (result.isEmpty()) result = def;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDouble(String path, double def) {
|
||||
return config.getDouble(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Double> getDoubleList(String path, List<Double> def) {
|
||||
List<Double> result = config.getDoubleList(path);
|
||||
if (result.isEmpty()) result = def;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(String path, int def) {
|
||||
return config.getInt(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String path) {
|
||||
return config.getString(path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(String path, String def) {
|
||||
return config.getString(path, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getStringList(String path, List<String> def) {
|
||||
List<String> result = config.getStringList(path);
|
||||
if (result.isEmpty()) result = def;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Integer> getIntList(String path, List<Integer> def) {
|
||||
List<Integer> result = config.getIntegerList(path);
|
||||
if (result.isEmpty()) result = def;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getKeys(String path) {
|
||||
Set<String> set = Objects.requireNonNull(config.getConfigurationSection(path)).getKeys(true);
|
||||
return set.stream().toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getKeys() {
|
||||
Set<String> set = Objects.requireNonNull(config.getRoot()).getKeys(true);
|
||||
return set.stream().toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Object> getList(String path) {
|
||||
return Collections.singletonList(config.getList(path));
|
||||
}
|
||||
}
|
||||
10
src/r1_21/java/org/adrianvictor/lib/text/TextColor.java
Normal file
10
src/r1_21/java/org/adrianvictor/lib/text/TextColor.java
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package org.adrianvictor.lib.text;
|
||||
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
public class TextColor implements org.adrianvictor.lib.text.provider.TextColorProvider {
|
||||
@Override
|
||||
public String colorize(String colorCode) {
|
||||
return NamedTextColor.NAMES.valueOr(colorCode, NamedTextColor.WHITE).toString();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue