make everything not static, it makes the api much easier to make
This commit is contained in:
parent
1aeae3f12a
commit
a08e973319
74 changed files with 796 additions and 507 deletions
|
@ -51,6 +51,7 @@ shadowJar {
|
||||||
relocate "space.arim.dazzleconf", "lol.pyr.znpcsplus.lib.dazzleconf"
|
relocate "space.arim.dazzleconf", "lol.pyr.znpcsplus.lib.dazzleconf"
|
||||||
|
|
||||||
relocate "lol.pyr.director", "lol.pyr.znpcsplus.lib.command"
|
relocate "lol.pyr.director", "lol.pyr.znpcsplus.lib.command"
|
||||||
|
relocate "lol.pyr.serviceinjector", "lol.pyr.znpcsplus.lib.serviceinjector"
|
||||||
minimize()
|
minimize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
package lol.pyr.znpcsplus;
|
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.api.ZApi;
|
|
||||||
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
|
||||||
|
|
||||||
public class ZNpcsApi implements ZApi {
|
|
||||||
@Override
|
|
||||||
public NpcRegistry getNpcRegistry() {
|
|
||||||
return NpcRegistryImpl.get();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,17 @@
|
||||||
package lol.pyr.znpcsplus;
|
package lol.pyr.znpcsplus;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
import com.github.retrooper.packetevents.PacketEvents;
|
||||||
|
import com.github.retrooper.packetevents.PacketEventsAPI;
|
||||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||||
|
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||||
import lol.pyr.director.adventure.command.CommandManager;
|
import lol.pyr.director.adventure.command.CommandManager;
|
||||||
import lol.pyr.director.adventure.command.MultiCommand;
|
import lol.pyr.director.adventure.command.MultiCommand;
|
||||||
import lol.pyr.director.adventure.parse.primitive.BooleanParser;
|
import lol.pyr.director.adventure.parse.primitive.BooleanParser;
|
||||||
import lol.pyr.director.adventure.parse.primitive.IntegerParser;
|
import lol.pyr.director.adventure.parse.primitive.IntegerParser;
|
||||||
|
import lol.pyr.znpcsplus.api.ZApi;
|
||||||
import lol.pyr.znpcsplus.api.ZApiProvider;
|
import lol.pyr.znpcsplus.api.ZApiProvider;
|
||||||
|
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
||||||
import lol.pyr.znpcsplus.commands.*;
|
import lol.pyr.znpcsplus.commands.*;
|
||||||
import lol.pyr.znpcsplus.commands.hologram.*;
|
import lol.pyr.znpcsplus.commands.hologram.*;
|
||||||
import lol.pyr.znpcsplus.commands.parsers.EntityPropertyParser;
|
import lol.pyr.znpcsplus.commands.parsers.EntityPropertyParser;
|
||||||
|
@ -16,72 +20,70 @@ import lol.pyr.znpcsplus.commands.parsers.NpcEntryParser;
|
||||||
import lol.pyr.znpcsplus.commands.parsers.NpcTypeParser;
|
import lol.pyr.znpcsplus.commands.parsers.NpcTypeParser;
|
||||||
import lol.pyr.znpcsplus.commands.storage.LoadAllCommand;
|
import lol.pyr.znpcsplus.commands.storage.LoadAllCommand;
|
||||||
import lol.pyr.znpcsplus.commands.storage.SaveAllCommand;
|
import lol.pyr.znpcsplus.commands.storage.SaveAllCommand;
|
||||||
import lol.pyr.znpcsplus.config.Configs;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
|
import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
|
||||||
|
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||||
|
import lol.pyr.znpcsplus.metadata.*;
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
||||||
|
import lol.pyr.znpcsplus.packets.*;
|
||||||
import lol.pyr.znpcsplus.scheduling.FoliaScheduler;
|
import lol.pyr.znpcsplus.scheduling.FoliaScheduler;
|
||||||
import lol.pyr.znpcsplus.scheduling.SpigotScheduler;
|
import lol.pyr.znpcsplus.scheduling.SpigotScheduler;
|
||||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
|
import lol.pyr.znpcsplus.skin.cache.SkinCache;
|
||||||
import lol.pyr.znpcsplus.skin.cache.SkinCacheCleanTask;
|
import lol.pyr.znpcsplus.skin.cache.SkinCacheCleanTask;
|
||||||
import lol.pyr.znpcsplus.tasks.NpcVisibilityTask;
|
import lol.pyr.znpcsplus.tasks.NpcVisibilityTask;
|
||||||
import lol.pyr.znpcsplus.updater.UpdateChecker;
|
import lol.pyr.znpcsplus.updater.UpdateChecker;
|
||||||
import lol.pyr.znpcsplus.updater.UpdateNotificationListener;
|
import lol.pyr.znpcsplus.updater.UpdateNotificationListener;
|
||||||
import lol.pyr.znpcsplus.user.User;
|
|
||||||
import lol.pyr.znpcsplus.user.UserListener;
|
import lol.pyr.znpcsplus.user.UserListener;
|
||||||
|
import lol.pyr.znpcsplus.user.UserManager;
|
||||||
import lol.pyr.znpcsplus.util.BungeeUtil;
|
import lol.pyr.znpcsplus.util.BungeeUtil;
|
||||||
import lol.pyr.znpcsplus.util.FoliaUtil;
|
import lol.pyr.znpcsplus.util.FoliaUtil;
|
||||||
|
import lol.pyr.znpcsplus.util.LazyLoader;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
import org.apache.commons.io.FileUtils;
|
|
||||||
import org.bstats.bukkit.Metrics;
|
import org.bstats.bukkit.Metrics;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.util.HashMap;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class ZNpcsPlus extends JavaPlugin {
|
public class ZNpcsPlus extends JavaPlugin implements ZApi {
|
||||||
private static final int PLUGIN_ID = 18244;
|
private static final int PLUGIN_ID = 18244;
|
||||||
public static boolean PLACEHOLDERS_SUPPORTED;
|
|
||||||
|
|
||||||
public static Logger LOGGER;
|
private TaskScheduler scheduler;
|
||||||
public static File PLUGIN_FOLDER;
|
private BukkitAudiences adventure;
|
||||||
public static File PATH_FOLDER;
|
private SkinCache skinCache;
|
||||||
|
|
||||||
public static TaskScheduler SCHEDULER;
|
private MetadataFactory metadataFactory;
|
||||||
public static BungeeUtil BUNGEE_UTIL;
|
|
||||||
public static BukkitAudiences ADVENTURE;
|
private NpcRegistryImpl npcRegistry;
|
||||||
public static LegacyComponentSerializer LEGACY_AMPERSAND_SERIALIZER = LegacyComponentSerializer.builder()
|
|
||||||
|
private UserManager userManager;
|
||||||
|
private final LegacyComponentSerializer textSerializer = LegacyComponentSerializer.builder()
|
||||||
.character('&')
|
.character('&')
|
||||||
.hexCharacter('#')
|
.hexCharacter('#')
|
||||||
.hexColors().build();
|
.hexColors().build();
|
||||||
|
private PacketEventsAPI<Plugin> packetEvents;
|
||||||
|
|
||||||
private boolean enabled = false;
|
private boolean enabled = false;
|
||||||
public static final String DEBUG_NPC_PREFIX = "debug_npc";
|
|
||||||
|
|
||||||
public static void debug(String str) {
|
|
||||||
if (!Configs.config().debugEnabled()) return;
|
|
||||||
LOGGER.info("[DEBUG] " + str);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
packetEvents = SpigotPacketEventsBuilder.build(this);
|
||||||
PacketEvents.getAPI().getSettings().checkForUpdates(false);
|
PacketEvents.setAPI(packetEvents);
|
||||||
PacketEvents.getAPI().load();
|
packetEvents.getSettings().checkForUpdates(false);
|
||||||
LOGGER = getLogger();
|
packetEvents.load();
|
||||||
PLUGIN_FOLDER = getDataFolder();
|
|
||||||
PATH_FOLDER = new File(PLUGIN_FOLDER, "paths");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void log(String str) {
|
private void log(String str) {
|
||||||
|
@ -95,71 +97,71 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
log(ChatColor.YELLOW + " /__ | \\| | |__ .__) " + ChatColor.GOLD + " | " + ChatColor.GRAY + "Maintained with " + ChatColor.RED + "\u2764 " + ChatColor.GRAY + " by Pyr#6969");
|
log(ChatColor.YELLOW + " /__ | \\| | |__ .__) " + ChatColor.GOLD + " | " + ChatColor.GRAY + "Maintained with " + ChatColor.RED + "\u2764 " + ChatColor.GRAY + " by Pyr#6969");
|
||||||
log("");
|
log("");
|
||||||
|
|
||||||
if (Bukkit.getPluginManager().isPluginEnabled("ServersNPC")) {
|
PluginManager pluginManager = Bukkit.getPluginManager();
|
||||||
|
|
||||||
|
if (pluginManager.isPluginEnabled("ServersNPC")) {
|
||||||
log(ChatColor.DARK_RED + " * Detected old version of ZNPCs! Disabling the plugin.");
|
log(ChatColor.DARK_RED + " * Detected old version of ZNPCs! Disabling the plugin.");
|
||||||
log("");
|
log("");
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
pluginManager.disablePlugin(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long before = System.currentTimeMillis();
|
long before = System.currentTimeMillis();
|
||||||
|
|
||||||
File oldFolder = new File(PLUGIN_FOLDER.getParent(), "ServersNPC");
|
|
||||||
if (!PLUGIN_FOLDER.exists() && oldFolder.exists()) {
|
|
||||||
log(ChatColor.WHITE + " * Converting old ZNPCs files...");
|
|
||||||
try {
|
|
||||||
FileUtils.moveDirectory(oldFolder, PLUGIN_FOLDER);
|
|
||||||
} catch (IOException e) {
|
|
||||||
log(ChatColor.RED + " * Failed to convert old ZNPCs files" + (e.getMessage() == null ? "" : " due to " + e.getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log(ChatColor.WHITE + " * Initializing Adventure...");
|
log(ChatColor.WHITE + " * Initializing Adventure...");
|
||||||
ADVENTURE = BukkitAudiences.create(this);
|
adventure = BukkitAudiences.create(this);
|
||||||
|
|
||||||
log(ChatColor.WHITE + " * Initializing PacketEvents...");
|
log(ChatColor.WHITE + " * Initializing PacketEvents...");
|
||||||
PacketEvents.getAPI().getEventManager().registerListener(new InteractionPacketListener(), PacketListenerPriority.MONITOR);
|
packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR);
|
||||||
PacketEvents.getAPI().init();
|
packetEvents.init();
|
||||||
|
|
||||||
PLACEHOLDERS_SUPPORTED = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI");
|
metadataFactory = setupMetadataFactory();
|
||||||
if (PLACEHOLDERS_SUPPORTED) log(ChatColor.WHITE + " * Enabling PlaceholderAPI support...");
|
PacketFactory packetFactory = setupPacketFactory();
|
||||||
|
|
||||||
PLUGIN_FOLDER.mkdirs();
|
getDataFolder().mkdirs();
|
||||||
PATH_FOLDER.mkdirs();
|
|
||||||
|
|
||||||
log(ChatColor.WHITE + " * Loading configurations...");
|
log(ChatColor.WHITE + " * Loading configurations...");
|
||||||
Configs.init(PLUGIN_FOLDER);
|
ConfigManager configManager = new ConfigManager(getDataFolder());
|
||||||
|
|
||||||
log(ChatColor.WHITE + " * Defining NPC types...");
|
log(ChatColor.WHITE + " * Defining NPC types...");
|
||||||
NpcTypeImpl.defineTypes();
|
NpcTypeImpl.defineTypes();
|
||||||
|
|
||||||
log(ChatColor.WHITE + " * Registering components...");
|
log(ChatColor.WHITE + " * Starting tasks & registering components...");
|
||||||
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||||||
new Metrics(this, PLUGIN_ID);
|
new Metrics(this, PLUGIN_ID);
|
||||||
SCHEDULER = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this);
|
scheduler = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this);
|
||||||
BUNGEE_UTIL = new BungeeUtil(this);
|
BungeeUtil bungeeUtil = new BungeeUtil(this);
|
||||||
Bukkit.getOnlinePlayers().forEach(User::get);
|
userManager = new UserManager();
|
||||||
|
Bukkit.getOnlinePlayers().forEach(userManager::get);
|
||||||
|
|
||||||
|
pluginManager.registerEvents(new UserListener(userManager), this);
|
||||||
|
scheduler.runDelayedTimerAsync(new NpcVisibilityTask(npcRegistry, configManager), 60L, 10L);
|
||||||
|
skinCache = new SkinCache(configManager);
|
||||||
|
scheduler.runDelayedTimerAsync(new SkinCacheCleanTask(skinCache), 1200, 1200);
|
||||||
|
|
||||||
registerCommands();
|
registerCommands();
|
||||||
|
|
||||||
log(ChatColor.WHITE + " * Starting tasks...");
|
if (configManager.getConfig().checkForUpdates()) {
|
||||||
new NpcVisibilityTask();
|
UpdateChecker updateChecker = new UpdateChecker(this.getDescription());
|
||||||
new SkinCacheCleanTask();
|
scheduler.runDelayedTimerAsync(updateChecker, 5L, 6000L);
|
||||||
new UserListener(this);
|
pluginManager.registerEvents(new UpdateNotificationListener(this, adventure, updateChecker), this);
|
||||||
if (Configs.config().checkForUpdates()) new UpdateNotificationListener(this, new UpdateChecker(this));
|
}
|
||||||
|
|
||||||
log(ChatColor.WHITE+ " * Loading NPCs...");
|
log(ChatColor.WHITE+ " * Loading NPCs...");
|
||||||
NpcRegistryImpl.get().reload();
|
ActionRegistry actionRegistry = new ActionRegistry(scheduler, adventure, bungeeUtil);
|
||||||
|
npcRegistry = new NpcRegistryImpl(configManager, this, packetFactory, actionRegistry);
|
||||||
|
npcRegistry.reload();
|
||||||
|
|
||||||
ZApiProvider.register(new ZNpcsApi());
|
ZApiProvider.register(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 (Configs.config().debugEnabled()) {
|
if (configManager.getConfig().debugEnabled()) {
|
||||||
World world = Bukkit.getWorld("world");
|
World world = Bukkit.getWorld("world");
|
||||||
if (world == null) world = Bukkit.getWorlds().get(0);
|
if (world == null) world = Bukkit.getWorlds().get(0);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (NpcTypeImpl type : NpcTypeImpl.values()) {
|
for (NpcTypeImpl type : NpcTypeImpl.values()) {
|
||||||
NpcEntryImpl entry = NpcRegistryImpl.get().create(ZNpcsPlus.DEBUG_NPC_PREFIX + i, world, type, new ZLocation(i * 3, 200, 0, 0, 0));
|
NpcEntryImpl entry = npcRegistry.create("debug_npc_" + i, world, type, new ZLocation(i * 3, 200, 0, 0, 0));
|
||||||
entry.setProcessed(true);
|
entry.setProcessed(true);
|
||||||
NpcImpl npc = entry.getNpc();
|
NpcImpl npc = entry.getNpc();
|
||||||
npc.getHologram().addLine(Component.text("Hello, World!"));
|
npc.getHologram().addLine(Component.text("Hello, World!"));
|
||||||
|
@ -168,22 +170,61 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PacketFactory setupPacketFactory() {
|
||||||
|
HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> versions = new HashMap<>();
|
||||||
|
versions.put(ServerVersion.V_1_8, LazyLoader.of(() -> new V1_8PacketFactory(scheduler, metadataFactory)));
|
||||||
|
versions.put(ServerVersion.V_1_9, LazyLoader.of(() -> new V1_9PacketFactory(scheduler, metadataFactory)));
|
||||||
|
versions.put(ServerVersion.V_1_10, LazyLoader.of(() -> new V1_10PacketFactory(scheduler, metadataFactory)));
|
||||||
|
versions.put(ServerVersion.V_1_14, LazyLoader.of(() -> new V1_14PacketFactory(scheduler, metadataFactory)));
|
||||||
|
versions.put(ServerVersion.V_1_19, LazyLoader.of(() -> new V1_19PacketFactory(scheduler, metadataFactory)));
|
||||||
|
|
||||||
|
ServerVersion version = packetEvents.getServerManager().getVersion();
|
||||||
|
if (versions.containsKey(version)) return versions.get(version).get();
|
||||||
|
for (ServerVersion v : ServerVersion.reversedValues()) {
|
||||||
|
if (v.isNewerThan(version)) continue;
|
||||||
|
if (!versions.containsKey(v)) continue;
|
||||||
|
return versions.get(v).get();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Unsupported version!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private MetadataFactory setupMetadataFactory() {
|
||||||
|
HashMap<ServerVersion, LazyLoader<? extends MetadataFactory>> versions = new HashMap<>();
|
||||||
|
versions.put(ServerVersion.V_1_8, LazyLoader.of(V1_8MetadataFactory::new));
|
||||||
|
versions.put(ServerVersion.V_1_9, LazyLoader.of(V1_9MetadataFactory::new));
|
||||||
|
versions.put(ServerVersion.V_1_10, LazyLoader.of(V1_10MetadataFactory::new));
|
||||||
|
versions.put(ServerVersion.V_1_13, LazyLoader.of(V1_13MetadataFactory::new));
|
||||||
|
versions.put(ServerVersion.V_1_14, LazyLoader.of(V1_14MetadataFactory::new));
|
||||||
|
versions.put(ServerVersion.V_1_16, LazyLoader.of(V1_16MetadataFactory::new));
|
||||||
|
versions.put(ServerVersion.V_1_17, LazyLoader.of(V1_17MetadataFactory::new));
|
||||||
|
|
||||||
|
ServerVersion version = packetEvents.getServerManager().getVersion();
|
||||||
|
if (versions.containsKey(version)) return versions.get(version).get();
|
||||||
|
for (ServerVersion v : ServerVersion.reversedValues()) {
|
||||||
|
if (v.isNewerThan(version)) continue;
|
||||||
|
if (!versions.containsKey(v)) continue;
|
||||||
|
return versions.get(v).get();
|
||||||
|
}
|
||||||
|
throw new RuntimeException("Unsupported version!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
NpcRegistryImpl.get().save();
|
npcRegistry.save();
|
||||||
ZApiProvider.unregister();
|
ZApiProvider.unregister();
|
||||||
Bukkit.getOnlinePlayers().forEach(User::remove);
|
Bukkit.getOnlinePlayers().forEach(userManager::remove);
|
||||||
ADVENTURE.close();
|
adventure.close();
|
||||||
ADVENTURE = null;
|
adventure = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerCommands() {
|
private void registerCommands() {
|
||||||
// TODO: Messages in here
|
// TODO: Messages in here
|
||||||
CommandManager manager = new CommandManager(this, ADVENTURE, context -> {});
|
CommandManager manager = new CommandManager(this, adventure, context -> {});
|
||||||
|
|
||||||
manager.registerParser(NpcTypeImpl.class, new NpcTypeParser(context -> {}));
|
manager.registerParser(NpcTypeImpl.class, new NpcTypeParser(context -> {}));
|
||||||
manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(context -> {}));
|
manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(npcRegistry, context -> {}));
|
||||||
manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(context -> {}));
|
manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(context -> {}));
|
||||||
manager.registerParser(Integer.class, new IntegerParser(context -> {}));
|
manager.registerParser(Integer.class, new IntegerParser(context -> {}));
|
||||||
manager.registerParser(Boolean.class, new BooleanParser(context -> {}));
|
manager.registerParser(Boolean.class, new BooleanParser(context -> {}));
|
||||||
|
@ -191,25 +232,30 @@ public class ZNpcsPlus extends JavaPlugin {
|
||||||
|
|
||||||
manager.registerCommand("npc", new MultiCommand()
|
manager.registerCommand("npc", new MultiCommand()
|
||||||
.addSubcommand("action", new ActionCommand())
|
.addSubcommand("action", new ActionCommand())
|
||||||
.addSubcommand("create", new CreateCommand())
|
.addSubcommand("create", new CreateCommand(npcRegistry))
|
||||||
.addSubcommand("skin", new SkinCommand())
|
.addSubcommand("skin", new SkinCommand(skinCache, npcRegistry))
|
||||||
.addSubcommand("delete", new DeleteCommand())
|
.addSubcommand("delete", new DeleteCommand(npcRegistry, adventure))
|
||||||
.addSubcommand("move", new MoveCommand())
|
.addSubcommand("move", new MoveCommand(npcRegistry))
|
||||||
.addSubcommand("properties", new PropertiesCommand())
|
.addSubcommand("properties", new PropertiesCommand(npcRegistry))
|
||||||
.addSubcommand("teleport", new TeleportCommand())
|
.addSubcommand("teleport", new TeleportCommand(npcRegistry))
|
||||||
.addSubcommand("list", new ListCommand())
|
.addSubcommand("list", new ListCommand(npcRegistry))
|
||||||
.addSubcommand("near", new NearCommand())
|
.addSubcommand("near", new NearCommand(npcRegistry))
|
||||||
.addSubcommand("type", new TypeCommand())
|
.addSubcommand("type", new TypeCommand(npcRegistry))
|
||||||
.addSubcommand("storage", new MultiCommand()
|
.addSubcommand("storage", new MultiCommand()
|
||||||
.addSubcommand("save", new SaveAllCommand())
|
.addSubcommand("save", new SaveAllCommand(npcRegistry))
|
||||||
.addSubcommand("load", new LoadAllCommand()))
|
.addSubcommand("reload", new LoadAllCommand(npcRegistry)))
|
||||||
.addSubcommand("holo", new MultiCommand()
|
.addSubcommand("holo", new MultiCommand()
|
||||||
.addSubcommand("add", new HoloAddCommand())
|
.addSubcommand("add", new HoloAddCommand(npcRegistry, textSerializer))
|
||||||
.addSubcommand("delete", new HoloDeleteCommand())
|
.addSubcommand("delete", new HoloDeleteCommand(npcRegistry))
|
||||||
.addSubcommand("info", new HoloInfoCommand())
|
.addSubcommand("info", new HoloInfoCommand(npcRegistry))
|
||||||
.addSubcommand("insert", new HoloInsertCommand())
|
.addSubcommand("insert", new HoloInsertCommand(npcRegistry, textSerializer))
|
||||||
.addSubcommand("set", new HoloSetCommand())
|
.addSubcommand("set", new HoloSetCommand(npcRegistry, textSerializer))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NpcRegistry getNpcRegistry() {
|
||||||
|
return npcRegistry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,16 +15,22 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CreateCommand implements CommandHandler {
|
public class CreateCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public CreateCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " create <id> <type>");
|
context.setUsage(context.getLabel() + " create <id> <type>");
|
||||||
Player player = context.ensureSenderIsPlayer();
|
Player player = context.ensureSenderIsPlayer();
|
||||||
|
|
||||||
String id = context.popString();
|
String id = context.popString();
|
||||||
if (NpcRegistryImpl.get().get(id) != null) context.halt(Component.text("NPC with that ID already exists.", NamedTextColor.RED));
|
if (npcRegistry.get(id) != null) context.halt(Component.text("NPC with that ID already exists.", NamedTextColor.RED));
|
||||||
NpcTypeImpl type = context.parse(NpcTypeImpl.class);
|
NpcTypeImpl type = context.parse(NpcTypeImpl.class);
|
||||||
|
|
||||||
NpcEntryImpl entry = NpcRegistryImpl.get().create(id, player.getWorld(), type, new ZLocation(player.getLocation()));
|
NpcEntryImpl entry = npcRegistry.create(id, player.getWorld(), type, new ZLocation(player.getLocation()));
|
||||||
entry.enableEverything();
|
entry.enableEverything();
|
||||||
|
|
||||||
context.send(Component.text("Created a " + type.getName() + " NPC with ID " + id + ".", NamedTextColor.GREEN));
|
context.send(Component.text("Created a " + type.getName() + " NPC with ID " + id + ".", NamedTextColor.GREEN));
|
||||||
|
@ -32,7 +38,7 @@ public class CreateCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestStream(NpcTypeImpl.values().stream().map(NpcTypeImpl::getName));
|
if (context.argSize() == 2) return context.suggestStream(NpcTypeImpl.values().stream().map(NpcTypeImpl::getName));
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,9 @@ package lol.pyr.znpcsplus.commands;
|
||||||
import lol.pyr.director.adventure.command.CommandContext;
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
|
@ -13,17 +13,25 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class DeleteCommand implements CommandHandler {
|
public class DeleteCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
private final BukkitAudiences adventure;
|
||||||
|
|
||||||
|
public DeleteCommand(NpcRegistryImpl npcRegistry, BukkitAudiences adventure) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
this.adventure = adventure;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " delete <id>");
|
context.setUsage(context.getLabel() + " delete <id>");
|
||||||
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
||||||
NpcRegistryImpl.get().delete(entry.getId());
|
npcRegistry.delete(entry.getId());
|
||||||
ZNpcsPlus.ADVENTURE.sender(context.getSender()).sendMessage(Component.text("Deleted NPC with ID: " + entry.getId(), NamedTextColor.GREEN));
|
adventure.sender(context.getSender()).sendMessage(Component.text("Deleted NPC with ID: " + entry.getId(), NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,17 @@ import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
|
||||||
public class ListCommand implements CommandHandler {
|
public class ListCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public ListCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
TextComponent.Builder component = Component.text("Npc's:\n").color(NamedTextColor.GOLD).toBuilder();
|
TextComponent.Builder component = Component.text("Npc's:\n").color(NamedTextColor.GOLD).toBuilder();
|
||||||
for (String id : NpcRegistryImpl.get().modifiableIds()) {
|
for (String id : npcRegistry.modifiableIds()) {
|
||||||
NpcImpl npc = NpcRegistryImpl.get().get(id).getNpc();
|
NpcImpl npc = npcRegistry.get(id).getNpc();
|
||||||
ZLocation location = npc.getLocation();
|
ZLocation location = npc.getLocation();
|
||||||
component.append(Component.text("ID: " + id, NamedTextColor.GREEN))
|
component.append(Component.text("ID: " + id, NamedTextColor.GREEN))
|
||||||
.append(Component.text(" | ", NamedTextColor.GRAY))
|
.append(Component.text(" | ", NamedTextColor.GRAY))
|
||||||
|
|
|
@ -15,6 +15,12 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class MoveCommand implements CommandHandler {
|
public class MoveCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public MoveCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " move <id>");
|
context.setUsage(context.getLabel() + " move <id>");
|
||||||
|
@ -26,7 +32,7 @@ public class MoveCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,13 +12,19 @@ import org.bukkit.entity.Player;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NearCommand implements CommandHandler {
|
public class NearCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public NearCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
Player player = context.ensureSenderIsPlayer();
|
Player player = context.ensureSenderIsPlayer();
|
||||||
int raw = context.parse(Integer.class);
|
int raw = context.parse(Integer.class);
|
||||||
double radius = Math.pow(raw, 2);
|
double radius = Math.pow(raw, 2);
|
||||||
|
|
||||||
String npcs = NpcRegistryImpl.get().allModifiable().stream()
|
String npcs = npcRegistry.allModifiable().stream()
|
||||||
.filter(entry -> entry.getNpc().getBukkitLocation().distanceSquared(player.getLocation()) < radius)
|
.filter(entry -> entry.getNpc().getBukkitLocation().distanceSquared(player.getLocation()) < radius)
|
||||||
.map(NpcEntryImpl::getId)
|
.map(NpcEntryImpl::getId)
|
||||||
.collect(Collectors.joining(", "));
|
.collect(Collectors.joining(", "));
|
||||||
|
|
|
@ -14,6 +14,12 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class PropertiesCommand implements CommandHandler {
|
public class PropertiesCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public PropertiesCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
||||||
|
@ -29,7 +35,7 @@ public class PropertiesCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestStream(context.suggestionParse(0, NpcEntryImpl.class)
|
if (context.argSize() == 2) return context.suggestStream(context.suggestionParse(0, NpcEntryImpl.class)
|
||||||
.getNpc().getType().getAllowedProperties().stream().map(EntityPropertyImpl::getName));
|
.getNpc().getType().getAllowedProperties().stream().map(EntityPropertyImpl::getName));
|
||||||
if (context.argSize() == 3) {
|
if (context.argSize() == 3) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
||||||
|
import lol.pyr.znpcsplus.skin.cache.SkinCache;
|
||||||
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
|
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
|
||||||
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
|
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
|
||||||
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
||||||
|
@ -18,6 +19,14 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SkinCommand implements CommandHandler {
|
public class SkinCommand implements CommandHandler {
|
||||||
|
private final SkinCache skinCache;
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public SkinCommand(SkinCache skinCache, NpcRegistryImpl npcRegistry) {
|
||||||
|
this.skinCache = skinCache;
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " skin <id> <type> [value]");
|
context.setUsage(context.getLabel() + " skin <id> <type> [value]");
|
||||||
|
@ -26,7 +35,7 @@ public class SkinCommand implements CommandHandler {
|
||||||
String type = context.popString();
|
String type = context.popString();
|
||||||
|
|
||||||
if (type.equalsIgnoreCase("mirror")) {
|
if (type.equalsIgnoreCase("mirror")) {
|
||||||
npc.setProperty(EntityPropertyImpl.SKIN, new MirrorDescriptor());
|
npc.setProperty(EntityPropertyImpl.SKIN, new MirrorDescriptor(skinCache));
|
||||||
npc.respawn();
|
npc.respawn();
|
||||||
context.halt(Component.text("The NPC's skin will now mirror the player that it's being displayed to", NamedTextColor.GREEN));
|
context.halt(Component.text("The NPC's skin will now mirror the player that it's being displayed to", NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
@ -35,7 +44,7 @@ public class SkinCommand implements CommandHandler {
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
String name = context.dumpAllArgs();
|
String name = context.dumpAllArgs();
|
||||||
context.send(Component.text("Fetching skin \"" + name + "\"...", NamedTextColor.GREEN));
|
context.send(Component.text("Fetching skin \"" + name + "\"...", NamedTextColor.GREEN));
|
||||||
PrefetchedDescriptor.forPlayer(name).thenAccept(skin -> {
|
PrefetchedDescriptor.forPlayer(skinCache, name).thenAccept(skin -> {
|
||||||
if (skin == null) {
|
if (skin == null) {
|
||||||
context.send(Component.text("Failed to fetch skin, are you sure the player name is valid?", NamedTextColor.RED));
|
context.send(Component.text("Failed to fetch skin, are you sure the player name is valid?", NamedTextColor.RED));
|
||||||
return;
|
return;
|
||||||
|
@ -50,7 +59,7 @@ public class SkinCommand implements CommandHandler {
|
||||||
if (type.equalsIgnoreCase("dynamic")) {
|
if (type.equalsIgnoreCase("dynamic")) {
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
String name = context.dumpAllArgs();
|
String name = context.dumpAllArgs();
|
||||||
npc.setProperty(EntityPropertyImpl.SKIN, new FetchingDescriptor(name));
|
npc.setProperty(EntityPropertyImpl.SKIN, new FetchingDescriptor(skinCache, name));
|
||||||
npc.respawn();
|
npc.respawn();
|
||||||
context.halt(Component.text("The NPC's skin will now be resolved per-player from \"" + name + "\""));
|
context.halt(Component.text("The NPC's skin will now be resolved per-player from \"" + name + "\""));
|
||||||
}
|
}
|
||||||
|
@ -59,7 +68,7 @@ public class SkinCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestLiteral("mirror", "static", "dynamic");
|
if (context.argSize() == 2) return context.suggestLiteral("mirror", "static", "dynamic");
|
||||||
if (context.matchSuggestion("*", "static")) return context.suggestPlayers();
|
if (context.matchSuggestion("*", "static")) return context.suggestPlayers();
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
|
@ -15,6 +15,12 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TeleportCommand implements CommandHandler {
|
public class TeleportCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public TeleportCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " teleport <id>");
|
context.setUsage(context.getLabel() + " teleport <id>");
|
||||||
|
@ -26,7 +32,7 @@ public class TeleportCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,12 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TypeCommand implements CommandHandler {
|
public class TypeCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl registry;
|
||||||
|
|
||||||
|
public TypeCommand(NpcRegistryImpl registry) {
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " type <id> <type>");
|
context.setUsage(context.getLabel() + " type <id> <type>");
|
||||||
|
@ -25,7 +31,7 @@ public class TypeCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(registry.modifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestStream(NpcTypeImpl.values().stream().map(NpcTypeImpl::getName));
|
if (context.argSize() == 2) return context.suggestStream(NpcTypeImpl.values().stream().map(NpcTypeImpl::getName));
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,29 +3,37 @@ package lol.pyr.znpcsplus.commands.hologram;
|
||||||
import lol.pyr.director.adventure.command.CommandContext;
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HoloAddCommand implements CommandHandler {
|
public class HoloAddCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl registry;
|
||||||
|
private final LegacyComponentSerializer textSerializer;
|
||||||
|
|
||||||
|
public HoloAddCommand(NpcRegistryImpl registry, LegacyComponentSerializer textSerializer) {
|
||||||
|
this.registry = registry;
|
||||||
|
this.textSerializer = textSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " holo add <id> <text>");
|
context.setUsage(context.getLabel() + " holo add <id> <text>");
|
||||||
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
hologram.addLine(ZNpcsPlus.LEGACY_AMPERSAND_SERIALIZER.deserialize(context.dumpAllArgs()));
|
hologram.addLine(textSerializer.deserialize(context.dumpAllArgs()));
|
||||||
context.send(Component.text("NPC line added!", NamedTextColor.GREEN));
|
context.send(Component.text("NPC line added!", NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(registry.modifiableIds());
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,12 @@ import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class HoloDeleteCommand implements CommandHandler {
|
public class HoloDeleteCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public HoloDeleteCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " holo delete <id> <line>");
|
context.setUsage(context.getLabel() + " holo delete <id> <line>");
|
||||||
|
@ -26,7 +32,7 @@ public class HoloDeleteCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
||||||
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
|
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
|
||||||
.map(String::valueOf));
|
.map(String::valueOf));
|
||||||
|
|
|
@ -14,6 +14,12 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HoloInfoCommand implements CommandHandler {
|
public class HoloInfoCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public HoloInfoCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " holo info <id>");
|
context.setUsage(context.getLabel() + " holo info <id>");
|
||||||
|
@ -26,7 +32,7 @@ public class HoloInfoCommand implements CommandHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,26 @@ package lol.pyr.znpcsplus.commands.hologram;
|
||||||
import lol.pyr.director.adventure.command.CommandContext;
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class HoloInsertCommand implements CommandHandler {
|
public class HoloInsertCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
private final LegacyComponentSerializer componentSerializer;
|
||||||
|
|
||||||
|
public HoloInsertCommand(NpcRegistryImpl npcRegistry, LegacyComponentSerializer componentSerializer) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
this.componentSerializer = componentSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " holo insert <id> <line> <text>");
|
context.setUsage(context.getLabel() + " holo insert <id> <line> <text>");
|
||||||
|
@ -22,13 +30,13 @@ public class HoloInsertCommand implements CommandHandler {
|
||||||
int line = context.parse(Integer.class);
|
int line = context.parse(Integer.class);
|
||||||
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
hologram.insertLine(line, ZNpcsPlus.LEGACY_AMPERSAND_SERIALIZER.deserialize(context.dumpAllArgs()));
|
hologram.insertLine(line, componentSerializer.deserialize(context.dumpAllArgs()));
|
||||||
context.send(Component.text("NPC line inserted!", NamedTextColor.GREEN));
|
context.send(Component.text("NPC line inserted!", NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
||||||
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
|
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
|
||||||
.map(String::valueOf));
|
.map(String::valueOf));
|
||||||
|
|
|
@ -3,18 +3,26 @@ package lol.pyr.znpcsplus.commands.hologram;
|
||||||
import lol.pyr.director.adventure.command.CommandContext;
|
import lol.pyr.director.adventure.command.CommandContext;
|
||||||
import lol.pyr.director.adventure.command.CommandHandler;
|
import lol.pyr.director.adventure.command.CommandHandler;
|
||||||
import lol.pyr.director.common.command.CommandExecutionException;
|
import lol.pyr.director.common.command.CommandExecutionException;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class HoloSetCommand implements CommandHandler {
|
public class HoloSetCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
private final LegacyComponentSerializer componentSerializer;
|
||||||
|
|
||||||
|
public HoloSetCommand(NpcRegistryImpl npcRegistry, LegacyComponentSerializer componentSerializer) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
this.componentSerializer = componentSerializer;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
context.setUsage(context.getLabel() + " holo set <id> <line> <text>");
|
context.setUsage(context.getLabel() + " holo set <id> <line> <text>");
|
||||||
|
@ -23,18 +31,18 @@ public class HoloSetCommand implements CommandHandler {
|
||||||
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
||||||
context.ensureArgsNotEmpty();
|
context.ensureArgsNotEmpty();
|
||||||
hologram.removeLine(line);
|
hologram.removeLine(line);
|
||||||
hologram.insertLine(line, ZNpcsPlus.LEGACY_AMPERSAND_SERIALIZER.deserialize(context.dumpAllArgs()));
|
hologram.insertLine(line, componentSerializer.deserialize(context.dumpAllArgs()));
|
||||||
context.send(Component.text("NPC line set!", NamedTextColor.GREEN));
|
context.send(Component.text("NPC line set!", NamedTextColor.GREEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
public List<String> suggest(CommandContext context) throws CommandExecutionException {
|
||||||
if (context.argSize() == 1) return context.suggestCollection(NpcRegistryImpl.get().modifiableIds());
|
if (context.argSize() == 1) return context.suggestCollection(npcRegistry.modifiableIds());
|
||||||
if (context.argSize() >= 2) {
|
if (context.argSize() >= 2) {
|
||||||
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
|
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
|
||||||
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
||||||
.limit(hologram.getLines().size()).map(String::valueOf));
|
.limit(hologram.getLines().size()).map(String::valueOf));
|
||||||
if (context.argSize() == 3) return context.suggestLiteral(ZNpcsPlus.LEGACY_AMPERSAND_SERIALIZER.serialize(
|
if (context.argSize() == 3) return context.suggestLiteral(componentSerializer.serialize(
|
||||||
hologram.getLine(context.suggestionParse(1, Integer.class))));
|
hologram.getLine(context.suggestionParse(1, Integer.class))));
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
|
|
@ -10,13 +10,16 @@ import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
|
|
||||||
public class NpcEntryParser extends ParserType<NpcEntryImpl> {
|
public class NpcEntryParser extends ParserType<NpcEntryImpl> {
|
||||||
public NpcEntryParser(Message<CommandContext> message) {
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public NpcEntryParser(NpcRegistryImpl npcRegistry, Message<CommandContext> message) {
|
||||||
super(message);
|
super(message);
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NpcEntryImpl parse(Deque<String> deque) throws CommandExecutionException {
|
public NpcEntryImpl parse(Deque<String> deque) throws CommandExecutionException {
|
||||||
NpcEntryImpl entry = NpcRegistryImpl.get().get(deque.pop());
|
NpcEntryImpl entry = npcRegistry.get(deque.pop());
|
||||||
if (entry == null || !entry.isAllowCommandModification()) throw new CommandExecutionException();
|
if (entry == null || !entry.isAllowCommandModification()) throw new CommandExecutionException();
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,16 @@ import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class LoadAllCommand implements CommandHandler {
|
public class LoadAllCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public LoadAllCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
NpcRegistryImpl.get().reload();
|
npcRegistry.reload();
|
||||||
context.send(Component.text("All NPCs have been re-loaded from storage", NamedTextColor.GREEN));
|
context.send(Component.text("All NPCs have been re-loaded from storage", NamedTextColor.GREEN));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,16 @@ import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class SaveAllCommand implements CommandHandler {
|
public class SaveAllCommand implements CommandHandler {
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public SaveAllCommand(NpcRegistryImpl npcRegistry) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(CommandContext context) throws CommandExecutionException {
|
public void run(CommandContext context) throws CommandExecutionException {
|
||||||
CompletableFuture.runAsync(() -> {
|
CompletableFuture.runAsync(() -> {
|
||||||
NpcRegistryImpl.get().save();
|
npcRegistry.save();
|
||||||
context.send(Component.text("All NPCs have been saved to storage", NamedTextColor.GREEN));
|
context.send(Component.text("All NPCs have been saved to storage", NamedTextColor.GREEN));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package lol.pyr.znpcsplus.config;
|
package lol.pyr.znpcsplus.config;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import space.arim.dazzleconf.ConfigurationFactory;
|
import space.arim.dazzleconf.ConfigurationFactory;
|
||||||
import space.arim.dazzleconf.ConfigurationOptions;
|
import space.arim.dazzleconf.ConfigurationOptions;
|
||||||
import space.arim.dazzleconf.error.ConfigFormatSyntaxException;
|
import space.arim.dazzleconf.error.ConfigFormatSyntaxException;
|
||||||
|
@ -13,13 +12,22 @@ import space.arim.dazzleconf.serialiser.ValueSerialiser;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class Configs {
|
public class ConfigManager {
|
||||||
private volatile static MainConfig config;
|
private final static Logger logger = Logger.getLogger("ZNPCsPlus Configuration Manager");
|
||||||
private static ConfigurationHelper<MainConfig> configHelper;
|
|
||||||
|
|
||||||
private volatile static MessageConfig messages;
|
private volatile MainConfig config;
|
||||||
private static ConfigurationHelper<MessageConfig> messagesHelper;
|
private final ConfigurationHelper<MainConfig> configHelper;
|
||||||
|
|
||||||
|
private volatile MessageConfig messages;
|
||||||
|
private final ConfigurationHelper<MessageConfig> messagesHelper;
|
||||||
|
|
||||||
|
public ConfigManager(File pluginFolder) {
|
||||||
|
configHelper = createHelper(MainConfig.class, new File(pluginFolder, "config.yaml"));
|
||||||
|
messagesHelper = createHelper(MessageConfig.class, new File(pluginFolder, "messages.yaml"), new ComponentSerializer());
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
private static <T> ConfigurationHelper<T> createHelper(Class<T> configClass, File file, ValueSerialiser<?>... serialisers) {
|
private static <T> ConfigurationHelper<T> createHelper(Class<T> configClass, File file, ValueSerialiser<?>... serialisers) {
|
||||||
SnakeYamlOptions yamlOptions = new SnakeYamlOptions.Builder().commentMode(CommentMode.fullComments()).build();
|
SnakeYamlOptions yamlOptions = new SnakeYamlOptions.Builder().commentMode(CommentMode.fullComments()).build();
|
||||||
|
@ -29,33 +37,27 @@ public class Configs {
|
||||||
return new ConfigurationHelper<>(file.getParentFile().toPath(), file.getName(), configFactory);
|
return new ConfigurationHelper<>(file.getParentFile().toPath(), file.getName(), configFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init(File pluginFolder) {
|
public void reload() {
|
||||||
configHelper = createHelper(MainConfig.class, new File(pluginFolder, "config.yaml"));
|
|
||||||
messagesHelper = createHelper(MessageConfig.class, new File(pluginFolder, "messages.yaml"), new ComponentSerializer());
|
|
||||||
load();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void load() {
|
|
||||||
try {
|
try {
|
||||||
config = configHelper.reloadConfigData();
|
config = configHelper.reloadConfigData();
|
||||||
messages = messagesHelper.reloadConfigData();
|
messages = messagesHelper.reloadConfigData();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
ZNpcsPlus.LOGGER.severe("Couldn't open config file!");
|
logger.severe("Couldn't open config file!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (ConfigFormatSyntaxException e) {
|
} catch (ConfigFormatSyntaxException e) {
|
||||||
ZNpcsPlus.LOGGER.severe("Invalid config syntax!");
|
logger.severe("Invalid config syntax!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (InvalidConfigException e) {
|
} catch (InvalidConfigException e) {
|
||||||
ZNpcsPlus.LOGGER.severe("Invalid config value!");
|
logger.severe("Invalid config value!");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MainConfig config() {
|
public MainConfig getConfig() {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MessageConfig messages() {
|
public MessageConfig getMessages() {
|
||||||
return messages;
|
return messages;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -89,7 +89,7 @@ public class EntityPropertyImpl<T> implements EntityProperty<T> {
|
||||||
private final static PropertyDeserializer<Component> COMPONENT_DESERIALIZER = str -> MiniMessage.miniMessage().deserialize(str);
|
private final static PropertyDeserializer<Component> COMPONENT_DESERIALIZER = str -> MiniMessage.miniMessage().deserialize(str);
|
||||||
|
|
||||||
private final static PropertySerializer<SkinDescriptor> DESCRIPTOR_SERIALIZER = descriptor -> ((BaseSkinDescriptor) descriptor).serialize();
|
private final static PropertySerializer<SkinDescriptor> DESCRIPTOR_SERIALIZER = descriptor -> ((BaseSkinDescriptor) descriptor).serialize();
|
||||||
private final static PropertyDeserializer<SkinDescriptor> DESCRIPTOR_DESERIALIZER = BaseSkinDescriptor::deserialize;
|
private final static PropertyDeserializer<SkinDescriptor> DESCRIPTOR_DESERIALIZER = property -> null; // TODO: An actual property registry // BaseSkinDescriptor::deserialize;
|
||||||
|
|
||||||
public static EntityPropertyImpl<NamedTextColor> GLOW = new EntityPropertyImpl<>("glow", NamedTextColor.class, COLOR_SERIALIZER, COLOR_DESERIALIZER);
|
public static EntityPropertyImpl<NamedTextColor> GLOW = new EntityPropertyImpl<>("glow", NamedTextColor.class, COLOR_SERIALIZER, COLOR_DESERIALIZER);
|
||||||
public static EntityPropertyImpl<Boolean> SKIN_LAYERS = new EntityPropertyImpl<>("skin_layers", true, BOOLEAN_SERIALIZER, BOOLEAN_DESERIALIZER);
|
public static EntityPropertyImpl<Boolean> SKIN_LAYERS = new EntityPropertyImpl<>("skin_layers", true, BOOLEAN_SERIALIZER, BOOLEAN_DESERIALIZER);
|
||||||
|
|
|
@ -13,6 +13,8 @@ import java.util.Collection;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class PacketEntity {
|
public class PacketEntity {
|
||||||
|
private final PacketFactory packetFactory;
|
||||||
|
|
||||||
private final PropertyHolder properties;
|
private final PropertyHolder properties;
|
||||||
private final int entityId;
|
private final int entityId;
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
|
@ -20,7 +22,8 @@ public class PacketEntity {
|
||||||
private final EntityType type;
|
private final EntityType type;
|
||||||
private ZLocation location;
|
private ZLocation location;
|
||||||
|
|
||||||
public PacketEntity(PropertyHolder properties, EntityType type, ZLocation location) {
|
public PacketEntity(PacketFactory packetFactory, PropertyHolder properties, EntityType type, ZLocation location) {
|
||||||
|
this.packetFactory = packetFactory;
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
this.entityId = reserveEntityID();
|
this.entityId = reserveEntityID();
|
||||||
this.uuid = UUID.randomUUID();
|
this.uuid = UUID.randomUUID();
|
||||||
|
@ -46,25 +49,25 @@ public class PacketEntity {
|
||||||
|
|
||||||
public void setLocation(ZLocation location, Collection<Player> viewers) {
|
public void setLocation(ZLocation location, Collection<Player> viewers) {
|
||||||
this.location = location;
|
this.location = location;
|
||||||
for (Player viewer : viewers) PacketFactory.get().teleportEntity(viewer, this);
|
for (Player viewer : viewers) packetFactory.teleportEntity(viewer, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void spawn(Player player) {
|
public void spawn(Player player) {
|
||||||
if (type == EntityTypes.PLAYER) PacketFactory.get().spawnPlayer(player, this, properties);
|
if (type == EntityTypes.PLAYER) packetFactory.spawnPlayer(player, this, properties);
|
||||||
else PacketFactory.get().spawnEntity(player, this, properties);
|
else packetFactory.spawnEntity(player, this, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void despawn(Player player) {
|
public void despawn(Player player) {
|
||||||
PacketFactory.get().destroyEntity(player, this, properties);
|
packetFactory.destroyEntity(player, this, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshMeta(Player player) {
|
public void refreshMeta(Player player) {
|
||||||
PacketFactory.get().sendAllMetadata(player, this, properties);
|
packetFactory.sendAllMetadata(player, this, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remakeTeam(Player player) {
|
public void remakeTeam(Player player) {
|
||||||
PacketFactory.get().removeTeam(player, this);
|
packetFactory.removeTeam(player, this);
|
||||||
PacketFactory.get().createTeam(player, this, properties);
|
packetFactory.createTeam(player, this, properties);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int reserveEntityID() {
|
private static int reserveEntityID() {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package lol.pyr.znpcsplus.hologram;
|
package lol.pyr.znpcsplus.hologram;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.api.hologram.Hologram;
|
import lol.pyr.znpcsplus.api.hologram.Hologram;
|
||||||
import lol.pyr.znpcsplus.config.Configs;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.util.Viewable;
|
import lol.pyr.znpcsplus.util.Viewable;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
@ -12,15 +13,20 @@ import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class HologramImpl extends Viewable implements Hologram {
|
public class HologramImpl extends Viewable implements Hologram {
|
||||||
|
private final ConfigManager configManager;
|
||||||
|
private final PacketFactory packetFactory;
|
||||||
|
|
||||||
private ZLocation location;
|
private ZLocation location;
|
||||||
private final List<HologramLine> lines = new ArrayList<>();
|
private final List<HologramLine> lines = new ArrayList<>();
|
||||||
|
|
||||||
public HologramImpl(ZLocation location) {
|
public HologramImpl(ConfigManager configManager, PacketFactory packetFactory, ZLocation location) {
|
||||||
|
this.configManager = configManager;
|
||||||
|
this.packetFactory = packetFactory;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLine(Component line) {
|
public void addLine(Component line) {
|
||||||
HologramLine newLine = new HologramLine(null, line);
|
HologramLine newLine = new HologramLine(packetFactory, null, line);
|
||||||
lines.add(newLine);
|
lines.add(newLine);
|
||||||
relocateLines();
|
relocateLines();
|
||||||
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
||||||
|
@ -46,7 +52,7 @@ public class HologramImpl extends Viewable implements Hologram {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insertLine(int index, Component line) {
|
public void insertLine(int index, Component line) {
|
||||||
HologramLine newLine = new HologramLine(null, line);
|
HologramLine newLine = new HologramLine(packetFactory, null, line);
|
||||||
lines.add(index, newLine);
|
lines.add(index, newLine);
|
||||||
relocateLines();
|
relocateLines();
|
||||||
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
||||||
|
@ -72,7 +78,7 @@ public class HologramImpl extends Viewable implements Hologram {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void relocateLines(HologramLine newLine) {
|
private void relocateLines(HologramLine newLine) {
|
||||||
final double lineSpacing = Configs.config().lineSpacing();
|
final double lineSpacing = configManager.getConfig().lineSpacing();
|
||||||
double height = location.getY() + (lines.size() - 1) * lineSpacing;
|
double height = location.getY() + (lines.size() - 1) * lineSpacing;
|
||||||
for (HologramLine line : lines) {
|
for (HologramLine line : lines) {
|
||||||
line.setLocation(location.withY(height), line == newLine ? Collections.emptySet() : getViewers());
|
line.setLocation(location.withY(height), line == newLine ? Collections.emptySet() : getViewers());
|
||||||
|
|
|
@ -5,6 +5,7 @@ import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
@ -15,9 +16,9 @@ public class HologramLine implements PropertyHolder {
|
||||||
private Component text;
|
private Component text;
|
||||||
private final PacketEntity armorStand;
|
private final PacketEntity armorStand;
|
||||||
|
|
||||||
public HologramLine(ZLocation location, Component text) {
|
public HologramLine(PacketFactory packetFactory, ZLocation location, Component text) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
armorStand = new PacketEntity(this, EntityTypes.ARMOR_STAND, location);
|
armorStand = new PacketEntity(packetFactory, this, EntityTypes.ARMOR_STAND, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component getText() {
|
public Component getText() {
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package lol.pyr.znpcsplus.interaction;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.interaction.types.*;
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
|
import lol.pyr.znpcsplus.util.BungeeUtil;
|
||||||
|
import lol.pyr.znpcsplus.util.StringSerializer;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ActionRegistry {
|
||||||
|
private final Map<Class<?>, StringSerializer<?>> serializerMap = new HashMap<>();
|
||||||
|
|
||||||
|
public ActionRegistry(TaskScheduler taskScheduler, BukkitAudiences adventure, BungeeUtil bungeeUtil) {
|
||||||
|
register(ConsoleCommandAction.class, new ConsoleCommandActionSerializer(taskScheduler));
|
||||||
|
register(PlayerCommandAction.class, new PlayerCommandActionSerializer(taskScheduler));
|
||||||
|
register(SwitchServerAction.class, new SwitchServerActionSerializer(bungeeUtil));
|
||||||
|
register(MessageAction.class, new MessageActionSerializer(adventure));
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T extends InteractionAction> void register(Class<T> clazz, StringSerializer<T> serializer) {
|
||||||
|
serializerMap.put(clazz, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends InteractionAction> T deserialize(String str) {
|
||||||
|
try {
|
||||||
|
String[] split = str.split(";");
|
||||||
|
Class<?> clazz = Class.forName(split[0]);
|
||||||
|
StringSerializer<T> serializer = (StringSerializer<T>) serializerMap.get(clazz);
|
||||||
|
if (serializer == null) return null;
|
||||||
|
return serializer.deserialize(String.join(";", Arrays.copyOfRange(split, 1, split.length)));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T extends InteractionAction> String serialize(T action) {
|
||||||
|
StringSerializer<T> serializer = (StringSerializer<T>) serializerMap.get(action.getClass());
|
||||||
|
if (serializer == null) return null;
|
||||||
|
return action.getClass().getName() + ";" + serializer.serialize(action);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,15 +4,13 @@ import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public abstract class NpcAction {
|
public abstract class InteractionAction {
|
||||||
private final UUID id;
|
private final UUID id;
|
||||||
private final long delay;
|
private final long delay;
|
||||||
protected final String argument;
|
|
||||||
|
|
||||||
protected NpcAction(long delay, String argument) {
|
protected InteractionAction(long delay) {
|
||||||
this.id = UUID.randomUUID();
|
this.id = UUID.randomUUID();
|
||||||
this.delay = delay;
|
this.delay = delay;
|
||||||
this.argument = argument;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UUID getUuid() {
|
public UUID getUuid() {
|
||||||
|
@ -23,11 +21,5 @@ public abstract class NpcAction {
|
||||||
return delay;
|
return delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getArgument() {
|
|
||||||
return argument;
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void run(Player player);
|
public abstract void run(Player player);
|
||||||
|
|
||||||
public abstract NpcActionType getType();
|
|
||||||
}
|
}
|
|
@ -8,23 +8,32 @@ import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
import lol.pyr.znpcsplus.user.User;
|
import lol.pyr.znpcsplus.user.User;
|
||||||
|
import lol.pyr.znpcsplus.user.UserManager;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class InteractionPacketListener implements PacketListener {
|
public class InteractionPacketListener implements PacketListener {
|
||||||
|
private final UserManager userManager;
|
||||||
|
private final NpcRegistryImpl npcRegistry;
|
||||||
|
|
||||||
|
public InteractionPacketListener(UserManager userManager, NpcRegistryImpl npcRegistry) {
|
||||||
|
this.userManager = userManager;
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPacketReceive(PacketReceiveEvent event) {
|
public void onPacketReceive(PacketReceiveEvent event) {
|
||||||
if (event.getPacketType() != PacketType.Play.Client.INTERACT_ENTITY) return;
|
if (event.getPacketType() != PacketType.Play.Client.INTERACT_ENTITY) return;
|
||||||
Player player = (Player) event.getPlayer();
|
Player player = (Player) event.getPlayer();
|
||||||
|
|
||||||
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
||||||
User user = User.get(player);
|
User user = userManager.get(player);
|
||||||
if (!user.canInteract()) return;
|
if (!user.canInteract()) return;
|
||||||
|
|
||||||
NpcEntryImpl entry = NpcRegistryImpl.get().getByEntityId(packet.getEntityId());
|
NpcEntryImpl entry = npcRegistry.getByEntityId(packet.getEntityId());
|
||||||
if (entry == null || !entry.isProcessed()) return;
|
if (entry == null || !entry.isProcessed()) return;
|
||||||
NpcImpl npc = entry.getNpc();
|
NpcImpl npc = entry.getNpc();
|
||||||
|
|
||||||
for (NpcAction action : npc.getActions()) {
|
for (InteractionAction action : npc.getActions()) {
|
||||||
if (action.getCooldown() > 0 && !user.actionCooldownCheck(action)) continue;
|
if (action.getCooldown() > 0 && !user.actionCooldownCheck(action)) continue;
|
||||||
action.run(player);
|
action.run(player);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.interaction;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
interface NpcActionDeserializer {
|
|
||||||
NpcAction deserialize(long delay, String argument);
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.interaction;
|
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.interaction.types.*;
|
|
||||||
|
|
||||||
public enum NpcActionType implements NpcActionDeserializer {
|
|
||||||
CONSOLE_CMD(ConsoleCommandAction::new),
|
|
||||||
MESSAGE(MessageAction::new),
|
|
||||||
PLAYER_CMD(PlayerCommandAction::new),
|
|
||||||
SERVER(SwitchServerAction::new);
|
|
||||||
|
|
||||||
private final NpcActionDeserializer deserializer;
|
|
||||||
|
|
||||||
NpcActionType(NpcActionDeserializer deserializer) {
|
|
||||||
this.deserializer = deserializer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public NpcAction deserialize(long delay, String str) {
|
|
||||||
return deserializer.deserialize(delay, str);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,25 +1,28 @@
|
||||||
package lol.pyr.znpcsplus.interaction.types;
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
import lol.pyr.znpcsplus.util.PapiUtil;
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class ConsoleCommandAction extends NpcAction {
|
public class ConsoleCommandAction extends InteractionAction {
|
||||||
public ConsoleCommandAction(long delay, String argument) {
|
private final TaskScheduler scheduler;
|
||||||
super(delay, argument);
|
private final String command;
|
||||||
|
|
||||||
|
public ConsoleCommandAction(TaskScheduler scheduler, String command, long delay) {
|
||||||
|
super(delay);
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.command = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(Player player) {
|
public void run(Player player) {
|
||||||
String cmd = argument.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
String cmd = command.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
||||||
ZNpcsPlus.SCHEDULER.runSync(() -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), ZNpcsPlus.PLACEHOLDERS_SUPPORTED ? PlaceholderAPI.setPlaceholders(player, cmd) : cmd));
|
scheduler.runSync(() -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), PapiUtil.set(player, cmd)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String getCommand() {
|
||||||
public NpcActionType getType() {
|
return command;
|
||||||
return NpcActionType.CONSOLE_CMD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
|
import lol.pyr.znpcsplus.util.StringSerializer;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class ConsoleCommandActionSerializer implements StringSerializer<ConsoleCommandAction> {
|
||||||
|
private final TaskScheduler scheduler;
|
||||||
|
|
||||||
|
public ConsoleCommandActionSerializer(TaskScheduler scheduler) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serialize(ConsoleCommandAction obj) {
|
||||||
|
return Base64.getEncoder().encodeToString(obj.getCommand().getBytes(StandardCharsets.UTF_8)) + ";" + obj.getCooldown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ConsoleCommandAction deserialize(String str) {
|
||||||
|
String[] split = str.split(";");
|
||||||
|
return new ConsoleCommandAction(scheduler, new String(Base64.getDecoder().decode(split[0]), StandardCharsets.UTF_8), Long.parseLong(split[1]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,27 +1,26 @@
|
||||||
package lol.pyr.znpcsplus.interaction.types;
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class MessageAction extends NpcAction {
|
public class MessageAction extends InteractionAction {
|
||||||
|
private final BukkitAudiences adventure;
|
||||||
private final Component message;
|
private final Component message;
|
||||||
|
|
||||||
public MessageAction(long delay, String argument) {
|
public MessageAction(BukkitAudiences adventure, Component message, long delay) {
|
||||||
super(delay, argument);
|
super(delay);
|
||||||
message = MiniMessage.miniMessage().deserialize(argument);
|
this.adventure = adventure;
|
||||||
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(Player player) {
|
public void run(Player player) {
|
||||||
ZNpcsPlus.ADVENTURE.player(player).sendMessage(message);
|
adventure.player(player).sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public Component getMessage() {
|
||||||
public NpcActionType getType() {
|
return message;
|
||||||
return NpcActionType.MESSAGE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.util.StringSerializer;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class MessageActionSerializer implements StringSerializer<MessageAction> {
|
||||||
|
private final BukkitAudiences adventure;
|
||||||
|
|
||||||
|
public MessageActionSerializer(BukkitAudiences adventure) {
|
||||||
|
this.adventure = adventure;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serialize(MessageAction obj) {
|
||||||
|
return Base64.getEncoder().encodeToString(MiniMessage.miniMessage().serialize(obj.getMessage()).getBytes(StandardCharsets.UTF_8)) + ";" + obj.getCooldown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MessageAction deserialize(String str) {
|
||||||
|
String[] split = str.split(";");
|
||||||
|
return new MessageAction(adventure, MiniMessage.miniMessage().deserialize(new String(Base64.getDecoder().decode(split[0]), StandardCharsets.UTF_8)), Long.parseLong(split[1]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,28 @@
|
||||||
package lol.pyr.znpcsplus.interaction.types;
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
import lol.pyr.znpcsplus.util.PapiUtil;
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class PlayerCommandAction extends NpcAction {
|
public class PlayerCommandAction extends InteractionAction {
|
||||||
public PlayerCommandAction(long delay, String argument) {
|
private final TaskScheduler scheduler;
|
||||||
super(delay, argument);
|
private final String command;
|
||||||
|
|
||||||
|
public PlayerCommandAction(TaskScheduler scheduler, String command, long delay) {
|
||||||
|
super(delay);
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.command = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(Player player) {
|
public void run(Player player) {
|
||||||
String cmd = argument.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
String cmd = command.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
||||||
ZNpcsPlus.SCHEDULER.runSync(() -> Bukkit.dispatchCommand(player, ZNpcsPlus.PLACEHOLDERS_SUPPORTED ? PlaceholderAPI.setPlaceholders(player, cmd) : cmd));
|
scheduler.runSync(() -> Bukkit.dispatchCommand(player, PapiUtil.set(player, cmd)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String getCommand() {
|
||||||
public NpcActionType getType() {
|
return command;
|
||||||
return NpcActionType.PLAYER_CMD;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
|
import lol.pyr.znpcsplus.util.StringSerializer;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class PlayerCommandActionSerializer implements StringSerializer<PlayerCommandAction> {
|
||||||
|
private final TaskScheduler scheduler;
|
||||||
|
|
||||||
|
public PlayerCommandActionSerializer(TaskScheduler scheduler) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serialize(PlayerCommandAction obj) {
|
||||||
|
return Base64.getEncoder().encodeToString(obj.getCommand().getBytes(StandardCharsets.UTF_8)) + ";" + obj.getCooldown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PlayerCommandAction deserialize(String str) {
|
||||||
|
String[] split = str.split(";");
|
||||||
|
return new PlayerCommandAction(scheduler, new String(Base64.getDecoder().decode(split[0]), StandardCharsets.UTF_8), Long.parseLong(split[1]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,25 @@
|
||||||
package lol.pyr.znpcsplus.interaction.types;
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
import lol.pyr.znpcsplus.util.BungeeUtil;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
public class SwitchServerAction extends NpcAction {
|
public class SwitchServerAction extends InteractionAction {
|
||||||
public SwitchServerAction(long delay, String argument) {
|
private final BungeeUtil bungeeUtil;
|
||||||
super(delay, argument);
|
private final String server;
|
||||||
|
|
||||||
|
public SwitchServerAction(BungeeUtil bungeeUtil, String server, long delay) {
|
||||||
|
super(delay);
|
||||||
|
this.bungeeUtil = bungeeUtil;
|
||||||
|
this.server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(Player player) {
|
public void run(Player player) {
|
||||||
ZNpcsPlus.BUNGEE_UTIL.sendPlayerToServer(player, argument);
|
bungeeUtil.sendPlayerToServer(player, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public String getServer() {
|
||||||
public NpcActionType getType() {
|
return server;
|
||||||
return NpcActionType.SERVER;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package lol.pyr.znpcsplus.interaction.types;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.util.BungeeUtil;
|
||||||
|
import lol.pyr.znpcsplus.util.StringSerializer;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
public class SwitchServerActionSerializer implements StringSerializer<SwitchServerAction> {
|
||||||
|
private final BungeeUtil bungeeUtil;
|
||||||
|
|
||||||
|
public SwitchServerActionSerializer(BungeeUtil bungeeUtil) {
|
||||||
|
this.bungeeUtil = bungeeUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String serialize(SwitchServerAction obj) {
|
||||||
|
return Base64.getEncoder().encodeToString(obj.getServer().getBytes(StandardCharsets.UTF_8)) + ";" + obj.getCooldown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SwitchServerAction deserialize(String str) {
|
||||||
|
String[] split = str.split(";");
|
||||||
|
return new SwitchServerAction(bungeeUtil, new String(Base64.getDecoder().decode(split[0]), StandardCharsets.UTF_8), Long.parseLong(split[1]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,9 @@
|
||||||
package lol.pyr.znpcsplus.metadata;
|
package lol.pyr.znpcsplus.metadata;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
|
||||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.util.LazyLoader;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 1.8 https://wiki.vg/index.php?title=Entity_metadata&oldid=7415
|
* 1.8 https://wiki.vg/index.php?title=Entity_metadata&oldid=7415
|
||||||
|
@ -31,33 +25,4 @@ public interface MetadataFactory {
|
||||||
EntityData silent(boolean enabled);
|
EntityData silent(boolean enabled);
|
||||||
Collection<EntityData> name(Component name);
|
Collection<EntityData> name(Component name);
|
||||||
EntityData noGravity();
|
EntityData noGravity();
|
||||||
|
|
||||||
MetadataFactory factory = get();
|
|
||||||
|
|
||||||
static MetadataFactory get() {
|
|
||||||
if (factory != null) return factory;
|
|
||||||
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
|
||||||
Map<ServerVersion, LazyLoader<? extends MetadataFactory>> factories = buildFactoryMap();
|
|
||||||
if (factories.containsKey(version)) return factories.get(version).get();
|
|
||||||
for (ServerVersion v : ServerVersion.reversedValues()) {
|
|
||||||
if (v.isNewerThan(version)) continue;
|
|
||||||
if (!factories.containsKey(v)) continue;
|
|
||||||
MetadataFactory f = factories.get(v).get();
|
|
||||||
ZNpcsPlus.debug("Using MetadataFactory Version " + v.name() + " (" + f.getClass().getName() + ")");
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Unsupported version!");
|
|
||||||
}
|
|
||||||
|
|
||||||
static Map<ServerVersion, LazyLoader<? extends MetadataFactory>> buildFactoryMap() {
|
|
||||||
HashMap<ServerVersion, LazyLoader<? extends MetadataFactory>> map = new HashMap<>();
|
|
||||||
map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_10, LazyLoader.of(V1_10Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_13, LazyLoader.of(V1_13Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_14, LazyLoader.of(V1_14Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_16, LazyLoader.of(V1_16Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_17, LazyLoader.of(V1_17Factory::new));
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package lol.pyr.znpcsplus.metadata;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityDataTypes;
|
||||||
|
|
||||||
public class V1_10Factory extends V1_9Factory {
|
public class V1_10MetadataFactory extends V1_9MetadataFactory {
|
||||||
@Override
|
@Override
|
||||||
public EntityData noGravity() {
|
public EntityData noGravity() {
|
||||||
return new EntityData(5, EntityDataTypes.BOOLEAN, true);
|
return new EntityData(5, EntityDataTypes.BOOLEAN, true);
|
|
@ -9,7 +9,7 @@ import net.kyori.adventure.text.Component;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class V1_13Factory extends V1_10Factory {
|
public class V1_13MetadataFactory extends V1_10MetadataFactory {
|
||||||
@Override
|
@Override
|
||||||
public Collection<EntityData> name(Component name) {
|
public Collection<EntityData> name(Component name) {
|
||||||
return ListUtil.immutableList(
|
return ListUtil.immutableList(
|
|
@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.metadata;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
|
||||||
public class V1_14Factory extends V1_13Factory {
|
public class V1_14MetadataFactory extends V1_13MetadataFactory {
|
||||||
@Override
|
@Override
|
||||||
public EntityData skinLayers(boolean enabled) {
|
public EntityData skinLayers(boolean enabled) {
|
||||||
return createSkinLayers(15, enabled);
|
return createSkinLayers(15, enabled);
|
|
@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.metadata;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
|
||||||
public class V1_16Factory extends V1_14Factory {
|
public class V1_16MetadataFactory extends V1_14MetadataFactory {
|
||||||
@Override
|
@Override
|
||||||
public EntityData skinLayers(boolean enabled) {
|
public EntityData skinLayers(boolean enabled) {
|
||||||
return createSkinLayers(16, enabled);
|
return createSkinLayers(16, enabled);
|
|
@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.metadata;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
|
|
||||||
public class V1_17Factory extends V1_16Factory {
|
public class V1_17MetadataFactory extends V1_16MetadataFactory {
|
||||||
@Override
|
@Override
|
||||||
public EntityData skinLayers(boolean enabled) {
|
public EntityData skinLayers(boolean enabled) {
|
||||||
return createSkinLayers(17, enabled);
|
return createSkinLayers(17, enabled);
|
|
@ -8,7 +8,7 @@ import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public class V1_8Factory implements MetadataFactory {
|
public class V1_8MetadataFactory implements MetadataFactory {
|
||||||
@Override
|
@Override
|
||||||
public EntityData skinLayers(boolean enabled) {
|
public EntityData skinLayers(boolean enabled) {
|
||||||
return createSkinLayers(12, enabled);
|
return createSkinLayers(12, enabled);
|
|
@ -8,7 +8,7 @@ import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
public class V1_9Factory extends V1_8Factory {
|
public class V1_9MetadataFactory extends V1_8MetadataFactory {
|
||||||
@Override
|
@Override
|
||||||
public EntityData skinLayers(boolean enabled) {
|
public EntityData skinLayers(boolean enabled) {
|
||||||
return createSkinLayers(13, enabled);
|
return createSkinLayers(13, enabled);
|
|
@ -2,10 +2,12 @@ package lol.pyr.znpcsplus.npc;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
import lol.pyr.znpcsplus.api.entity.EntityProperty;
|
||||||
import lol.pyr.znpcsplus.api.npc.Npc;
|
import lol.pyr.znpcsplus.api.npc.Npc;
|
||||||
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.util.Viewable;
|
import lol.pyr.znpcsplus.util.Viewable;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -16,6 +18,7 @@ import org.bukkit.entity.Player;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class NpcImpl extends Viewable implements Npc {
|
public class NpcImpl extends Viewable implements Npc {
|
||||||
|
private final PacketFactory packetFactory;
|
||||||
private final String worldName;
|
private final String worldName;
|
||||||
private PacketEntity entity;
|
private PacketEntity entity;
|
||||||
private ZLocation location;
|
private ZLocation location;
|
||||||
|
@ -23,25 +26,26 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
private final HologramImpl hologram;
|
private final HologramImpl hologram;
|
||||||
|
|
||||||
private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>();
|
private final Map<EntityPropertyImpl<?>, Object> propertyMap = new HashMap<>();
|
||||||
private final Set<NpcAction> actions = new HashSet<>();
|
private final Set<InteractionAction> actions = new HashSet<>();
|
||||||
|
|
||||||
protected NpcImpl(World world, NpcTypeImpl type, ZLocation location) {
|
protected NpcImpl(ConfigManager configManager, World world, NpcTypeImpl type, ZLocation location, PacketFactory packetFactory) {
|
||||||
this(world.getName(), type, location);
|
this(configManager, packetFactory, world.getName(), type, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NpcImpl(String world, NpcTypeImpl type, ZLocation location) {
|
public NpcImpl(ConfigManager configManager, PacketFactory packetFactory, String world, NpcTypeImpl type, ZLocation location) {
|
||||||
|
this.packetFactory = packetFactory;
|
||||||
this.worldName = world;
|
this.worldName = world;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.location = location;
|
this.location = location;
|
||||||
entity = new PacketEntity(this, type.getType(), location);
|
entity = new PacketEntity(packetFactory, this, type.getType(), location);
|
||||||
hologram = new HologramImpl(location.withY(location.getY() + type.getHologramOffset()));
|
hologram = new HologramImpl(configManager, packetFactory, location.withY(location.getY() + type.getHologramOffset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setType(NpcTypeImpl type) {
|
public void setType(NpcTypeImpl type) {
|
||||||
UNSAFE_hideAll();
|
UNSAFE_hideAll();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
entity = new PacketEntity(this, type.getType(), entity.getLocation());
|
entity = new PacketEntity(packetFactory, this, type.getType(), entity.getLocation());
|
||||||
UNSAFE_showAll();
|
UNSAFE_showAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,11 +134,11 @@ public class NpcImpl extends Viewable implements Npc {
|
||||||
return Collections.unmodifiableSet(propertyMap.keySet());
|
return Collections.unmodifiableSet(propertyMap.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<NpcAction> getActions() {
|
public Collection<InteractionAction> getActions() {
|
||||||
return Collections.unmodifiableSet(actions);
|
return Collections.unmodifiableSet(actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAction(NpcAction action) {
|
public void addAction(InteractionAction action) {
|
||||||
actions.add(action);
|
actions.add(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package lol.pyr.znpcsplus.npc;
|
package lol.pyr.znpcsplus.npc;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||||
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
||||||
import lol.pyr.znpcsplus.api.npc.NpcType;
|
import lol.pyr.znpcsplus.api.npc.NpcType;
|
||||||
import lol.pyr.znpcsplus.config.Configs;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
|
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.storage.NpcStorage;
|
import lol.pyr.znpcsplus.storage.NpcStorage;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
|
@ -14,25 +17,23 @@ import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class NpcRegistryImpl implements NpcRegistry {
|
public class NpcRegistryImpl implements NpcRegistry {
|
||||||
private final static NpcRegistryImpl registry = new NpcRegistryImpl();
|
private final NpcStorage storage;
|
||||||
public static NpcRegistryImpl get() {
|
private final PacketFactory packetFactory;
|
||||||
return registry;
|
private final ConfigManager configManager;
|
||||||
}
|
|
||||||
|
|
||||||
private final NpcStorage STORAGE;
|
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry) {
|
||||||
|
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry);
|
||||||
private NpcRegistryImpl() {
|
this.packetFactory = packetFactory;
|
||||||
if (registry != null) throw new UnsupportedOperationException("This class can only be instanciated once!");
|
this.configManager = configManager;
|
||||||
STORAGE = Configs.config().storageType().create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reload() {
|
public void reload() {
|
||||||
npcMap.clear();
|
npcMap.clear();
|
||||||
for (NpcEntryImpl entry : STORAGE.loadNpcs()) npcMap.put(entry.getId(), entry);
|
for (NpcEntryImpl entry : storage.loadNpcs()) npcMap.put(entry.getId(), entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
STORAGE.saveNpcs(npcMap.values().stream().filter(NpcEntryImpl::isSave).collect(Collectors.toList()));
|
storage.saveNpcs(npcMap.values().stream().filter(NpcEntryImpl::isSave).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<String, NpcEntryImpl> npcMap = new HashMap<>();
|
private final Map<String, NpcEntryImpl> npcMap = new HashMap<>();
|
||||||
|
@ -73,7 +74,7 @@ public class NpcRegistryImpl implements NpcRegistry {
|
||||||
public NpcEntryImpl create(String id, World world, NpcTypeImpl type, ZLocation location) {
|
public NpcEntryImpl create(String id, World world, NpcTypeImpl type, ZLocation location) {
|
||||||
id = id.toLowerCase();
|
id = id.toLowerCase();
|
||||||
if (npcMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!");
|
if (npcMap.containsKey(id)) throw new IllegalArgumentException("An npc with the id " + id + " already exists!");
|
||||||
NpcImpl npc = new NpcImpl(world, type, location);
|
NpcImpl npc = new NpcImpl(configManager, world, type, location, packetFactory);
|
||||||
NpcEntryImpl entry = new NpcEntryImpl(id, npc);
|
NpcEntryImpl entry = new NpcEntryImpl(id, npc);
|
||||||
npcMap.put(id, entry);
|
npcMap.put(id, entry);
|
||||||
return entry;
|
return entry;
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
package lol.pyr.znpcsplus.packets;
|
package lol.pyr.znpcsplus.packets;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.PacketEvents;
|
|
||||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
|
||||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.util.LazyLoader;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public interface PacketFactory {
|
public interface PacketFactory {
|
||||||
|
@ -24,31 +21,4 @@ public interface PacketFactory {
|
||||||
Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
||||||
void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
||||||
void sendMetadata(Player player, PacketEntity entity, List<EntityData> data);
|
void sendMetadata(Player player, PacketEntity entity, List<EntityData> data);
|
||||||
|
|
||||||
PacketFactory factory = get();
|
|
||||||
|
|
||||||
static PacketFactory get() {
|
|
||||||
if (factory != null) return factory;
|
|
||||||
ServerVersion version = PacketEvents.getAPI().getServerManager().getVersion();
|
|
||||||
Map<ServerVersion, LazyLoader<? extends PacketFactory>> factories = buildFactoryMap();
|
|
||||||
if (factories.containsKey(version)) return factories.get(version).get();
|
|
||||||
for (ServerVersion v : ServerVersion.reversedValues()) {
|
|
||||||
if (v.isNewerThan(version)) continue;
|
|
||||||
if (!factories.containsKey(v)) continue;
|
|
||||||
PacketFactory f = factories.get(v).get();
|
|
||||||
ZNpcsPlus.debug("Using PacketFactory Version " + v.name() + " (" + f.getClass().getName() + ")");
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
throw new RuntimeException("Unsupported version!");
|
|
||||||
}
|
|
||||||
|
|
||||||
static Map<ServerVersion, LazyLoader<? extends PacketFactory>> buildFactoryMap() {
|
|
||||||
HashMap<ServerVersion, LazyLoader<? extends PacketFactory>> map = new HashMap<>();
|
|
||||||
map.put(ServerVersion.V_1_8, LazyLoader.of(V1_8Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_9, LazyLoader.of(V1_9Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_10, LazyLoader.of(V1_10Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_14, LazyLoader.of(V1_14Factory::new));
|
|
||||||
map.put(ServerVersion.V_1_19, LazyLoader.of(V1_19Factory::new));
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,20 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class V1_10Factory extends V1_9Factory {
|
public class V1_10PacketFactory extends V1_9PacketFactory {
|
||||||
|
public V1_10PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory) {
|
||||||
|
super(scheduler, metadataFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||||
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
||||||
add(data, MetadataFactory.get().noGravity());
|
add(data, metadataFactory.noGravity());
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,12 +4,18 @@ import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
|
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class V1_14Factory extends V1_10Factory {
|
public class V1_14PacketFactory extends V1_10PacketFactory {
|
||||||
|
public V1_14PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory) {
|
||||||
|
super(scheduler, metadataFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
|
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||||
ZLocation location = entity.getLocation();
|
ZLocation location = entity.getLocation();
|
|
@ -7,13 +7,19 @@ import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPl
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
|
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
|
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class V1_19Factory extends V1_14Factory {
|
public class V1_19PacketFactory extends V1_14PacketFactory {
|
||||||
|
public V1_19PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory) {
|
||||||
|
super(scheduler, metadataFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> addTabPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
|
public CompletableFuture<Void> addTabPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||||
if (entity.getType() != EntityTypes.PLAYER) return CompletableFuture.completedFuture(null);
|
if (entity.getType() != EntityTypes.PLAYER) return CompletableFuture.completedFuture(null);
|
|
@ -10,11 +10,11 @@ import com.github.retrooper.packetevents.protocol.player.UserProfile;
|
||||||
import com.github.retrooper.packetevents.util.Vector3d;
|
import com.github.retrooper.packetevents.util.Vector3d;
|
||||||
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
import com.github.retrooper.packetevents.wrapper.PacketWrapper;
|
||||||
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
@ -24,7 +24,15 @@ import org.bukkit.entity.Player;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class V1_8Factory implements PacketFactory {
|
public class V1_8PacketFactory implements PacketFactory {
|
||||||
|
protected final TaskScheduler scheduler;
|
||||||
|
protected final MetadataFactory metadataFactory;
|
||||||
|
|
||||||
|
public V1_8PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.metadataFactory = metadataFactory;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
|
public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||||
addTabPlayer(player, entity, properties).thenAccept(ignored -> {
|
addTabPlayer(player, entity, properties).thenAccept(ignored -> {
|
||||||
|
@ -34,7 +42,7 @@ public class V1_8Factory implements PacketFactory {
|
||||||
entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), Collections.emptyList()));
|
entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), Collections.emptyList()));
|
||||||
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
|
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
|
||||||
sendAllMetadata(player, entity, properties);
|
sendAllMetadata(player, entity, properties);
|
||||||
ZNpcsPlus.SCHEDULER.runLaterAsync(() -> removeTabPlayer(player, entity), 60);
|
scheduler.runLaterAsync(() -> removeTabPlayer(player, entity), 60);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,10 +114,10 @@ public class V1_8Factory implements PacketFactory {
|
||||||
@Override
|
@Override
|
||||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||||
HashMap<Integer, EntityData> data = new HashMap<>();
|
HashMap<Integer, EntityData> data = new HashMap<>();
|
||||||
if (entity.getType() == EntityTypes.PLAYER) add(data, MetadataFactory.get().skinLayers(properties.getProperty(EntityPropertyImpl.SKIN_LAYERS)));
|
if (entity.getType() == EntityTypes.PLAYER) add(data, metadataFactory.skinLayers(properties.getProperty(EntityPropertyImpl.SKIN_LAYERS)));
|
||||||
add(data, MetadataFactory.get().effects(properties.getProperty(EntityPropertyImpl.FIRE), false, properties.getProperty(EntityPropertyImpl.INVISIBLE)));
|
add(data, metadataFactory.effects(properties.getProperty(EntityPropertyImpl.FIRE), false, properties.getProperty(EntityPropertyImpl.INVISIBLE)));
|
||||||
add(data, MetadataFactory.get().silent(properties.getProperty(EntityPropertyImpl.SILENT)));
|
add(data, metadataFactory.silent(properties.getProperty(EntityPropertyImpl.SILENT)));
|
||||||
if (properties.hasProperty(EntityPropertyImpl.NAME)) addAll(data, MetadataFactory.get().name(properties.getProperty(EntityPropertyImpl.NAME)));
|
if (properties.hasProperty(EntityPropertyImpl.NAME)) addAll(data, metadataFactory.name(properties.getProperty(EntityPropertyImpl.NAME)));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,15 +5,20 @@ import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||||
|
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class V1_9Factory extends V1_8Factory {
|
public class V1_9PacketFactory extends V1_8PacketFactory {
|
||||||
|
public V1_9PacketFactory(TaskScheduler scheduler, MetadataFactory metadataFactory) {
|
||||||
|
super(scheduler, metadataFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||||
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
||||||
add(data, MetadataFactory.get().effects(properties.getProperty(EntityPropertyImpl.FIRE), properties.hasProperty(EntityPropertyImpl.GLOW), properties.getProperty(EntityPropertyImpl.INVISIBLE)));
|
add(data, metadataFactory.effects(properties.getProperty(EntityPropertyImpl.FIRE), properties.hasProperty(EntityPropertyImpl.GLOW), properties.getProperty(EntityPropertyImpl.INVISIBLE)));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
package lol.pyr.znpcsplus.reflection;
|
package lol.pyr.znpcsplus.reflection;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.util.VersionUtil;
|
import lol.pyr.znpcsplus.util.VersionUtil;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public abstract class ReflectionLazyLoader<T> {
|
public abstract class ReflectionLazyLoader<T> {
|
||||||
|
private final static Logger logger = Logger.getLogger("ZNPCsPlus Reflection");
|
||||||
protected final List<String> possibleClassNames;
|
protected final List<String> possibleClassNames;
|
||||||
protected List<Class<?>> reflectionClasses = new ArrayList<>();
|
protected List<Class<?>> reflectionClasses = new ArrayList<>();
|
||||||
protected final boolean strict;
|
protected final boolean strict;
|
||||||
|
@ -34,25 +35,21 @@ public abstract class ReflectionLazyLoader<T> {
|
||||||
if (eval == null) throw new RuntimeException("Returned value is null");
|
if (eval == null) throw new RuntimeException("Returned value is null");
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
if (strict) {
|
if (strict) {
|
||||||
warn(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON THE ZNPCSPLUS GITHUB ----- ");
|
logger.warning(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON THE ZNPCSPLUS GITHUB ----- ");
|
||||||
warn(getClass().getSimpleName() + " failed!");
|
logger.warning(getClass().getSimpleName() + " failed!");
|
||||||
warn("Class Names: " + possibleClassNames);
|
logger.warning("Class Names: " + possibleClassNames);
|
||||||
warn("Reflection Type: " + getClass().getCanonicalName());
|
logger.warning("Reflection Type: " + getClass().getCanonicalName());
|
||||||
warn("Bukkit Version: " + VersionUtil.BUKKIT_VERSION + " (" + VersionUtil.getBukkitPackage() + ")");
|
logger.warning("Bukkit Version: " + VersionUtil.BUKKIT_VERSION + " (" + VersionUtil.getBukkitPackage() + ")");
|
||||||
printDebugInfo(this::warn);
|
printDebugInfo(logger::warning);
|
||||||
warn("Exception:");
|
logger.warning("Exception:");
|
||||||
throwable.printStackTrace();
|
throwable.printStackTrace();
|
||||||
warn(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON THE ZNPCSPLUS GITHUB ----- ");
|
logger.warning(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON THE ZNPCSPLUS GITHUB ----- ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
return this.cached;
|
return this.cached;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void warn(String message) {
|
|
||||||
ZNpcsPlus.LOGGER.warning("[Reflection] " + message);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract T load() throws Exception;
|
protected abstract T load() throws Exception;
|
||||||
protected void printDebugInfo(Consumer<String> logger) {}
|
protected void printDebugInfo(Consumer<String> logger) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package lol.pyr.znpcsplus.skin;
|
||||||
|
|
||||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||||
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
||||||
|
import lol.pyr.znpcsplus.skin.cache.SkinCache;
|
||||||
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
|
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
|
||||||
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
|
import lol.pyr.znpcsplus.skin.descriptor.MirrorDescriptor;
|
||||||
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
||||||
|
@ -17,10 +18,10 @@ public interface BaseSkinDescriptor extends SkinDescriptor {
|
||||||
boolean supportsInstant(Player player);
|
boolean supportsInstant(Player player);
|
||||||
String serialize();
|
String serialize();
|
||||||
|
|
||||||
static BaseSkinDescriptor deserialize(String str) {
|
static BaseSkinDescriptor deserialize(SkinCache skinCache, String str) {
|
||||||
String[] arr = str.split(";");
|
String[] arr = str.split(";");
|
||||||
if (arr[0].equalsIgnoreCase("mirror")) return new MirrorDescriptor();
|
if (arr[0].equalsIgnoreCase("mirror")) return new MirrorDescriptor(skinCache);
|
||||||
else if (arr[0].equalsIgnoreCase("fetching")) return new FetchingDescriptor(arr[1]);
|
else if (arr[0].equalsIgnoreCase("fetching")) return new FetchingDescriptor(skinCache, arr[1]);
|
||||||
else if (arr[0].equalsIgnoreCase("prefetched")) {
|
else if (arr[0].equalsIgnoreCase("prefetched")) {
|
||||||
List<TextureProperty> properties = new ArrayList<>();
|
List<TextureProperty> properties = new ArrayList<>();
|
||||||
for (int i = 0; i < (arr.length - 1) / 3; i++) {
|
for (int i = 0; i < (arr.length - 1) / 3; i++) {
|
||||||
|
|
|
@ -3,8 +3,7 @@ package lol.pyr.znpcsplus.skin.cache;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.google.gson.JsonParser;
|
import com.google.gson.JsonParser;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.config.Configs;
|
|
||||||
import lol.pyr.znpcsplus.reflection.Reflections;
|
import lol.pyr.znpcsplus.reflection.Reflections;
|
||||||
import lol.pyr.znpcsplus.skin.Skin;
|
import lol.pyr.znpcsplus.skin.Skin;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -22,17 +21,26 @@ import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class SkinCache {
|
public class SkinCache {
|
||||||
private final static Map<String, Skin> cache = new ConcurrentHashMap<>();
|
private final static Logger logger = Logger.getLogger("ZNPCsPlus Skin Cache");
|
||||||
private final static Map<String, CachedId> idCache = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public static void cleanCache() {
|
private final ConfigManager configManager;
|
||||||
|
|
||||||
|
private final Map<String, Skin> cache = new ConcurrentHashMap<>();
|
||||||
|
private final Map<String, CachedId> idCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
public SkinCache(ConfigManager configManager) {
|
||||||
|
this.configManager = configManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cleanCache() {
|
||||||
for (Map.Entry<String, Skin> entry : cache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey());
|
for (Map.Entry<String, Skin> entry : cache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey());
|
||||||
for (Map.Entry<String, CachedId> entry : idCache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey());
|
for (Map.Entry<String, CachedId> entry : idCache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompletableFuture<Skin> fetchByName(String name) {
|
public CompletableFuture<Skin> fetchByName(String name) {
|
||||||
Player player = Bukkit.getPlayerExact(name);
|
Player player = Bukkit.getPlayerExact(name);
|
||||||
if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player));
|
if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player));
|
||||||
|
|
||||||
|
@ -52,8 +60,8 @@ public class SkinCache {
|
||||||
return fetchByUUID(id).join();
|
return fetchByUUID(id).join();
|
||||||
}
|
}
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
if (!Configs.config().disableSkinFetcherWarnings()) {
|
if (!configManager.getConfig().disableSkinFetcherWarnings()) {
|
||||||
ZNpcsPlus.LOGGER.warning("Failed to uuid from player name:");
|
logger.warning("Failed to uuid from player name:");
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -63,11 +71,11 @@ public class SkinCache {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompletableFuture<Skin> fetchByUUID(UUID uuid) {
|
public CompletableFuture<Skin> fetchByUUID(UUID uuid) {
|
||||||
return fetchByUUID(uuid.toString().replace("-", ""));
|
return fetchByUUID(uuid.toString().replace("-", ""));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isNameFullyCached(String s) {
|
public boolean isNameFullyCached(String s) {
|
||||||
String name = s.toLowerCase();
|
String name = s.toLowerCase();
|
||||||
if (!idCache.containsKey(name)) return false;
|
if (!idCache.containsKey(name)) return false;
|
||||||
CachedId id = idCache.get(name);
|
CachedId id = idCache.get(name);
|
||||||
|
@ -76,7 +84,7 @@ public class SkinCache {
|
||||||
return !skin.isExpired();
|
return !skin.isExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Skin getFullyCachedByName(String s) {
|
public Skin getFullyCachedByName(String s) {
|
||||||
String name = s.toLowerCase();
|
String name = s.toLowerCase();
|
||||||
if (!idCache.containsKey(name)) return null;
|
if (!idCache.containsKey(name)) return null;
|
||||||
CachedId id = idCache.get(name);
|
CachedId id = idCache.get(name);
|
||||||
|
@ -86,7 +94,7 @@ public class SkinCache {
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompletableFuture<Skin> fetchByUUID(String uuid) {
|
public CompletableFuture<Skin> fetchByUUID(String uuid) {
|
||||||
Player player = Bukkit.getPlayer(uuid);
|
Player player = Bukkit.getPlayer(uuid);
|
||||||
if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player));
|
if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player));
|
||||||
|
|
||||||
|
@ -108,8 +116,8 @@ public class SkinCache {
|
||||||
return skin;
|
return skin;
|
||||||
}
|
}
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
if (!Configs.config().disableSkinFetcherWarnings()) {
|
if (!configManager.getConfig().disableSkinFetcherWarnings()) {
|
||||||
ZNpcsPlus.LOGGER.warning("Failed to fetch skin:");
|
logger.warning("Failed to fetch skin:");
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -119,7 +127,7 @@ public class SkinCache {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Skin getFromPlayer(Player player) {
|
public Skin getFromPlayer(Player player) {
|
||||||
try {
|
try {
|
||||||
Object playerHandle = Reflections.GET_HANDLE_PLAYER_METHOD.get().invoke(player);
|
Object playerHandle = Reflections.GET_HANDLE_PLAYER_METHOD.get().invoke(player);
|
||||||
GameProfile gameProfile = (GameProfile) Reflections.GET_PROFILE_METHOD.get().invoke(playerHandle, new Object[0]);
|
GameProfile gameProfile = (GameProfile) Reflections.GET_PROFILE_METHOD.get().invoke(playerHandle, new Object[0]);
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
package lol.pyr.znpcsplus.skin.cache;
|
package lol.pyr.znpcsplus.skin.cache;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
public class SkinCacheCleanTask extends BukkitRunnable {
|
public class SkinCacheCleanTask extends BukkitRunnable {
|
||||||
public SkinCacheCleanTask() {
|
private final SkinCache skinCache;
|
||||||
ZNpcsPlus.SCHEDULER.runDelayedTimerAsync(this, 1200, 1200);
|
|
||||||
|
public SkinCacheCleanTask(SkinCache skinCache) {
|
||||||
|
this.skinCache = skinCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
SkinCache.cleanCache();
|
skinCache.cleanCache();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,36 @@
|
||||||
package lol.pyr.znpcsplus.skin.descriptor;
|
package lol.pyr.znpcsplus.skin.descriptor;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
||||||
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
||||||
import lol.pyr.znpcsplus.skin.Skin;
|
import lol.pyr.znpcsplus.skin.Skin;
|
||||||
import lol.pyr.znpcsplus.skin.cache.SkinCache;
|
import lol.pyr.znpcsplus.skin.cache.SkinCache;
|
||||||
import me.clip.placeholderapi.PlaceholderAPI;
|
import lol.pyr.znpcsplus.util.PapiUtil;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class FetchingDescriptor implements BaseSkinDescriptor, SkinDescriptor {
|
public class FetchingDescriptor implements BaseSkinDescriptor, SkinDescriptor {
|
||||||
|
private final SkinCache skinCache;
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
public FetchingDescriptor(String name) {
|
public FetchingDescriptor(SkinCache skinCache, String name) {
|
||||||
|
this.skinCache = skinCache;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Skin> fetch(Player player) {
|
public CompletableFuture<Skin> fetch(Player player) {
|
||||||
return SkinCache.fetchByName(papi(player));
|
return skinCache.fetchByName(PapiUtil.set(player, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Skin fetchInstant(Player player) {
|
public Skin fetchInstant(Player player) {
|
||||||
return SkinCache.getFullyCachedByName(papi(player));
|
return skinCache.getFullyCachedByName(PapiUtil.set(player, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsInstant(Player player) {
|
public boolean supportsInstant(Player player) {
|
||||||
return SkinCache.isNameFullyCached(papi(player));
|
return skinCache.isNameFullyCached(PapiUtil.set(player, name));
|
||||||
}
|
|
||||||
|
|
||||||
private String papi(Player player) {
|
|
||||||
if (ZNpcsPlus.PLACEHOLDERS_SUPPORTED) return PlaceholderAPI.setPlaceholders(player, name);
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|
|
@ -9,17 +9,20 @@ import org.bukkit.entity.Player;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class MirrorDescriptor implements BaseSkinDescriptor, SkinDescriptor {
|
public class MirrorDescriptor implements BaseSkinDescriptor, SkinDescriptor {
|
||||||
|
private final SkinCache skinCache;
|
||||||
|
|
||||||
public MirrorDescriptor() {}
|
public MirrorDescriptor(SkinCache skinCache) {
|
||||||
|
this.skinCache = skinCache;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Skin> fetch(Player player) {
|
public CompletableFuture<Skin> fetch(Player player) {
|
||||||
return CompletableFuture.completedFuture(SkinCache.getFromPlayer(player));
|
return CompletableFuture.completedFuture(skinCache.getFromPlayer(player));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Skin fetchInstant(Player player) {
|
public Skin fetchInstant(Player player) {
|
||||||
return SkinCache.getFromPlayer(player);
|
return skinCache.getFromPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -16,8 +16,8 @@ public class PrefetchedDescriptor implements BaseSkinDescriptor, SkinDescriptor
|
||||||
this.skin = skin;
|
this.skin = skin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompletableFuture<PrefetchedDescriptor> forPlayer(String name) {
|
public static CompletableFuture<PrefetchedDescriptor> forPlayer(SkinCache cache, String name) {
|
||||||
return CompletableFuture.supplyAsync(() -> new PrefetchedDescriptor(SkinCache.fetchByName(name).join()));
|
return CompletableFuture.supplyAsync(() -> new PrefetchedDescriptor(cache.fetchByName(name).join()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
package lol.pyr.znpcsplus.storage;
|
package lol.pyr.znpcsplus.storage;
|
||||||
|
|
||||||
|
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||||
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
|
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.storage.yaml.YamlStorage;
|
import lol.pyr.znpcsplus.storage.yaml.YamlStorage;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
public enum NpcStorageType {
|
public enum NpcStorageType {
|
||||||
YAML {
|
YAML {
|
||||||
@Override
|
@Override
|
||||||
public NpcStorage create() {
|
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry) {
|
||||||
return new YamlStorage();
|
return new YamlStorage(packetFactory, configManager, actionRegistry, new File(plugin.getDataFolder(), "data"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public abstract NpcStorage create();
|
public abstract NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.storage;
|
|
||||||
|
|
||||||
public class SerializationException extends RuntimeException {
|
|
||||||
public SerializationException(String message) {
|
|
||||||
super(message);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,13 +1,13 @@
|
||||||
package lol.pyr.znpcsplus.storage.yaml;
|
package lol.pyr.znpcsplus.storage.yaml;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||||
import lol.pyr.znpcsplus.hologram.HologramLine;
|
import lol.pyr.znpcsplus.hologram.HologramLine;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
||||||
|
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||||
import lol.pyr.znpcsplus.storage.NpcStorage;
|
import lol.pyr.znpcsplus.storage.NpcStorage;
|
||||||
import lol.pyr.znpcsplus.util.ZLocation;
|
import lol.pyr.znpcsplus.util.ZLocation;
|
||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
@ -16,28 +16,32 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class YamlStorage implements NpcStorage {
|
public class YamlStorage implements NpcStorage {
|
||||||
private final File npcsFolder;
|
private final PacketFactory packetFactory;
|
||||||
|
private final ConfigManager configManager;
|
||||||
|
private final ActionRegistry actionRegistry;
|
||||||
|
private final File folder;
|
||||||
|
|
||||||
public YamlStorage() {
|
public YamlStorage(PacketFactory packetFactory, ConfigManager configManager, ActionRegistry actionRegistry, File folder) {
|
||||||
npcsFolder = new File(ZNpcsPlus.PLUGIN_FOLDER, "npcs");
|
this.packetFactory = packetFactory;
|
||||||
if (!npcsFolder.exists()) npcsFolder.mkdirs();
|
this.configManager = configManager;
|
||||||
|
this.actionRegistry = actionRegistry;
|
||||||
|
this.folder = folder;
|
||||||
|
if (!this.folder.exists()) this.folder.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
@SuppressWarnings("ConstantConditions")
|
||||||
@Override
|
@Override
|
||||||
public Collection<NpcEntryImpl> loadNpcs() {
|
public Collection<NpcEntryImpl> loadNpcs() {
|
||||||
File[] files = npcsFolder.listFiles();
|
File[] files = folder.listFiles();
|
||||||
if (files == null || files.length == 0) return Collections.emptyList();
|
if (files == null || files.length == 0) return Collections.emptyList();
|
||||||
List<NpcEntryImpl> npcs = new ArrayList<>();
|
List<NpcEntryImpl> npcs = new ArrayList<>();
|
||||||
for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) {
|
for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) {
|
||||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
|
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
|
||||||
NpcImpl npc = new NpcImpl(config.getString("world"), NpcTypeImpl.byName(config.getString("type")),
|
NpcImpl npc = new NpcImpl(configManager, packetFactory, config.getString("world"), NpcTypeImpl.byName(config.getString("type")),
|
||||||
deserializeLocation(config.getConfigurationSection("location")));
|
deserializeLocation(config.getConfigurationSection("location")));
|
||||||
|
|
||||||
ConfigurationSection properties = config.getConfigurationSection("properties");
|
ConfigurationSection properties = config.getConfigurationSection("properties");
|
||||||
|
@ -48,16 +52,8 @@ public class YamlStorage implements NpcStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String line : config.getStringList("hologram")) {
|
for (String line : config.getStringList("hologram")) npc.getHologram().addLine(MiniMessage.miniMessage().deserialize(line));
|
||||||
npc.getHologram().addLine(MiniMessage.miniMessage().deserialize(line));
|
for (String s : config.getStringList("actions")) npc.addAction(actionRegistry.deserialize(s));
|
||||||
}
|
|
||||||
|
|
||||||
int amt = config.getInt("action-amount");
|
|
||||||
for (int i = 1; i <= amt; i++) {
|
|
||||||
String key = "actions." + i;
|
|
||||||
npc.addAction(NpcActionType.valueOf(config.getString(key + ".type"))
|
|
||||||
.deserialize(config.getInt(key + ".cooldown"), config.getString(key + ".argument")));
|
|
||||||
}
|
|
||||||
|
|
||||||
NpcEntryImpl entry = new NpcEntryImpl(config.getString("id"), npc);
|
NpcEntryImpl entry = new NpcEntryImpl(config.getString("id"), npc);
|
||||||
entry.setProcessed(config.getBoolean("is-processed"));
|
entry.setProcessed(config.getBoolean("is-processed"));
|
||||||
|
@ -71,7 +67,7 @@ public class YamlStorage implements NpcStorage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void saveNpcs(Collection<NpcEntryImpl> npcs) {
|
public void saveNpcs(Collection<NpcEntryImpl> npcs) {
|
||||||
File[] files = npcsFolder.listFiles();
|
File[] files = folder.listFiles();
|
||||||
if (files != null && files.length != 0) for (File file : files) file.delete();
|
if (files != null && files.length != 0) for (File file : files) file.delete();
|
||||||
for (NpcEntryImpl entry : npcs) try {
|
for (NpcEntryImpl entry : npcs) try {
|
||||||
YamlConfiguration config = new YamlConfiguration();
|
YamlConfiguration config = new YamlConfiguration();
|
||||||
|
@ -93,17 +89,12 @@ public class YamlStorage implements NpcStorage {
|
||||||
lines.add(MiniMessage.miniMessage().serialize(line.getText()));
|
lines.add(MiniMessage.miniMessage().serialize(line.getText()));
|
||||||
}
|
}
|
||||||
config.set("hologram", lines);
|
config.set("hologram", lines);
|
||||||
|
config.set("actions", npc.getActions().stream()
|
||||||
|
.map(actionRegistry::serialize)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
|
||||||
int i = 0;
|
config.save(new File(folder, entry.getId() + ".yml"));
|
||||||
for (NpcAction action : npc.getActions()) { i++;
|
|
||||||
String key = "actions." + i;
|
|
||||||
config.set(key + ".type", action.getType().name());
|
|
||||||
config.set(key + ".cooldown", action.getCooldown());
|
|
||||||
config.set(key + ".argument", action.getArgument());
|
|
||||||
}
|
|
||||||
config.set("action-amount", i);
|
|
||||||
|
|
||||||
config.save(new File(npcsFolder, entry.getId() + ".yml"));
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package lol.pyr.znpcsplus.tasks;
|
package lol.pyr.znpcsplus.tasks;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||||
import lol.pyr.znpcsplus.config.Configs;
|
|
||||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||||
|
@ -11,13 +10,17 @@ import org.bukkit.scheduler.BukkitRunnable;
|
||||||
import org.bukkit.util.NumberConversions;
|
import org.bukkit.util.NumberConversions;
|
||||||
|
|
||||||
public class NpcVisibilityTask extends BukkitRunnable {
|
public class NpcVisibilityTask extends BukkitRunnable {
|
||||||
public NpcVisibilityTask() {
|
private final NpcRegistryImpl npcRegistry;
|
||||||
ZNpcsPlus.SCHEDULER.runDelayedTimerAsync(this, 60L, 10L);
|
private final ConfigManager configManager;
|
||||||
|
|
||||||
|
public NpcVisibilityTask(NpcRegistryImpl npcRegistry, ConfigManager configManager) {
|
||||||
|
this.npcRegistry = npcRegistry;
|
||||||
|
this.configManager = configManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
double distSq = NumberConversions.square(Configs.config().viewDistance());
|
double distSq = NumberConversions.square(configManager.getConfig().viewDistance());
|
||||||
for (NpcEntryImpl entry : NpcRegistryImpl.get().all()) {
|
for (NpcEntryImpl entry : npcRegistry.all()) {
|
||||||
if (!entry.isProcessed()) continue;
|
if (!entry.isProcessed()) continue;
|
||||||
NpcImpl npc = entry.getNpc();
|
NpcImpl npc = entry.getNpc();
|
||||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||||
|
|
|
@ -1,24 +1,26 @@
|
||||||
package lol.pyr.znpcsplus.updater;
|
package lol.pyr.znpcsplus.updater;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import me.robertlit.spigotresources.api.Resource;
|
import me.robertlit.spigotresources.api.Resource;
|
||||||
import me.robertlit.spigotresources.api.SpigotResourcesAPI;
|
import me.robertlit.spigotresources.api.SpigotResourcesAPI;
|
||||||
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class UpdateChecker extends BukkitRunnable {
|
public class UpdateChecker extends BukkitRunnable {
|
||||||
private final static SpigotResourcesAPI api = new SpigotResourcesAPI(1, TimeUnit.MINUTES);
|
private final static Logger logger = Logger.getLogger("ZNPCsPlus Update Checker");
|
||||||
public final static int RESOURCE_ID = 109380;
|
private final static int RESOURCE_ID = 109380;
|
||||||
public final static String DOWNLOAD_LINK = "https://www.spigotmc.org/resources/znpcsplus.109380/";
|
public final static String DOWNLOAD_LINK = "https://www.spigotmc.org/resources/znpcsplus.109380/";
|
||||||
|
|
||||||
private final ZNpcsPlus plugin;
|
private final SpigotResourcesAPI api = new SpigotResourcesAPI(1, TimeUnit.MINUTES);
|
||||||
|
|
||||||
|
private final PluginDescriptionFile info;
|
||||||
private Status status = Status.UNKNOWN;
|
private Status status = Status.UNKNOWN;
|
||||||
private String newestVersion = "N/A";
|
private String newestVersion = "N/A";
|
||||||
|
|
||||||
public UpdateChecker(ZNpcsPlus plugin) {
|
public UpdateChecker(PluginDescriptionFile info) {
|
||||||
this.plugin = plugin;
|
this.info = info;
|
||||||
ZNpcsPlus.SCHEDULER.runDelayedTimerAsync(this, 5L, 6000L);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -26,7 +28,7 @@ public class UpdateChecker extends BukkitRunnable {
|
||||||
if (resource == null) return;
|
if (resource == null) return;
|
||||||
newestVersion = resource.getVersion();
|
newestVersion = resource.getVersion();
|
||||||
|
|
||||||
int current = versionToNumber(plugin.getDescription().getVersion());
|
int current = versionToNumber(info.getVersion());
|
||||||
int newest = versionToNumber(newestVersion);
|
int newest = versionToNumber(newestVersion);
|
||||||
|
|
||||||
status = current >= newest ? Status.LATEST_VERSION : Status.UPDATE_NEEDED;
|
status = current >= newest ? Status.LATEST_VERSION : Status.UPDATE_NEEDED;
|
||||||
|
@ -34,8 +36,8 @@ public class UpdateChecker extends BukkitRunnable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyConsole() {
|
private void notifyConsole() {
|
||||||
ZNpcsPlus.LOGGER.warning("Version " + getLatestVersion() + " of " + plugin.getDescription().getName() + " is available now!");
|
logger.warning("Version " + getLatestVersion() + " of " + info.getName() + " is available now!");
|
||||||
ZNpcsPlus.LOGGER.warning("Download it at " + UpdateChecker.DOWNLOAD_LINK);
|
logger.warning("Download it at " + UpdateChecker.DOWNLOAD_LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int versionToNumber(String version) {
|
private int versionToNumber(String version) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package lol.pyr.znpcsplus.updater;
|
package lol.pyr.znpcsplus.updater;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
import net.kyori.adventure.text.event.ClickEvent;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
@ -11,12 +12,13 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
|
||||||
public class UpdateNotificationListener implements Listener {
|
public class UpdateNotificationListener implements Listener {
|
||||||
private final ZNpcsPlus plugin;
|
private final ZNpcsPlus plugin;
|
||||||
|
private final BukkitAudiences adventure;
|
||||||
private final UpdateChecker updateChecker;
|
private final UpdateChecker updateChecker;
|
||||||
|
|
||||||
public UpdateNotificationListener(ZNpcsPlus plugin, UpdateChecker updateChecker) {
|
public UpdateNotificationListener(ZNpcsPlus plugin, BukkitAudiences adventure, UpdateChecker updateChecker) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
|
this.adventure = adventure;
|
||||||
this.updateChecker = updateChecker;
|
this.updateChecker = updateChecker;
|
||||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
@ -25,7 +27,7 @@ public class UpdateNotificationListener implements Listener {
|
||||||
if (updateChecker.getStatus() != UpdateChecker.Status.UPDATE_NEEDED) return;
|
if (updateChecker.getStatus() != UpdateChecker.Status.UPDATE_NEEDED) return;
|
||||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||||
if (!event.getPlayer().isOnline()) return;
|
if (!event.getPlayer().isOnline()) return;
|
||||||
ZNpcsPlus.ADVENTURE.player(event.getPlayer())
|
adventure.player(event.getPlayer())
|
||||||
.sendMessage(Component.text(plugin.getDescription().getName() + " v" + updateChecker.getLatestVersion() + " is available now!", NamedTextColor.GOLD).appendNewline()
|
.sendMessage(Component.text(plugin.getDescription().getName() + " v" + updateChecker.getLatestVersion() + " is available now!", NamedTextColor.GOLD).appendNewline()
|
||||||
.append(Component.text("Click this message to open the Spigot page (CLICK)", NamedTextColor.YELLOW)).clickEvent(ClickEvent.openUrl(UpdateChecker.DOWNLOAD_LINK)));
|
.append(Component.text("Click this message to open the Spigot page (CLICK)", NamedTextColor.YELLOW)).clickEvent(ClickEvent.openUrl(UpdateChecker.DOWNLOAD_LINK)));
|
||||||
}, 100L);
|
}, 100L);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package lol.pyr.znpcsplus.user;
|
package lol.pyr.znpcsplus.user;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
@ -9,24 +9,6 @@ import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class User {
|
public class User {
|
||||||
private final static Map<UUID, User> USER_MAP = new HashMap<>();
|
|
||||||
|
|
||||||
public static User get(Player player) {
|
|
||||||
return get(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static User get(UUID uuid) {
|
|
||||||
return USER_MAP.computeIfAbsent(uuid, User::new);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void remove(Player player) {
|
|
||||||
remove(player.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void remove(UUID uuid) {
|
|
||||||
USER_MAP.remove(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
private final UUID uuid;
|
private final UUID uuid;
|
||||||
private long lastNpcInteraction;
|
private long lastNpcInteraction;
|
||||||
private final Map<UUID, Long> actionCooldownMap = new HashMap<>();
|
private final Map<UUID, Long> actionCooldownMap = new HashMap<>();
|
||||||
|
@ -51,7 +33,7 @@ public class User {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean actionCooldownCheck(NpcAction action) {
|
public boolean actionCooldownCheck(InteractionAction action) {
|
||||||
UUID id = action.getUuid();
|
UUID id = action.getUuid();
|
||||||
if (System.currentTimeMillis() - actionCooldownMap.getOrDefault(id, 0L) >= action.getCooldown()) {
|
if (System.currentTimeMillis() - actionCooldownMap.getOrDefault(id, 0L) >= action.getCooldown()) {
|
||||||
actionCooldownMap.put(id, System.currentTimeMillis());
|
actionCooldownMap.put(id, System.currentTimeMillis());
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
package lol.pyr.znpcsplus.user;
|
package lol.pyr.znpcsplus.user;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
public class UserListener implements Listener {
|
public class UserListener implements Listener {
|
||||||
public UserListener(ZNpcsPlus plugin) {
|
private final UserManager manager;
|
||||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
|
||||||
|
public UserListener(UserManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onJoin(PlayerJoinEvent event) {
|
public void onJoin(PlayerJoinEvent event) {
|
||||||
User.get(event.getPlayer());
|
manager.get(event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onQuit(PlayerQuitEvent event) {
|
public void onQuit(PlayerQuitEvent event) {
|
||||||
User.remove(event.getPlayer().getUniqueId());
|
manager.remove(event.getPlayer().getUniqueId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
plugin/src/main/java/lol/pyr/znpcsplus/user/UserManager.java
Normal file
27
plugin/src/main/java/lol/pyr/znpcsplus/user/UserManager.java
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package lol.pyr.znpcsplus.user;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class UserManager {
|
||||||
|
private final Map<UUID, User> userMap = new HashMap<>();
|
||||||
|
|
||||||
|
public User get(Player player) {
|
||||||
|
return get(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public User get(UUID uuid) {
|
||||||
|
return userMap.computeIfAbsent(uuid, User::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Player player) {
|
||||||
|
remove(player.getUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(UUID uuid) {
|
||||||
|
userMap.remove(uuid);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package lol.pyr.znpcsplus.util;
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
|
||||||
import lol.pyr.znpcsplus.reflection.Reflections;
|
import lol.pyr.znpcsplus.reflection.Reflections;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
|
@ -24,7 +23,7 @@ public class FoliaUtil {
|
||||||
else try {
|
else try {
|
||||||
Reflections.FOLIA_TELEPORT_ASYNC.get().invoke(entity, location);
|
Reflections.FOLIA_TELEPORT_ASYNC.get().invoke(entity, location);
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
ZNpcsPlus.LOGGER.severe("Error while teleporting entity:");
|
System.err.println("Error while teleporting entity:");
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
19
plugin/src/main/java/lol/pyr/znpcsplus/util/PapiUtil.java
Normal file
19
plugin/src/main/java/lol/pyr/znpcsplus/util/PapiUtil.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
|
import me.clip.placeholderapi.PlaceholderAPI;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
public class PapiUtil {
|
||||||
|
private static boolean isSupported() {
|
||||||
|
return Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String set(String str) {
|
||||||
|
return set(null, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String set(Player player, String str) {
|
||||||
|
return isSupported() ? PlaceholderAPI.setPlaceholders(player, str) : str;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package lol.pyr.znpcsplus.util;
|
||||||
|
|
||||||
|
public interface StringSerializer<T> {
|
||||||
|
String serialize(T obj);
|
||||||
|
T deserialize(String str);
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
package lol.pyr.znpcsplus.util;
|
|
||||||
|
|
||||||
public class StringUtil {
|
|
||||||
public static boolean startsWithIgnoreCase(String s1, String s2) {
|
|
||||||
return s1.toLowerCase().startsWith(s2.toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue