diff --git a/src/main/java/org/maxgamer/QuickShop/Config/ConfigManager.java b/src/main/java/org/maxgamer/QuickShop/Config/ConfigManager.java index 1367f67..842f9f7 100644 --- a/src/main/java/org/maxgamer/QuickShop/Config/ConfigManager.java +++ b/src/main/java/org/maxgamer/QuickShop/Config/ConfigManager.java @@ -9,8 +9,8 @@ import org.bukkit.Material; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.inventory.ItemStack; import org.maxgamer.QuickShop.QuickShop; -import org.maxgamer.QuickShop.Shop.Item.FakeItem_17; -import org.maxgamer.QuickShop.Shop.Item.FakeItem_18_110; +import org.maxgamer.QuickShop.Shop.Item.FakeItem_17_18; +import org.maxgamer.QuickShop.Shop.Item.FakeItem_19_110; import pw.yumc.YumCore.bukkit.Log; import pw.yumc.YumCore.config.FileConfig; @@ -90,13 +90,13 @@ public class ConfigManager { if (config.getBoolean("fakeitem", true)) { try { plugin.getLogger().info("启用虚拟悬浮物 尝试启动中..."); - FakeItem_18_110.register(plugin); + FakeItem_19_110.register(plugin); plugin.getLogger().info("虚拟悬浮物功能测试正常(1.8-1.10.2)..."); fakeItem = true; } catch (final Throwable e) { Log.debug(e); try { - FakeItem_17.register(plugin); + FakeItem_17_18.register(plugin); plugin.getLogger().info("虚拟悬浮物功能测试正常(1.7)..."); fakeItem = true; } catch (final Throwable e2) { diff --git a/src/main/java/org/maxgamer/QuickShop/Shop/Item/DisplayItem.java b/src/main/java/org/maxgamer/QuickShop/Shop/Item/DisplayItem.java index b6b9378..46397c7 100644 --- a/src/main/java/org/maxgamer/QuickShop/Shop/Item/DisplayItem.java +++ b/src/main/java/org/maxgamer/QuickShop/Shop/Item/DisplayItem.java @@ -19,17 +19,17 @@ public abstract class DisplayItem { if (plugin.getConfigManager().isDisplay()) { if (plugin.getConfigManager().isFakeItem()) { try { - return new FakeItem_18_110(shop, shop.getItem()); + return new FakeItem_19_110(shop, shop.getItem()); } catch (final Throwable e) { Log.debug(e); try { - return new FakeItem_17(shop, shop.getItem()); + return new FakeItem_17_18(shop, shop.getItem()); } catch (final Throwable e2) { Log.debug(e2); - return new NormalItem(shop, shop.getItem()); } } } + return new NormalItem(shop, shop.getItem()); } return null; } diff --git a/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_17.java b/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem.java similarity index 73% rename from src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_17.java rename to src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem.java index 83b8d2c..16ddab8 100644 --- a/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_17.java +++ b/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -20,31 +21,30 @@ import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.events.PacketAdapter; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.wrappers.WrappedWatchableObject; /** - * Minecraft 虚拟悬浮物品工具类 - * 需要depend ProtocolLib + * Minecraft 虚拟悬浮物品工具类 需要depend ProtocolLib 4.x * * @author 橙子(chengzi) - * @version 1.0.1 + * @version 1.1.1 */ -public class FakeItem_17 extends DisplayItem { +public abstract class FakeItem extends DisplayItem { - private static Map> fakes = new HashMap<>(); + private static Map> fakes = new HashMap<>(); private static boolean registered = false; private static int lastId = Integer.MAX_VALUE; - private final ItemStack itemStack; - private final Location location; - private final int eid; - private boolean created = false; + protected final ItemStack itemStack; + protected final Location location; + protected final int eid; + protected final UUID uuid; + protected boolean created = false; - public FakeItem_17(final ContainerShop containerShop, final ItemStack item) { + public FakeItem(final ContainerShop containerShop, final ItemStack item) { this.itemStack = item; this.location = containerShop.getLocation().clone().add(0.5, 1, 0.5); this.eid = getFakeEntityId(); - create(); + this.uuid = UUID.randomUUID(); } public static boolean isRegistered() { @@ -75,9 +75,9 @@ public class FakeItem_17 extends DisplayItem { final Player p = event.getPlayer(); final int chunkX = packet.getIntegers().read(0); final int chunkZ = packet.getIntegers().read(1); - final List fakesInChunk = fakes.get(getChunkIdentifyString(p.getWorld().getChunkAt(chunkX, chunkZ))); + final List fakesInChunk = fakes.get(getChunkIdentifyString(p.getWorld().getChunkAt(chunkX, chunkZ))); if (fakesInChunk != null) { - for (final FakeItem_17 fake : fakesInChunk) { + for (final FakeItem fake : fakesInChunk) { ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getSpawnPacket()); ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getVelocityPacket()); ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getMetadataPacket()); @@ -96,9 +96,9 @@ public class FakeItem_17 extends DisplayItem { final int[] chunksX = packet.getIntegerArrays().read(0); final int[] chunksZ = packet.getIntegerArrays().read(1); for (int i = 0; i < chunksX.length; i++) { - final List fakesInChunk = fakes.get(getChunkIdentifyString(p.getWorld().getChunkAt(chunksX[i], chunksZ[i]))); + final List fakesInChunk = fakes.get(getChunkIdentifyString(p.getWorld().getChunkAt(chunksX[i], chunksZ[i]))); if (fakesInChunk != null) { - for (final FakeItem_17 fake : fakesInChunk) { + for (final FakeItem fake : fakesInChunk) { ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getSpawnPacket()); ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getVelocityPacket()); ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getMetadataPacket()); @@ -123,10 +123,6 @@ public class FakeItem_17 extends DisplayItem { return lastId--; } - private static int getNormalizedDistance(final double value) { - return (int) Math.floor(value * 32.0D); - } - @Override public Location getDisplayLocation() { return location; @@ -172,7 +168,7 @@ public class FakeItem_17 extends DisplayItem { ProtocolLibrary.getProtocolManager().broadcastServerPacket(getMetadataPacket()); final String chunkId = getChunkIdentifyString(location.getChunk()); - List fakesInChunk = fakes.get(chunkId); + List fakesInChunk = fakes.get(chunkId); if (fakesInChunk == null) { fakesInChunk = new ArrayList<>(); } @@ -188,7 +184,7 @@ public class FakeItem_17 extends DisplayItem { ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDestoryPacket()); final String chunkId = getChunkIdentifyString(location.getChunk()); - final List fakesInChunk = fakes.get(chunkId); + final List fakesInChunk = fakes.get(chunkId); if (fakesInChunk == null) { // NOTE: This is what should not happens if everything is correct. created = false; @@ -205,30 +201,14 @@ public class FakeItem_17 extends DisplayItem { return fakePacket; } - private PacketContainer getMetadataPacket() { - final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); - fakePacket.getIntegers().write(0, eid); - final WrappedWatchableObject itemMeta = new WrappedWatchableObject(10, itemStack); - final List entityMetaList = new ArrayList<>(1); - entityMetaList.add(itemMeta); - fakePacket.getWatchableCollectionModifier().write(0, entityMetaList); - return fakePacket; - } - - private PacketContainer getSpawnPacket() { - final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.SPAWN_ENTITY); - fakePacket.getIntegers().write(0, eid); - fakePacket.getIntegers().write(1, getNormalizedDistance(location.getX())); - fakePacket.getIntegers().write(2, getNormalizedDistance(location.getY())); - fakePacket.getIntegers().write(3, getNormalizedDistance(location.getZ())); - fakePacket.getIntegers().write(9, 2); - return fakePacket; - } - private PacketContainer getVelocityPacket() { final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_VELOCITY); fakePacket.getIntegers().write(0, eid); return fakePacket; } + protected abstract PacketContainer getMetadataPacket(); + + protected abstract PacketContainer getSpawnPacket(); + } diff --git a/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_17_18.java b/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_17_18.java new file mode 100644 index 0000000..09e8567 --- /dev/null +++ b/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_17_18.java @@ -0,0 +1,53 @@ +package org.maxgamer.QuickShop.Shop.Item; + +import java.util.ArrayList; +import java.util.List; + +import org.bukkit.inventory.ItemStack; +import org.maxgamer.QuickShop.Shop.ContainerShop; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedWatchableObject; + +/** + * Minecraft 虚拟悬浮物品工具类 + * 需要depend ProtocolLib + * + * @author 橙子(chengzi) + * @version 1.0.1 + */ +public class FakeItem_17_18 extends FakeItem { + + public FakeItem_17_18(final ContainerShop containerShop, final ItemStack item) { + super(containerShop, item); + } + + private static int getNormalizedDistance(final double value) { + return (int) Math.floor(value * 32.0D); + } + + @Override + protected PacketContainer getMetadataPacket() { + final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); + fakePacket.getIntegers().write(0, eid); + final WrappedWatchableObject itemMeta = new WrappedWatchableObject(10, itemStack); + final List entityMetaList = new ArrayList<>(1); + entityMetaList.add(itemMeta); + fakePacket.getWatchableCollectionModifier().write(0, entityMetaList); + return fakePacket; + } + + @Override + protected PacketContainer getSpawnPacket() { + final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.SPAWN_ENTITY); + fakePacket.getIntegers().write(0, eid); + fakePacket.getIntegers().write(1, getNormalizedDistance(location.getX())); + fakePacket.getIntegers().write(2, getNormalizedDistance(location.getY())); + fakePacket.getIntegers().write(3, getNormalizedDistance(location.getZ())); + fakePacket.getIntegers().write(9, 2); + return fakePacket; + } + +} diff --git a/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_18_110.java b/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_18_110.java deleted file mode 100644 index 4f0b6ab..0000000 --- a/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_18_110.java +++ /dev/null @@ -1,226 +0,0 @@ -package org.maxgamer.QuickShop.Shop.Item; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -import org.bukkit.Bukkit; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.entity.Item; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginManager; -import org.maxgamer.QuickShop.Shop.ContainerShop; - -import com.comphenix.protocol.PacketType; -import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.events.PacketAdapter; -import com.comphenix.protocol.events.PacketContainer; -import com.comphenix.protocol.events.PacketEvent; -import com.comphenix.protocol.wrappers.WrappedDataWatcher; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject; -import com.google.common.base.Optional; - -/** - * Minecraft 虚拟悬浮物品工具类 - * 需要depend ProtocolLib 4.x - * - * @author 橙子(chengzi) - * @version 1.1.0 - */ -public class FakeItem_18_110 extends DisplayItem { - - private static Map> fakes = new HashMap<>(); - private static boolean registered = false; - private static int lastId = Integer.MAX_VALUE; - - private final ItemStack itemStack; - private final Location location; - private final int eid; - private final UUID uuid; - private boolean created = false; - - public FakeItem_18_110(final ContainerShop containerShop, final ItemStack item) { - this.itemStack = item; - this.location = containerShop.getLocation().clone().add(0.5, 1, 0.5); - this.eid = getFakeEntityId(); - this.uuid = UUID.randomUUID(); - } - - public static boolean isRegistered() { - return registered; - } - - public static void register(final Plugin plugin) { - if (registered) { - return; - } - final PluginManager pm = Bukkit.getPluginManager(); - final Plugin p = pm.getPlugin("ProtocolLib"); - if (p != null) { - if (!p.isEnabled()) { - pm.enablePlugin(p); - } - if (!p.isEnabled()) { - throw new IllegalStateException("前置插件ProtocolLib启动失败 请检查版本."); - } - } else { - throw new IllegalStateException("服务器未找到前置插件ProtocolLib."); - } - final PacketAdapter chunkPacketListener = new PacketAdapter(plugin, PacketType.Play.Server.MAP_CHUNK) { - @Override - public void onPacketSending(final PacketEvent event) { - try { - final PacketContainer packet = event.getPacket(); - final Player p = event.getPlayer(); - final int chunkX = packet.getIntegers().read(0); - final int chunkZ = packet.getIntegers().read(1); - final List fakesInChunk = fakes.get(getChunkIdentifyString(p.getWorld().getChunkAt(chunkX, chunkZ))); - if (fakesInChunk != null) { - for (final FakeItem_18_110 fake : fakesInChunk) { - ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getSpawnPacket()); - ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getMetadataPacket()); - } - } - } catch (final Exception e) { - } - } - }; - final PacketAdapter chunkBulkPacketListener = new PacketAdapter(plugin, PacketType.Play.Server.MAP_CHUNK) { - @Override - public void onPacketSending(final PacketEvent event) { - try { - final PacketContainer packet = event.getPacket(); - final Player p = event.getPlayer(); - final int[] chunksX = packet.getIntegerArrays().read(0); - final int[] chunksZ = packet.getIntegerArrays().read(1); - for (int i = 0; i < chunksX.length; i++) { - final List fakesInChunk = fakes.get(getChunkIdentifyString(p.getWorld().getChunkAt(chunksX[i], chunksZ[i]))); - if (fakesInChunk != null) { - for (final FakeItem_18_110 fake : fakesInChunk) { - ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getSpawnPacket()); - ProtocolLibrary.getProtocolManager().sendServerPacket(p, fake.getMetadataPacket()); - } - - } - } - } catch (final Exception e) { - } - } - }; - ProtocolLibrary.getProtocolManager().addPacketListener(chunkPacketListener); - ProtocolLibrary.getProtocolManager().addPacketListener(chunkBulkPacketListener); - registered = true; - } - - private static String getChunkIdentifyString(final Chunk chunk) { - return chunk.getWorld().getName() + "@@" + chunk.getX() + "@@" + chunk.getZ(); - } - - private static int getFakeEntityId() { - return lastId--; - } - - @Override - public Location getDisplayLocation() { - return location; - } - - @Override - public Item getItem() { - return null; - } - - @Override - public void remove() { - destory(); - } - - @Override - public boolean removeDupe() { - return true; - } - - @Override - public void respawn() { - ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDestoryPacket()); - ProtocolLibrary.getProtocolManager().broadcastServerPacket(getSpawnPacket()); - ProtocolLibrary.getProtocolManager().broadcastServerPacket(getMetadataPacket()); - } - - @Override - public void spawn() { - create(); - } - - private void create() { - if (!registered) { - throw new IllegalStateException("You have to call the register method first."); - } - if (created) { - return; - } - ProtocolLibrary.getProtocolManager().broadcastServerPacket(getSpawnPacket()); - ProtocolLibrary.getProtocolManager().broadcastServerPacket(getMetadataPacket()); - - final String chunkId = getChunkIdentifyString(location.getChunk()); - List fakesInChunk = fakes.get(chunkId); - if (fakesInChunk == null) { - fakesInChunk = new ArrayList<>(); - } - fakesInChunk.add(this); - fakes.put(chunkId, fakesInChunk); - created = true; - } - - private void destory() { - if (!created) { - return; - } - ProtocolLibrary.getProtocolManager().broadcastServerPacket(getDestoryPacket()); - - final String chunkId = getChunkIdentifyString(location.getChunk()); - final List fakesInChunk = fakes.get(chunkId); - if (fakesInChunk == null) { - // NOTE: This is what should not happens if everything is correct. - created = false; - return; - } - fakesInChunk.remove(this); - fakes.put(chunkId, fakesInChunk); - created = false; - } - - private PacketContainer getDestoryPacket() { - final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_DESTROY, true); - fakePacket.getIntegerArrays().write(0, new int[] { eid }); - return fakePacket; - } - - private PacketContainer getMetadataPacket() { - final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); - fakePacket.getIntegers().write(0, eid); - final WrappedDataWatcher wr = new WrappedDataWatcher(); - final Serializer serializer = WrappedDataWatcher.Registry.getItemStackSerializer(true); - final WrappedDataWatcherObject object = new WrappedDataWatcher.WrappedDataWatcherObject(6, serializer); - wr.setObject(object, Optional.of(itemStack)); - fakePacket.getWatchableCollectionModifier().write(0, wr.getWatchableObjects()); - return fakePacket; - } - - private PacketContainer getSpawnPacket() { - final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.SPAWN_ENTITY); - fakePacket.getIntegers().write(0, eid); - fakePacket.getModifier().write(1, uuid); - fakePacket.getDoubles().write(0, location.getX()); - fakePacket.getDoubles().write(1, location.getY()); - fakePacket.getDoubles().write(2, location.getZ()); - fakePacket.getIntegers().write(6, 2); - return fakePacket; - } -} diff --git a/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_19_110.java b/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_19_110.java new file mode 100644 index 0000000..2a6f413 --- /dev/null +++ b/src/main/java/org/maxgamer/QuickShop/Shop/Item/FakeItem_19_110.java @@ -0,0 +1,50 @@ +package org.maxgamer.QuickShop.Shop.Item; + +import org.bukkit.inventory.ItemStack; +import org.maxgamer.QuickShop.Shop.ContainerShop; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.events.PacketContainer; +import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer; +import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject; +import com.google.common.base.Optional; + +/** + * Minecraft 虚拟悬浮物品工具类 + * 需要depend ProtocolLib 4.x + * + * @author 橙子(chengzi) + * @version 1.1.0 + */ +public class FakeItem_19_110 extends FakeItem { + + public FakeItem_19_110(final ContainerShop containerShop, final ItemStack item) { + super(containerShop, item); + } + + @Override + protected PacketContainer getMetadataPacket() { + final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA); + fakePacket.getIntegers().write(0, eid); + final WrappedDataWatcher wr = new WrappedDataWatcher(); + final Serializer serializer = WrappedDataWatcher.Registry.getItemStackSerializer(true); + final WrappedDataWatcherObject object = new WrappedDataWatcher.WrappedDataWatcherObject(6, serializer); + wr.setObject(object, Optional.of(itemStack)); + fakePacket.getWatchableCollectionModifier().write(0, wr.getWatchableObjects()); + return fakePacket; + } + + @Override + protected PacketContainer getSpawnPacket() { + final PacketContainer fakePacket = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.SPAWN_ENTITY); + fakePacket.getIntegers().write(0, eid); + fakePacket.getModifier().write(1, uuid); + fakePacket.getDoubles().write(0, location.getX()); + fakePacket.getDoubles().write(1, location.getY()); + fakePacket.getDoubles().write(2, location.getZ()); + fakePacket.getIntegers().write(6, 2); + return fakePacket; + } +}