Fix inventory stuff, esp in 1.17

This commit is contained in:
libraryaddict 2021-07-10 20:13:01 +12:00
parent bba628a511
commit 60ff44e8b1
3 changed files with 126 additions and 59 deletions

View File

@ -1,7 +1,9 @@
package me.libraryaddict.disguise.utilities.listeners;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import lombok.Getter;
@ -19,13 +21,11 @@ import me.libraryaddict.disguise.utilities.LibsPremium;
import me.libraryaddict.disguise.utilities.modded.ModdedEntity;
import me.libraryaddict.disguise.utilities.modded.ModdedManager;
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.RandomUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.*;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@ -43,6 +43,7 @@ import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.scheduler.BukkitRunnable;
@ -235,6 +236,67 @@ public class DisguiseListener implements Listener {
}
}
@EventHandler
public void onHeldItemSwitch(PlayerItemHeldEvent event) {
Player player = event.getPlayer();
Disguise disguise = DisguiseAPI.getDisguise(player, player);
if (disguise == null || !disguise.isHidingHeldItemFromSelf()) {
return;
}
// From logging, it seems that both bukkit and nms uses the same thing for the slot switching.
// 0 1 2 3 - 8
// If the packet is coming, then I need to replace the item they are switching to
// As for the old item, I need to restore it.
org.bukkit.inventory.ItemStack currentlyHeld = player.getItemInHand();
// If his old weapon isn't air
if (currentlyHeld != null && currentlyHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(NmsVersion.v1_17.isSupported() ? 2 : 1, event.getPreviousSlot() + 36);
if (NmsVersion.v1_17.isSupported()) {
mods.write(1, ReflectionManager.getIncrementedStateId(player));
}
packet.getItemModifier().write(0, currentlyHeld);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
org.bukkit.inventory.ItemStack newHeld = player.getInventory().getItem(event.getNewSlot());
// If his new weapon isn't air either!
if (newHeld != null && newHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(NmsVersion.v1_17.isSupported() ? 2 : 1, event.getNewSlot() + 36);
if (NmsVersion.v1_17.isSupported()) {
mods.write(1, ReflectionManager.getIncrementedStateId(player));
}
packet.getItemModifier().write(0, new ItemStack(Material.AIR));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
@EventHandler
public void onChunkUnload(ChunkUnloadEvent event) {
if (!DisguiseConfig.isSaveEntityDisguises()) {

View File

@ -30,8 +30,8 @@ public class PacketListenerInventory extends PacketAdapter {
private LibsDisguises libsDisguises;
public PacketListenerInventory(LibsDisguises plugin) {
super(plugin, ListenerPriority.HIGH, Server.SET_SLOT, Server.WINDOW_ITEMS, PacketType.Play.Client.HELD_ITEM_SLOT,
PacketType.Play.Client.SET_CREATIVE_SLOT, PacketType.Play.Client.WINDOW_CLICK);
super(plugin, ListenerPriority.HIGH, Server.SET_SLOT, Server.WINDOW_ITEMS, PacketType.Play.Client.SET_CREATIVE_SLOT,
PacketType.Play.Client.WINDOW_CLICK);
libsDisguises = plugin;
}
@ -87,7 +87,12 @@ public class PacketListenerInventory extends PacketAdapter {
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
mods.write(NmsVersion.v1_17.isSupported() ? 2 : 1, slot);
if (NmsVersion.v1_17.isSupported()) {
mods.write(1, ReflectionManager.getIncrementedStateId(player));
}
packet.getItemModifier().write(0, new ItemStack(Material.AIR));
try {
@ -109,7 +114,12 @@ public class PacketListenerInventory extends PacketAdapter {
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
mods.write(NmsVersion.v1_17.isSupported() ? 2 : 1, slot);
if (NmsVersion.v1_17.isSupported()) {
mods.write(1, ReflectionManager.getIncrementedStateId(player));
}
packet.getItemModifier().write(0, new ItemStack(Material.AIR));
try {
@ -121,57 +131,19 @@ public class PacketListenerInventory extends PacketAdapter {
}
}
}
}
// If the player switched item, aka he moved from slot 1 to slot 2
else if (event.getPacketType() == PacketType.Play.Client.HELD_ITEM_SLOT) {
if (disguise.isHidingHeldItemFromSelf()) {
// From logging, it seems that both bukkit and nms uses the same thing for the slot switching.
// 0 1 2 3 - 8
// If the packet is coming, then I need to replace the item they are switching to
// As for the old item, I need to restore it.
org.bukkit.inventory.ItemStack currentlyHeld = player.getItemInHand();
// If his old weapon isn't air
if (currentlyHeld != null && currentlyHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, player.getInventory().getHeldItemSlot() + 36);
packet.getItemModifier().write(0, currentlyHeld);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
org.bukkit.inventory.ItemStack newHeld = player.getInventory().getItem(event.getPacket().getIntegers().read(0));
// If his new weapon isn't air either!
if (newHeld != null && newHeld.getType() != Material.AIR) {
PacketContainer packet = new PacketContainer(Server.SET_SLOT);
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, event.getPacket().getIntegers().read(0) + 36);
packet.getItemModifier().write(0, new ItemStack(Material.AIR));
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
} else if (event.getPacketType() == PacketType.Play.Client.WINDOW_CLICK) {
int slot = event.getPacket().getIntegers().read(1);
int slot = event.getPacket().getIntegers().read(NmsVersion.v1_17.isSupported() ? 2 : 1);
org.bukkit.inventory.ItemStack clickedItem;
int type;
if (event.getPacket().getShorts().read(0) == 1) {
if (NmsVersion.v1_17.isSupported()) {
type = event.getPacket().getIntegers().read(3);
} else {
type = event.getPacket().getShorts().read(0);
}
if (type == 1) {
// Its a shift click
clickedItem = event.getPacket().getItemModifier().read(0);
@ -205,7 +177,12 @@ public class PacketListenerInventory extends PacketAdapter {
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
mods.write(NmsVersion.v1_17.isSupported() ? 2 : 1, slot);
if (NmsVersion.v1_17.isSupported()) {
mods.write(1, ReflectionManager.getIncrementedStateId(player));
}
packet.getItemModifier().write(0, new ItemStack(Material.AIR));
try {
@ -225,8 +202,11 @@ public class PacketListenerInventory extends PacketAdapter {
StructureModifier<Object> mods = packet.getModifier();
mods.write(0, 0);
mods.write(1, slot);
packet.getItemModifier().write(0, new ItemStack(Material.AIR));
mods.write(NmsVersion.v1_17.isSupported() ? 2 : 1, slot);
if (NmsVersion.v1_17.isSupported()) {
mods.write(1, ReflectionManager.getIncrementedStateId(player));
}
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false);
@ -269,7 +249,7 @@ public class PacketListenerInventory extends PacketAdapter {
if (event.getPacketType() == Server.SET_SLOT) {
// The raw slot
// nms code has the start of the hotbar being 36.
int slot = event.getPacket().getIntegers().read(1);
int slot = event.getPacket().getIntegers().read(NmsVersion.v1_17.isSupported() ? 2 : 1);
// If the slot is a armor slot
if (slot >= 5 && slot <= 8) {

View File

@ -115,6 +115,8 @@ public class ReflectionManager {
private static Method setScore;
private static HashMap<String, String> classLocations = new HashMap<>();
private static Field playerConnection;
private static Method incrementedInventoryStateId;
private static Field playerInventoryContainer;
public static void init() {
try {
@ -132,6 +134,16 @@ public class ReflectionManager {
entityCountField = f;
break;
}
for (Field f : getNmsClass("EntityHuman").getDeclaredFields()) {
if (!f.getType().getSimpleName().equals("ContainerPlayer")) {
continue;
}
f.setAccessible(true);
playerInventoryContainer = f;
break;
}
} else {
entityCountField = getNmsField("Entity", "entityCount");
}
@ -198,6 +210,7 @@ public class ReflectionManager {
villagerTypeRegistry = getNmsField("IRegistry", "ao").get(null);
playerConnection = getNmsField("EntityPlayer", "b");
connectionEntityMethod = getNmsMethod("PlayerConnection", "d");
incrementedInventoryStateId = getNmsMethod("Container", "incrementStateId");
} else {
villagerProfessionRegistry = getNmsField("IRegistry", "VILLAGER_PROFESSION").get(null);
villagerTypeRegistry = getNmsField("IRegistry", "VILLAGER_TYPE").get(null);
@ -342,6 +355,18 @@ public class ReflectionManager {
return false;
}
public static int getIncrementedStateId(Player player) {
try {
Object container = playerInventoryContainer.get(getNmsEntity(player));
return (int) incrementedInventoryStateId.invoke(container);
} catch (Exception ex) {
ex.printStackTrace();
}
return 0;
}
public static boolean isSupported(AccessibleObject obj) {
if (obj.isAnnotationPresent(NmsAddedIn.class)) {
NmsAddedIn added = obj.getAnnotation(NmsAddedIn.class);