Merge branch 'Pyrbu:master' into master

This commit is contained in:
D3v1s0m 2023-04-22 23:44:26 +05:30 committed by GitHub
commit 333577bc43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 151 additions and 186 deletions

@ -15,6 +15,9 @@ repositories {
maven { maven {
url "https://repo.extendedclip.com/content/repositories/placeholderapi/" url "https://repo.extendedclip.com/content/repositories/placeholderapi/"
} }
maven {
url "https://repo.codemc.io/repository/maven-snapshots/"
}
maven { maven {
url "https://jitpack.io/" url "https://jitpack.io/"
} }
@ -24,8 +27,6 @@ dependencies {
compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT" compileOnly "org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT"
compileOnly "me.clip:placeholderapi:2.11.1" compileOnly "me.clip:placeholderapi:2.11.1"
//noinspection GradlePackageUpdate
compileOnly "io.netty:netty-all:4.1.87.Final"
compileOnly "com.mojang:authlib:3.4.40" compileOnly "com.mojang:authlib:3.4.40"
compileOnly "com.mojang:datafixerupper:6.0.8" compileOnly "com.mojang:datafixerupper:6.0.8"
@ -35,6 +36,7 @@ dependencies {
implementation "org.bstats:bstats-bukkit:3.0.2" implementation "org.bstats:bstats-bukkit:3.0.2"
implementation "com.github.robertlit:SpigotResourcesAPI:2.0" implementation "com.github.robertlit:SpigotResourcesAPI:2.0"
implementation "net.kyori:adventure-platform-bukkit:4.3.0" implementation "net.kyori:adventure-platform-bukkit:4.3.0"
implementation "com.github.retrooper.packetevents:spigot:2.0.0-SNAPSHOT"
} }
group "lol.pyr" group "lol.pyr"
@ -53,6 +55,7 @@ shadowJar {
relocate "org.checkerframework", "lol.pyr.znpcsplus.lib.checkerframework" relocate "org.checkerframework", "lol.pyr.znpcsplus.lib.checkerframework"
relocate "javax.annotation", "lol.pyr.znpcsplus.lib.javaxannotation" relocate "javax.annotation", "lol.pyr.znpcsplus.lib.javaxannotation"
relocate "com.google", "lol.pyr.znpcsplus.lib.google" relocate "com.google", "lol.pyr.znpcsplus.lib.google"
relocate "com.github.retrooper.packetevents", "lol.pyr.znpcsplus.lib.packetevents"
minimize() minimize()
} }

@ -1,7 +1,7 @@
package io.github.znetworkw.znpcservers.listeners; package io.github.znetworkw.znpcservers.listeners;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel; import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel;
import io.github.znetworkw.znpcservers.npc.event.NPCInteractEvent; import io.github.znetworkw.znpcservers.npc.interaction.NPCInteractEvent;
import io.github.znetworkw.znpcservers.user.EventService; import io.github.znetworkw.znpcservers.user.EventService;
import io.github.znetworkw.znpcservers.user.ZUser; import io.github.znetworkw.znpcservers.user.ZUser;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -12,7 +12,6 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@SuppressWarnings("deprecation")
public class PlayerListener implements Listener { public class PlayerListener implements Listener {
public PlayerListener(Plugin serversNPC) { public PlayerListener(Plugin serversNPC) {
serversNPC.getServer().getPluginManager().registerEvents(this, serversNPC); serversNPC.getServer().getPluginManager().registerEvents(this, serversNPC);

@ -8,7 +8,7 @@ import io.github.znetworkw.znpcservers.UnexpectedCallException;
import io.github.znetworkw.znpcservers.reflection.Reflections; import io.github.znetworkw.znpcservers.reflection.Reflections;
import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel; import io.github.znetworkw.znpcservers.npc.conversation.ConversationModel;
import io.github.znetworkw.znpcservers.npc.hologram.Hologram; import io.github.znetworkw.znpcservers.npc.hologram.Hologram;
import io.github.znetworkw.znpcservers.npc.packet.PacketCache; import io.github.znetworkw.znpcservers.npc.nms.PacketCache;
import io.github.znetworkw.znpcservers.user.ZUser; import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.Utils; import io.github.znetworkw.znpcservers.utility.Utils;
import io.github.znetworkw.znpcservers.utility.location.ZLocation; import io.github.znetworkw.znpcservers.utility.location.ZLocation;
@ -176,7 +176,7 @@ public class NPC {
try { try {
Object nmsWorld = Reflections.GET_HANDLE_WORLD_METHOD.get().invoke(getLocation().getWorld()); Object nmsWorld = Reflections.GET_HANDLE_WORLD_METHOD.get().invoke(getLocation().getWorld());
boolean isPlayer = (npcType == NPCType.PLAYER); boolean isPlayer = (npcType == NPCType.PLAYER);
this.nmsEntity = isPlayer ? this.packets.getProxyInstance().getPlayerPacket(nmsWorld, this.gameProfile) : (Utils.versionNewer(14) ? npcType.getConstructor().newInstance(npcType.getNmsEntityType(), nmsWorld) : npcType.getConstructor().newInstance(nmsWorld)); this.nmsEntity = isPlayer ? this.packets.getNms().getPlayerPacket(nmsWorld, this.gameProfile) : (Utils.versionNewer(14) ? npcType.getConstructor().newInstance(npcType.getNmsEntityType(), nmsWorld) : npcType.getConstructor().newInstance(nmsWorld));
this.bukkitEntity = Reflections.GET_BUKKIT_ENTITY_METHOD.get().invoke(this.nmsEntity); this.bukkitEntity = Reflections.GET_BUKKIT_ENTITY_METHOD.get().invoke(this.nmsEntity);
this.uuid = (UUID) Reflections.GET_UNIQUE_ID_METHOD.get().invoke(this.nmsEntity, new Object[0]); this.uuid = (UUID) Reflections.GET_UNIQUE_ID_METHOD.get().invoke(this.nmsEntity, new Object[0]);
if (isPlayer) { if (isPlayer) {
@ -193,7 +193,7 @@ public class NPC {
this.packets.flushCache("spawnPacket", "removeTab"); this.packets.flushCache("spawnPacket", "removeTab");
this.entityID = (Integer) Reflections.GET_ENTITY_ID.get().invoke(this.nmsEntity, new Object[0]); this.entityID = (Integer) Reflections.GET_ENTITY_ID.get().invoke(this.nmsEntity, new Object[0]);
FunctionFactory.findFunctionsForNpc(this).forEach(function -> function.resolve(this)); FunctionFactory.findFunctionsForNpc(this).forEach(function -> function.resolve(this));
getPackets().getProxyInstance().update(this.packets); getPackets().getNms().update(this.packets);
this.hologram.createHologram(); this.hologram.createHologram();
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException); throw new UnexpectedCallException(operationException);
@ -208,20 +208,20 @@ public class NPC {
this.viewers.add(user); this.viewers.add(user);
boolean npcIsPlayer = (this.npcPojo.getNpcType() == NPCType.PLAYER); boolean npcIsPlayer = (this.npcPojo.getNpcType() == NPCType.PLAYER);
if (FunctionFactory.isTrue(this, "glow") || npcIsPlayer) { if (FunctionFactory.isTrue(this, "glow") || npcIsPlayer) {
ImmutableList<Object> scoreboardPackets = this.packets.getProxyInstance().updateScoreboard(this); ImmutableList<Object> scoreboardPackets = this.packets.getNms().updateScoreboard(this);
scoreboardPackets.forEach(p -> Utils.sendPackets(user, p)); scoreboardPackets.forEach(p -> Utils.sendPackets(user, p));
} }
if (npcIsPlayer) { if (npcIsPlayer) {
if (FunctionFactory.isTrue(this, "mirror")) updateProfile(user.getGameProfile().getProperties()); if (FunctionFactory.isTrue(this, "mirror")) updateProfile(user.getGameProfile().getProperties());
Utils.sendPackets(user, this.tabConstructor, this.updateTabConstructor); Utils.sendPackets(user, this.tabConstructor, this.updateTabConstructor);
} }
Utils.sendPackets(user, this.packets.getProxyInstance().getSpawnPacket(this.nmsEntity, npcIsPlayer)); Utils.sendPackets(user, this.packets.getNms().getSpawnPacket(this.nmsEntity, npcIsPlayer));
if (FunctionFactory.isTrue(this, "holo")) this.hologram.spawn(user); if (FunctionFactory.isTrue(this, "holo")) this.hologram.spawn(user);
updateMetadata(Collections.singleton(user)); updateMetadata(Collections.singleton(user));
sendEquipPackets(user); sendEquipPackets(user);
lookAt(user, getLocation(), true); lookAt(user, getLocation(), true);
if (npcIsPlayer) { if (npcIsPlayer) {
Object removeTabPacket = this.packets.getProxyInstance().getTabRemovePacket(this.nmsEntity); Object removeTabPacket = this.packets.getNms().getTabRemovePacket(this.nmsEntity);
ZNPCsPlus.SCHEDULER.scheduleSyncDelayedTask(() -> Utils.sendPackets(user, removeTabPacket, this.updateTabConstructor), 60); ZNPCsPlus.SCHEDULER.scheduleSyncDelayedTask(() -> Utils.sendPackets(user, removeTabPacket, this.updateTabConstructor), 60);
} }
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
@ -238,9 +238,9 @@ public class NPC {
private void handleDelete(ZUser user) { private void handleDelete(ZUser user) {
try { try {
if (this.npcPojo.getNpcType() == NPCType.PLAYER) this.packets.getProxyInstance().getTabRemovePacket(this.nmsEntity); if (this.npcPojo.getNpcType() == NPCType.PLAYER) this.packets.getNms().getTabRemovePacket(this.nmsEntity);
this.hologram.delete(user); this.hologram.delete(user);
Utils.sendPackets(user, this.packets.getProxyInstance().getDestroyPacket(this.entityID)); Utils.sendPackets(user, this.packets.getNms().getDestroyPacket(this.entityID));
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException); throw new UnexpectedCallException(operationException);
} }
@ -267,7 +267,7 @@ public class NPC {
protected void updateMetadata(Iterable<ZUser> users) { protected void updateMetadata(Iterable<ZUser> users) {
try { try {
Object metaData = this.packets.getProxyInstance().getMetadataPacket(this.entityID, this.nmsEntity); Object metaData = this.packets.getNms().getMetadataPacket(this.entityID, this.nmsEntity);
for (ZUser user : users) Utils.sendPackets(user, metaData); for (ZUser user : users) Utils.sendPackets(user, metaData);
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
operationException.getCause().printStackTrace(); operationException.getCause().printStackTrace();
@ -290,7 +290,7 @@ public class NPC {
public void sendEquipPackets(ZUser zUser) { public void sendEquipPackets(ZUser zUser) {
if (this.npcPojo.getNpcEquip().isEmpty()) return; if (this.npcPojo.getNpcEquip().isEmpty()) return;
try { try {
ImmutableList<Object> equipPackets = this.packets.getProxyInstance().getEquipPackets(this); ImmutableList<Object> equipPackets = this.packets.getNms().getEquipPackets(this);
equipPackets.forEach(o -> Utils.sendPackets(zUser, o)); equipPackets.forEach(o -> Utils.sendPackets(zUser, o));
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException.getCause()); throw new UnexpectedCallException(operationException.getCause());
@ -314,7 +314,7 @@ public class NPC {
} }
public Location getLocation() { public Location getLocation() {
if (this.npcPath != null && this.npcPath.getLocation() != null) return this.npcPath.getLocation().bukkitLocation(); if (this.npcPath != null && this.npcPath.getLocation() != null) return this.npcPath.getLocation().bukkitLocation();
return this.npcPojo.getLocation().bukkitLocation(); return this.npcPojo.getLocation().bukkitLocation();
} }
} }

@ -2,7 +2,7 @@ package io.github.znetworkw.znpcservers.npc;
import com.google.common.base.MoreObjects; import com.google.common.base.MoreObjects;
import lol.pyr.znpcsplus.ZNPCsPlus; import lol.pyr.znpcsplus.ZNPCsPlus;
import io.github.znetworkw.znpcservers.npc.event.ClickType; import io.github.znetworkw.znpcservers.npc.interaction.ClickType;
import io.github.znetworkw.znpcservers.user.ZUser; import io.github.znetworkw.znpcservers.user.ZUser;
import io.github.znetworkw.znpcservers.utility.Utils; import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;

@ -26,7 +26,7 @@ public class GlowFunction extends NPCFunction {
.get().invoke(npc.getNmsEntity()), Reflections.DATA_WATCHER_OBJECT_CONSTRUCTOR .get().invoke(npc.getNmsEntity()), Reflections.DATA_WATCHER_OBJECT_CONSTRUCTOR
.get().newInstance(0, Reflections.DATA_WATCHER_REGISTER_FIELD .get().newInstance(0, Reflections.DATA_WATCHER_REGISTER_FIELD
.get()), (byte) (!FunctionFactory.isTrue(npc, this) ? 64 : 0)); .get()), (byte) (!FunctionFactory.isTrue(npc, this) ? 64 : 0));
npc.getPackets().getProxyInstance().update(npc.getPackets()); npc.getPackets().getNms().update(npc.getPackets());
npc.deleteViewers(); npc.deleteViewers();
return NPCFunction.ResultType.SUCCESS; return NPCFunction.ResultType.SUCCESS;
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
@ -35,7 +35,7 @@ public class GlowFunction extends NPCFunction {
} }
protected boolean allow(NPC npc) { protected boolean allow(NPC npc) {
return npc.getPackets().getProxyInstance().allowGlowColor(); return npc.getPackets().getNms().allowGlowColor();
} }
public NPCFunction.ResultType resolve(NPC npc) { public NPCFunction.ResultType resolve(NPC npc) {

@ -56,7 +56,7 @@ public class Hologram {
public void spawn(ZUser user) { public void spawn(ZUser user) {
this.hologramLines.forEach(hologramLine -> { this.hologramLines.forEach(hologramLine -> {
try { try {
Object entityPlayerPacketSpawn = this.npc.getPackets().getProxyInstance().getHologramSpawnPacket(hologramLine.armorStand); Object entityPlayerPacketSpawn = this.npc.getPackets().getNms().getHologramSpawnPacket(hologramLine.armorStand);
Utils.sendPackets(user, entityPlayerPacketSpawn); Utils.sendPackets(user, entityPlayerPacketSpawn);
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
delete(user); delete(user);
@ -67,7 +67,7 @@ public class Hologram {
public void delete(ZUser user) { public void delete(ZUser user) {
this.hologramLines.forEach(hologramLine -> { this.hologramLines.forEach(hologramLine -> {
try { try {
Utils.sendPackets(user, this.npc.getPackets().getProxyInstance().getDestroyPacket(hologramLine.id)); Utils.sendPackets(user, this.npc.getPackets().getNms().getDestroyPacket(hologramLine.id));
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException); throw new UnexpectedCallException(operationException);
} }
@ -78,7 +78,7 @@ public class Hologram {
for (HologramLine hologramLine : this.hologramLines) { for (HologramLine hologramLine : this.hologramLines) {
try { try {
updateLine(hologramLine.line, hologramLine.armorStand, user); updateLine(hologramLine.line, hologramLine.armorStand, user);
Object metaData = this.npc.getPackets().getProxyInstance().getMetadataPacket(hologramLine.id, hologramLine.armorStand); Object metaData = this.npc.getPackets().getNms().getMetadataPacket(hologramLine.id, hologramLine.armorStand);
Utils.sendPackets(user, metaData); Utils.sendPackets(user, metaData);
} catch (ReflectiveOperationException operationException) { } catch (ReflectiveOperationException operationException) {
throw new UnexpectedCallException(operationException); throw new UnexpectedCallException(operationException);

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.event; package io.github.znetworkw.znpcservers.npc.interaction;
public enum ClickType { public enum ClickType {
RIGHT, LEFT, DEFAULT; RIGHT, LEFT, DEFAULT;

@ -0,0 +1,46 @@
package io.github.znetworkw.znpcservers.npc.interaction;
import com.github.retrooper.packetevents.event.PacketListener;
import com.github.retrooper.packetevents.event.PacketReceiveEvent;
import com.github.retrooper.packetevents.protocol.packettype.PacketType;
import com.github.retrooper.packetevents.wrapper.play.client.WrapperPlayClientInteractEntity;
import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.NPCAction;
import io.github.znetworkw.znpcservers.user.ZUser;
import lol.pyr.znpcsplus.ZNPCsPlus;
import org.bukkit.Bukkit;
import java.util.List;
public class InteractionPacketListener implements PacketListener {
@Override
public void onPacketReceive(PacketReceiveEvent event) {
if (event.getPacketType() != PacketType.Play.Client.INTERACT_ENTITY) return;
WrapperPlayClientInteractEntity packet = new WrapperPlayClientInteractEntity(event);
ZUser user = ZUser.find(event.getUser().getUUID());
long lastInteract = System.nanoTime() - user.getLastInteract();
if (user.getLastInteract() != 0L && lastInteract < 1000000000L) return;
NPC npc = NPC.all().stream().filter(n -> n.getEntityID() == packet.getEntityId()).findFirst().orElse(null);
if (npc == null) return;
ClickType clickType = ClickType.forName(packet.getAction().name());
user.updateLastInteract();
ZNPCsPlus.SCHEDULER.runTask(() -> {
Bukkit.getServer().getPluginManager().callEvent(new NPCInteractEvent(user.toPlayer(), clickType, npc));
List<NPCAction> actions = npc.getNpcPojo().getClickActions();
if (actions == null) return;
for (NPCAction action : actions) {
if (action.getClickType() != ClickType.DEFAULT && action.getClickType() != clickType) continue;
if (action.getDelay() > 0) {
int actionId = npc.getNpcPojo().getClickActions().indexOf(action);
if (user.getLastClicked().containsKey(actionId) && System.nanoTime() - user.getLastClicked().get(actionId) < action.getFixedDelay()) continue;
user.getLastClicked().put(actionId, System.nanoTime());
}
action.run(user, action.getAction());
}
});
}
}

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.event; package io.github.znetworkw.znpcservers.npc.interaction;
import io.github.znetworkw.znpcservers.npc.NPC; import io.github.znetworkw.znpcservers.npc.NPC;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
@ -14,7 +14,7 @@ import org.bukkit.inventory.ItemStack;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
public interface Packet { public interface NMS {
int version(); int version();
@PacketValue(keyName = "playerPacket") @PacketValue(keyName = "playerPacket")

@ -0,0 +1,19 @@
package io.github.znetworkw.znpcservers.npc.nms;
import com.google.common.collect.ImmutableSet;
import io.github.znetworkw.znpcservers.utility.Utils;
import java.util.Comparator;
public final class NMSFactory {
public static final ImmutableSet<NMS> ALL = ImmutableSet.of(new NMSV8(), new NMSV9(), new NMSV16(), new NMSV17(), new NMSV18(), new NMSV19());
public static final NMS NMS_FOR_CURRENT_VERSION = findPacketForVersion(Utils.BUKKIT_VERSION);
public static NMS findPacketForVersion(int version) {
return ALL.stream()
.filter(NMS -> (version >= NMS.version()))
.max(Comparator.comparing(NMS::version))
.orElseThrow(() -> new IllegalArgumentException("No packet instance found for version: " + version));
}
}

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
@ -11,7 +11,7 @@ import org.bukkit.inventory.ItemStack;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class PacketV16 extends PacketV9 { public class NMSV16 extends NMSV9 {
public int version() { public int version() {
return 16; return 16;
} }

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.reflection.Reflections; import io.github.znetworkw.znpcservers.reflection.Reflections;
@ -6,7 +6,7 @@ import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.utility.Utils; import io.github.znetworkw.znpcservers.utility.Utils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
public class PacketV17 extends PacketV16 { public class NMSV17 extends NMSV16 {
public int version() { public int version() {
return 17; return 17;
} }

@ -1,10 +1,10 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import io.github.znetworkw.znpcservers.reflection.Reflections; import io.github.znetworkw.znpcservers.reflection.Reflections;
import io.github.znetworkw.znpcservers.npc.NPC; import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.utility.Utils; import io.github.znetworkw.znpcservers.utility.Utils;
public class PacketV18 extends PacketV17 { public class NMSV18 extends NMSV17 {
public int version() { public int version() {
return 18; return 18;
} }

@ -1,10 +1,10 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.reflection.Reflections; import io.github.znetworkw.znpcservers.reflection.Reflections;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
public class PacketV19 extends PacketV18 { public class NMSV19 extends NMSV18 {
public int version() { public int version() {
return 19; return 19;
} }

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
@ -12,7 +12,7 @@ import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Map; import java.util.Map;
public class PacketV8 implements Packet { public class NMSV8 implements NMS {
public int version() { public int version() {
return 8; return 8;
} }

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import io.github.znetworkw.znpcservers.reflection.Reflections; import io.github.znetworkw.znpcservers.reflection.Reflections;
@ -9,7 +9,7 @@ import org.bukkit.inventory.ItemStack;
import java.util.Map; import java.util.Map;
public class PacketV9 extends PacketV8 { public class NMSV9 extends NMSV8 {
public int version() { public int version() {
return 9; return 9;
} }

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@ -16,7 +16,7 @@ public class PacketCache {
static { static {
ImmutableMap.Builder<Method, PacketValue> methodPacketValueBuilder = ImmutableMap.builder(); ImmutableMap.Builder<Method, PacketValue> methodPacketValueBuilder = ImmutableMap.builder();
for (Method method : Packet.class.getMethods()) { for (Method method : NMS.class.getMethods()) {
if (method.isAnnotationPresent(PacketValue.class)) if (method.isAnnotationPresent(PacketValue.class))
methodPacketValueBuilder.put(method, method.getAnnotation(PacketValue.class)); methodPacketValueBuilder.put(method, method.getAnnotation(PacketValue.class));
} }
@ -25,26 +25,26 @@ public class PacketCache {
private final Map<String, Object> packetResultCache = new ConcurrentHashMap<>(); private final Map<String, Object> packetResultCache = new ConcurrentHashMap<>();
private final Packet proxyInstance; private final NMS nms;
public PacketCache(Packet packet) { public PacketCache(NMS NMS) {
this.proxyInstance = newProxyInstance(packet); this.nms = newNMSInstance(NMS);
} }
public PacketCache() { public PacketCache() {
this(PacketFactory.PACKET_FOR_CURRENT_VERSION); this(NMSFactory.NMS_FOR_CURRENT_VERSION);
} }
public Packet getProxyInstance() { public NMS getNms() {
return this.proxyInstance; return this.nms;
} }
protected Packet newProxyInstance(Packet packet) { protected NMS newNMSInstance(NMS NMS) {
return (Packet) Proxy.newProxyInstance(packet return (NMS) Proxy.newProxyInstance(NMS
.getClass().getClassLoader(), new Class[]{Packet.class}, new PacketHandler(this, packet)); .getClass().getClassLoader(), new Class[]{NMS.class}, new PacketHandler(this, NMS));
} }
private Object getOrCache(Packet instance, Method method, Object[] args) { private Object getOrCache(NMS instance, Method method, Object[] args) {
if (!VALUE_LOOKUP_BY_NAME.containsKey(method)) if (!VALUE_LOOKUP_BY_NAME.containsKey(method))
throw new IllegalStateException("value not found for method: " + method.getName()); throw new IllegalStateException("value not found for method: " + method.getName());
PacketValue packetValue = VALUE_LOOKUP_BY_NAME.get(method); PacketValue packetValue = VALUE_LOOKUP_BY_NAME.get(method);
@ -73,9 +73,9 @@ public class PacketCache {
private static class PacketHandler implements InvocationHandler { private static class PacketHandler implements InvocationHandler {
private final PacketCache packetCache; private final PacketCache packetCache;
private final Packet packets; private final NMS packets;
public PacketHandler(PacketCache packetCache, Packet packets) { public PacketHandler(PacketCache packetCache, NMS packets) {
this.packetCache = packetCache; this.packetCache = packetCache;
this.packets = packets; this.packets = packets;
} }

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

@ -1,4 +1,4 @@
package io.github.znetworkw.znpcservers.npc.packet; package io.github.znetworkw.znpcservers.npc.nms;
import java.util.Arrays; import java.util.Arrays;

@ -1,19 +0,0 @@
package io.github.znetworkw.znpcservers.npc.packet;
import com.google.common.collect.ImmutableSet;
import io.github.znetworkw.znpcservers.utility.Utils;
import java.util.Comparator;
public final class PacketFactory {
public static final ImmutableSet<Packet> ALL = ImmutableSet.of(new PacketV8(), new PacketV9(), new PacketV16(), new PacketV17(), new PacketV18(), new PacketV19());
public static final Packet PACKET_FOR_CURRENT_VERSION = findPacketForVersion(Utils.BUKKIT_VERSION);
public static Packet findPacketForVersion(int version) {
return ALL.stream()
.filter(packet -> (version >= packet.version()))
.max(Comparator.comparing(Packet::version))
.orElseThrow(() -> new IllegalArgumentException("No packet instance found for version: " + version));
}
}

@ -6,7 +6,6 @@ import io.github.znetworkw.znpcservers.reflection.types.ConstructorReflection;
import io.github.znetworkw.znpcservers.reflection.types.FieldReflection; import io.github.znetworkw.znpcservers.reflection.types.FieldReflection;
import io.github.znetworkw.znpcservers.reflection.types.MethodReflection; import io.github.znetworkw.znpcservers.reflection.types.MethodReflection;
import io.github.znetworkw.znpcservers.utility.Utils; import io.github.znetworkw.znpcservers.utility.Utils;
import io.netty.channel.Channel;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandMap; import org.bukkit.command.CommandMap;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -23,9 +22,6 @@ import java.util.UUID;
* inaccessible things from the server jar like packets, raw entity classes, etc. * inaccessible things from the server jar like packets, raw entity classes, etc.
*/ */
public final class Reflections { public final class Reflections {
public static final Class<?> PACKET_PLAY_IN_USE_ENTITY_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
.withClassName("PacketPlayInUseEntity")).get();
public static final Class<?> ENUM_PLAYER_INFO_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET) public static final Class<?> ENUM_PLAYER_INFO_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
.withClassName("PacketPlayOutPlayerInfo$EnumPlayerInfoAction") .withClassName("PacketPlayOutPlayerInfo$EnumPlayerInfoAction")
.withClassName("ClientboundPlayerInfoUpdatePacket$a")).get(); .withClassName("ClientboundPlayerInfoUpdatePacket$a")).get();
@ -409,9 +405,6 @@ public final class Reflections {
public static final Class<?> PLAYER_CONNECTION_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SERVER_NETWORK) public static final Class<?> PLAYER_CONNECTION_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.SERVER_NETWORK)
.withClassName("PlayerConnection")).get(); .withClassName("PlayerConnection")).get();
public static final Class<?> NETWORK_MANAGER_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.NETWORK)
.withClassName("NetworkManager")).get();
public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET) public static final Class<?> PACKET_PLAY_OUT_PLAYER_INFO_CLASS = new ClassReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
.withClassName("PacketPlayOutPlayerInfo") .withClassName("PacketPlayOutPlayerInfo")
.withClassName("ClientboundPlayerInfoUpdatePacket")).get(); .withClassName("ClientboundPlayerInfoUpdatePacket")).get();
@ -674,19 +667,6 @@ public final class Reflections {
.withClassName(ENTITY_PLAYER_CLASS) .withClassName(ENTITY_PLAYER_CLASS)
.withFieldName((Utils.BUKKIT_VERSION > 16) ? "b" : "playerConnection")); .withFieldName((Utils.BUKKIT_VERSION > 16) ? "b" : "playerConnection"));
public static final ReflectionLazyLoader<Field> NETWORK_MANAGER_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
.withClassName(PLAYER_CONNECTION_CLASS)
.withFieldName((Utils.BUKKIT_VERSION > 16) ? "a" : "networkManager")
.withExpectResult(NETWORK_MANAGER_CLASS));
public static final ReflectionLazyLoader<Field> CHANNEL_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.SERVER_NETWORK)
.withClassName(NETWORK_MANAGER_CLASS)
.withExpectResult(Channel.class));
public static final ReflectionLazyLoader<Field> PACKET_IN_USE_ENTITY_ID_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
.withClassName("PacketPlayInUseEntity")
.withFieldName("a"));
public static final ReflectionLazyLoader<Object> ADD_PLAYER_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.PACKET) public static final ReflectionLazyLoader<Object> ADD_PLAYER_FIELD = new FieldReflection(new ReflectionBuilder(ReflectionPackage.PACKET)
.withClassName("PacketPlayOutPlayerInfo$EnumPlayerInfoAction") .withClassName("PacketPlayOutPlayerInfo$EnumPlayerInfoAction")
.withClassName("ClientboundPlayerInfoUpdatePacket$a") .withClassName("ClientboundPlayerInfoUpdatePacket$a")

@ -1,20 +1,10 @@
package io.github.znetworkw.znpcservers.user; package io.github.znetworkw.znpcservers.user;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import io.github.znetworkw.znpcservers.exception.ChannelRegistrationException;
import io.github.znetworkw.znpcservers.npc.NPC; import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.NPCAction;
import io.github.znetworkw.znpcservers.npc.event.ClickType;
import io.github.znetworkw.znpcservers.npc.event.NPCInteractEvent;
import io.github.znetworkw.znpcservers.reflection.Reflections; import io.github.znetworkw.znpcservers.reflection.Reflections;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToMessageDecoder;
import lol.pyr.znpcsplus.ZNPCsPlus;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
@ -47,52 +37,6 @@ public class ZUser {
} catch (IllegalAccessException | InvocationTargetException e) { } catch (IllegalAccessException | InvocationTargetException e) {
throw new IllegalStateException("can't create user for player " + uuid.toString(), e.getCause()); throw new IllegalStateException("can't create user for player " + uuid.toString(), e.getCause());
} }
if (tryRegisterChannel() != null) ZNPCsPlus.SCHEDULER.runTaskTimer(new ChannelRegistrationFallbackTask(this), 3);
}
private static class ChannelRegistrationFallbackTask extends BukkitRunnable {
private final ZUser user;
private int tries = 5;
private ChannelRegistrationFallbackTask(ZUser user) {
this.user = user;
}
@Override
public void run() {
ChannelRegistrationException ex = user.tryRegisterChannel();
Player player = user.toPlayer();
if (player == null) {
tries--;
return;
}
else if (!player.isOnline() || ex == null) {
cancel();
return;
}
if (tries-- > 0) return;
cancel();
player.kickPlayer(ChatColor.RED + "[ZNPCsPlus]\n" +
ChatColor.WHITE + "Couldn't inject interaction detector to channel\n" +
ChatColor.WHITE + "Please report this at https://github.com/Pyrbu/ZNPCsPlus");
ZNPCsPlus.LOGGER.severe("Couldn't inject interaction detector to channel for player " + player.getName() + " (" + player.getUniqueId() + ")");
ZNPCsPlus.LOGGER.severe("Channel names: " + ex.getChannelNames());
ex.printStackTrace();
}
}
private ChannelRegistrationException tryRegisterChannel() {
Channel channel = null;
try {
channel = (Channel) Reflections.CHANNEL_FIELD.get().get(Reflections.NETWORK_MANAGER_FIELD.get().get(this.playerConnection));
if (channel.pipeline().names().contains("npc_interact")) channel.pipeline().remove("npc_interact");
channel.pipeline().addAfter("decoder", "npc_interact", new ZNPCSocketDecoder());
return null;
} catch (IllegalAccessException e) {
throw new RuntimeException("illegal access exception while trying to register npc_interact channel");
} catch (NoSuchElementException e) {
return new ChannelRegistrationException(e, channel == null ? List.of() : channel.pipeline().names());
}
} }
public static ZUser find(UUID uuid) { public static ZUser find(UUID uuid) {
@ -141,40 +85,15 @@ public class ZUser {
return Bukkit.getPlayer(this.uuid); return Bukkit.getPlayer(this.uuid);
} }
class ZNPCSocketDecoder extends MessageToMessageDecoder<Object> { public long getLastInteract() {
protected void decode(ChannelHandlerContext channelHandlerContext, Object packet, List<Object> out) throws Exception { return lastInteract;
out.add(packet); }
if (packet.getClass() == Reflections.PACKET_PLAY_IN_USE_ENTITY_CLASS) {
long lastInteractNanos = System.nanoTime() - ZUser.this.lastInteract; public Map<Integer, Long> getLastClicked() {
if (ZUser.this.lastInteract != 0L && lastInteractNanos < 1000000000L) return lastClicked;
return; }
int entityId = Reflections.PACKET_IN_USE_ENTITY_ID_FIELD.get().getInt(packet);
NPC npc = NPC.all().stream().filter(npc1 -> (npc1.getEntityID() == entityId)).findFirst().orElse(null); public void updateLastInteract() {
if (npc == null) this.lastInteract = System.nanoTime();
return;
ClickType clickName = ClickType.forName(npc.getPackets().getProxyInstance().getClickType(packet).toString());
ZUser.this.lastInteract = System.nanoTime();
ZNPCsPlus.SCHEDULER.scheduleSyncDelayedTask(() -> {
Bukkit.getServer().getPluginManager().callEvent(new NPCInteractEvent(ZUser.this.toPlayer(), clickName, npc));
List<NPCAction> actions = npc.getNpcPojo().getClickActions();
if (actions == null || actions.isEmpty())
return;
for (NPCAction npcAction : actions) {
if (npcAction.getClickType() != ClickType.DEFAULT && clickName != npcAction.getClickType())
continue;
if (npcAction.getDelay() > 0) {
int actionId = npc.getNpcPojo().getClickActions().indexOf(npcAction);
if (ZUser.this.lastClicked.containsKey(actionId)) {
long lastClickNanos = System.nanoTime() - ZUser.this.lastClicked.get(actionId);
if (lastClickNanos < npcAction.getFixedDelay())
continue;
}
ZUser.this.lastClicked.put(actionId, System.nanoTime());
}
npcAction.run(ZUser.this, npcAction.getAction());
}
}, 1);
}
}
} }
} }

@ -49,7 +49,7 @@ public final class Utils {
} }
public static void sendTitle(Player player, String title, String subTitle) { public static void sendTitle(Player player, String title, String subTitle) {
player.sendTitle(toColor(title), toColor(subTitle), 1, 3, 1); player.sendTitle(toColor(title), toColor(subTitle), 20, 60, 20);
} }
public static void setValue(Object fieldInstance, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { public static void setValue(Object fieldInstance, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException {

@ -1,7 +1,10 @@
package lol.pyr.znpcsplus; package lol.pyr.znpcsplus;
import com.github.retrooper.packetevents.PacketEvents;
import com.github.retrooper.packetevents.event.PacketListenerPriority;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import io.github.retrooper.packetevents.factory.spigot.SpigotPacketEventsBuilder;
import io.github.znetworkw.znpcservers.commands.list.DefaultCommand; import io.github.znetworkw.znpcservers.commands.list.DefaultCommand;
import io.github.znetworkw.znpcservers.configuration.Configuration; import io.github.znetworkw.znpcservers.configuration.Configuration;
import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants; import io.github.znetworkw.znpcservers.configuration.ConfigurationConstants;
@ -11,6 +14,7 @@ import io.github.znetworkw.znpcservers.npc.NPC;
import io.github.znetworkw.znpcservers.npc.NPCModel; import io.github.znetworkw.znpcservers.npc.NPCModel;
import io.github.znetworkw.znpcservers.npc.NPCPath; import io.github.znetworkw.znpcservers.npc.NPCPath;
import io.github.znetworkw.znpcservers.npc.NPCType; import io.github.znetworkw.znpcservers.npc.NPCType;
import io.github.znetworkw.znpcservers.npc.interaction.InteractionPacketListener;
import io.github.znetworkw.znpcservers.npc.task.NPCPositionTask; import io.github.znetworkw.znpcservers.npc.task.NPCPositionTask;
import io.github.znetworkw.znpcservers.npc.task.NPCSaveTask; import io.github.znetworkw.znpcservers.npc.task.NPCSaveTask;
import io.github.znetworkw.znpcservers.npc.task.NPCVisibilityTask; import io.github.znetworkw.znpcservers.npc.task.NPCVisibilityTask;
@ -70,6 +74,8 @@ public class ZNPCsPlus extends JavaPlugin {
@Override @Override
public void onLoad() { public void onLoad() {
PacketEvents.setAPI(SpigotPacketEventsBuilder.build(this));
PacketEvents.getAPI().getSettings().checkForUpdates(false);
LOGGER = getLogger(); LOGGER = getLogger();
PLUGIN_FOLDER = getDataFolder(); PLUGIN_FOLDER = getDataFolder();
PATH_FOLDER = new File(PLUGIN_FOLDER, "paths"); PATH_FOLDER = new File(PLUGIN_FOLDER, "paths");
@ -104,9 +110,13 @@ public class ZNPCsPlus extends JavaPlugin {
} }
} }
log(ChatColor.WHITE + " * Initializing adventure..."); 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();
PLUGIN_FOLDER.mkdirs(); PLUGIN_FOLDER.mkdirs();
PATH_FOLDER.mkdirs(); PATH_FOLDER.mkdirs();

@ -3,5 +3,13 @@ main: lol.pyr.znpcsplus.ZNPCsPlus
load: POSTWORLD load: POSTWORLD
version: ${version} version: ${version}
api-version: 1.13 api-version: 1.13
softdepend: [PlaceholderAPI, ServersNPC] softdepend:
- PlaceholderAPI
- ServersNPC
- ProtocolLib
- ProtocolSupport
- ViaVersion
- ViaBackwards
- ViaRewind
- Geyser-Spigot
authors: [Gonzalez (g0b#3830), Pyr (Pyr#6969)] authors: [Gonzalez (g0b#3830), Pyr (Pyr#6969)]