start with an api

This commit is contained in:
Pyrbu 2023-04-27 00:58:09 +01:00
parent baf6ea2622
commit 0c345935e6
85 changed files with 369 additions and 251 deletions

34
api/build.gradle Normal file

@ -0,0 +1,34 @@
plugins {
id "maven-publish"
}
dependencies {
compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT"
compileOnly "net.kyori:adventure-platform-bukkit:4.3.0"
compileOnly "com.github.retrooper.packetevents:spigot:2.0.0-SNAPSHOT"
}
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom {
name.set("znpcsplus")
description.set("A fork of the ZNPCs plugin")
url.set("https://github.com/Pyrbu/ZNPCsPlus")
}
}
}
repositories {
maven {
if (properties.containsKey("DIST_USERNAME") && properties.containsKey("DIST_PASSWORD")) {
credentials {
username properties.get("DIST_USERNAME")
password properties.get("DIST_PASSWORD")
}
}
url = uri("https://repo.pyr.lol/releases/")
}
}
}

@ -0,0 +1,11 @@
package lol.pyr.znpcsplus.api;
import net.kyori.adventure.text.Component;
public interface Hologram {
void addLine(Component line);
Component getLine(int index);
void removeLine(int index);
void clearLines();
void insertLine(int index, Component line);
}

@ -0,0 +1,14 @@
package lol.pyr.znpcsplus.api;
import lol.pyr.znpcsplus.api.npc.NPC;
import java.util.Collection;
public interface NPCRegistry {
NPC get(String id);
Collection<? extends NPC> all();
NPC getByEntityId(int id);
Collection<String> getRegisteredIds();
void register(String id, NPC npc);
void unregister(String id);
}

@ -0,0 +1,8 @@
package lol.pyr.znpcsplus.api;
import lol.pyr.znpcsplus.api.npc.EntityProperty;
public interface PropertyHolder {
<T> T getProperty(EntityProperty<T> key);
boolean hasProperty(EntityProperty<?> key);
}

@ -0,0 +1,11 @@
package lol.pyr.znpcsplus.api;
import lol.pyr.znpcsplus.api.npc.NPC;
import lol.pyr.znpcsplus.api.npc.NPCType;
import lol.pyr.znpcsplus.util.ZLocation;
import org.bukkit.World;
public interface ZApi {
NPCRegistry getNPCRegistry();
NPC createNPC(World world, NPCType type, ZLocation location);
}

@ -0,0 +1,25 @@
package lol.pyr.znpcsplus.api;
public class ZApiProvider {
private static ZApi plugin = null;
private ZApiProvider() {
throw new UnsupportedOperationException();
}
public static ZApi get() {
if (plugin == null) throw new IllegalStateException(
"ZNPCsPlus plugin isn't enabled yet!\n" +
"Please add it to your plugin.yml as a depend or softdepend."
);
return plugin;
}
public static void register(ZApi plugin) {
ZApiProvider.plugin = plugin;
}
public static void unregister() {
ZApiProvider.plugin = null;
}
}

@ -1,6 +1,6 @@
package lol.pyr.znpcsplus.entity; package lol.pyr.znpcsplus.api.npc;
import lol.pyr.znpcsplus.skin.SkinDescriptor; import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;

@ -0,0 +1,8 @@
package lol.pyr.znpcsplus.api.npc;
import lol.pyr.znpcsplus.api.Hologram;
import lol.pyr.znpcsplus.api.PropertyHolder;
public interface NPC extends PropertyHolder {
Hologram getHologram();
}

@ -1,10 +1,9 @@
package lol.pyr.znpcsplus.npc; package lol.pyr.znpcsplus.api.npc;
import com.github.retrooper.packetevents.PacketEvents; import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.manager.server.ServerVersion; import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.type.EntityType; import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.znpcsplus.entity.EntityProperty;
import java.util.*; import java.util.*;
@ -47,26 +46,31 @@ public class NPCType {
return allowedProperties; return allowedProperties;
} }
private static void register(Builder builder) { private static NPCType define(Builder builder) {
register(builder.build()); return define(builder.build());
} }
private static void register(NPCType type) { private static NPCType define(NPCType type) {
BY_NAME.put(type.getName(), type); BY_NAME.put(type.getName(), type);
return type;
} }
static { public static final NPCType PLAYER = define(
register(new Builder("player", EntityTypes.PLAYER) new Builder("player", EntityTypes.PLAYER)
.addProperties(EntityProperty.SKIN, EntityProperty.SKIN_LAYERS) .addProperties(EntityProperty.SKIN, EntityProperty.SKIN_LAYERS)
.setHologramOffset(-0.45D)); .setHologramOffset(-0.45D));
register(new Builder("creeper", EntityTypes.CREEPER)
.setHologramOffset(-0.6D)); public static final NPCType CREEPER = define(
register(new Builder("zombie", EntityTypes.ZOMBIE) new Builder("creeper", EntityTypes.CREEPER)
.setHologramOffset(-0.3D)); .setHologramOffset(-0.6D));
register(new Builder("skeleton", EntityTypes.SKELETON)
.setHologramOffset(-0.3D)); public static final NPCType ZOMBIE = define(
} new Builder("zombie", EntityTypes.ZOMBIE)
.setHologramOffset(-0.3D));
public static final NPCType SKELETON = define(
new Builder("skeleton", EntityTypes.SKELETON)
.setHologramOffset(-0.3D));
private static final class Builder { private static final class Builder {
private final String name; private final String name;

@ -0,0 +1,4 @@
package lol.pyr.znpcsplus.api.skin;
public interface SkinDescriptor {
}

@ -1,19 +1,18 @@
package lol.pyr.znpcsplus.entity; package lol.pyr.znpcsplus.util;
import com.github.retrooper.packetevents.util.Vector3d; import com.github.retrooper.packetevents.util.Vector3d;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.util.NumberConversions; import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
public class PacketLocation { public class ZLocation {
private final double x; private final double x;
private final double y; private final double y;
private final double z; private final double z;
private final float yaw; private final float yaw;
private final float pitch; private final float pitch;
public PacketLocation(double x, double y, double z, float yaw, float pitch) { public ZLocation(double x, double y, double z, float yaw, float pitch) {
this.x = x; this.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
@ -21,7 +20,7 @@ public class PacketLocation {
this.pitch = pitch; this.pitch = pitch;
} }
public PacketLocation(Location location) { public ZLocation(Location location) {
this(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); this(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
} }
@ -49,12 +48,8 @@ public class PacketLocation {
return new Location(world, this.x, this.y, this.z, this.yaw, this.pitch); return new Location(world, this.x, this.y, this.z, this.yaw, this.pitch);
} }
public PacketLocation withY(double y) { public ZLocation withY(double y) {
return new PacketLocation(x, y, z, yaw, pitch); return new ZLocation(x, y, z, yaw, pitch);
}
public Vector toVector() {
return new Vector(x, y, z);
} }
public Vector3d toVector3d() { public Vector3d toVector3d() {
@ -64,16 +59,16 @@ public class PacketLocation {
private static final double _2PI = 2 * Math.PI; private static final double _2PI = 2 * Math.PI;
public Location lookingAt(Location loc) { public Location lookingAt(Location loc) {
return lookingAt(new PacketLocation(loc)).toBukkitLocation(loc.getWorld()); return lookingAt(new ZLocation(loc)).toBukkitLocation(loc.getWorld());
} }
public PacketLocation lookingAt(PacketLocation loc) { public ZLocation lookingAt(ZLocation loc) {
final double x = loc.getX() - this.x; final double x = loc.getX() - this.x;
final double z = loc.getZ() - this.z; final double z = loc.getZ() - this.z;
final double y = loc.getY() - this.y; final double y = loc.getY() - this.y;
if (x == 0 && z == 0) { if (x == 0 && z == 0) {
return new PacketLocation(this.x, this.y, this.z, this.yaw, y > 0 ? -90 : 90); return new ZLocation(this.x, this.y, this.z, this.yaw, y > 0 ? -90 : 90);
} }
double x2 = NumberConversions.square(x); double x2 = NumberConversions.square(x);
@ -84,6 +79,6 @@ public class PacketLocation {
float yaw = (float) Math.toDegrees((theta + _2PI) % _2PI); float yaw = (float) Math.toDegrees((theta + _2PI) % _2PI);
float pitch = (float) Math.toDegrees(Math.atan(-y / xz)); float pitch = (float) Math.toDegrees(Math.atan(-y / xz));
return new PacketLocation(this.x, this.y, this.z, yaw, pitch); return new ZLocation(this.x, this.y, this.z, yaw, pitch);
} }
} }

@ -1,103 +1,20 @@
plugins { subprojects {
id "java" apply plugin: "java"
id "maven-publish"
id "com.github.johnrengelman.shadow" version "8.1.1"
id "xyz.jpenilla.run-paper" version "2.0.1"
}
repositories { group "lol.pyr"
mavenCentral() version "1.0.5"
maven {
url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" compileJava {
options.release.set(16)
} }
maven {
url "https://repo.papermc.io/repository/maven-public/"
}
maven {
url "https://repo.extendedclip.com/content/repositories/placeholderapi/"
}
maven {
url "https://repo.codemc.io/repository/maven-snapshots/"
}
maven {
url "https://jitpack.io/"
}
}
dependencies {
compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT"
compileOnly "me.clip:placeholderapi:2.11.1"
compileOnly "com.mojang:authlib:3.4.40"
compileOnly "com.mojang:datafixerupper:6.0.8"
implementation "commons-io:commons-io:2.11.0"
implementation "com.google.code.gson:gson:2.10.1"
implementation "org.bstats:bstats-bukkit:3.0.2"
implementation "com.github.robertlit:SpigotResourcesAPI:2.0"
implementation "net.kyori:adventure-platform-bukkit:4.3.0"
implementation "net.kyori:adventure-text-minimessage:4.13.1"
implementation "com.github.retrooper.packetevents:spigot:2.0.0-SNAPSHOT"
implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1"
}
group "lol.pyr"
version "1.0.5"
compileJava {
options.release.set(17)
}
shadowJar {
archiveClassifier.set ""
relocate "org.bstats", "lol.pyr.znpcsplus.lib.bstats"
relocate "org.apache.commons", "lol.pyr.znpcsplus.lib.commons"
relocate "me.robertlit.spigotresources", "lol.pyr.znpcsplus.lib.spigotresources"
relocate "net.kyori", "lol.pyr.znpcsplus.lib.kyori"
relocate "org.checkerframework", "lol.pyr.znpcsplus.lib.checkerframework"
relocate "javax.annotation", "lol.pyr.znpcsplus.lib.javaxannotation"
relocate "com.google", "lol.pyr.znpcsplus.lib.google"
relocate "com.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.api"
relocate "io.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.impl"
relocate "org.yaml.snakeyaml", "lol.pyr.znpcsplus.lib.snakeyaml"
relocate "space.arim.dazzleconf", "lol.pyr.znpcsplus.lib.dazzleconf"
minimize()
}
processResources {
expand("version": version)
}
runServer {
minecraftVersion "1.19.4"
}
tasks.assemble.dependsOn shadowJar
tasks.compileJava.dependsOn clean
publishing {
publications {
mavenJava(MavenPublication) {
from components.java
pom {
name.set("znpcsplus")
description.set("A fork of the ZNPCs plugin")
url.set("https://github.com/Pyrbu/ZNPCsPlus")
}
}
}
repositories { repositories {
mavenCentral()
maven { maven {
if (properties.containsKey("DIST_USERNAME") && properties.containsKey("DIST_PASSWORD")) { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/"
credentials { }
username properties.get("DIST_USERNAME") maven {
password properties.get("DIST_PASSWORD") url "https://repo.codemc.io/repository/maven-snapshots/"
}
}
url = uri("https://repo.pyr.lol/releases/")
} }
} }
} }

64
plugin/build.gradle Normal file

@ -0,0 +1,64 @@
plugins {
id "com.github.johnrengelman.shadow" version "8.1.1"
id "xyz.jpenilla.run-paper" version "2.0.1"
}
repositories {
maven {
url "https://repo.extendedclip.com/content/repositories/placeholderapi/"
}
maven {
url "https://jitpack.io/"
}
maven {
url "https://repo.papermc.io/repository/maven-public/"
}
}
dependencies {
compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT"
compileOnly "me.clip:placeholderapi:2.11.1"
compileOnly "com.mojang:authlib:3.4.40"
compileOnly "com.mojang:datafixerupper:4.0.26"
implementation "commons-io:commons-io:2.11.0"
implementation "com.google.code.gson:gson:2.10.1"
implementation "org.bstats:bstats-bukkit:3.0.2"
implementation "com.github.robertlit:SpigotResourcesAPI:2.0"
implementation "net.kyori:adventure-platform-bukkit:4.3.0"
implementation "net.kyori:adventure-text-minimessage:4.13.1"
implementation "com.github.retrooper.packetevents:spigot:2.0.0-SNAPSHOT"
implementation "space.arim.dazzleconf:dazzleconf-ext-snakeyaml:1.2.1"
implementation project(":api")
}
shadowJar {
archiveClassifier.set ""
relocate "org.bstats", "lol.pyr.znpcsplus.lib.bstats"
relocate "org.apache.commons", "lol.pyr.znpcsplus.lib.commons"
relocate "me.robertlit.spigotresources", "lol.pyr.znpcsplus.lib.spigotresources"
relocate "net.kyori", "lol.pyr.znpcsplus.lib.kyori"
relocate "org.checkerframework", "lol.pyr.znpcsplus.lib.checkerframework"
relocate "javax.annotation", "lol.pyr.znpcsplus.lib.javaxannotation"
relocate "com.google", "lol.pyr.znpcsplus.lib.google"
relocate "com.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.api"
relocate "io.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents.impl"
relocate "org.yaml.snakeyaml", "lol.pyr.znpcsplus.lib.snakeyaml"
relocate "space.arim.dazzleconf", "lol.pyr.znpcsplus.lib.dazzleconf"
minimize()
}
processResources {
expand("version": version)
}
runServer {
minecraftVersion "1.19.4"
}
tasks.assemble.dependsOn shadowJar
tasks.compileJava.dependsOn clean

@ -0,0 +1,20 @@
package lol.pyr.znpcsplus;
import lol.pyr.znpcsplus.api.ZApi;
import lol.pyr.znpcsplus.api.NPCRegistry;
import lol.pyr.znpcsplus.api.npc.NPC;
import lol.pyr.znpcsplus.api.npc.NPCType;
import lol.pyr.znpcsplus.util.ZLocation;
import org.bukkit.World;
public class ZNPCsApi implements ZApi {
@Override
public NPCRegistry getNPCRegistry() {
return lol.pyr.znpcsplus.npc.NPCRegistry.get();
}
@Override
public NPC createNPC(World world, NPCType type, ZLocation location) {
return new lol.pyr.znpcsplus.npc.NPC(world, type, location);
}
}

@ -7,15 +7,15 @@ import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder
import io.github.znetworkw.znpcservers.listeners.InventoryListener; import io.github.znetworkw.znpcservers.listeners.InventoryListener;
import io.github.znetworkw.znpcservers.utility.BungeeUtils; import io.github.znetworkw.znpcservers.utility.BungeeUtils;
import io.github.znetworkw.znpcservers.utility.SchedulerUtils; import io.github.znetworkw.znpcservers.utility.SchedulerUtils;
import lol.pyr.znpcsplus.api.ZApiProvider;
import lol.pyr.znpcsplus.api.npc.EntityProperty;
import lol.pyr.znpcsplus.api.npc.NPCType;
import lol.pyr.znpcsplus.config.Configs; import lol.pyr.znpcsplus.config.Configs;
import lol.pyr.znpcsplus.entity.EntityProperty;
import lol.pyr.znpcsplus.entity.PacketLocation;
import lol.pyr.znpcsplus.interaction.InteractionPacketListener; import lol.pyr.znpcsplus.interaction.InteractionPacketListener;
import lol.pyr.znpcsplus.interaction.types.ConsoleCommandAction; import lol.pyr.znpcsplus.interaction.types.ConsoleCommandAction;
import lol.pyr.znpcsplus.interaction.types.MessageAction; import lol.pyr.znpcsplus.interaction.types.MessageAction;
import lol.pyr.znpcsplus.npc.NPC; import lol.pyr.znpcsplus.npc.NPC;
import lol.pyr.znpcsplus.npc.NPCRegistry; import lol.pyr.znpcsplus.npc.NPCRegistry;
import lol.pyr.znpcsplus.npc.NPCType;
import lol.pyr.znpcsplus.skin.cache.SkinCache; import lol.pyr.znpcsplus.skin.cache.SkinCache;
import lol.pyr.znpcsplus.skin.cache.SkinCacheCleanTask; import lol.pyr.znpcsplus.skin.cache.SkinCacheCleanTask;
import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor; import lol.pyr.znpcsplus.skin.descriptor.FetchingDescriptor;
@ -26,6 +26,7 @@ import lol.pyr.znpcsplus.updater.UpdateChecker;
import lol.pyr.znpcsplus.updater.UpdateNotificationListener; import lol.pyr.znpcsplus.updater.UpdateNotificationListener;
import lol.pyr.znpcsplus.user.User; import lol.pyr.znpcsplus.user.User;
import lol.pyr.znpcsplus.user.UserListener; import lol.pyr.znpcsplus.user.UserListener;
import lol.pyr.znpcsplus.util.ZLocation;
import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
@ -126,6 +127,7 @@ public class ZNPCsPlus extends JavaPlugin {
new UserListener(this); new UserListener(this);
if (Configs.config().checkForUpdates()) new UpdateNotificationListener(this, new UpdateChecker(this)); if (Configs.config().checkForUpdates()) new UpdateNotificationListener(this, new UpdateChecker(this));
ZApiProvider.register(new ZNPCsApi());
enabled = true; enabled = true;
log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)"); log(ChatColor.WHITE + " * Loading complete! (" + (System.currentTimeMillis() - before) + "ms)");
log(""); log("");
@ -137,7 +139,7 @@ public class ZNPCsPlus extends JavaPlugin {
World world = Bukkit.getWorld("world"); World world = Bukkit.getWorld("world");
if (world == null) world = Bukkit.getWorlds().get(0); if (world == null) world = Bukkit.getWorlds().get(0);
for (NPCType type : NPCType.values()) { for (NPCType type : NPCType.values()) {
NPC npc = new NPC(world, type, new PacketLocation(x * 3, 200, z * 3, 0, 0)); NPC npc = new NPC(world, type, new ZLocation(x * 3, 200, z * 3, 0, 0));
if (type.getType() == EntityTypes.PLAYER) { if (type.getType() == EntityTypes.PLAYER) {
SkinCache.fetchByName("Notch").thenAccept(skin -> npc.setProperty(EntityProperty.SKIN, new PrefetchedDescriptor(skin))); SkinCache.fetchByName("Notch").thenAccept(skin -> npc.setProperty(EntityProperty.SKIN, new PrefetchedDescriptor(skin)));
npc.setProperty(EntityProperty.INVISIBLE, true); npc.setProperty(EntityProperty.INVISIBLE, true);
@ -145,27 +147,28 @@ public class ZNPCsPlus extends JavaPlugin {
npc.setProperty(EntityProperty.GLOW, NamedTextColor.RED); npc.setProperty(EntityProperty.GLOW, NamedTextColor.RED);
// npc.setProperty(EntityProperty.FIRE, true); // npc.setProperty(EntityProperty.FIRE, true);
npc.getHologram().addLine(Component.text("Hello, World!")); npc.getHologram().addLine(Component.text("Hello, World!"));
NPCRegistry.register("debug_npc" + (z * wrap + x), npc); NPCRegistry.get().register("debug_npc" + (z * wrap + x), npc);
if (x++ > wrap) { if (x++ > wrap) {
x = 0; x = 0;
z++; z++;
} }
} }
NPC npc = new NPC(world, NPCType.byName("player"), new PacketLocation(x * 3, 200, z * 3, 0, 0)); NPC npc = new NPC(world, NPCType.byName("player"), new ZLocation(x * 3, 200, z * 3, 0, 0));
npc.setProperty(EntityProperty.SKIN, new FetchingDescriptor("jeb_")); npc.setProperty(EntityProperty.SKIN, new FetchingDescriptor("jeb_"));
npc.addAction(new MessageAction(1000L, "<red>Hi, I'm jeb!")); npc.addAction(new MessageAction(1000L, "<red>Hi, I'm jeb!"));
NPCRegistry.register("debug_npc" + (z * wrap + x), npc); NPCRegistry.get().register("debug_npc" + (z * wrap + x), npc);
x++; x++;
npc = new NPC(world, NPCType.byName("player"), new PacketLocation(x * 3, 200, z * 3, 0, 0)); npc = new NPC(world, NPCType.byName("player"), new ZLocation(x * 3, 200, z * 3, 0, 0));
npc.setProperty(EntityProperty.SKIN, new MirrorDescriptor()); npc.setProperty(EntityProperty.SKIN, new MirrorDescriptor());
npc.addAction(new ConsoleCommandAction(1000L, "kick {player}")); npc.addAction(new ConsoleCommandAction(1000L, "kick {player}"));
NPCRegistry.register("debug_npc" + (z * wrap + x), npc); NPCRegistry.get().register("debug_npc" + (z * wrap + x), npc);
} }
} }
@Override @Override
public void onDisable() { public void onDisable() {
if (!enabled) return; if (!enabled) return;
ZApiProvider.unregister();
Bukkit.getOnlinePlayers().forEach(User::remove); Bukkit.getOnlinePlayers().forEach(User::remove);
ADVENTURE.close(); ADVENTURE.close();
ADVENTURE = null; ADVENTURE = null;

@ -4,7 +4,9 @@ import com.github.retrooper.packetevents.protocol.entity.type.EntityType;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import io.github.znetworkw.znpcservers.reflection.Reflections; import io.github.znetworkw.znpcservers.reflection.Reflections;
import io.github.znetworkw.znpcservers.utility.Utils; import io.github.znetworkw.znpcservers.utility.Utils;
import lol.pyr.znpcsplus.api.PropertyHolder;
import lol.pyr.znpcsplus.packets.PacketFactory; import lol.pyr.znpcsplus.packets.PacketFactory;
import lol.pyr.znpcsplus.util.ZLocation;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Collection; import java.util.Collection;
@ -16,9 +18,9 @@ public class PacketEntity {
private final UUID uuid; private final UUID uuid;
private final EntityType type; private final EntityType type;
private PacketLocation location; private ZLocation location;
public PacketEntity(PropertyHolder properties, EntityType type, PacketLocation location) { public PacketEntity(PropertyHolder properties, EntityType type, ZLocation location) {
this.properties = properties; this.properties = properties;
this.entityId = reserveEntityID(); this.entityId = reserveEntityID();
this.uuid = UUID.randomUUID(); this.uuid = UUID.randomUUID();
@ -30,7 +32,7 @@ public class PacketEntity {
return entityId; return entityId;
} }
public PacketLocation getLocation() { public ZLocation getLocation() {
return location; return location;
} }
@ -42,7 +44,7 @@ public class PacketEntity {
return type; return type;
} }
public void setLocation(PacketLocation location, Collection<Player> viewers) { public void setLocation(ZLocation location, Collection<Player> viewers) {
this.location = location; this.location = location;
for (Player viewer : viewers) PacketFactory.get().teleportEntity(viewer, this); for (Player viewer : viewers) PacketFactory.get().teleportEntity(viewer, this);
} }

@ -1,7 +1,7 @@
package lol.pyr.znpcsplus.hologram; package lol.pyr.znpcsplus.hologram;
import lol.pyr.znpcsplus.config.Configs; import lol.pyr.znpcsplus.config.Configs;
import lol.pyr.znpcsplus.entity.PacketLocation; import lol.pyr.znpcsplus.util.ZLocation;
import lol.pyr.znpcsplus.util.Viewable; import lol.pyr.znpcsplus.util.Viewable;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -10,11 +10,11 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
public class Hologram extends Viewable { public class Hologram extends Viewable implements lol.pyr.znpcsplus.api.Hologram {
private PacketLocation location; private ZLocation location;
private final List<HologramLine> lines = new ArrayList<>(); private final List<HologramLine> lines = new ArrayList<>();
public Hologram(PacketLocation location) { public Hologram(ZLocation location) {
this.location = location; this.location = location;
} }
@ -25,8 +25,8 @@ public class Hologram extends Viewable {
for (Player viewer : getViewers()) newLine.show(viewer.getPlayer()); for (Player viewer : getViewers()) newLine.show(viewer.getPlayer());
} }
public HologramLine getLine(int index) { public Component getLine(int index) {
return lines.get(index); return lines.get(index).getText();
} }
public void removeLine(int index) { public void removeLine(int index) {
@ -57,7 +57,7 @@ public class Hologram extends Viewable {
for (HologramLine line : lines) line.hide(player); for (HologramLine line : lines) line.hide(player);
} }
public void setLocation(PacketLocation location) { public void setLocation(ZLocation location) {
this.location = location; this.location = location;
relocateLines(); relocateLines();
} }

@ -1,10 +1,10 @@
package lol.pyr.znpcsplus.hologram; package lol.pyr.znpcsplus.hologram;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.znpcsplus.entity.EntityProperty; import lol.pyr.znpcsplus.api.PropertyHolder;
import lol.pyr.znpcsplus.api.npc.EntityProperty;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.entity.PacketLocation; import lol.pyr.znpcsplus.util.ZLocation;
import lol.pyr.znpcsplus.entity.PropertyHolder;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -14,7 +14,7 @@ public class HologramLine implements PropertyHolder {
private Component text; private Component text;
private final PacketEntity armorStand; private final PacketEntity armorStand;
public HologramLine(PacketLocation location, Component text) { public HologramLine(ZLocation location, Component text) {
this.text = text; this.text = text;
armorStand = new PacketEntity(this, EntityTypes.ARMOR_STAND, location); armorStand = new PacketEntity(this, EntityTypes.ARMOR_STAND, location);
} }
@ -35,20 +35,20 @@ public class HologramLine implements PropertyHolder {
armorStand.despawn(player); armorStand.despawn(player);
} }
public void setLocation(PacketLocation location, Collection<Player> viewers) { public void setLocation(ZLocation location, Collection<Player> viewers) {
armorStand.setLocation(location, viewers); armorStand.setLocation(location, viewers);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public <T> T getProperty(EntityProperty<T> key) { public <T> T getProperty(EntityProperty<T> key) {
if (key == EntityProperty.INVISIBLE) return (T) Boolean.TRUE; if (key == lol.pyr.znpcsplus.api.npc.EntityProperty.INVISIBLE) return (T) Boolean.TRUE;
if (key == EntityProperty.NAME) return (T) text; if (key == lol.pyr.znpcsplus.api.npc.EntityProperty.NAME) return (T) text;
return key.getDefaultValue(); return key.getDefaultValue();
} }
@Override @Override
public boolean hasProperty(EntityProperty<?> key) { public boolean hasProperty(EntityProperty<?> key) {
return key == EntityProperty.NAME || key == EntityProperty.INVISIBLE; return key == lol.pyr.znpcsplus.api.npc.EntityProperty.NAME || key == lol.pyr.znpcsplus.api.npc.EntityProperty.INVISIBLE;
} }
} }

@ -20,7 +20,7 @@ public class InteractionPacketListener implements PacketListener {
User user = User.get(player); User user = User.get(player);
if (!user.canInteract()) return; if (!user.canInteract()) return;
NPC npc = NPCRegistry.getByEntityId(packet.getEntityId()); NPC npc = NPCRegistry.get().getByEntityId(packet.getEntityId());
if (npc == null) return; if (npc == null) return;
ZNPCsPlus.SCHEDULER.runNextTick(() -> { ZNPCsPlus.SCHEDULER.runNextTick(() -> {

@ -1,32 +1,32 @@
package lol.pyr.znpcsplus.npc; package lol.pyr.znpcsplus.npc;
import lol.pyr.znpcsplus.entity.EntityProperty; import lol.pyr.znpcsplus.api.npc.EntityProperty;
import lol.pyr.znpcsplus.api.npc.NPCType;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.entity.PacketLocation;
import lol.pyr.znpcsplus.entity.PropertyHolder;
import lol.pyr.znpcsplus.hologram.Hologram; import lol.pyr.znpcsplus.hologram.Hologram;
import lol.pyr.znpcsplus.interaction.NPCAction; import lol.pyr.znpcsplus.interaction.NPCAction;
import lol.pyr.znpcsplus.util.Viewable; import lol.pyr.znpcsplus.util.Viewable;
import lol.pyr.znpcsplus.util.ZLocation;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.*; import java.util.*;
public class NPC extends Viewable implements PropertyHolder { public class NPC extends Viewable implements lol.pyr.znpcsplus.api.npc.NPC {
protected static final Set<NPC> _ALL_NPCS = new HashSet<>(); protected static final Set<NPC> _ALL_NPCS = new HashSet<>();
private final Set<Player> viewers = new HashSet<>(); private final Set<Player> viewers = new HashSet<>();
private final String worldName; private final String worldName;
private PacketEntity entity; private PacketEntity entity;
private PacketLocation location; private ZLocation location;
private NPCType type; private NPCType type;
private final Hologram hologram; private final Hologram hologram;
private final Map<EntityProperty<?>, Object> propertyMap = new HashMap<>(); private final Map<EntityProperty<?>, Object> propertyMap = new HashMap<>();
private final Set<NPCAction> actions = new HashSet<>(); private final Set<NPCAction> actions = new HashSet<>();
public NPC(World world, NPCType type, PacketLocation location) { public NPC(World world, NPCType type, ZLocation location) {
this.worldName = world.getName(); this.worldName = world.getName();
this.type = type; this.type = type;
this.location = location; this.location = location;
@ -50,11 +50,11 @@ public class NPC extends Viewable implements PropertyHolder {
return entity; return entity;
} }
public PacketLocation getLocation() { public ZLocation getLocation() {
return location; return location;
} }
public void setLocation(PacketLocation location) { public void setLocation(ZLocation location) {
this.location = location; this.location = location;
entity.setLocation(location, viewers); entity.setLocation(location, viewers);
hologram.setLocation(location.withY(location.getY() + type.getHologramOffset())); hologram.setLocation(location.withY(location.getY() + type.getHologramOffset()));

@ -0,0 +1,46 @@
package lol.pyr.znpcsplus.npc;
import lol.pyr.znpcsplus.api.npc.NPC;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class NPCRegistry implements lol.pyr.znpcsplus.api.NPCRegistry {
private final static NPCRegistry registry = new NPCRegistry();
public static NPCRegistry get() {
return registry;
}
private final Map<String, NPC> npcMap = new HashMap<>();
private NPCRegistry() {
if (registry != null) throw new UnsupportedOperationException("This class can only be instanciated once!");
}
public NPC get(String id) {
return npcMap.get(id);
}
public Collection<lol.pyr.znpcsplus.npc.NPC> all() {
return Collections.unmodifiableSet(lol.pyr.znpcsplus.npc.NPC._ALL_NPCS);
}
public lol.pyr.znpcsplus.npc.NPC getByEntityId(int id) {
return all().stream().filter(npc -> npc.getEntity().getEntityId() == id).findFirst().orElse(null);
}
public Collection<String> getRegisteredIds() {
return Collections.unmodifiableSet(npcMap.keySet());
}
public void register(String id, NPC npc) {
npcMap.put(id, npc);
}
public void unregister(String id) {
npcMap.remove(id);
}
}

@ -5,7 +5,7 @@ import com.github.retrooper.packetevents.manager.server.ServerVersion;
import com.github.retrooper.packetevents.protocol.entity.data.EntityData; import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import lol.pyr.znpcsplus.ZNPCsPlus; import lol.pyr.znpcsplus.ZNPCsPlus;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.entity.PropertyHolder; import lol.pyr.znpcsplus.api.PropertyHolder;
import lol.pyr.znpcsplus.util.LazyLoader; import lol.pyr.znpcsplus.util.LazyLoader;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

@ -2,9 +2,9 @@ package lol.pyr.znpcsplus.packets;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerSpawnEntity;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.entity.PacketLocation; import lol.pyr.znpcsplus.util.ZLocation;
import lol.pyr.znpcsplus.entity.EntityProperty; import lol.pyr.znpcsplus.api.npc.EntityProperty;
import lol.pyr.znpcsplus.entity.PropertyHolder; import lol.pyr.znpcsplus.api.PropertyHolder;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.Optional; import java.util.Optional;
@ -12,7 +12,7 @@ import java.util.Optional;
public class V1_14Factory extends V1_9Factory { public class V1_14Factory extends V1_9Factory {
@Override @Override
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) { public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
PacketLocation location = entity.getLocation(); ZLocation location = entity.getLocation();
sendPacket(player, new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(), sendPacket(player, new WrapperPlayServerSpawnEntity(entity.getEntityId(), Optional.of(entity.getUuid()), entity.getType(),
location.toVector3d(), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.empty())); location.toVector3d(), location.getPitch(), location.getYaw(), location.getYaw(), 0, Optional.empty()));
if (properties.hasProperty(EntityProperty.GLOW)) createTeam(player, entity, properties); if (properties.hasProperty(EntityProperty.GLOW)) createTeam(player, entity, properties);

@ -6,7 +6,7 @@ import com.github.retrooper.packetevents.protocol.player.UserProfile;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoRemove;
import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate; import com.github.retrooper.packetevents.wrapper.play.server.WrapperPlayServerPlayerInfoUpdate;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.entity.PropertyHolder; import lol.pyr.znpcsplus.api.PropertyHolder;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

@ -11,12 +11,12 @@ import com.github.retrooper.packetevents.util.Vector3d;
import com.github.retrooper.packetevents.wrapper.PacketWrapper; import com.github.retrooper.packetevents.wrapper.PacketWrapper;
import com.github.retrooper.packetevents.wrapper.play.server.*; import com.github.retrooper.packetevents.wrapper.play.server.*;
import lol.pyr.znpcsplus.ZNPCsPlus; import lol.pyr.znpcsplus.ZNPCsPlus;
import lol.pyr.znpcsplus.api.PropertyHolder;
import lol.pyr.znpcsplus.api.npc.EntityProperty;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.entity.PacketLocation;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.entity.EntityProperty; import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
import lol.pyr.znpcsplus.entity.PropertyHolder; import lol.pyr.znpcsplus.util.ZLocation;
import lol.pyr.znpcsplus.skin.SkinDescriptor;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -31,7 +31,7 @@ public class V1_8Factory implements PacketFactory {
public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) { public void spawnPlayer(Player player, PacketEntity entity, PropertyHolder properties) {
addTabPlayer(player, entity, properties).thenAccept(ignored -> { addTabPlayer(player, entity, properties).thenAccept(ignored -> {
createTeam(player, entity, properties); createTeam(player, entity, properties);
PacketLocation location = entity.getLocation(); ZLocation location = entity.getLocation();
sendPacket(player, new WrapperPlayServerSpawnPlayer(entity.getEntityId(), sendPacket(player, new WrapperPlayServerSpawnPlayer(entity.getEntityId(),
entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), List.of())); entity.getUuid(), location.toVector3d(), location.getYaw(), location.getPitch(), List.of()));
sendAllMetadata(player, entity, properties); sendAllMetadata(player, entity, properties);
@ -41,7 +41,7 @@ public class V1_8Factory implements PacketFactory {
@Override @Override
public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) { public void spawnEntity(Player player, PacketEntity entity, PropertyHolder properties) {
PacketLocation location = entity.getLocation(); ZLocation location = entity.getLocation();
EntityType type = entity.getType(); EntityType type = entity.getType();
ClientVersion clientVersion = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion(); ClientVersion clientVersion = PacketEvents.getAPI().getServerManager().getVersion().toClientVersion();
sendPacket(player, type.getLegacyId(clientVersion) == -1 ? sendPacket(player, type.getLegacyId(clientVersion) == -1 ?
@ -60,7 +60,7 @@ public class V1_8Factory implements PacketFactory {
@Override @Override
public void teleportEntity(Player player, PacketEntity entity) { public void teleportEntity(Player player, PacketEntity entity) {
PacketLocation location = entity.getLocation(); ZLocation location = entity.getLocation();
sendPacket(player, new WrapperPlayServerEntityTeleport(entity.getEntityId(), sendPacket(player, new WrapperPlayServerEntityTeleport(entity.getEntityId(),
location.toVector3d(), location.getYaw(), location.getPitch(), true)); location.toVector3d(), location.getYaw(), location.getPitch(), true));
} }
@ -127,7 +127,7 @@ public class V1_8Factory implements PacketFactory {
protected CompletableFuture<UserProfile> skinned(Player player, PropertyHolder properties, UserProfile profile) { protected CompletableFuture<UserProfile> skinned(Player player, PropertyHolder properties, UserProfile profile) {
if (!properties.hasProperty(EntityProperty.SKIN)) return CompletableFuture.completedFuture(profile); if (!properties.hasProperty(EntityProperty.SKIN)) return CompletableFuture.completedFuture(profile);
SkinDescriptor descriptor = properties.getProperty(EntityProperty.SKIN); BaseSkinDescriptor descriptor = (BaseSkinDescriptor) properties.getProperty(EntityProperty.SKIN);
if (descriptor.supportsInstant(player)) { if (descriptor.supportsInstant(player)) {
descriptor.fetchInstant(player).apply(profile); descriptor.fetchInstant(player).apply(profile);
return CompletableFuture.completedFuture(profile); return CompletableFuture.completedFuture(profile);

@ -4,8 +4,8 @@ import com.github.retrooper.packetevents.protocol.entity.data.EntityData;
import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes; import com.github.retrooper.packetevents.protocol.entity.type.EntityTypes;
import lol.pyr.znpcsplus.entity.PacketEntity; import lol.pyr.znpcsplus.entity.PacketEntity;
import lol.pyr.znpcsplus.metadata.MetadataFactory; import lol.pyr.znpcsplus.metadata.MetadataFactory;
import lol.pyr.znpcsplus.entity.EntityProperty; import lol.pyr.znpcsplus.api.npc.EntityProperty;
import lol.pyr.znpcsplus.entity.PropertyHolder; import lol.pyr.znpcsplus.api.PropertyHolder;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;

@ -4,7 +4,7 @@ import org.bukkit.entity.Player;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public interface SkinDescriptor { public interface BaseSkinDescriptor {
CompletableFuture<Skin> fetch(Player player); CompletableFuture<Skin> fetch(Player player);
Skin fetchInstant(Player player); Skin fetchInstant(Player player);
boolean supportsInstant(Player player); boolean supportsInstant(Player player);

@ -22,11 +22,11 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class SkinCache { public class SkinCache {
private final static Map<String, Skin> cache = new ConcurrentHashMap<>(); private final static Map<String, lol.pyr.znpcsplus.skin.Skin> cache = new ConcurrentHashMap<>();
private final static Map<String, CachedId> idCache = new ConcurrentHashMap<>(); private final static Map<String, CachedId> idCache = new ConcurrentHashMap<>();
public static void cleanCache() { public static void cleanCache() {
for (Map.Entry<String, Skin> entry : cache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey()); for (Map.Entry<String, lol.pyr.znpcsplus.skin.Skin> entry : cache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey());
for (Map.Entry<String, CachedId> entry : idCache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey()); for (Map.Entry<String, CachedId> entry : idCache.entrySet()) if (entry.getValue().isExpired()) cache.remove(entry.getKey());
} }
@ -68,16 +68,16 @@ public class SkinCache {
if (!idCache.containsKey(name)) return false; if (!idCache.containsKey(name)) return false;
CachedId id = idCache.get(name); CachedId id = idCache.get(name);
if (id.isExpired() || !cache.containsKey(id.getId())) return false; if (id.isExpired() || !cache.containsKey(id.getId())) return false;
Skin skin = cache.get(id.getId()); lol.pyr.znpcsplus.skin.Skin skin = cache.get(id.getId());
return !skin.isExpired(); return !skin.isExpired();
} }
public static Skin getFullyCachedByName(String s) { public static lol.pyr.znpcsplus.skin.Skin getFullyCachedByName(String s) {
String name = s.toLowerCase(); String name = s.toLowerCase();
if (!idCache.containsKey(name)) return null; if (!idCache.containsKey(name)) return null;
CachedId id = idCache.get(name); CachedId id = idCache.get(name);
if (id.isExpired() || !cache.containsKey(id.getId())) return null; if (id.isExpired() || !cache.containsKey(id.getId())) return null;
Skin skin = cache.get(id.getId()); lol.pyr.znpcsplus.skin.Skin skin = cache.get(id.getId());
if (skin.isExpired()) return null; if (skin.isExpired()) return null;
return skin; return skin;
} }
@ -87,7 +87,7 @@ public class SkinCache {
if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player)); if (player != null && player.isOnline()) return CompletableFuture.completedFuture(getFromPlayer(player));
if (cache.containsKey(uuid)) { if (cache.containsKey(uuid)) {
Skin skin = cache.get(uuid); lol.pyr.znpcsplus.skin.Skin skin = cache.get(uuid);
if (!skin.isExpired()) return CompletableFuture.completedFuture(skin); if (!skin.isExpired()) return CompletableFuture.completedFuture(skin);
} }
@ -98,7 +98,7 @@ public class SkinCache {
connection = (HttpURLConnection) url.openConnection(); connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET"); connection.setRequestMethod("GET");
try (Reader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)) { try (Reader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)) {
Skin skin = new Skin(JsonParser.parseReader(reader).getAsJsonObject()); lol.pyr.znpcsplus.skin.Skin skin = new lol.pyr.znpcsplus.skin.Skin(JsonParser.parseReader(reader).getAsJsonObject());
cache.put(uuid, skin); cache.put(uuid, skin);
return skin; return skin;
} }
@ -115,7 +115,7 @@ public class SkinCache {
try { try {
Object playerHandle = Reflections.GET_HANDLE_PLAYER_METHOD.get().invoke(player); Object playerHandle = Reflections.GET_HANDLE_PLAYER_METHOD.get().invoke(player);
GameProfile gameProfile = (GameProfile) Reflections.GET_PROFILE_METHOD.get().invoke(playerHandle, new Object[0]); GameProfile gameProfile = (GameProfile) Reflections.GET_PROFILE_METHOD.get().invoke(playerHandle, new Object[0]);
return new Skin(gameProfile.getProperties()); return new lol.pyr.znpcsplus.skin.Skin(gameProfile.getProperties());
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

@ -1,15 +1,16 @@
package lol.pyr.znpcsplus.skin.descriptor; package lol.pyr.znpcsplus.skin.descriptor;
import lol.pyr.znpcsplus.ZNPCsPlus; 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.Skin;
import lol.pyr.znpcsplus.skin.SkinDescriptor;
import lol.pyr.znpcsplus.skin.cache.SkinCache; import lol.pyr.znpcsplus.skin.cache.SkinCache;
import me.clip.placeholderapi.PlaceholderAPI; import me.clip.placeholderapi.PlaceholderAPI;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class FetchingDescriptor implements SkinDescriptor { public class FetchingDescriptor implements BaseSkinDescriptor, SkinDescriptor {
private final String name; private final String name;
public FetchingDescriptor(String name) { public FetchingDescriptor(String name) {

@ -1,13 +1,14 @@
package lol.pyr.znpcsplus.skin.descriptor; package lol.pyr.znpcsplus.skin.descriptor;
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
import lol.pyr.znpcsplus.skin.Skin; import lol.pyr.znpcsplus.skin.Skin;
import lol.pyr.znpcsplus.skin.SkinDescriptor;
import lol.pyr.znpcsplus.skin.cache.SkinCache; import lol.pyr.znpcsplus.skin.cache.SkinCache;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class MirrorDescriptor implements SkinDescriptor { public class MirrorDescriptor implements BaseSkinDescriptor, SkinDescriptor {
public MirrorDescriptor() {} public MirrorDescriptor() {}

@ -1,12 +1,13 @@
package lol.pyr.znpcsplus.skin.descriptor; package lol.pyr.znpcsplus.skin.descriptor;
import lol.pyr.znpcsplus.api.skin.SkinDescriptor;
import lol.pyr.znpcsplus.skin.BaseSkinDescriptor;
import lol.pyr.znpcsplus.skin.Skin; import lol.pyr.znpcsplus.skin.Skin;
import lol.pyr.znpcsplus.skin.SkinDescriptor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
public class PrefetchedDescriptor implements SkinDescriptor { public class PrefetchedDescriptor implements BaseSkinDescriptor, SkinDescriptor {
private final Skin skin; private final Skin skin;
public PrefetchedDescriptor(Skin skin) { public PrefetchedDescriptor(Skin skin) {

@ -16,7 +16,7 @@ public class NPCVisibilityTask extends BukkitRunnable {
public void run() { public void run() {
double distSq = NumberConversions.square(Configs.config().viewDistance()); double distSq = NumberConversions.square(Configs.config().viewDistance());
for (NPC npc : NPCRegistry.all()) for (Player player : Bukkit.getOnlinePlayers()) { for (NPC npc : NPCRegistry.get().all()) for (Player player : Bukkit.getOnlinePlayers()) {
boolean inRange = (player.getWorld() == npc.getWorld() && player.getLocation().distanceSquared(npc.getLocation().toBukkitLocation(npc.getWorld())) <= distSq); boolean inRange = (player.getWorld() == npc.getWorld() && player.getLocation().distanceSquared(npc.getLocation().toBukkitLocation(npc.getWorld())) <= distSq);
if (!inRange && npc.isShown(player)) npc.hide(player); if (!inRange && npc.isShown(player)) npc.hide(player);
if (inRange && !npc.isShown(player)) npc.show(player); if (inRange && !npc.isShown(player)) npc.show(player);

@ -1,2 +1,3 @@
rootProject.name = 'ZNPCsPlus' rootProject.name = "ZNPCsPlus"
include "api", "plugin"

@ -1,18 +0,0 @@
package lol.pyr.znpcsplus.entity;
public interface PropertyHolder {
<T> T getProperty(EntityProperty<T> key);
boolean hasProperty(EntityProperty<?> key);
PropertyHolder EMPTY = new PropertyHolder() {
@Override
public <T> T getProperty(EntityProperty<T> key) {
return null;
}
@Override
public boolean hasProperty(EntityProperty<?> key) {
return false;
}
};
}

@ -1,34 +0,0 @@
package lol.pyr.znpcsplus.npc;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class NPCRegistry {
private static final Map<String, NPC> npcMap = new HashMap<>();
public static NPC get(String id) {
return npcMap.get(id);
}
public static Collection<NPC> all() {
return Collections.unmodifiableSet(NPC._ALL_NPCS);
}
public static NPC getByEntityId(int id) {
return all().stream().filter(npc -> npc.getEntity().getEntityId() == id).findFirst().orElse(null);
}
public static Collection<String> ids() {
return Collections.unmodifiableSet(npcMap.keySet());
}
public static void register(String id, NPC npc) {
npcMap.put(id, npc);
}
public static void unregister(String id) {
npcMap.remove(id);
}
}