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 "lol.pyr.director", "lol.pyr.znpcsplus.lib.command"
|
||||
relocate "lol.pyr.serviceinjector", "lol.pyr.znpcsplus.lib.serviceinjector"
|
||||
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;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.PacketEventsAPI;
|
||||
import com.github.retrooper.packetevents.event.PacketListenerPriority;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
|
||||
import lol.pyr.director.adventure.command.CommandManager;
|
||||
import lol.pyr.director.adventure.command.MultiCommand;
|
||||
import lol.pyr.director.adventure.parse.primitive.BooleanParser;
|
||||
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.npc.NpcRegistry;
|
||||
import lol.pyr.znpcsplus.commands.*;
|
||||
import lol.pyr.znpcsplus.commands.hologram.*;
|
||||
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.storage.LoadAllCommand;
|
||||
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.interaction.InteractionPacketListener;
|
||||
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||
import lol.pyr.znpcsplus.metadata.*;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
||||
import lol.pyr.znpcsplus.packets.*;
|
||||
import lol.pyr.znpcsplus.scheduling.FoliaScheduler;
|
||||
import lol.pyr.znpcsplus.scheduling.SpigotScheduler;
|
||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||
import lol.pyr.znpcsplus.skin.cache.SkinCache;
|
||||
import lol.pyr.znpcsplus.skin.cache.SkinCacheCleanTask;
|
||||
import lol.pyr.znpcsplus.tasks.NpcVisibilityTask;
|
||||
import lol.pyr.znpcsplus.updater.UpdateChecker;
|
||||
import lol.pyr.znpcsplus.updater.UpdateNotificationListener;
|
||||
import lol.pyr.znpcsplus.user.User;
|
||||
import lol.pyr.znpcsplus.user.UserListener;
|
||||
import lol.pyr.znpcsplus.user.UserManager;
|
||||
import lol.pyr.znpcsplus.util.BungeeUtil;
|
||||
import lol.pyr.znpcsplus.util.FoliaUtil;
|
||||
import lol.pyr.znpcsplus.util.LazyLoader;
|
||||
import lol.pyr.znpcsplus.util.ZLocation;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class ZNpcsPlus extends JavaPlugin {
|
||||
public class ZNpcsPlus extends JavaPlugin implements ZApi {
|
||||
private static final int PLUGIN_ID = 18244;
|
||||
public static boolean PLACEHOLDERS_SUPPORTED;
|
||||
|
||||
public static Logger LOGGER;
|
||||
public static File PLUGIN_FOLDER;
|
||||
public static File PATH_FOLDER;
|
||||
private TaskScheduler scheduler;
|
||||
private BukkitAudiences adventure;
|
||||
private SkinCache skinCache;
|
||||
|
||||
public static TaskScheduler SCHEDULER;
|
||||
public static BungeeUtil BUNGEE_UTIL;
|
||||
public static BukkitAudiences ADVENTURE;
|
||||
public static LegacyComponentSerializer LEGACY_AMPERSAND_SERIALIZER = LegacyComponentSerializer.builder()
|
||||
private MetadataFactory metadataFactory;
|
||||
|
||||
private NpcRegistryImpl npcRegistry;
|
||||
|
||||
private UserManager userManager;
|
||||
private final LegacyComponentSerializer textSerializer = LegacyComponentSerializer.builder()
|
||||
.character('&')
|
||||
.hexCharacter('#')
|
||||
.hexColors().build();
|
||||
private PacketEventsAPI<Plugin> packetEvents;
|
||||
|
||||
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
|
||||
public void onLoad() {
|
||||
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
|
||||
PacketEvents.getAPI().getSettings().checkForUpdates(false);
|
||||
PacketEvents.getAPI().load();
|
||||
LOGGER = getLogger();
|
||||
PLUGIN_FOLDER = getDataFolder();
|
||||
PATH_FOLDER = new File(PLUGIN_FOLDER, "paths");
|
||||
packetEvents = SpigotPacketEventsBuilder.build(this);
|
||||
PacketEvents.setAPI(packetEvents);
|
||||
packetEvents.getSettings().checkForUpdates(false);
|
||||
packetEvents.load();
|
||||
}
|
||||
|
||||
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("");
|
||||
|
||||
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("");
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
pluginManager.disablePlugin(this);
|
||||
return;
|
||||
}
|
||||
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...");
|
||||
ADVENTURE = BukkitAudiences.create(this);
|
||||
adventure = BukkitAudiences.create(this);
|
||||
|
||||
log(ChatColor.WHITE + " * Initializing PacketEvents...");
|
||||
PacketEvents.getAPI().getEventManager().registerListener(new InteractionPacketListener(), PacketListenerPriority.MONITOR);
|
||||
PacketEvents.getAPI().init();
|
||||
packetEvents.getEventManager().registerListener(new InteractionPacketListener(userManager, npcRegistry), PacketListenerPriority.MONITOR);
|
||||
packetEvents.init();
|
||||
|
||||
PLACEHOLDERS_SUPPORTED = Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI");
|
||||
if (PLACEHOLDERS_SUPPORTED) log(ChatColor.WHITE + " * Enabling PlaceholderAPI support...");
|
||||
metadataFactory = setupMetadataFactory();
|
||||
PacketFactory packetFactory = setupPacketFactory();
|
||||
|
||||
PLUGIN_FOLDER.mkdirs();
|
||||
PATH_FOLDER.mkdirs();
|
||||
getDataFolder().mkdirs();
|
||||
|
||||
log(ChatColor.WHITE + " * Loading configurations...");
|
||||
Configs.init(PLUGIN_FOLDER);
|
||||
ConfigManager configManager = new ConfigManager(getDataFolder());
|
||||
|
||||
log(ChatColor.WHITE + " * Defining NPC types...");
|
||||
NpcTypeImpl.defineTypes();
|
||||
|
||||
log(ChatColor.WHITE + " * Registering components...");
|
||||
log(ChatColor.WHITE + " * Starting tasks & registering components...");
|
||||
getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||||
new Metrics(this, PLUGIN_ID);
|
||||
SCHEDULER = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this);
|
||||
BUNGEE_UTIL = new BungeeUtil(this);
|
||||
Bukkit.getOnlinePlayers().forEach(User::get);
|
||||
scheduler = FoliaUtil.isFolia() ? new FoliaScheduler(this) : new SpigotScheduler(this);
|
||||
BungeeUtil bungeeUtil = new BungeeUtil(this);
|
||||
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();
|
||||
|
||||
log(ChatColor.WHITE + " * Starting tasks...");
|
||||
new NpcVisibilityTask();
|
||||
new SkinCacheCleanTask();
|
||||
new UserListener(this);
|
||||
if (Configs.config().checkForUpdates()) new UpdateNotificationListener(this, new UpdateChecker(this));
|
||||
if (configManager.getConfig().checkForUpdates()) {
|
||||
UpdateChecker updateChecker = new UpdateChecker(this.getDescription());
|
||||
scheduler.runDelayedTimerAsync(updateChecker, 5L, 6000L);
|
||||
pluginManager.registerEvents(new UpdateNotificationListener(this, adventure, updateChecker), this);
|
||||
}
|
||||
|
||||
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;
|
||||
log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)");
|
||||
log("");
|
||||
|
||||
if (Configs.config().debugEnabled()) {
|
||||
if (configManager.getConfig().debugEnabled()) {
|
||||
World world = Bukkit.getWorld("world");
|
||||
if (world == null) world = Bukkit.getWorlds().get(0);
|
||||
int i = 0;
|
||||
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);
|
||||
NpcImpl npc = entry.getNpc();
|
||||
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
|
||||
public void onDisable() {
|
||||
if (!enabled) return;
|
||||
NpcRegistryImpl.get().save();
|
||||
npcRegistry.save();
|
||||
ZApiProvider.unregister();
|
||||
Bukkit.getOnlinePlayers().forEach(User::remove);
|
||||
ADVENTURE.close();
|
||||
ADVENTURE = null;
|
||||
Bukkit.getOnlinePlayers().forEach(userManager::remove);
|
||||
adventure.close();
|
||||
adventure = null;
|
||||
}
|
||||
|
||||
private void registerCommands() {
|
||||
// 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(NpcEntryImpl.class, new NpcEntryParser(context -> {}));
|
||||
manager.registerParser(NpcEntryImpl.class, new NpcEntryParser(npcRegistry, context -> {}));
|
||||
manager.registerParser(EntityPropertyImpl.class, new EntityPropertyParser(context -> {}));
|
||||
manager.registerParser(Integer.class, new IntegerParser(context -> {}));
|
||||
manager.registerParser(Boolean.class, new BooleanParser(context -> {}));
|
||||
|
@ -191,25 +232,30 @@ public class ZNpcsPlus extends JavaPlugin {
|
|||
|
||||
manager.registerCommand("npc", new MultiCommand()
|
||||
.addSubcommand("action", new ActionCommand())
|
||||
.addSubcommand("create", new CreateCommand())
|
||||
.addSubcommand("skin", new SkinCommand())
|
||||
.addSubcommand("delete", new DeleteCommand())
|
||||
.addSubcommand("move", new MoveCommand())
|
||||
.addSubcommand("properties", new PropertiesCommand())
|
||||
.addSubcommand("teleport", new TeleportCommand())
|
||||
.addSubcommand("list", new ListCommand())
|
||||
.addSubcommand("near", new NearCommand())
|
||||
.addSubcommand("type", new TypeCommand())
|
||||
.addSubcommand("create", new CreateCommand(npcRegistry))
|
||||
.addSubcommand("skin", new SkinCommand(skinCache, npcRegistry))
|
||||
.addSubcommand("delete", new DeleteCommand(npcRegistry, adventure))
|
||||
.addSubcommand("move", new MoveCommand(npcRegistry))
|
||||
.addSubcommand("properties", new PropertiesCommand(npcRegistry))
|
||||
.addSubcommand("teleport", new TeleportCommand(npcRegistry))
|
||||
.addSubcommand("list", new ListCommand(npcRegistry))
|
||||
.addSubcommand("near", new NearCommand(npcRegistry))
|
||||
.addSubcommand("type", new TypeCommand(npcRegistry))
|
||||
.addSubcommand("storage", new MultiCommand()
|
||||
.addSubcommand("save", new SaveAllCommand())
|
||||
.addSubcommand("load", new LoadAllCommand()))
|
||||
.addSubcommand("save", new SaveAllCommand(npcRegistry))
|
||||
.addSubcommand("reload", new LoadAllCommand(npcRegistry)))
|
||||
.addSubcommand("holo", new MultiCommand()
|
||||
.addSubcommand("add", new HoloAddCommand())
|
||||
.addSubcommand("delete", new HoloDeleteCommand())
|
||||
.addSubcommand("info", new HoloInfoCommand())
|
||||
.addSubcommand("insert", new HoloInsertCommand())
|
||||
.addSubcommand("set", new HoloSetCommand())
|
||||
.addSubcommand("add", new HoloAddCommand(npcRegistry, textSerializer))
|
||||
.addSubcommand("delete", new HoloDeleteCommand(npcRegistry))
|
||||
.addSubcommand("info", new HoloInfoCommand(npcRegistry))
|
||||
.addSubcommand("insert", new HoloInsertCommand(npcRegistry, textSerializer))
|
||||
.addSubcommand("set", new HoloSetCommand(npcRegistry, textSerializer))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpcRegistry getNpcRegistry() {
|
||||
return npcRegistry;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,16 +15,22 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
public class CreateCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public CreateCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " create <id> <type>");
|
||||
Player player = context.ensureSenderIsPlayer();
|
||||
|
||||
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);
|
||||
|
||||
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();
|
||||
|
||||
context.send(Component.text("Created a " + type.getName() + " NPC with ID " + id + ".", NamedTextColor.GREEN));
|
||||
|
@ -32,7 +38,7 @@ public class CreateCommand implements CommandHandler {
|
|||
|
||||
@Override
|
||||
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));
|
||||
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.CommandHandler;
|
||||
import lol.pyr.director.common.command.CommandExecutionException;
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
|
@ -13,17 +13,25 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
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
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " delete <id>");
|
||||
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
||||
NpcRegistryImpl.get().delete(entry.getId());
|
||||
ZNpcsPlus.ADVENTURE.sender(context.getSender()).sendMessage(Component.text("Deleted NPC with ID: " + entry.getId(), NamedTextColor.GREEN));
|
||||
npcRegistry.delete(entry.getId());
|
||||
adventure.sender(context.getSender()).sendMessage(Component.text("Deleted NPC with ID: " + entry.getId(), NamedTextColor.GREEN));
|
||||
}
|
||||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,17 @@ import net.kyori.adventure.text.event.ClickEvent;
|
|||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
||||
public class ListCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public ListCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
TextComponent.Builder component = Component.text("Npc's:\n").color(NamedTextColor.GOLD).toBuilder();
|
||||
for (String id : NpcRegistryImpl.get().modifiableIds()) {
|
||||
NpcImpl npc = NpcRegistryImpl.get().get(id).getNpc();
|
||||
for (String id : npcRegistry.modifiableIds()) {
|
||||
NpcImpl npc = npcRegistry.get(id).getNpc();
|
||||
ZLocation location = npc.getLocation();
|
||||
component.append(Component.text("ID: " + id, NamedTextColor.GREEN))
|
||||
.append(Component.text(" | ", NamedTextColor.GRAY))
|
||||
|
|
|
@ -15,6 +15,12 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
public class MoveCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public MoveCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " move <id>");
|
||||
|
@ -26,7 +32,7 @@ public class MoveCommand implements CommandHandler {
|
|||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,13 +12,19 @@ import org.bukkit.entity.Player;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class NearCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public NearCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
Player player = context.ensureSenderIsPlayer();
|
||||
int raw = context.parse(Integer.class);
|
||||
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)
|
||||
.map(NpcEntryImpl::getId)
|
||||
.collect(Collectors.joining(", "));
|
||||
|
|
|
@ -14,6 +14,12 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
public class PropertiesCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public PropertiesCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
NpcEntryImpl entry = context.parse(NpcEntryImpl.class);
|
||||
|
@ -29,7 +35,7 @@ public class PropertiesCommand implements CommandHandler {
|
|||
|
||||
@Override
|
||||
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)
|
||||
.getNpc().getType().getAllowedProperties().stream().map(EntityPropertyImpl::getName));
|
||||
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.NpcRegistryImpl;
|
||||
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.MirrorDescriptor;
|
||||
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
||||
|
@ -18,6 +19,14 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
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
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " skin <id> <type> [value]");
|
||||
|
@ -26,7 +35,7 @@ public class SkinCommand implements CommandHandler {
|
|||
String type = context.popString();
|
||||
|
||||
if (type.equalsIgnoreCase("mirror")) {
|
||||
npc.setProperty(EntityPropertyImpl.SKIN, new MirrorDescriptor());
|
||||
npc.setProperty(EntityPropertyImpl.SKIN, new MirrorDescriptor(skinCache));
|
||||
npc.respawn();
|
||||
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();
|
||||
String name = context.dumpAllArgs();
|
||||
context.send(Component.text("Fetching skin \"" + name + "\"...", NamedTextColor.GREEN));
|
||||
PrefetchedDescriptor.forPlayer(name).thenAccept(skin -> {
|
||||
PrefetchedDescriptor.forPlayer(skinCache, name).thenAccept(skin -> {
|
||||
if (skin == null) {
|
||||
context.send(Component.text("Failed to fetch skin, are you sure the player name is valid?", NamedTextColor.RED));
|
||||
return;
|
||||
|
@ -50,7 +59,7 @@ public class SkinCommand implements CommandHandler {
|
|||
if (type.equalsIgnoreCase("dynamic")) {
|
||||
context.ensureArgsNotEmpty();
|
||||
String name = context.dumpAllArgs();
|
||||
npc.setProperty(EntityPropertyImpl.SKIN, new FetchingDescriptor(name));
|
||||
npc.setProperty(EntityPropertyImpl.SKIN, new FetchingDescriptor(skinCache, name));
|
||||
npc.respawn();
|
||||
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
|
||||
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.matchSuggestion("*", "static")) return context.suggestPlayers();
|
||||
return Collections.emptyList();
|
||||
|
|
|
@ -15,6 +15,12 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
public class TeleportCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public TeleportCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " teleport <id>");
|
||||
|
@ -26,7 +32,7 @@ public class TeleportCommand implements CommandHandler {
|
|||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,12 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
public class TypeCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl registry;
|
||||
|
||||
public TypeCommand(NpcRegistryImpl registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " type <id> <type>");
|
||||
|
@ -25,7 +31,7 @@ public class TypeCommand implements CommandHandler {
|
|||
|
||||
@Override
|
||||
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));
|
||||
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.CommandHandler;
|
||||
import lol.pyr.director.common.command.CommandExecutionException;
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
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
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " holo add <id> <text>");
|
||||
HologramImpl hologram = context.parse(NpcEntryImpl.class).getNpc().getHologram();
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,12 @@ import java.util.List;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
public class HoloDeleteCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public HoloDeleteCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " holo delete <id> <line>");
|
||||
|
@ -26,7 +32,7 @@ public class HoloDeleteCommand implements CommandHandler {
|
|||
|
||||
@Override
|
||||
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)
|
||||
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
|
||||
.map(String::valueOf));
|
||||
|
|
|
@ -14,6 +14,12 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
public class HoloInfoCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public HoloInfoCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " holo info <id>");
|
||||
|
@ -26,7 +32,7 @@ public class HoloInfoCommand implements CommandHandler {
|
|||
|
||||
@Override
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,18 +3,26 @@ package lol.pyr.znpcsplus.commands.hologram;
|
|||
import lol.pyr.director.adventure.command.CommandContext;
|
||||
import lol.pyr.director.adventure.command.CommandHandler;
|
||||
import lol.pyr.director.common.command.CommandExecutionException;
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
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
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
context.setUsage(context.getLabel() + " holo insert <id> <line> <text>");
|
||||
|
@ -22,13 +30,13 @@ public class HoloInsertCommand implements CommandHandler {
|
|||
int line = context.parse(Integer.class);
|
||||
if (line < 0 || line >= hologram.getLines().size()) context.halt(Component.text("Invalid line number!", NamedTextColor.RED));
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
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)
|
||||
.limit(context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram().getLines().size())
|
||||
.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.CommandHandler;
|
||||
import lol.pyr.director.common.command.CommandExecutionException;
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.hologram.HologramImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
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
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
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));
|
||||
context.ensureArgsNotEmpty();
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
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) {
|
||||
HologramImpl hologram = context.suggestionParse(0, NpcEntryImpl.class).getNpc().getHologram();
|
||||
if (context.argSize() == 2) return context.suggestStream(Stream.iterate(0, n -> n + 1)
|
||||
.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))));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
|
|
|
@ -10,13 +10,16 @@ import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
|||
import java.util.Deque;
|
||||
|
||||
public class NpcEntryParser extends ParserType<NpcEntryImpl> {
|
||||
public NpcEntryParser(Message<CommandContext> message) {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public NpcEntryParser(NpcRegistryImpl npcRegistry, Message<CommandContext> message) {
|
||||
super(message);
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
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();
|
||||
return entry;
|
||||
}
|
||||
|
|
|
@ -12,10 +12,16 @@ import java.util.List;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class LoadAllCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public LoadAllCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
NpcRegistryImpl.get().reload();
|
||||
npcRegistry.reload();
|
||||
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;
|
||||
|
||||
public class SaveAllCommand implements CommandHandler {
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
|
||||
public SaveAllCommand(NpcRegistryImpl npcRegistry) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(CommandContext context) throws CommandExecutionException {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
NpcRegistryImpl.get().save();
|
||||
npcRegistry.save();
|
||||
context.send(Component.text("All NPCs have been saved to storage", NamedTextColor.GREEN));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package lol.pyr.znpcsplus.config;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import space.arim.dazzleconf.ConfigurationFactory;
|
||||
import space.arim.dazzleconf.ConfigurationOptions;
|
||||
import space.arim.dazzleconf.error.ConfigFormatSyntaxException;
|
||||
|
@ -13,13 +12,22 @@ import space.arim.dazzleconf.serialiser.ValueSerialiser;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class Configs {
|
||||
private volatile static MainConfig config;
|
||||
private static ConfigurationHelper<MainConfig> configHelper;
|
||||
public class ConfigManager {
|
||||
private final static Logger logger = Logger.getLogger("ZNPCsPlus Configuration Manager");
|
||||
|
||||
private volatile static MessageConfig messages;
|
||||
private static ConfigurationHelper<MessageConfig> messagesHelper;
|
||||
private volatile MainConfig config;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
public static void init(File pluginFolder) {
|
||||
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() {
|
||||
public void reload() {
|
||||
try {
|
||||
config = configHelper.reloadConfigData();
|
||||
messages = messagesHelper.reloadConfigData();
|
||||
} catch (IOException e) {
|
||||
ZNpcsPlus.LOGGER.severe("Couldn't open config file!");
|
||||
logger.severe("Couldn't open config file!");
|
||||
e.printStackTrace();
|
||||
} catch (ConfigFormatSyntaxException e) {
|
||||
ZNpcsPlus.LOGGER.severe("Invalid config syntax!");
|
||||
logger.severe("Invalid config syntax!");
|
||||
e.printStackTrace();
|
||||
} catch (InvalidConfigException e) {
|
||||
ZNpcsPlus.LOGGER.severe("Invalid config value!");
|
||||
logger.severe("Invalid config value!");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static MainConfig config() {
|
||||
public MainConfig getConfig() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public static MessageConfig messages() {
|
||||
public MessageConfig getMessages() {
|
||||
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 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<Boolean> SKIN_LAYERS = new EntityPropertyImpl<>("skin_layers", true, BOOLEAN_SERIALIZER, BOOLEAN_DESERIALIZER);
|
||||
|
|
|
@ -13,6 +13,8 @@ import java.util.Collection;
|
|||
import java.util.UUID;
|
||||
|
||||
public class PacketEntity {
|
||||
private final PacketFactory packetFactory;
|
||||
|
||||
private final PropertyHolder properties;
|
||||
private final int entityId;
|
||||
private final UUID uuid;
|
||||
|
@ -20,7 +22,8 @@ public class PacketEntity {
|
|||
private final EntityType type;
|
||||
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.entityId = reserveEntityID();
|
||||
this.uuid = UUID.randomUUID();
|
||||
|
@ -46,25 +49,25 @@ public class PacketEntity {
|
|||
|
||||
public void setLocation(ZLocation location, Collection<Player> viewers) {
|
||||
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) {
|
||||
if (type == EntityTypes.PLAYER) PacketFactory.get().spawnPlayer(player, this, properties);
|
||||
else PacketFactory.get().spawnEntity(player, this, properties);
|
||||
if (type == EntityTypes.PLAYER) packetFactory.spawnPlayer(player, this, properties);
|
||||
else packetFactory.spawnEntity(player, this, properties);
|
||||
}
|
||||
|
||||
public void despawn(Player player) {
|
||||
PacketFactory.get().destroyEntity(player, this, properties);
|
||||
packetFactory.destroyEntity(player, this, properties);
|
||||
}
|
||||
|
||||
public void refreshMeta(Player player) {
|
||||
PacketFactory.get().sendAllMetadata(player, this, properties);
|
||||
packetFactory.sendAllMetadata(player, this, properties);
|
||||
}
|
||||
|
||||
public void remakeTeam(Player player) {
|
||||
PacketFactory.get().removeTeam(player, this);
|
||||
PacketFactory.get().createTeam(player, this, properties);
|
||||
packetFactory.removeTeam(player, this);
|
||||
packetFactory.createTeam(player, this, properties);
|
||||
}
|
||||
|
||||
private static int reserveEntityID() {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package lol.pyr.znpcsplus.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.ZLocation;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
@ -12,15 +13,20 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
public class HologramImpl extends Viewable implements Hologram {
|
||||
private final ConfigManager configManager;
|
||||
private final PacketFactory packetFactory;
|
||||
|
||||
private ZLocation location;
|
||||
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;
|
||||
}
|
||||
|
||||
public void addLine(Component line) {
|
||||
HologramLine newLine = new HologramLine(null, line);
|
||||
HologramLine newLine = new HologramLine(packetFactory, null, line);
|
||||
lines.add(newLine);
|
||||
relocateLines();
|
||||
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) {
|
||||
HologramLine newLine = new HologramLine(null, line);
|
||||
HologramLine newLine = new HologramLine(packetFactory, null, line);
|
||||
lines.add(index, newLine);
|
||||
relocateLines();
|
||||
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
|
||||
|
@ -72,7 +78,7 @@ public class HologramImpl extends Viewable implements Hologram {
|
|||
}
|
||||
|
||||
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;
|
||||
for (HologramLine line : lines) {
|
||||
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.entity.EntityPropertyImpl;
|
||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||
import lol.pyr.znpcsplus.util.ZLocation;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -15,9 +16,9 @@ public class HologramLine implements PropertyHolder {
|
|||
private Component text;
|
||||
private final PacketEntity armorStand;
|
||||
|
||||
public HologramLine(ZLocation location, Component text) {
|
||||
public HologramLine(PacketFactory packetFactory, ZLocation location, Component text) {
|
||||
this.text = text;
|
||||
armorStand = new PacketEntity(this, EntityTypes.ARMOR_STAND, location);
|
||||
armorStand = new PacketEntity(packetFactory, this, EntityTypes.ARMOR_STAND, location);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
public abstract class NpcAction {
|
||||
public abstract class InteractionAction {
|
||||
private final UUID id;
|
||||
private final long delay;
|
||||
protected final String argument;
|
||||
|
||||
protected NpcAction(long delay, String argument) {
|
||||
protected InteractionAction(long delay) {
|
||||
this.id = UUID.randomUUID();
|
||||
this.delay = delay;
|
||||
this.argument = argument;
|
||||
}
|
||||
|
||||
public UUID getUuid() {
|
||||
|
@ -23,11 +21,5 @@ public abstract class NpcAction {
|
|||
return delay;
|
||||
}
|
||||
|
||||
public String getArgument() {
|
||||
return argument;
|
||||
}
|
||||
|
||||
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.NpcRegistryImpl;
|
||||
import lol.pyr.znpcsplus.user.User;
|
||||
import lol.pyr.znpcsplus.user.UserManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
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
|
||||
public void onPacketReceive(PacketReceiveEvent event) {
|
||||
if (event.getPacketType() != PacketType.Play.Client.INTERACT_ENTITY) return;
|
||||
Player player = (Player) event.getPlayer();
|
||||
|
||||
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
|
||||
User user = User.get(player);
|
||||
User user = userManager.get(player);
|
||||
if (!user.canInteract()) return;
|
||||
|
||||
NpcEntryImpl entry = NpcRegistryImpl.get().getByEntityId(packet.getEntityId());
|
||||
NpcEntryImpl entry = npcRegistry.getByEntityId(packet.getEntityId());
|
||||
if (entry == null || !entry.isProcessed()) return;
|
||||
NpcImpl npc = entry.getNpc();
|
||||
|
||||
for (NpcAction action : npc.getActions()) {
|
||||
for (InteractionAction action : npc.getActions()) {
|
||||
if (action.getCooldown() > 0 && !user.actionCooldownCheck(action)) continue;
|
||||
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;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||
import lol.pyr.znpcsplus.util.PapiUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class ConsoleCommandAction extends NpcAction {
|
||||
public ConsoleCommandAction(long delay, String argument) {
|
||||
super(delay, argument);
|
||||
public class ConsoleCommandAction extends InteractionAction {
|
||||
private final TaskScheduler scheduler;
|
||||
private final String command;
|
||||
|
||||
public ConsoleCommandAction(TaskScheduler scheduler, String command, long delay) {
|
||||
super(delay);
|
||||
this.scheduler = scheduler;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player player) {
|
||||
String cmd = argument.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
||||
ZNpcsPlus.SCHEDULER.runSync(() -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), ZNpcsPlus.PLACEHOLDERS_SUPPORTED ? PlaceholderAPI.setPlaceholders(player, cmd) : cmd));
|
||||
String cmd = command.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
||||
scheduler.runSync(() -> Bukkit.dispatchCommand(Bukkit.getConsoleSender(), PapiUtil.set(player, cmd)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpcActionType getType() {
|
||||
return NpcActionType.CONSOLE_CMD;
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
||||
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class MessageAction extends NpcAction {
|
||||
public class MessageAction extends InteractionAction {
|
||||
private final BukkitAudiences adventure;
|
||||
private final Component message;
|
||||
|
||||
public MessageAction(long delay, String argument) {
|
||||
super(delay, argument);
|
||||
message = MiniMessage.miniMessage().deserialize(argument);
|
||||
public MessageAction(BukkitAudiences adventure, Component message, long delay) {
|
||||
super(delay);
|
||||
this.adventure = adventure;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player player) {
|
||||
ZNpcsPlus.ADVENTURE.player(player).sendMessage(message);
|
||||
adventure.player(player).sendMessage(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpcActionType getType() {
|
||||
return NpcActionType.MESSAGE;
|
||||
public Component getMessage() {
|
||||
return 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;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||
import lol.pyr.znpcsplus.util.PapiUtil;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class PlayerCommandAction extends NpcAction {
|
||||
public PlayerCommandAction(long delay, String argument) {
|
||||
super(delay, argument);
|
||||
public class PlayerCommandAction extends InteractionAction {
|
||||
private final TaskScheduler scheduler;
|
||||
private final String command;
|
||||
|
||||
public PlayerCommandAction(TaskScheduler scheduler, String command, long delay) {
|
||||
super(delay);
|
||||
this.scheduler = scheduler;
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player player) {
|
||||
String cmd = argument.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
||||
ZNpcsPlus.SCHEDULER.runSync(() -> Bukkit.dispatchCommand(player, ZNpcsPlus.PLACEHOLDERS_SUPPORTED ? PlaceholderAPI.setPlaceholders(player, cmd) : cmd));
|
||||
String cmd = command.replace("{player}", player.getName()).replace("{uuid}", player.getUniqueId().toString());
|
||||
scheduler.runSync(() -> Bukkit.dispatchCommand(player, PapiUtil.set(player, cmd)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpcActionType getType() {
|
||||
return NpcActionType.PLAYER_CMD;
|
||||
public String getCommand() {
|
||||
return command;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
||||
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||
import lol.pyr.znpcsplus.util.BungeeUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class SwitchServerAction extends NpcAction {
|
||||
public SwitchServerAction(long delay, String argument) {
|
||||
super(delay, argument);
|
||||
public class SwitchServerAction extends InteractionAction {
|
||||
private final BungeeUtil bungeeUtil;
|
||||
private final String server;
|
||||
|
||||
public SwitchServerAction(BungeeUtil bungeeUtil, String server, long delay) {
|
||||
super(delay);
|
||||
this.bungeeUtil = bungeeUtil;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(Player player) {
|
||||
ZNpcsPlus.BUNGEE_UTIL.sendPlayerToServer(player, argument);
|
||||
bungeeUtil.sendPlayerToServer(player, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NpcActionType getType() {
|
||||
return NpcActionType.SERVER;
|
||||
public String getServer() {
|
||||
return 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;
|
||||
|
||||
import com.github.retrooper.packetevents.PacketEvents;
|
||||
import com.github.retrooper.packetevents.manager.server.ServerVersion;
|
||||
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 java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 1.8 https://wiki.vg/index.php?title=Entity_metadata&oldid=7415
|
||||
|
@ -31,33 +25,4 @@ public interface MetadataFactory {
|
|||
EntityData silent(boolean enabled);
|
||||
Collection<EntityData> name(Component name);
|
||||
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.EntityDataTypes;
|
||||
|
||||
public class V1_10Factory extends V1_9Factory {
|
||||
public class V1_10MetadataFactory extends V1_9MetadataFactory {
|
||||
@Override
|
||||
public EntityData noGravity() {
|
||||
return new EntityData(5, EntityDataTypes.BOOLEAN, true);
|
|
@ -9,7 +9,7 @@ import net.kyori.adventure.text.Component;
|
|||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
|
||||
public class V1_13Factory extends V1_10Factory {
|
||||
public class V1_13MetadataFactory extends V1_10MetadataFactory {
|
||||
@Override
|
||||
public Collection<EntityData> name(Component name) {
|
||||
return ListUtil.immutableList(
|
|
@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.metadata;
|
|||
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||
|
||||
public class V1_14Factory extends V1_13Factory {
|
||||
public class V1_14MetadataFactory extends V1_13MetadataFactory {
|
||||
@Override
|
||||
public EntityData skinLayers(boolean enabled) {
|
||||
return createSkinLayers(15, enabled);
|
|
@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.metadata;
|
|||
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||
|
||||
public class V1_16Factory extends V1_14Factory {
|
||||
public class V1_16MetadataFactory extends V1_14MetadataFactory {
|
||||
@Override
|
||||
public EntityData skinLayers(boolean enabled) {
|
||||
return createSkinLayers(16, enabled);
|
|
@ -2,7 +2,7 @@ package lol.pyr.znpcsplus.metadata;
|
|||
|
||||
import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
|
||||
|
||||
public class V1_17Factory extends V1_16Factory {
|
||||
public class V1_17MetadataFactory extends V1_16MetadataFactory {
|
||||
@Override
|
||||
public EntityData skinLayers(boolean enabled) {
|
||||
return createSkinLayers(17, enabled);
|
|
@ -8,7 +8,7 @@ import net.kyori.adventure.text.Component;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
public class V1_8Factory implements MetadataFactory {
|
||||
public class V1_8MetadataFactory implements MetadataFactory {
|
||||
@Override
|
||||
public EntityData skinLayers(boolean enabled) {
|
||||
return createSkinLayers(12, enabled);
|
|
@ -8,7 +8,7 @@ import net.kyori.adventure.text.Component;
|
|||
|
||||
import java.util.Collection;
|
||||
|
||||
public class V1_9Factory extends V1_8Factory {
|
||||
public class V1_9MetadataFactory extends V1_8MetadataFactory {
|
||||
@Override
|
||||
public EntityData skinLayers(boolean 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.npc.Npc;
|
||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||
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.ZLocation;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -16,6 +18,7 @@ import org.bukkit.entity.Player;
|
|||
import java.util.*;
|
||||
|
||||
public class NpcImpl extends Viewable implements Npc {
|
||||
private final PacketFactory packetFactory;
|
||||
private final String worldName;
|
||||
private PacketEntity entity;
|
||||
private ZLocation location;
|
||||
|
@ -23,25 +26,26 @@ public class NpcImpl extends Viewable implements Npc {
|
|||
private final HologramImpl hologram;
|
||||
|
||||
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) {
|
||||
this(world.getName(), type, location);
|
||||
protected NpcImpl(ConfigManager configManager, World world, NpcTypeImpl type, ZLocation location, PacketFactory packetFactory) {
|
||||
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.type = type;
|
||||
this.location = location;
|
||||
entity = new PacketEntity(this, type.getType(), location);
|
||||
hologram = new HologramImpl(location.withY(location.getY() + type.getHologramOffset()));
|
||||
entity = new PacketEntity(packetFactory, this, type.getType(), location);
|
||||
hologram = new HologramImpl(configManager, packetFactory, location.withY(location.getY() + type.getHologramOffset()));
|
||||
}
|
||||
|
||||
|
||||
public void setType(NpcTypeImpl type) {
|
||||
UNSAFE_hideAll();
|
||||
this.type = type;
|
||||
entity = new PacketEntity(this, type.getType(), entity.getLocation());
|
||||
entity = new PacketEntity(packetFactory, this, type.getType(), entity.getLocation());
|
||||
UNSAFE_showAll();
|
||||
}
|
||||
|
||||
|
@ -130,11 +134,11 @@ public class NpcImpl extends Viewable implements Npc {
|
|||
return Collections.unmodifiableSet(propertyMap.keySet());
|
||||
}
|
||||
|
||||
public Collection<NpcAction> getActions() {
|
||||
public Collection<InteractionAction> getActions() {
|
||||
return Collections.unmodifiableSet(actions);
|
||||
}
|
||||
|
||||
public void addAction(NpcAction action) {
|
||||
public void addAction(InteractionAction action) {
|
||||
actions.add(action);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
package lol.pyr.znpcsplus.npc;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.api.npc.NpcRegistry;
|
||||
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.util.ZLocation;
|
||||
import org.bukkit.World;
|
||||
|
@ -14,25 +17,23 @@ import java.util.Map;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class NpcRegistryImpl implements NpcRegistry {
|
||||
private final static NpcRegistryImpl registry = new NpcRegistryImpl();
|
||||
public static NpcRegistryImpl get() {
|
||||
return registry;
|
||||
}
|
||||
private final NpcStorage storage;
|
||||
private final PacketFactory packetFactory;
|
||||
private final ConfigManager configManager;
|
||||
|
||||
private final NpcStorage STORAGE;
|
||||
|
||||
private NpcRegistryImpl() {
|
||||
if (registry != null) throw new UnsupportedOperationException("This class can only be instanciated once!");
|
||||
STORAGE = Configs.config().storageType().create();
|
||||
public NpcRegistryImpl(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry) {
|
||||
storage = configManager.getConfig().storageType().create(configManager, plugin, packetFactory, actionRegistry);
|
||||
this.packetFactory = packetFactory;
|
||||
this.configManager = configManager;
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
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() {
|
||||
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<>();
|
||||
|
@ -73,7 +74,7 @@ public class NpcRegistryImpl implements NpcRegistry {
|
|||
public NpcEntryImpl create(String id, World world, NpcTypeImpl type, ZLocation location) {
|
||||
id = id.toLowerCase();
|
||||
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);
|
||||
npcMap.put(id, entry);
|
||||
return entry;
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
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 lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||
import lol.pyr.znpcsplus.util.LazyLoader;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface PacketFactory {
|
||||
|
@ -24,31 +21,4 @@ public interface PacketFactory {
|
|||
Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
||||
void sendAllMetadata(Player player, PacketEntity entity, PropertyHolder properties);
|
||||
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.entity.PacketEntity;
|
||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
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
|
||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||
Map<Integer, EntityData> data = super.generateMetadata(player, entity, properties);
|
||||
add(data, MetadataFactory.get().noGravity());
|
||||
add(data, metadataFactory.noGravity());
|
||||
return data;
|
||||
}
|
||||
}
|
|
@ -4,12 +4,18 @@ import com.github.retrooper.packetevents.util.Vector3d;
|
|||
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
|
||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||
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 org.bukkit.entity.Player;
|
||||
|
||||
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
|
||||
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||
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 lol.pyr.znpcsplus.entity.PacketEntity;
|
||||
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 org.bukkit.entity.Player;
|
||||
|
||||
import java.util.EnumSet;
|
||||
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
|
||||
public CompletableFuture<Void> addTabPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||
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.wrapper.PacketWrapper;
|
||||
import com.github.retrooper.packetevents.wrapper.play.server.*;
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
||||
import lol.pyr.znpcsplus.util.ZLocation;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
@ -24,7 +24,15 @@ import org.bukkit.entity.Player;
|
|||
import java.util.*;
|
||||
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
|
||||
public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||
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()));
|
||||
sendPacket(player, new WrapperPlayServerEntityHeadLook(entity.getEntityId(), location.getYaw()));
|
||||
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
|
||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder properties) {
|
||||
HashMap<Integer, EntityData> data = new HashMap<>();
|
||||
if (entity.getType() == EntityTypes.PLAYER) add(data, MetadataFactory.get().skinLayers(properties.getProperty(EntityPropertyImpl.SKIN_LAYERS)));
|
||||
add(data, MetadataFactory.get().effects(properties.getProperty(EntityPropertyImpl.FIRE), false, properties.getProperty(EntityPropertyImpl.INVISIBLE)));
|
||||
add(data, MetadataFactory.get().silent(properties.getProperty(EntityPropertyImpl.SILENT)));
|
||||
if (properties.hasProperty(EntityPropertyImpl.NAME)) addAll(data, MetadataFactory.get().name(properties.getProperty(EntityPropertyImpl.NAME)));
|
||||
if (entity.getType() == EntityTypes.PLAYER) add(data, metadataFactory.skinLayers(properties.getProperty(EntityPropertyImpl.SKIN_LAYERS)));
|
||||
add(data, metadataFactory.effects(properties.getProperty(EntityPropertyImpl.FIRE), false, properties.getProperty(EntityPropertyImpl.INVISIBLE)));
|
||||
add(data, metadataFactory.silent(properties.getProperty(EntityPropertyImpl.SILENT)));
|
||||
if (properties.hasProperty(EntityPropertyImpl.NAME)) addAll(data, metadataFactory.name(properties.getProperty(EntityPropertyImpl.NAME)));
|
||||
return data;
|
||||
}
|
||||
|
|
@ -5,15 +5,20 @@ import lol.pyr.znpcsplus.api.entity.PropertyHolder;
|
|||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||
import lol.pyr.znpcsplus.entity.PacketEntity;
|
||||
import lol.pyr.znpcsplus.metadata.MetadataFactory;
|
||||
import lol.pyr.znpcsplus.scheduling.TaskScheduler;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
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
|
||||
public Map<Integer, EntityData> generateMetadata(Player player, PacketEntity entity, PropertyHolder 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;
|
||||
}
|
||||
}
|
|
@ -1,13 +1,14 @@
|
|||
package lol.pyr.znpcsplus.reflection;
|
||||
|
||||
import lol.pyr.znpcsplus.util.VersionUtil;
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public abstract class ReflectionLazyLoader<T> {
|
||||
private final static Logger logger = Logger.getLogger("ZNPCsPlus Reflection");
|
||||
protected final List<String> possibleClassNames;
|
||||
protected List<Class<?>> reflectionClasses = new ArrayList<>();
|
||||
protected final boolean strict;
|
||||
|
@ -34,25 +35,21 @@ public abstract class ReflectionLazyLoader<T> {
|
|||
if (eval == null) throw new RuntimeException("Returned value is null");
|
||||
} catch (Throwable throwable) {
|
||||
if (strict) {
|
||||
warn(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON THE ZNPCSPLUS GITHUB ----- ");
|
||||
warn(getClass().getSimpleName() + " failed!");
|
||||
warn("Class Names: " + possibleClassNames);
|
||||
warn("Reflection Type: " + getClass().getCanonicalName());
|
||||
warn("Bukkit Version: " + VersionUtil.BUKKIT_VERSION + " (" + VersionUtil.getBukkitPackage() + ")");
|
||||
printDebugInfo(this::warn);
|
||||
warn("Exception:");
|
||||
logger.warning(" ----- REFLECTION FAILURE DEBUG INFORMATION, REPORT THIS ON THE ZNPCSPLUS GITHUB ----- ");
|
||||
logger.warning(getClass().getSimpleName() + " failed!");
|
||||
logger.warning("Class Names: " + possibleClassNames);
|
||||
logger.warning("Reflection Type: " + getClass().getCanonicalName());
|
||||
logger.warning("Bukkit Version: " + VersionUtil.BUKKIT_VERSION + " (" + VersionUtil.getBukkitPackage() + ")");
|
||||
printDebugInfo(logger::warning);
|
||||
logger.warning("Exception:");
|
||||
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;
|
||||
return this.cached;
|
||||
}
|
||||
|
||||
private void warn(String message) {
|
||||
ZNpcsPlus.LOGGER.warning("[Reflection] " + message);
|
||||
}
|
||||
|
||||
protected abstract T load() throws Exception;
|
||||
protected void printDebugInfo(Consumer<String> logger) {}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package lol.pyr.znpcsplus.skin;
|
|||
|
||||
import com.github.retrooper.packetevents.protocol.player.TextureProperty;
|
||||
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.MirrorDescriptor;
|
||||
import lol.pyr.znpcsplus.skin.descriptor.PrefetchedDescriptor;
|
||||
|
@ -17,10 +18,10 @@ public interface BaseSkinDescriptor extends SkinDescriptor {
|
|||
boolean supportsInstant(Player player);
|
||||
String serialize();
|
||||
|
||||
static BaseSkinDescriptor deserialize(String str) {
|
||||
static BaseSkinDescriptor deserialize(SkinCache skinCache, String str) {
|
||||
String[] arr = str.split(";");
|
||||
if (arr[0].equalsIgnoreCase("mirror")) return new MirrorDescriptor();
|
||||
else if (arr[0].equalsIgnoreCase("fetching")) return new FetchingDescriptor(arr[1]);
|
||||
if (arr[0].equalsIgnoreCase("mirror")) return new MirrorDescriptor(skinCache);
|
||||
else if (arr[0].equalsIgnoreCase("fetching")) return new FetchingDescriptor(skinCache, arr[1]);
|
||||
else if (arr[0].equalsIgnoreCase("prefetched")) {
|
||||
List<TextureProperty> properties = new ArrayList<>();
|
||||
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.JsonParser;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.config.Configs;
|
||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||
import lol.pyr.znpcsplus.reflection.Reflections;
|
||||
import lol.pyr.znpcsplus.skin.Skin;
|
||||
import org.bukkit.Bukkit;
|
||||
|
@ -22,17 +21,26 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class SkinCache {
|
||||
private final static Map<String, Skin> cache = new ConcurrentHashMap<>();
|
||||
private final static Map<String, CachedId> idCache = new ConcurrentHashMap<>();
|
||||
private final static Logger logger = Logger.getLogger("ZNPCsPlus Skin Cache");
|
||||
|
||||
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, 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);
|
||||
if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player));
|
||||
|
||||
|
@ -52,8 +60,8 @@ public class SkinCache {
|
|||
return fetchByUUID(id).join();
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
if (!Configs.config().disableSkinFetcherWarnings()) {
|
||||
ZNpcsPlus.LOGGER.warning("Failed to uuid from player name:");
|
||||
if (!configManager.getConfig().disableSkinFetcherWarnings()) {
|
||||
logger.warning("Failed to uuid from player name:");
|
||||
exception.printStackTrace();
|
||||
}
|
||||
} 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("-", ""));
|
||||
}
|
||||
|
||||
public static boolean isNameFullyCached(String s) {
|
||||
public boolean isNameFullyCached(String s) {
|
||||
String name = s.toLowerCase();
|
||||
if (!idCache.containsKey(name)) return false;
|
||||
CachedId id = idCache.get(name);
|
||||
|
@ -76,7 +84,7 @@ public class SkinCache {
|
|||
return !skin.isExpired();
|
||||
}
|
||||
|
||||
public static Skin getFullyCachedByName(String s) {
|
||||
public Skin getFullyCachedByName(String s) {
|
||||
String name = s.toLowerCase();
|
||||
if (!idCache.containsKey(name)) return null;
|
||||
CachedId id = idCache.get(name);
|
||||
|
@ -86,7 +94,7 @@ public class SkinCache {
|
|||
return skin;
|
||||
}
|
||||
|
||||
public static CompletableFuture<Skin> fetchByUUID(String uuid) {
|
||||
public CompletableFuture<Skin> fetchByUUID(String uuid) {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player));
|
||||
|
||||
|
@ -108,8 +116,8 @@ public class SkinCache {
|
|||
return skin;
|
||||
}
|
||||
} catch (IOException exception) {
|
||||
if (!Configs.config().disableSkinFetcherWarnings()) {
|
||||
ZNpcsPlus.LOGGER.warning("Failed to fetch skin:");
|
||||
if (!configManager.getConfig().disableSkinFetcherWarnings()) {
|
||||
logger.warning("Failed to fetch skin:");
|
||||
exception.printStackTrace();
|
||||
}
|
||||
} finally {
|
||||
|
@ -119,7 +127,7 @@ public class SkinCache {
|
|||
});
|
||||
}
|
||||
|
||||
public static Skin getFromPlayer(Player player) {
|
||||
public Skin getFromPlayer(Player player) {
|
||||
try {
|
||||
Object playerHandle = Reflections.GET_HANDLE_PLAYER_METHOD.get().invoke(player);
|
||||
GameProfile gameProfile = (GameProfile) Reflections.GET_PROFILE_METHOD.get().invoke(playerHandle, new Object[0]);
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
package lol.pyr.znpcsplus.skin.cache;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class SkinCacheCleanTask extends BukkitRunnable {
|
||||
public SkinCacheCleanTask() {
|
||||
ZNpcsPlus.SCHEDULER.runDelayedTimerAsync(this, 1200, 1200);
|
||||
private final SkinCache skinCache;
|
||||
|
||||
public SkinCacheCleanTask(SkinCache skinCache) {
|
||||
this.skinCache = skinCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
SkinCache.cleanCache();
|
||||
skinCache.cleanCache();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,40 +1,36 @@
|
|||
package lol.pyr.znpcsplus.skin.descriptor;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
|
||||
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
|
||||
import lol.pyr.znpcsplus.skin.Skin;
|
||||
import lol.pyr.znpcsplus.skin.cache.SkinCache;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import lol.pyr.znpcsplus.util.PapiUtil;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FetchingDescriptor implements BaseSkinDescriptor, SkinDescriptor {
|
||||
private final SkinCache skinCache;
|
||||
private final String name;
|
||||
|
||||
public FetchingDescriptor(String name) {
|
||||
public FetchingDescriptor(SkinCache skinCache, String name) {
|
||||
this.skinCache = skinCache;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Skin> fetch(Player player) {
|
||||
return SkinCache.fetchByName(papi(player));
|
||||
return skinCache.fetchByName(PapiUtil.set(player, name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Skin fetchInstant(Player player) {
|
||||
return SkinCache.getFullyCachedByName(papi(player));
|
||||
return skinCache.getFullyCachedByName(PapiUtil.set(player, name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsInstant(Player player) {
|
||||
return SkinCache.isNameFullyCached(papi(player));
|
||||
}
|
||||
|
||||
private String papi(Player player) {
|
||||
if (ZNpcsPlus.PLACEHOLDERS_SUPPORTED) return PlaceholderAPI.setPlaceholders(player, name);
|
||||
return name;
|
||||
return skinCache.isNameFullyCached(PapiUtil.set(player, name));
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
|
|
@ -9,17 +9,20 @@ import org.bukkit.entity.Player;
|
|||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class MirrorDescriptor implements BaseSkinDescriptor, SkinDescriptor {
|
||||
private final SkinCache skinCache;
|
||||
|
||||
public MirrorDescriptor() {}
|
||||
public MirrorDescriptor(SkinCache skinCache) {
|
||||
this.skinCache = skinCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Skin> fetch(Player player) {
|
||||
return CompletableFuture.completedFuture(SkinCache.getFromPlayer(player));
|
||||
return CompletableFuture.completedFuture(skinCache.getFromPlayer(player));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Skin fetchInstant(Player player) {
|
||||
return SkinCache.getFromPlayer(player);
|
||||
return skinCache.getFromPlayer(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,8 +16,8 @@ public class PrefetchedDescriptor implements BaseSkinDescriptor, SkinDescriptor
|
|||
this.skin = skin;
|
||||
}
|
||||
|
||||
public static CompletableFuture<PrefetchedDescriptor> forPlayer(String name) {
|
||||
return CompletableFuture.supplyAsync(() -> new PrefetchedDescriptor(SkinCache.fetchByName(name).join()));
|
||||
public static CompletableFuture<PrefetchedDescriptor> forPlayer(SkinCache cache, String name) {
|
||||
return CompletableFuture.supplyAsync(() -> new PrefetchedDescriptor(cache.fetchByName(name).join()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
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 java.io.File;
|
||||
|
||||
public enum NpcStorageType {
|
||||
YAML {
|
||||
@Override
|
||||
public NpcStorage create() {
|
||||
return new YamlStorage();
|
||||
public NpcStorage create(ConfigManager configManager, ZNpcsPlus plugin, PacketFactory packetFactory, ActionRegistry actionRegistry) {
|
||||
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;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||
import lol.pyr.znpcsplus.entity.EntityPropertyImpl;
|
||||
import lol.pyr.znpcsplus.hologram.HologramLine;
|
||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
||||
import lol.pyr.znpcsplus.interaction.NpcActionType;
|
||||
import lol.pyr.znpcsplus.interaction.ActionRegistry;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcTypeImpl;
|
||||
import lol.pyr.znpcsplus.packets.PacketFactory;
|
||||
import lol.pyr.znpcsplus.storage.NpcStorage;
|
||||
import lol.pyr.znpcsplus.util.ZLocation;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
|
@ -16,28 +16,32 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
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() {
|
||||
npcsFolder = new File(ZNpcsPlus.PLUGIN_FOLDER, "npcs");
|
||||
if (!npcsFolder.exists()) npcsFolder.mkdirs();
|
||||
public YamlStorage(PacketFactory packetFactory, ConfigManager configManager, ActionRegistry actionRegistry, File folder) {
|
||||
this.packetFactory = packetFactory;
|
||||
this.configManager = configManager;
|
||||
this.actionRegistry = actionRegistry;
|
||||
this.folder = folder;
|
||||
if (!this.folder.exists()) this.folder.mkdirs();
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Override
|
||||
public Collection<NpcEntryImpl> loadNpcs() {
|
||||
File[] files = npcsFolder.listFiles();
|
||||
File[] files = folder.listFiles();
|
||||
if (files == null || files.length == 0) return Collections.emptyList();
|
||||
List<NpcEntryImpl> npcs = new ArrayList<>();
|
||||
for (File file : files) if (file.isFile() && file.getName().toLowerCase().endsWith(".yml")) {
|
||||
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")));
|
||||
|
||||
ConfigurationSection properties = config.getConfigurationSection("properties");
|
||||
|
@ -48,16 +52,8 @@ public class YamlStorage implements NpcStorage {
|
|||
}
|
||||
}
|
||||
|
||||
for (String line : config.getStringList("hologram")) {
|
||||
npc.getHologram().addLine(MiniMessage.miniMessage().deserialize(line));
|
||||
}
|
||||
|
||||
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")));
|
||||
}
|
||||
for (String line : config.getStringList("hologram")) npc.getHologram().addLine(MiniMessage.miniMessage().deserialize(line));
|
||||
for (String s : config.getStringList("actions")) npc.addAction(actionRegistry.deserialize(s));
|
||||
|
||||
NpcEntryImpl entry = new NpcEntryImpl(config.getString("id"), npc);
|
||||
entry.setProcessed(config.getBoolean("is-processed"));
|
||||
|
@ -71,7 +67,7 @@ public class YamlStorage implements NpcStorage {
|
|||
|
||||
@Override
|
||||
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();
|
||||
for (NpcEntryImpl entry : npcs) try {
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
|
@ -93,17 +89,12 @@ public class YamlStorage implements NpcStorage {
|
|||
lines.add(MiniMessage.miniMessage().serialize(line.getText()));
|
||||
}
|
||||
config.set("hologram", lines);
|
||||
config.set("actions", npc.getActions().stream()
|
||||
.map(actionRegistry::serialize)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
int i = 0;
|
||||
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"));
|
||||
config.save(new File(folder, entry.getId() + ".yml"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package lol.pyr.znpcsplus.tasks;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.config.Configs;
|
||||
import lol.pyr.znpcsplus.config.ConfigManager;
|
||||
import lol.pyr.znpcsplus.npc.NpcEntryImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcImpl;
|
||||
import lol.pyr.znpcsplus.npc.NpcRegistryImpl;
|
||||
|
@ -11,13 +10,17 @@ import org.bukkit.scheduler.BukkitRunnable;
|
|||
import org.bukkit.util.NumberConversions;
|
||||
|
||||
public class NpcVisibilityTask extends BukkitRunnable {
|
||||
public NpcVisibilityTask() {
|
||||
ZNpcsPlus.SCHEDULER.runDelayedTimerAsync(this, 60L, 10L);
|
||||
private final NpcRegistryImpl npcRegistry;
|
||||
private final ConfigManager configManager;
|
||||
|
||||
public NpcVisibilityTask(NpcRegistryImpl npcRegistry, ConfigManager configManager) {
|
||||
this.npcRegistry = npcRegistry;
|
||||
this.configManager = configManager;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
double distSq = NumberConversions.square(Configs.config().viewDistance());
|
||||
for (NpcEntryImpl entry : NpcRegistryImpl.get().all()) {
|
||||
double distSq = NumberConversions.square(configManager.getConfig().viewDistance());
|
||||
for (NpcEntryImpl entry : npcRegistry.all()) {
|
||||
if (!entry.isProcessed()) continue;
|
||||
NpcImpl npc = entry.getNpc();
|
||||
for (Player player : Bukkit.getOnlinePlayers()) {
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
package lol.pyr.znpcsplus.updater;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import me.robertlit.spigotresources.api.Resource;
|
||||
import me.robertlit.spigotresources.api.SpigotResourcesAPI;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
public class UpdateChecker extends BukkitRunnable {
|
||||
private final static SpigotResourcesAPI api = new SpigotResourcesAPI(1, TimeUnit.MINUTES);
|
||||
public final static int RESOURCE_ID = 109380;
|
||||
private final static Logger logger = Logger.getLogger("ZNPCsPlus Update Checker");
|
||||
private final static int RESOURCE_ID = 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 String newestVersion = "N/A";
|
||||
|
||||
public UpdateChecker(ZNpcsPlus plugin) {
|
||||
this.plugin = plugin;
|
||||
ZNpcsPlus.SCHEDULER.runDelayedTimerAsync(this, 5L, 6000L);
|
||||
public UpdateChecker(PluginDescriptionFile info) {
|
||||
this.info = info;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
@ -26,7 +28,7 @@ public class UpdateChecker extends BukkitRunnable {
|
|||
if (resource == null) return;
|
||||
newestVersion = resource.getVersion();
|
||||
|
||||
int current = versionToNumber(plugin.getDescription().getVersion());
|
||||
int current = versionToNumber(info.getVersion());
|
||||
int newest = versionToNumber(newestVersion);
|
||||
|
||||
status = current >= newest ? Status.LATEST_VERSION : Status.UPDATE_NEEDED;
|
||||
|
@ -34,8 +36,8 @@ public class UpdateChecker extends BukkitRunnable {
|
|||
}
|
||||
|
||||
private void notifyConsole() {
|
||||
ZNpcsPlus.LOGGER.warning("Version " + getLatestVersion() + " of " + plugin.getDescription().getName() + " is available now!");
|
||||
ZNpcsPlus.LOGGER.warning("Download it at " + UpdateChecker.DOWNLOAD_LINK);
|
||||
logger.warning("Version " + getLatestVersion() + " of " + info.getName() + " is available now!");
|
||||
logger.warning("Download it at " + UpdateChecker.DOWNLOAD_LINK);
|
||||
}
|
||||
|
||||
private int versionToNumber(String version) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package lol.pyr.znpcsplus.updater;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
|
@ -11,12 +12,13 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
|||
|
||||
public class UpdateNotificationListener implements Listener {
|
||||
private final ZNpcsPlus plugin;
|
||||
private final BukkitAudiences adventure;
|
||||
private final UpdateChecker updateChecker;
|
||||
|
||||
public UpdateNotificationListener(ZNpcsPlus plugin, UpdateChecker updateChecker) {
|
||||
public UpdateNotificationListener(ZNpcsPlus plugin, BukkitAudiences adventure, UpdateChecker updateChecker) {
|
||||
this.plugin = plugin;
|
||||
this.adventure = adventure;
|
||||
this.updateChecker = updateChecker;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -25,7 +27,7 @@ public class UpdateNotificationListener implements Listener {
|
|||
if (updateChecker.getStatus() != UpdateChecker.Status.UPDATE_NEEDED) return;
|
||||
Bukkit.getScheduler().runTaskLater(plugin, () -> {
|
||||
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()
|
||||
.append(Component.text("Click this message to open the Spigot page (CLICK)", NamedTextColor.YELLOW)).clickEvent(ClickEvent.openUrl(UpdateChecker.DOWNLOAD_LINK)));
|
||||
}, 100L);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package lol.pyr.znpcsplus.user;
|
||||
|
||||
import lol.pyr.znpcsplus.interaction.NpcAction;
|
||||
import lol.pyr.znpcsplus.interaction.InteractionAction;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
@ -9,24 +9,6 @@ import java.util.Map;
|
|||
import java.util.UUID;
|
||||
|
||||
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 long lastNpcInteraction;
|
||||
private final Map<UUID, Long> actionCooldownMap = new HashMap<>();
|
||||
|
@ -51,7 +33,7 @@ public class User {
|
|||
return uuid;
|
||||
}
|
||||
|
||||
public boolean actionCooldownCheck(NpcAction action) {
|
||||
public boolean actionCooldownCheck(InteractionAction action) {
|
||||
UUID id = action.getUuid();
|
||||
if (System.currentTimeMillis() - actionCooldownMap.getOrDefault(id, 0L) >= action.getCooldown()) {
|
||||
actionCooldownMap.put(id, System.currentTimeMillis());
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
package lol.pyr.znpcsplus.user;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
public class UserListener implements Listener {
|
||||
public UserListener(ZNpcsPlus plugin) {
|
||||
Bukkit.getPluginManager().registerEvents(this, plugin);
|
||||
private final UserManager manager;
|
||||
|
||||
public UserListener(UserManager manager) {
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
User.get(event.getPlayer());
|
||||
manager.get(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
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;
|
||||
|
||||
import lol.pyr.znpcsplus.ZNpcsPlus;
|
||||
import lol.pyr.znpcsplus.reflection.Reflections;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
|
@ -24,7 +23,7 @@ public class FoliaUtil {
|
|||
else try {
|
||||
Reflections.FOLIA_TELEPORT_ASYNC.get().invoke(entity, location);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
ZNpcsPlus.LOGGER.severe("Error while teleporting entity:");
|
||||
System.err.println("Error while teleporting entity:");
|
||||
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