use this amazing config library i just found

This commit is contained in:
Pyrbu 2023-04-26 17:08:14 +01:00
parent 59804031f5
commit 79cc7e6b7e
9 changed files with 134 additions and 164 deletions

@ -37,6 +37,7 @@ dependencies {
implementation "com.github.robertlit:SpigotResourcesAPI:2.0" implementation "com.github.robertlit:SpigotResourcesAPI:2.0"
implementation "net.kyori:adventure-platform-bukkit:4.3.0" implementation "net.kyori:adventure-platform-bukkit:4.3.0"
implementation "com.github.retrooper.packetevents:spigot:2.0.0-SNAPSHOT" implementation "com.github.retrooper.packetevents:spigot:2.0.0-SNAPSHOT"
implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1"
} }
group "lol.pyr" group "lol.pyr"
@ -55,8 +56,12 @@ shadowJar {
relocate "org.checkerframework", "lol.pyr.znpcsplus.lib.checkerframework" relocate "org.checkerframework", "lol.pyr.znpcsplus.lib.checkerframework"
relocate "javax.annotation", "lol.pyr.znpcsplus.lib.javaxannotation" relocate "javax.annotation", "lol.pyr.znpcsplus.lib.javaxannotation"
relocate "com.google", "lol.pyr.znpcsplus.lib.google" relocate "com.google", "lol.pyr.znpcsplus.lib.google"
relocate "com.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.api" relocate "com.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.api"
relocate "io.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.impl" relocate "io.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.impl"
relocate "org.yaml.snakeyaml", "lol.pyr.znpcsplus.lib.snakeyaml"
relocate "space.arim.dazzleconf", "lol.pyr.znpcsplus.lib.dazzleconf"
minimize() minimize()
} }

@ -1,74 +0,0 @@
package io.github.znetworkw.znpcservers.configuration;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.internal.$Gson$Types;
import io.github.znetworkw.znpcservers.utility.Utils;
import lol.pyr.znpcsplus.ZNPCsPlus;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.Map;
import java.util.stream.Collectors;
public class Configuration {
private static final Charset CHARSET = StandardCharsets.UTF_8;
private final String name;
private final Path path;
private final Map<ConfigurationValue, Object> configurationValues;
public static final Configuration CONFIGURATION = new Configuration("config");
public static final Configuration MESSAGES = new Configuration("messages");
protected Configuration(String name) {
this(name, ZNPCsPlus.PLUGIN_FOLDER.toPath().resolve(name + ".json"));
}
private Configuration(String name, Path path) {
if (!path.getFileName().toString().endsWith(".json")) throw new IllegalStateException("Invalid configuration format for: " + path.getFileName());
this.name = name;
this.path = path;
this.configurationValues = ConfigurationValue.VALUES_BY_NAME.get(name).stream().collect(Collectors.toMap((c) -> c, ConfigurationValue::getValue));
this.onLoad();
this.save();
}
protected void onLoad() {
try (Reader reader = Files.newBufferedReader(this.path, CHARSET)) {
JsonElement data = JsonParser.parseReader(reader);
if (data == null) return;
for(ConfigurationValue configValue : this.configurationValues.keySet()) {
boolean single = this.configurationValues.size() == 1;
JsonElement jsonElement = single ? data : (data.isJsonObject() ? data.getAsJsonObject().get(configValue.name()) : null);
if (jsonElement == null || jsonElement.isJsonNull()) continue;
if (!single && configValue.getPrimitiveType().isEnum()) this.configurationValues.put(configValue, ZNPCsPlus.GSON.fromJson(jsonElement, configValue.getPrimitiveType()));
else this.configurationValues.put(configValue, ZNPCsPlus.GSON.fromJson(jsonElement, $Gson$Types.newParameterizedTypeWithOwner(null, configValue.getValue().getClass(), configValue.getPrimitiveType())));
}
} catch (NoSuchFileException ignored) {
} catch (IOException ex) {
throw new IllegalStateException("Failed to read configuration: " + this.name);
}
}
public void save() {
try (Writer writer = Files.newBufferedWriter(this.path, CHARSET)) {
ZNPCsPlus.GSON.toJson(this.configurationValues.size() == 1 ? this.configurationValues.values().iterator().next() : this.configurationValues, writer);
} catch (IOException ex) {
throw new IllegalStateException("Failed to save configuration: " + this.name);
}
}
@SuppressWarnings("unchecked")
public <T> T getValue(ConfigurationValue configValue) {
return (T)this.configurationValues.get(configValue);
}
public void sendMessage(org.bukkit.command.CommandSender sender, ConfigurationValue configValue, Object... replaces) {
sender.sendMessage(Utils.toColor(String.format(this.getValue(configValue), replaces)));
}
}

@ -1,8 +0,0 @@
package io.github.znetworkw.znpcservers.configuration;
public final class ConfigurationConstants {
public static final String SPACE_SYMBOL = Configuration.CONFIGURATION.getValue(ConfigurationValue.REPLACE_SYMBOL);
public static final boolean DEBUG_ENABLED = Configuration.CONFIGURATION.getValue(ConfigurationValue.DEBUG_ENABLED);
public static final int VIEW_DISTANCE = Configuration.CONFIGURATION.<Integer>getValue(ConfigurationValue.VIEW_DISTANCE);
public static final boolean CHECK_FOR_UPDATES = Configuration.CONFIGURATION.getValue(ConfigurationValue.CHECK_FOR_UPDATES);
}

@ -1,77 +0,0 @@
package io.github.znetworkw.znpcservers.configuration;
import com.google.common.collect.ImmutableSet;
import io.github.znetworkw.znpcservers.utility.GuavaCollectors;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
public enum ConfigurationValue {
VIEW_DISTANCE("config", 32, Integer.class),
REPLACE_SYMBOL("config", "-", String.class),
SAVE_NPCS_DELAY_SECONDS("config", 600, Integer.class),
MAX_PATH_LOCATIONS("config", 500, Integer.class),
DEBUG_ENABLED("config", false, Boolean.class),
LINE_SPACING("config", 0.3D, Double.class),
ANIMATION_RGB("config", false, Boolean.class),
CHECK_FOR_UPDATES("config", true, Boolean.class),
NO_PERMISSION("messages", "&cYou do not have permission to execute this command.", String.class),
SUCCESS("messages", "&aSuccess!", String.class),
INCORRECT_USAGE("messages", "&cThe arguments you specified are invalid. Type &f/znpcs&c for examples.", String.class),
COMMAND_NOT_FOUND("messages", "&cThe command you specified does not exist!", String.class),
COMMAND_ERROR("messages", "&cAn error occurred when executing this command. See console for more information.", String.class),
INVALID_NUMBER("messages", "&cThe ID you have specified is invalid. Please use positive integers only!", String.class),
NPC_NOT_FOUND("messages", "&cNo NPCs could be found with this ID!", String.class),
TOO_FEW_ARGUMENTS("messages", "&cThis command does not contain enough arguments. Type &f/znpcs&c or view our documentation for a list/examples of existing arguments.", String.class),
PATH_START("messages", "&aSuccess! Move to create a path for your NPC. When finished, type &f/znpcs path exit&c to exit path creation.", String.class),
EXIT_PATH("messages", "&cYou have exited path creation.", String.class),
PATH_FOUND("messages", "&cThere is already a path with this name.", String.class),
NPC_FOUND("messages", "&cThere is already an NPC with this ID.", String.class),
NO_PATH_FOUND("messages", "&cThe path you have specified does not exist.", String.class),
NO_SKIN_FOUND("messages", "&cThe skin username/URL you have specified does not exist or is invalid.", String.class),
NO_NPC_FOUND("messages", "&cThe NPC you have specified does not exist.", String.class),
NO_ACTION_FOUND("messages", "&cThis action does not exist! Type &f/znpcs&c or view our documentation for a list/examples of existing action types.", String.class),
METHOD_NOT_FOUND("messages", "&cThis method does not exist! Type &f/znpcs&c or view our documentation for a list/examples of existing methods.", String.class),
INVALID_NAME_LENGTH("messages", "&cThe name you specified either too short or long. Please enter a positive integer of (3 to 16) characters.", String.class),
UNSUPPORTED_ENTITY("messages", "&cThis entity type not available in your current server version.", String.class),
PATH_SET_INCORRECT_USAGE("messages", "&eUsage: &aset <npc_id> <path_name>", String.class),
ACTION_ADD_INCORRECT_USAGE("messages", "&eUsage: &a<SERVER/CMD/MESSAGE/CONSOLE> <actionValue>", String.class),
ACTION_DELAY_INCORRECT_USAGE("messages", "&eUsage: &a<action_id> <delay>", String.class),
CONVERSATION_SET_INCORRECT_USAGE("messages", "&cUsage: <npc_id> <conversation_name> <RADIUS/CLICK>", String.class),
NO_CONVERSATION_FOUND("messages", "&cThe conversation you have specified does not exist!", String.class),
CONVERSATION_FOUND("messages", "&cThere is already a conversation with this name.", String.class),
INVALID_SIZE("messages", "&cThe position you have specified cannot exceed the limit.", String.class),
FETCHING_SKIN("messages", "&aFetching skin for name: &f%s&a. Please wait...", String.class),
CANT_GET_SKIN("messages", "&cCould not fetch skin for name: %s.", String.class),
GET_SKIN("messages", "&aSkin successfully fetched!", String.class),
NOT_SUPPORTED_NPC_TYPE("messages", "&cThis NPC type doesn't exists or is not supported in your current server version.", String.class);
public static final Map<String, ImmutableSet<ConfigurationValue>> VALUES_BY_NAME;
static {
VALUES_BY_NAME = Arrays.stream(values()).collect(Collectors.groupingBy(ConfigurationValue::getConfigName, GuavaCollectors.toImmutableSet()));
}
private final String configName;
private final Object value;
private final Class<?> primitiveType;
ConfigurationValue(String configName, Object value, Class<?> primitiveType) {
this.configName = configName;
this.value = value;
this.primitiveType = primitiveType;
}
public String getConfigName() {
return this.configName;
}
public Object getValue() {
return this.value;
}
public Class<?> getPrimitiveType() {
return this.primitiveType;
}
}

@ -6,11 +6,11 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder; import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
import io.github.znetworkw.znpcservers.listeners.InventoryListener; import io.github.znetworkw.znpcservers.listeners.InventoryListener;
import io.github.znetworkw.znpcservers.utility.BungeeUtils; import io.github.znetworkw.znpcservers.utility.BungeeUtils;
import io.github.znetworkw.znpcservers.utility.SchedulerUtils; import io.github.znetworkw.znpcservers.utility.SchedulerUtils;
import io.github.znetworkw.znpcservers.utility.itemstack.ItemStackSerializer; import io.github.znetworkw.znpcservers.utility.itemstack.ItemStackSerializer;
import lol.pyr.znpcsplus.config.Configs;
import lol.pyr.znpcsplus.entity.EntityProperty; import lol.pyr.znpcsplus.entity.EntityProperty;
import lol.pyr.znpcsplus.entity.PacketLocation; import lol.pyr.znpcsplus.entity.PacketLocation;
import lol.pyr.znpcsplus.interaction.InteractionPacketListener; import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
@ -110,6 +110,9 @@ public class ZNPCsPlus extends JavaPlugin {
PLUGIN_FOLDER.mkdirs(); PLUGIN_FOLDER.mkdirs();
PATH_FOLDER.mkdirs(); PATH_FOLDER.mkdirs();
log(ChatColor.WHITE + " * Loading configurations...");
Configs.init(PLUGIN_FOLDER);
log(ChatColor.WHITE + " * Registering components..."); log(ChatColor.WHITE + " * Registering components...");
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord"); getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
new Metrics(this, PLUGIN_ID); new Metrics(this, PLUGIN_ID);
@ -122,13 +125,13 @@ public class ZNPCsPlus extends JavaPlugin {
new InventoryListener(this); new InventoryListener(this);
new SkinCacheCleanTask(this); new SkinCacheCleanTask(this);
new UserListener(this); new UserListener(this);
if (ConfigurationConstants.CHECK_FOR_UPDATES) new UpdateNotificationListener(this, new UpdateChecker(this)); if (Configs.config().checkForUpdates()) new UpdateNotificationListener(this, new UpdateChecker(this));
enabled = true; enabled = true;
log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)"); log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)");
log(""); log("");
if (ConfigurationConstants.DEBUG_ENABLED) { if (Configs.config().debugEnabled()) {
int wrap = 20; int wrap = 20;
int x = 0; int x = 0;
int z = 0; int z = 0;

@ -0,0 +1,58 @@
package lol.pyr.znpcsplus.config;
import lol.pyr.znpcsplus.ZNPCsPlus;
import space.arim.dazzleconf.ConfigurationFactory;
import space.arim.dazzleconf.ConfigurationOptions;
import space.arim.dazzleconf.error.ConfigFormatSyntaxException;
import space.arim.dazzleconf.error.InvalidConfigException;
import space.arim.dazzleconf.ext.snakeyaml.CommentMode;
import space.arim.dazzleconf.ext.snakeyaml.SnakeYamlConfigurationFactory;
import space.arim.dazzleconf.ext.snakeyaml.SnakeYamlOptions;
import space.arim.dazzleconf.helper.ConfigurationHelper;
import java.io.File;
import java.io.IOException;
public class Configs {
private volatile static MainConfig config;
private static ConfigurationHelper<MainConfig> configHelper;
private volatile static MessageConfig messages;
private static ConfigurationHelper<MessageConfig> messagesHelper;
private static <T> ConfigurationHelper<T> createHelper(Class<T> configClass, File file) {
SnakeYamlOptions yamlOptions = new SnakeYamlOptions.Builder().commentMode(CommentMode.fullComments()).build();
ConfigurationFactory<T> configFactory = SnakeYamlConfigurationFactory.create(configClass, ConfigurationOptions.defaults(), yamlOptions);
return new ConfigurationHelper<>(file.getParentFile().toPath(), file.getName(), configFactory);
}
public static void init(File pluginFolder) {
configHelper = createHelper(MainConfig.class, new File(pluginFolder, "config.yaml"));
messagesHelper = createHelper(MessageConfig.class, new File(pluginFolder, "messages.yaml"));
load();
}
public static void load() {
try {
config = configHelper.reloadConfigData();
messages = messagesHelper.reloadConfigData();
} catch (IOException e) {
ZNPCsPlus.LOGGER.severe("Couldn't open config file!");
e.printStackTrace();
} catch (ConfigFormatSyntaxException e) {
ZNPCsPlus.LOGGER.severe("Invalid config syntax!");
e.printStackTrace();
} catch (InvalidConfigException e) {
ZNPCsPlus.LOGGER.severe("Invalid config value!");
e.printStackTrace();
}
}
public static MainConfig config() {
return config;
}
public static MessageConfig messages() {
return messages;
}
}

@ -0,0 +1,24 @@
package lol.pyr.znpcsplus.config;
import space.arim.dazzleconf.annote.ConfKey;
import static space.arim.dazzleconf.annote.ConfDefault.*;
// TODO: Add comments to the values using @ConfComments()
public interface MainConfig {
@ConfKey("view-distance")
@DefaultInteger(32)
int viewDistance();
@ConfKey("line-spacing")
@DefaultDouble(0.3D)
double lineSpacing();
@ConfKey("debug-enabled")
@DefaultBoolean(false)
boolean debugEnabled();
@ConfKey("check-for-updates")
@DefaultBoolean(true)
boolean checkForUpdates();
}

@ -0,0 +1,38 @@
package lol.pyr.znpcsplus.config;
/**
* (OLD CONFIGURATION)
* NO_PERMISSION("messages", "&cYou do not have permission to execute this command.", String.class),
* SUCCESS("messages", "&aSuccess!", String.class),
* INCORRECT_USAGE("messages", "&cThe arguments you specified are invalid. Type &f/znpcs&c for examples.", String.class),
* COMMAND_NOT_FOUND("messages", "&cThe command you specified does not exist!", String.class),
* COMMAND_ERROR("messages", "&cAn error occurred when executing this command. See console for more information.", String.class),
* INVALID_NUMBER("messages", "&cThe ID you have specified is invalid. Please use positive integers only!", String.class),
* NPC_NOT_FOUND("messages", "&cNo NPCs could be found with this ID!", String.class),
* TOO_FEW_ARGUMENTS("messages", "&cThis command does not contain enough arguments. Type &f/znpcs&c or view our documentation for a list/examples of existing arguments.", String.class),
* PATH_START("messages", "&aSuccess! Move to create a path for your NPC. When finished, type &f/znpcs path exit&c to exit path creation.", String.class),
* EXIT_PATH("messages", "&cYou have exited path creation.", String.class),
* PATH_FOUND("messages", "&cThere is already a path with this name.", String.class),
* NPC_FOUND("messages", "&cThere is already an NPC with this ID.", String.class),
* NO_PATH_FOUND("messages", "&cThe path you have specified does not exist.", String.class),
* NO_SKIN_FOUND("messages", "&cThe skin username/URL you have specified does not exist or is invalid.", String.class),
* NO_NPC_FOUND("messages", "&cThe NPC you have specified does not exist.", String.class),
* NO_ACTION_FOUND("messages", "&cThis action does not exist! Type &f/znpcs&c or view our documentation for a list/examples of existing action types.", String.class),
* METHOD_NOT_FOUND("messages", "&cThis method does not exist! Type &f/znpcs&c or view our documentation for a list/examples of existing methods.", String.class),
* INVALID_NAME_LENGTH("messages", "&cThe name you specified either too short or long. Please enter a positive integer of (3 to 16) characters.", String.class),
* UNSUPPORTED_ENTITY("messages", "&cThis entity type not available in your current server version.", String.class),
* PATH_SET_INCORRECT_USAGE("messages", "&eUsage: &aset <npc_id> <path_name>", String.class),
* ACTION_ADD_INCORRECT_USAGE("messages", "&eUsage: &a<SERVER/CMD/MESSAGE/CONSOLE> <actionValue>", String.class),
* ACTION_DELAY_INCORRECT_USAGE("messages", "&eUsage: &a<action_id> <delay>", String.class),
* CONVERSATION_SET_INCORRECT_USAGE("messages", "&cUsage: <npc_id> <conversation_name> <RADIUS/CLICK>", String.class),
* NO_CONVERSATION_FOUND("messages", "&cThe conversation you have specified does not exist!", String.class),
* CONVERSATION_FOUND("messages", "&cThere is already a conversation with this name.", String.class),
* INVALID_SIZE("messages", "&cThe position you have specified cannot exceed the limit.", String.class),
* FETCHING_SKIN("messages", "&aFetching skin for name: &f%s&a. Please wait...", String.class),
* CANT_GET_SKIN("messages", "&cCould not fetch skin for name: %s.", String.class),
* GET_SKIN("messages", "&aSkin successfully fetched!", String.class),
* NOT_SUPPORTED_NPC_TYPE("messages", "&cThis NPC type doesn't exists or is not supported in your current server version.", String.class);
*/
public interface MessageConfig {
}

@ -1,12 +1,13 @@
package lol.pyr.znpcsplus.tasks; package lol.pyr.znpcsplus.tasks;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants; import lol.pyr.znpcsplus.config.Configs;
import lol.pyr.znpcsplus.npc.NPC; import lol.pyr.znpcsplus.npc.NPC;
import lol.pyr.znpcsplus.npc.NPCRegistry; import lol.pyr.znpcsplus.npc.NPCRegistry;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.NumberConversions;
public class NPCVisibilityTask extends BukkitRunnable { public class NPCVisibilityTask extends BukkitRunnable {
public NPCVisibilityTask(Plugin plugin) { public NPCVisibilityTask(Plugin plugin) {
@ -14,7 +15,7 @@ public class NPCVisibilityTask extends BukkitRunnable {
} }
public void run() { public void run() {
int distSq = ConfigurationConstants.VIEW_DISTANCE * ConfigurationConstants.VIEW_DISTANCE; double distSq = NumberConversions.square(Configs.config().viewDistance());
for (NPC npc : NPCRegistry.all()) for (Player player : Bukkit.getOnlinePlayers()) { for (NPC npc : NPCRegistry.all()) for (Player player : Bukkit.getOnlinePlayers()) {
boolean inRange = (player.getWorld() == npc.getWorld() && player.getLocation().distanceSquared(npc.getLocation().toBukkitLocation(npc.getWorld())) <= distSq); boolean inRange = (player.getWorld() == npc.getWorld() && player.getLocation().distanceSquared(npc.getLocation().toBukkitLocation(npc.getWorld())) <= distSq);
if (!inRange && npc.isShown(player)) npc.hide(player); if (!inRange && npc.isShown(player)) npc.hide(player);