diff --git a/.idea/encodings.xml b/.idea/encodings.xml index 8d3469f..337d139 100644 --- a/.idea/encodings.xml +++ b/.idea/encodings.xml @@ -1,8 +1,6 @@ - - diff --git a/.idea/misc.xml b/.idea/misc.xml index 6410ee3..200af21 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -15,8 +15,22 @@ + - + \ No newline at end of file diff --git a/API/pom.xml b/API/pom.xml deleted file mode 100644 index 172cb4c..0000000 --- a/API/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-API - - - 11 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - - - src/main/resources - true - - - - - - - MG-Dev Jenkins CI Maven Repository - https://ci.mg-dev.eu/plugin/repository/everything - - - - - - com.bergerkiller.bukkit - BKCommonLib - 1.19-v1 - provided - - - \ No newline at end of file diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapWrapper.java b/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapWrapper.java deleted file mode 100644 index e797653..0000000 --- a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapWrapper.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.api; - -public abstract class MapWrapper { - protected ArrayImage content; - - public MapWrapper(ArrayImage image) { - this.content = image; - } - - public abstract MapController getController(); - - public ArrayImage getContent() { - return content; - } -} diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/PacketListener.java b/API/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/PacketListener.java deleted file mode 100644 index 6079a40..0000000 --- a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/PacketListener.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.listeners; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; -import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.util.Vector; - -public abstract class PacketListener implements Listener { - protected JavaPlugin plugin; - - public static PacketListener construct(JavaPlugin plugin) throws IllegalStateException { - String packageName = Bukkit.getServer().getClass().getPackage().getName(); - String version = packageName.substring(packageName.lastIndexOf('.') + 1); - - plugin.getLogger().info("Initializing the packet handler for Minecraft version " + version + "..."); - - try { - final Class clazz = Class.forName("tech.sbdevelopment.mapreflectionapi.nms.PacketListener_" + version); - if (PacketListener.class.isAssignableFrom(clazz)) { - return (PacketListener) clazz.getDeclaredConstructor().newInstance(); - } else { - throw new IllegalStateException("Plugin corrupted! Detected invalid PacketListener class."); - } - } catch (Exception ex) { - throw new IllegalStateException("This Minecraft version (" + version + ") is not supported! Contact the developer to get support."); - } - } - - public void init(JavaPlugin plugin) { - this.plugin = plugin; - Bukkit.getPluginManager().registerEvents(this, plugin); - } - - @EventHandler - public void onJoin(PlayerJoinEvent e) { - injectPlayer(e.getPlayer()); - } - - @EventHandler - public void onQuit(PlayerQuitEvent e) { - removePlayer(e.getPlayer()); - } - - protected abstract void injectPlayer(Player p); - - public abstract void removePlayer(Player p); - - protected abstract Vector vec3DToVector(Object vec3d); - - protected boolean hasField(Object packet, String field) { - try { - packet.getClass().getDeclaredField(field); - return true; - } catch (NoSuchFieldException ex) { - return false; - } - } -} diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtil.java b/API/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtil.java deleted file mode 100644 index 9c508a7..0000000 --- a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtil.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.util; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; - -public class ReflectionUtil { - public static Object getField(Object packet, String field) throws NoSuchFieldException, IllegalAccessException { - Field f = packet.getClass().getDeclaredField(field); - f.setAccessible(true); - return f.get(packet); - } - - public static Object getField(Class clazz, String field) throws NoSuchFieldException, IllegalAccessException { - Field f = clazz.getDeclaredField(field); - f.setAccessible(true); - return f.get(null); - } - - public static void setField(Object packet, String field, Object value) throws NoSuchFieldException, IllegalAccessException { - Field f = packet.getClass().getDeclaredField(field); - f.setAccessible(true); - f.set(packet, value); - } - - public static Object getValue(Object packet, String method) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { - Method m = packet.getClass().getDeclaredMethod(method, null); - m.setAccessible(true); - return m.invoke(packet, null); - } -} diff --git a/Dist/pom.xml b/Dist/pom.xml deleted file mode 100644 index 29d8267..0000000 --- a/Dist/pom.xml +++ /dev/null @@ -1,101 +0,0 @@ - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - jar - - MapReflectionAPI-Dist - - - ../target - ${project.parent.name}-${project.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - org.apache.maven.plugins - maven-shade-plugin - 3.3.0 - - - package - - shade - - - false - - - - - tech.sbdevelopment:MapReflectionAPI* - - - - - - - - - - - - tech.sbdevelopment - MapReflectionAPI-API - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_19_R1 - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_18_R2 - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_16_R3 - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_17_R1 - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_15_R1 - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_14_R1 - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_13_R2 - ${project.parent.version} - - - tech.sbdevelopment - MapReflectionAPI-NMS-v1_12_R1 - ${project.parent.version} - - - \ No newline at end of file diff --git a/NMS-v1_12_R1/pom.xml b/NMS-v1_12_R1/pom.xml deleted file mode 100644 index 97d3164..0000000 --- a/NMS-v1_12_R1/pom.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_12_R1 - - - 1.12.2-R0.1-SNAPSHOT - 11 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_12_R1.java b/NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_12_R1.java deleted file mode 100644 index 1063510..0000000 --- a/NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_12_R1.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.server.v1_12_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class PacketListener_v1_12_R1 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap) { - PacketPlayOutMap packetPlayOutMap = (PacketPlayOutMap) packet; - - int id = (int) getField(packetPlayOutMap, "a"); - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity) { - PacketPlayInUseEntity packetPlayInUseEntity = (PacketPlayInUseEntity) packet; - - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - PacketPlayInUseEntity.EnumEntityUseAction action = packetPlayInUseEntity.a(); //action - EnumHand hand = packetPlayInUseEntity.b(); //hand - Vec3D pos = packetPlayInUseEntity.c(); //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, action.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot) { - PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) packet; - - int slot = packetPlayInSetCreativeSlot.a(); - ItemStack item = packetPlayInSetCreativeSlot.getItemStack(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel.pipeline(); - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel; - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D)) return new Vector(0, 0, 0); - - Vec3D vec3dObj = (Vec3D) vec3d; - return new Vector(vec3dObj.x, vec3dObj.y, vec3dObj.z); - } -} diff --git a/NMS-v1_13_R2/pom.xml b/NMS-v1_13_R2/pom.xml deleted file mode 100644 index 1e53137..0000000 --- a/NMS-v1_13_R2/pom.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_13_R2 - - - 1.13.2-R0.1-SNAPSHOT - 11 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_13_R2.java b/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_13_R2.java deleted file mode 100644 index cc34470..0000000 --- a/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_13_R2.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_13_R2.PacketPlayOutMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; -import org.bukkit.entity.Player; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MapSender_v1_13_R2 { - private static final List sendQueue = new ArrayList<>(); - private static int senderID = -1; - - public static void addToQueue(final int id, final ArrayImage content, final Player player) { - QueuedMap toSend = new QueuedMap(id, content, player); - if (sendQueue.contains(toSend)) return; - sendQueue.add(toSend); - - runSender(); - } - - private static void runSender() { - if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty()) - return; - - senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> { - if (sendQueue.isEmpty()) return; - - for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) { - QueuedMap current = sendQueue.get(0); - if (current == null) return; - - sendMap(current.id, current.image, current.player); - - if (!sendQueue.isEmpty()) sendQueue.remove(0); - } - }, 0, 2); - } - - public static void sendMap(final int id0, final ArrayImage content, final Player player) { - if (player == null || !player.isOnline()) { - List toRemove = new ArrayList<>(); - for (QueuedMap qMap : sendQueue) { - if (qMap == null) continue; - - if (qMap.player == null || !qMap.player.isOnline()) { - toRemove.add(qMap); - } - } - Bukkit.getScheduler().cancelTask(senderID); - sendQueue.removeAll(toRemove); - - return; - } - - final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //??? - new ArrayList<>(), //Icons - content.array, //Data - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY //Y size (2nd Y pos) - ); - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - static final class QueuedMap { - private final int id; - private final ArrayImage image; - private final Player player; - - QueuedMap(int id, ArrayImage image, Player player) { - this.id = id; - this.image = image; - this.player = player; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - var that = (QueuedMap) obj; - return this.id == that.id && - Objects.equals(this.image, that.image) && - Objects.equals(this.player, that.player); - } - - @Override - public int hashCode() { - return Objects.hash(id, image, player); - } - - @Override - public String toString() { - return "QueuedMap[" + - "id=" + id + ", " + - "image=" + image + ", " + - "player=" + player + ']'; - } - } -} diff --git a/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_13_R2.java b/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_13_R2.java deleted file mode 100644 index 13b0efa..0000000 --- a/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_13_R2.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_13_R2.*; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_13_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; -import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; - -import java.util.*; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class MapWrapper_v1_13_R2 extends MapWrapper { - protected MapController controller = new MapController() { - private final Map viewers = new HashMap<>(); - - @Override - public void addViewer(Player player) throws MapLimitExceededException { - if (!isViewing(player)) { - viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player)); - } - } - - @Override - public void removeViewer(OfflinePlayer player) { - viewers.remove(player.getUniqueId()); - } - - @Override - public void clearViewers() { - for (UUID uuid : viewers.keySet()) { - viewers.remove(uuid); - } - } - - @Override - public boolean isViewing(OfflinePlayer player) { - if (player == null) return false; - return viewers.containsKey(player.getUniqueId()); - } - - @Override - public int getMapId(OfflinePlayer player) { - if (isViewing(player)) { - return viewers.get(player.getUniqueId()); - } - return -1; - } - - @Override - public void update(ArrayImage content) { - MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); - if (duplicate != null) { - MapWrapper_v1_13_R2.this.content = duplicate.getContent(); - return; - } - - MapWrapper_v1_13_R2.this.content = content; - - for (UUID id : viewers.keySet()) { - sendContent(Bukkit.getPlayer(id)); - } - } - - @Override - public ArrayImage getContent() { - return MapWrapper_v1_13_R2.this.getContent(); - } - - @Override - public void sendContent(Player player) { - sendContent(player, false); - } - - @Override - public void sendContent(Player player, boolean withoutQueue) { - if (!isViewing(player)) return; - - int id = getMapId(player); - if (withoutQueue) { - MapSender_v1_13_R2.sendMap(id, MapWrapper_v1_13_R2.this.content, player); - } else { - MapSender_v1_13_R2.addToQueue(id, MapWrapper_v1_13_R2.this.content, player); - } - } - - @Override - public void showInInventory(Player player, int slot, boolean force) { - if (!isViewing(player)) return; - - if (player.getGameMode() == GameMode.CREATIVE && !force) return; - - if (slot < 9) { - slot += 36; - } else if (slot > 35 && slot != 45) { - slot = 8 - (slot - 36); - } - - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().defaultContainer.windowId; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - net.minecraft.server.v1_13_R2.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - - @Override - public void showInInventory(Player player, int slot) { - showInInventory(player, slot, false); - } - - @Override - public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.FILLED_MAP && !force) return; - showInInventory(player, player.getInventory().getHeldItemSlot(), force); - } - - @Override - public void showInHand(Player player) { - showInHand(player, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame) { - showInFrame(player, frame, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.FILLED_MAP && !force) return; - showInFrame(player, frame.getEntityId()); - } - - @Override - public void showInFrame(Player player, int entityId) { - showInFrame(player, entityId, null); - } - - @Override - public void showInFrame(Player player, int entityId, String debugInfo) { - if (!isViewing(player)) return; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - if (debugInfo != null) { - ItemMeta itemMeta = stack.getItemMeta(); - itemMeta.setDisplayName(debugInfo); - stack.setItemMeta(itemMeta); - } - - Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> { - ItemFrame frame = getItemFrameById(player.getWorld(), entityId); - if (frame != null) { - frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_13_R2.this)); - } - - sendItemFramePacket(player, entityId, stack, getMapId(player)); - }); - } - - @Override - public void clearFrame(Player player, int entityId) { - - } - - @Override - public void clearFrame(Player player, ItemFrame frame) { - - } - - @Override - public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; - - Entity entity = craftWorld.getHandle().getEntity(entityId); - if (entity == null) return null; - - org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); - if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity; - - return null; - } - - private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.server.v1_13_R2.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - nmsStack.getOrCreateTag().setInt("map", mapId); //getOrCreateTag putInt - - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); - - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "e"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - }; - - public MapWrapper_v1_13_R2(ArrayImage image) { - super(image); - } - - @Override - public MapController getController() { - return controller; - } -} diff --git a/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_13_R2.java b/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_13_R2.java deleted file mode 100644 index e8b28ce..0000000 --- a/NMS-v1_13_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_13_R2.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.server.v1_13_R2.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_13_R2.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class PacketListener_v1_13_R2 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap) { - PacketPlayOutMap packetPlayOutMap = (PacketPlayOutMap) packet; - - int id = (int) getField(packetPlayOutMap, "a"); - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity) { - PacketPlayInUseEntity packetPlayInUseEntity = (PacketPlayInUseEntity) packet; - - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - PacketPlayInUseEntity.EnumEntityUseAction action = packetPlayInUseEntity.b(); //action - EnumHand hand = packetPlayInUseEntity.c(); //hand - Vec3D pos = packetPlayInUseEntity.d(); //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, action.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot) { - PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) packet; - - int slot = packetPlayInSetCreativeSlot.b(); - ItemStack item = packetPlayInSetCreativeSlot.getItemStack(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel.pipeline(); - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel; - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D)) return new Vector(0, 0, 0); - - Vec3D vec3dObj = (Vec3D) vec3d; - return new Vector(vec3dObj.x, vec3dObj.y, vec3dObj.z); - } -} diff --git a/NMS-v1_14_R1/pom.xml b/NMS-v1_14_R1/pom.xml deleted file mode 100644 index 51f3551..0000000 --- a/NMS-v1_14_R1/pom.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_14_R1 - - - 1.14.4-R0.1-SNAPSHOT - 11 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_14_R1.java b/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_14_R1.java deleted file mode 100644 index afc893e..0000000 --- a/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_14_R1.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_14_R1.PacketPlayOutMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MapSender_v1_14_R1 { - private static final List sendQueue = new ArrayList<>(); - private static int senderID = -1; - - public static void addToQueue(final int id, final ArrayImage content, final Player player) { - QueuedMap toSend = new QueuedMap(id, content, player); - if (sendQueue.contains(toSend)) return; - sendQueue.add(toSend); - - runSender(); - } - - private static void runSender() { - if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty()) - return; - - senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> { - if (sendQueue.isEmpty()) return; - - for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) { - QueuedMap current = sendQueue.get(0); - if (current == null) return; - - sendMap(current.id, current.image, current.player); - - if (!sendQueue.isEmpty()) sendQueue.remove(0); - } - }, 0, 2); - } - - public static void sendMap(final int id0, final ArrayImage content, final Player player) { - if (player == null || !player.isOnline()) { - List toRemove = new ArrayList<>(); - for (QueuedMap qMap : sendQueue) { - if (qMap == null) continue; - - if (qMap.player == null || !qMap.player.isOnline()) { - toRemove.add(qMap); - } - } - Bukkit.getScheduler().cancelTask(senderID); - sendQueue.removeAll(toRemove); - - return; - } - - final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //Tracking position - false, //Locked - new ArrayList<>(), //Icons - content.array, //Data - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY //Y size (2nd Y pos) - ); - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - static final class QueuedMap { - private final int id; - private final ArrayImage image; - private final Player player; - - QueuedMap(int id, ArrayImage image, Player player) { - this.id = id; - this.image = image; - this.player = player; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - var that = (QueuedMap) obj; - return this.id == that.id && - Objects.equals(this.image, that.image) && - Objects.equals(this.player, that.player); - } - - @Override - public int hashCode() { - return Objects.hash(id, image, player); - } - - @Override - public String toString() { - return "QueuedMap[" + - "id=" + id + ", " + - "image=" + image + ", " + - "player=" + player + ']'; - } - } -} diff --git a/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_14_R1.java b/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_14_R1.java deleted file mode 100644 index 4e526c9..0000000 --- a/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_14_R1.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_14_R1.*; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; -import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; - -import java.util.*; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class MapWrapper_v1_14_R1 extends MapWrapper { - protected MapController controller = new MapController() { - private final Map viewers = new HashMap<>(); - - @Override - public void addViewer(Player player) throws MapLimitExceededException { - if (!isViewing(player)) { - viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player)); - } - } - - @Override - public void removeViewer(OfflinePlayer player) { - viewers.remove(player.getUniqueId()); - } - - @Override - public void clearViewers() { - for (UUID uuid : viewers.keySet()) { - viewers.remove(uuid); - } - } - - @Override - public boolean isViewing(OfflinePlayer player) { - if (player == null) return false; - return viewers.containsKey(player.getUniqueId()); - } - - @Override - public int getMapId(OfflinePlayer player) { - if (isViewing(player)) { - return viewers.get(player.getUniqueId()); - } - return -1; - } - - @Override - public void update(ArrayImage content) { - MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); - if (duplicate != null) { - MapWrapper_v1_14_R1.this.content = duplicate.getContent(); - return; - } - - MapWrapper_v1_14_R1.this.content = content; - - for (UUID id : viewers.keySet()) { - sendContent(Bukkit.getPlayer(id)); - } - } - - @Override - public ArrayImage getContent() { - return MapWrapper_v1_14_R1.this.getContent(); - } - - @Override - public void sendContent(Player player) { - sendContent(player, false); - } - - @Override - public void sendContent(Player player, boolean withoutQueue) { - if (!isViewing(player)) return; - - int id = getMapId(player); - if (withoutQueue) { - MapSender_v1_14_R1.sendMap(id, MapWrapper_v1_14_R1.this.content, player); - } else { - MapSender_v1_14_R1.addToQueue(id, MapWrapper_v1_14_R1.this.content, player); - } - } - - @Override - public void showInInventory(Player player, int slot, boolean force) { - if (!isViewing(player)) return; - - if (player.getGameMode() == GameMode.CREATIVE && !force) return; - - if (slot < 9) { - slot += 36; - } else if (slot > 35 && slot != 45) { - slot = 8 - (slot - 36); - } - - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().defaultContainer.windowId; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - net.minecraft.server.v1_14_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - - @Override - public void showInInventory(Player player, int slot) { - showInInventory(player, slot, false); - } - - @Override - public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.FILLED_MAP && !force) return; - showInInventory(player, player.getInventory().getHeldItemSlot(), force); - } - - @Override - public void showInHand(Player player) { - showInHand(player, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame) { - showInFrame(player, frame, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.FILLED_MAP && !force) return; - showInFrame(player, frame.getEntityId()); - } - - @Override - public void showInFrame(Player player, int entityId) { - showInFrame(player, entityId, null); - } - - @Override - public void showInFrame(Player player, int entityId, String debugInfo) { - if (!isViewing(player)) return; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - if (debugInfo != null) { - ItemMeta itemMeta = stack.getItemMeta(); - itemMeta.setDisplayName(debugInfo); - stack.setItemMeta(itemMeta); - } - - Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> { - ItemFrame frame = getItemFrameById(player.getWorld(), entityId); - if (frame != null) { - frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_14_R1.this)); - } - - sendItemFramePacket(player, entityId, stack, getMapId(player)); - }); - } - - @Override - public void clearFrame(Player player, int entityId) { - - } - - @Override - public void clearFrame(Player player, ItemFrame frame) { - - } - - @Override - public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; - - Entity entity = craftWorld.getHandle().getEntity(entityId); - if (entity == null) return null; - - org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); - if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity; - - return null; - } - - private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.server.v1_14_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - nmsStack.getOrCreateTag().setInt("map", mapId); //getOrCreateTag putInt - - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); - - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "ITEM"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - }; - - public MapWrapper_v1_14_R1(ArrayImage image) { - super(image); - } - - @Override - public MapController getController() { - return controller; - } -} diff --git a/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_14_R1.java b/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_14_R1.java deleted file mode 100644 index 1083801..0000000 --- a/NMS-v1_14_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_14_R1.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.server.v1_14_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class PacketListener_v1_14_R1 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap) { - PacketPlayOutMap packetPlayOutMap = (PacketPlayOutMap) packet; - - int id = (int) getField(packetPlayOutMap, "a"); - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity) { - PacketPlayInUseEntity packetPlayInUseEntity = (PacketPlayInUseEntity) packet; - - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - PacketPlayInUseEntity.EnumEntityUseAction action = packetPlayInUseEntity.b(); //action - EnumHand hand = packetPlayInUseEntity.c(); //hand - Vec3D pos = packetPlayInUseEntity.d(); //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, action.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot) { - PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) packet; - - int slot = packetPlayInSetCreativeSlot.b(); - ItemStack item = packetPlayInSetCreativeSlot.getItemStack(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel.pipeline(); - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel; - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D)) return new Vector(0, 0, 0); - - Vec3D vec3dObj = (Vec3D) vec3d; - return new Vector(vec3dObj.x, vec3dObj.y, vec3dObj.z); - } -} diff --git a/NMS-v1_15_R1/pom.xml b/NMS-v1_15_R1/pom.xml deleted file mode 100644 index cce4f6d..0000000 --- a/NMS-v1_15_R1/pom.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_15_R1 - - - 1.15.2-R0.1-SNAPSHOT - 11 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_15_R1.java b/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_15_R1.java deleted file mode 100644 index e16c48e..0000000 --- a/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_15_R1.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_15_R1.PacketPlayOutMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MapSender_v1_15_R1 { - private static final List sendQueue = new ArrayList<>(); - private static int senderID = -1; - - public static void addToQueue(final int id, final ArrayImage content, final Player player) { - QueuedMap toSend = new QueuedMap(id, content, player); - if (sendQueue.contains(toSend)) return; - sendQueue.add(toSend); - - runSender(); - } - - private static void runSender() { - if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty()) - return; - - senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> { - if (sendQueue.isEmpty()) return; - - for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) { - QueuedMap current = sendQueue.get(0); - if (current == null) return; - - sendMap(current.id, current.image, current.player); - - if (!sendQueue.isEmpty()) sendQueue.remove(0); - } - }, 0, 2); - } - - public static void sendMap(final int id0, final ArrayImage content, final Player player) { - if (player == null || !player.isOnline()) { - List toRemove = new ArrayList<>(); - for (QueuedMap qMap : sendQueue) { - if (qMap == null) continue; - - if (qMap.player == null || !qMap.player.isOnline()) { - toRemove.add(qMap); - } - } - Bukkit.getScheduler().cancelTask(senderID); - sendQueue.removeAll(toRemove); - - return; - } - - final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //Tracking position - false, //Locked - new ArrayList<>(), //Icons - content.array, //Data - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY //Y size (2nd Y pos) - ); - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - static final class QueuedMap { - private final int id; - private final ArrayImage image; - private final Player player; - - QueuedMap(int id, ArrayImage image, Player player) { - this.id = id; - this.image = image; - this.player = player; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - var that = (QueuedMap) obj; - return this.id == that.id && - Objects.equals(this.image, that.image) && - Objects.equals(this.player, that.player); - } - - @Override - public int hashCode() { - return Objects.hash(id, image, player); - } - - @Override - public String toString() { - return "QueuedMap[" + - "id=" + id + ", " + - "image=" + image + ", " + - "player=" + player + ']'; - } - } -} diff --git a/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_15_R1.java b/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_15_R1.java deleted file mode 100644 index 51db039..0000000 --- a/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_15_R1.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_15_R1.*; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_15_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; -import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; - -import java.util.*; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class MapWrapper_v1_15_R1 extends MapWrapper { - - protected MapController controller = new MapController() { - private final Map viewers = new HashMap<>(); - - @Override - public void addViewer(Player player) throws MapLimitExceededException { - if (!isViewing(player)) { - viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player)); - } - } - - @Override - public void removeViewer(OfflinePlayer player) { - viewers.remove(player.getUniqueId()); - } - - @Override - public void clearViewers() { - for (UUID uuid : viewers.keySet()) { - viewers.remove(uuid); - } - } - - @Override - public boolean isViewing(OfflinePlayer player) { - if (player == null) return false; - return viewers.containsKey(player.getUniqueId()); - } - - @Override - public int getMapId(OfflinePlayer player) { - if (isViewing(player)) { - return viewers.get(player.getUniqueId()); - } - return -1; - } - - @Override - public void update(ArrayImage content) { - MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); - if (duplicate != null) { - MapWrapper_v1_15_R1.this.content = duplicate.getContent(); - return; - } - - MapWrapper_v1_15_R1.this.content = content; - - for (UUID id : viewers.keySet()) { - sendContent(Bukkit.getPlayer(id)); - } - } - - @Override - public ArrayImage getContent() { - return MapWrapper_v1_15_R1.this.getContent(); - } - - @Override - public void sendContent(Player player) { - sendContent(player, false); - } - - @Override - public void sendContent(Player player, boolean withoutQueue) { - if (!isViewing(player)) return; - - int id = getMapId(player); - if (withoutQueue) { - MapSender_v1_15_R1.sendMap(id, MapWrapper_v1_15_R1.this.content, player); - } else { - MapSender_v1_15_R1.addToQueue(id, MapWrapper_v1_15_R1.this.content, player); - } - } - - @Override - public void showInInventory(Player player, int slot, boolean force) { - if (!isViewing(player)) return; - - if (player.getGameMode() == GameMode.CREATIVE && !force) return; - - if (slot < 9) { - slot += 36; - } else if (slot > 35 && slot != 45) { - slot = 8 - (slot - 36); - } - - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().defaultContainer.windowId; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - net.minecraft.server.v1_15_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - - @Override - public void showInInventory(Player player, int slot) { - showInInventory(player, slot, false); - } - - @Override - public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.FILLED_MAP && !force) return; - showInInventory(player, player.getInventory().getHeldItemSlot(), force); - } - - @Override - public void showInHand(Player player) { - showInHand(player, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame) { - showInFrame(player, frame, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.FILLED_MAP && !force) return; - showInFrame(player, frame.getEntityId()); - } - - @Override - public void showInFrame(Player player, int entityId) { - showInFrame(player, entityId, null); - } - - @Override - public void showInFrame(Player player, int entityId, String debugInfo) { - if (!isViewing(player)) return; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - if (debugInfo != null) { - ItemMeta itemMeta = stack.getItemMeta(); - itemMeta.setDisplayName(debugInfo); - stack.setItemMeta(itemMeta); - } - - Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> { - ItemFrame frame = getItemFrameById(player.getWorld(), entityId); - if (frame != null) { - frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_15_R1.this)); - } - - sendItemFramePacket(player, entityId, stack, getMapId(player)); - }); - } - - @Override - public void clearFrame(Player player, int entityId) { - - } - - @Override - public void clearFrame(Player player, ItemFrame frame) { - - } - - @Override - public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; - - Entity entity = craftWorld.getHandle().getEntity(entityId); - if (entity == null) return null; - - org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); - if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity; - - return null; - } - - private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.server.v1_15_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - nmsStack.getOrCreateTag().setInt("map", mapId); //getOrCreateTag putInt - - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); - - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "ITEM"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - }; - - public MapWrapper_v1_15_R1(ArrayImage image) { - super(image); - } - - @Override - public MapController getController() { - return controller; - } -} diff --git a/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_15_R1.java b/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_15_R1.java deleted file mode 100644 index ba807c1..0000000 --- a/NMS-v1_15_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_15_R1.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.server.v1_15_R1.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class PacketListener_v1_15_R1 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap) { - PacketPlayOutMap packetPlayOutMap = (PacketPlayOutMap) packet; - - int id = (int) getField(packetPlayOutMap, "a"); - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity) { - PacketPlayInUseEntity packetPlayInUseEntity = (PacketPlayInUseEntity) packet; - - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - PacketPlayInUseEntity.EnumEntityUseAction action = packetPlayInUseEntity.b(); //action - EnumHand hand = packetPlayInUseEntity.c(); //hand - Vec3D pos = packetPlayInUseEntity.d(); //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, action.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot) { - PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) packet; - - int slot = packetPlayInSetCreativeSlot.b(); - ItemStack item = packetPlayInSetCreativeSlot.getItemStack(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel.pipeline(); - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel; - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D)) return new Vector(0, 0, 0); - - Vec3D vec3dObj = (Vec3D) vec3d; - return new Vector(vec3dObj.x, vec3dObj.y, vec3dObj.z); - } -} diff --git a/NMS-v1_16_R3/pom.xml b/NMS-v1_16_R3/pom.xml deleted file mode 100644 index 17b221c..0000000 --- a/NMS-v1_16_R3/pom.xml +++ /dev/null @@ -1,54 +0,0 @@ - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_16_R3 - - - 1.16.4-R0.1-SNAPSHOT - 11 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_16_R3.java b/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_16_R3.java deleted file mode 100644 index 661205c..0000000 --- a/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_16_R3.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_16_R3.PacketPlayOutMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; -import org.bukkit.entity.Player; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -public class MapSender_v1_16_R3 { - private static final List sendQueue = new ArrayList<>(); - private static int senderID = -1; - - public static void addToQueue(final int id, final ArrayImage content, final Player player) { - QueuedMap toSend = new QueuedMap(id, content, player); - if (sendQueue.contains(toSend)) return; - sendQueue.add(toSend); - - runSender(); - } - - private static void runSender() { - if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty()) - return; - - senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> { - if (sendQueue.isEmpty()) return; - - for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) { - QueuedMap current = sendQueue.get(0); - if (current == null) return; - - sendMap(current.id, current.image, current.player); - - if (!sendQueue.isEmpty()) sendQueue.remove(0); - } - }, 0, 2); - } - - public static void sendMap(final int id0, final ArrayImage content, final Player player) { - if (player == null || !player.isOnline()) { - List toRemove = new ArrayList<>(); - for (QueuedMap qMap : sendQueue) { - if (qMap == null) continue; - - if (qMap.player == null || !qMap.player.isOnline()) { - toRemove.add(qMap); - } - } - Bukkit.getScheduler().cancelTask(senderID); - sendQueue.removeAll(toRemove); - - return; - } - - final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //Tracking position - false, //Locked - new ArrayList<>(), //Icons - content.array, //Data - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY //Y size (2nd Y pos) - ); - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - static final class QueuedMap { - private final int id; - private final ArrayImage image; - private final Player player; - - QueuedMap(int id, ArrayImage image, Player player) { - this.id = id; - this.image = image; - this.player = player; - } - - @Override - public boolean equals(Object obj) { - if (obj == this) return true; - if (obj == null || obj.getClass() != this.getClass()) return false; - var that = (QueuedMap) obj; - return this.id == that.id && - Objects.equals(this.image, that.image) && - Objects.equals(this.player, that.player); - } - - @Override - public int hashCode() { - return Objects.hash(id, image, player); - } - - @Override - public String toString() { - return "QueuedMap[" + - "id=" + id + ", " + - "image=" + image + ", " + - "player=" + player + ']'; - } - } -} diff --git a/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_16_R3.java b/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_16_R3.java deleted file mode 100644 index 061f41b..0000000 --- a/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_16_R3.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.server.v1_16_R3.*; -import org.bukkit.Material; -import org.bukkit.World; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_16_R3.CraftWorld; -import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; -import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; - -import java.util.*; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class MapWrapper_v1_16_R3 extends MapWrapper { - protected MapController controller = new MapController() { - private final Map viewers = new HashMap<>(); - - @Override - public void addViewer(Player player) throws MapLimitExceededException { - if (!isViewing(player)) { - viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player)); - } - } - - @Override - public void removeViewer(OfflinePlayer player) { - viewers.remove(player.getUniqueId()); - } - - @Override - public void clearViewers() { - for (UUID uuid : viewers.keySet()) { - viewers.remove(uuid); - } - } - - @Override - public boolean isViewing(OfflinePlayer player) { - if (player == null) return false; - return viewers.containsKey(player.getUniqueId()); - } - - @Override - public int getMapId(OfflinePlayer player) { - if (isViewing(player)) { - return viewers.get(player.getUniqueId()); - } - return -1; - } - - @Override - public void update(ArrayImage content) { - MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); - if (duplicate != null) { - MapWrapper_v1_16_R3.this.content = duplicate.getContent(); - return; - } - - MapWrapper_v1_16_R3.this.content = content; - - for (UUID id : viewers.keySet()) { - sendContent(Bukkit.getPlayer(id)); - } - } - - @Override - public ArrayImage getContent() { - return MapWrapper_v1_16_R3.this.getContent(); - } - - @Override - public void sendContent(Player player) { - sendContent(player, false); - } - - @Override - public void sendContent(Player player, boolean withoutQueue) { - if (!isViewing(player)) return; - - int id = getMapId(player); - if (withoutQueue) { - MapSender_v1_16_R3.sendMap(id, MapWrapper_v1_16_R3.this.content, player); - } else { - MapSender_v1_16_R3.addToQueue(id, MapWrapper_v1_16_R3.this.content, player); - } - } - - @Override - public void showInInventory(Player player, int slot, boolean force) { - if (!isViewing(player)) return; - - if (player.getGameMode() == GameMode.CREATIVE && !force) return; - - if (slot < 9) { - slot += 36; - } else if (slot > 35 && slot != 45) { - slot = 8 - (slot - 36); - } - - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().defaultContainer.windowId; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - - @Override - public void showInInventory(Player player, int slot) { - showInInventory(player, slot, false); - } - - @Override - public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.FILLED_MAP && !force) return; - showInInventory(player, player.getInventory().getHeldItemSlot(), force); - } - - @Override - public void showInHand(Player player) { - showInHand(player, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame) { - showInFrame(player, frame, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.FILLED_MAP && !force) return; - showInFrame(player, frame.getEntityId()); - } - - @Override - public void showInFrame(Player player, int entityId) { - showInFrame(player, entityId, null); - } - - @Override - public void showInFrame(Player player, int entityId, String debugInfo) { - if (!isViewing(player)) return; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - if (debugInfo != null) { - ItemMeta itemMeta = stack.getItemMeta(); - itemMeta.setDisplayName(debugInfo); - stack.setItemMeta(itemMeta); - } - - Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> { - ItemFrame frame = getItemFrameById(player.getWorld(), entityId); - if (frame != null) { - frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_16_R3.this)); - } - - sendItemFramePacket(player, entityId, stack, getMapId(player)); - }); - } - - @Override - public void clearFrame(Player player, int entityId) { - - } - - @Override - public void clearFrame(Player player, ItemFrame frame) { - - } - - @Override - public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; - - Entity entity = craftWorld.getHandle().getEntity(entityId); - if (entity == null) return null; - - org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); - if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity; - - return null; - } - - private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.server.v1_16_R3.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - nmsStack.getOrCreateTag().setInt("map", mapId); //getOrCreateTag putInt - - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); - - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "ITEM"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } - }; - - public MapWrapper_v1_16_R3(ArrayImage image) { - super(image); - } - - @Override - public MapController getController() { - return controller; - } -} diff --git a/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_16_R3.java b/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_16_R3.java deleted file mode 100644 index 3e846ba..0000000 --- a/NMS-v1_16_R3/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_16_R3.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.server.v1_16_R3.*; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_16_R3.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class PacketListener_v1_16_R3 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap) { - PacketPlayOutMap packetPlayOutMap = (PacketPlayOutMap) packet; - - int id = (int) getField(packetPlayOutMap, "a"); - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity) { - PacketPlayInUseEntity packetPlayInUseEntity = (PacketPlayInUseEntity) packet; - - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - PacketPlayInUseEntity.EnumEntityUseAction action = packetPlayInUseEntity.b(); //action - EnumHand hand = packetPlayInUseEntity.c(); //hand - Vec3D pos = packetPlayInUseEntity.d(); //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, action.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot) { - PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot = (PacketPlayInSetCreativeSlot) packet; - - int slot = packetPlayInSetCreativeSlot.b(); - ItemStack item = packetPlayInSetCreativeSlot.getItemStack(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel.pipeline(); - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().playerConnection.networkManager.channel; - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D)) return new Vector(0, 0, 0); - - Vec3D vec3dObj = (Vec3D) vec3d; - return new Vector(vec3dObj.x, vec3dObj.y, vec3dObj.z); - } -} diff --git a/NMS-v1_17_R1/pom.xml b/NMS-v1_17_R1/pom.xml deleted file mode 100644 index b36444c..0000000 --- a/NMS-v1_17_R1/pom.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_17_R1 - - - 1.17.1-R0.1-SNAPSHOT - 16 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_17_R1.java b/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_17_R1.java deleted file mode 100644 index c639def..0000000 --- a/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_17_R1.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.network.protocol.game.PacketPlayOutMap; -import net.minecraft.world.level.saveddata.maps.WorldMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; - -import java.util.ArrayList; -import java.util.List; - -public class MapSender_v1_17_R1 { - private static final List sendQueue = new ArrayList<>(); - private static int senderID = -1; - - public static void addToQueue(final int id, final ArrayImage content, final Player player) { - QueuedMap toSend = new QueuedMap(id, content, player); - if (sendQueue.contains(toSend)) return; - sendQueue.add(toSend); - - runSender(); - } - - private static void runSender() { - if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty()) - return; - - senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> { - if (sendQueue.isEmpty()) return; - - for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) { - QueuedMap current = sendQueue.get(0); - if (current == null) return; - - sendMap(current.id, current.image, current.player); - - if (!sendQueue.isEmpty()) sendQueue.remove(0); - } - }, 0, 2); - } - - public static void sendMap(final int id0, final ArrayImage content, final Player player) { - if (player == null || !player.isOnline()) { - List toRemove = new ArrayList<>(); - for (QueuedMap qMap : sendQueue) { - if (qMap == null) continue; - - if (qMap.player == null || !qMap.player.isOnline()) { - toRemove.add(qMap); - } - } - Bukkit.getScheduler().cancelTask(senderID); - sendQueue.removeAll(toRemove); - - return; - } - - final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - WorldMap.b updateData = new WorldMap.b( - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY, //Y size (2nd Y pos) - content.array //Data - ); - - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //Show icons - new ArrayList<>(), //Icons - updateData - ); - - ((CraftPlayer) player).getHandle().b.sendPacket(packet); //connection send() - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - record QueuedMap(int id, ArrayImage image, Player player) { - } -} \ No newline at end of file diff --git a/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_17_R1.java b/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_17_R1.java deleted file mode 100644 index e31eb45..0000000 --- a/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_17_R1.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata; -import net.minecraft.network.protocol.game.PacketPlayOutSetSlot; -import net.minecraft.network.syncher.DataWatcher; -import net.minecraft.network.syncher.DataWatcherObject; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.decoration.EntityItemFrame; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_17_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; -import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; - -import java.util.*; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class MapWrapper_v1_17_R1 extends MapWrapper { - protected MapController controller = new MapController() { - private final Map viewers = new HashMap<>(); - - @Override - public void addViewer(Player player) throws MapLimitExceededException { - if (!isViewing(player)) { - viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player)); - } - } - - @Override - public void removeViewer(OfflinePlayer player) { - viewers.remove(player.getUniqueId()); - } - - @Override - public void clearViewers() { - for (UUID uuid : viewers.keySet()) { - viewers.remove(uuid); - } - } - - @Override - public boolean isViewing(OfflinePlayer player) { - if (player == null) return false; - return viewers.containsKey(player.getUniqueId()); - } - - @Override - public int getMapId(OfflinePlayer player) { - if (isViewing(player)) { - return viewers.get(player.getUniqueId()); - } - return -1; - } - - @Override - public void update(ArrayImage content) { - MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); - if (duplicate != null) { - MapWrapper_v1_17_R1.this.content = duplicate.getContent(); - return; - } - - MapWrapper_v1_17_R1.this.content = content; - - for (UUID id : viewers.keySet()) { - sendContent(Bukkit.getPlayer(id)); - } - } - - @Override - public ArrayImage getContent() { - return MapWrapper_v1_17_R1.this.getContent(); - } - - @Override - public void sendContent(Player player) { - sendContent(player, false); - } - - @Override - public void sendContent(Player player, boolean withoutQueue) { - if (!isViewing(player)) return; - - int id = getMapId(player); - if (withoutQueue) { - MapSender_v1_17_R1.sendMap(id, MapWrapper_v1_17_R1.this.content, player); - } else { - MapSender_v1_17_R1.addToQueue(id, MapWrapper_v1_17_R1.this.content, player); - } - } - - @Override - public void showInInventory(Player player, int slot, boolean force) { - if (!isViewing(player)) return; - - if (player.getGameMode() == GameMode.CREATIVE && !force) return; - - if (slot < 9) { - slot += 36; - } else if (slot > 35 && slot != 45) { - slot = 8 - (slot - 36); - } - - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().bU.j; //inventoryMenu containerId - int stateId = craftPlayer.getHandle().bU.getStateId(); //inventoryMenu getStateId() - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, stateId, slot, nmsStack); - ((CraftPlayer) player).getHandle().b.sendPacket(packet); - } - - @Override - public void showInInventory(Player player, int slot) { - showInInventory(player, slot, false); - } - - @Override - public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.FILLED_MAP && !force) return; - showInInventory(player, player.getInventory().getHeldItemSlot(), force); - } - - @Override - public void showInHand(Player player) { - showInHand(player, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame) { - showInFrame(player, frame, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.FILLED_MAP && !force) return; - showInFrame(player, frame.getEntityId()); - } - - @Override - public void showInFrame(Player player, int entityId) { - showInFrame(player, entityId, null); - } - - @Override - public void showInFrame(Player player, int entityId, String debugInfo) { - if (!isViewing(player)) return; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - if (debugInfo != null) { - ItemMeta itemMeta = stack.getItemMeta(); - itemMeta.setDisplayName(debugInfo); - stack.setItemMeta(itemMeta); - } - - Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> { - ItemFrame frame = getItemFrameById(player.getWorld(), entityId); - if (frame != null) { - frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_17_R1.this)); - } - - sendItemFramePacket(player, entityId, stack, getMapId(player)); - }); - } - - @Override - public void clearFrame(Player player, int entityId) { - - } - - @Override - public void clearFrame(Player player, ItemFrame frame) { - - } - - @Override - public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; - - Entity entity = craftWorld.getHandle().getEntity(entityId); - if (entity == null) return null; - - if (entity instanceof ItemFrame) return (ItemFrame) entity; - - return null; - } - - private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - nmsStack.getOrCreateTag().setInt("map", mapId); //getOrCreateTag putInt - - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); - - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "ao"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - ((CraftPlayer) player).getHandle().b.sendPacket(packet); - } - }; - - public MapWrapper_v1_17_R1(ArrayImage image) { - super(image); - } - - @Override - public MapController getController() { - return controller; - } -} \ No newline at end of file diff --git a/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_17_R1.java b/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_17_R1.java deleted file mode 100644 index 1b26136..0000000 --- a/NMS-v1_17_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_17_R1.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot; -import net.minecraft.network.protocol.game.PacketPlayInUseEntity; -import net.minecraft.network.protocol.game.PacketPlayOutMap; -import net.minecraft.world.EnumHand; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3D; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_17_R1.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.*; - -public class PacketListener_v1_17_R1 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap packetPlayOutMap) { - int id = (int) getField(packetPlayOutMap, "a"); - - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity packetPlayInUseEntity) { - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - Object action = getField(packetPlayInUseEntity, "b"); //action - Enum actionEnum = (Enum) getValue(action, "a"); //action type - EnumHand hand = hasField(action, "a") ? (EnumHand) getField(action, "a") : null; //hand - Vec3D pos = hasField(action, "b") ? (Vec3D) getField(action, "b") : null; //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, actionEnum.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot) { - int slot = packetPlayInSetCreativeSlot.b(); - ItemStack item = packetPlayInSetCreativeSlot.getItemStack(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().b.a.k.pipeline(); //connection connection channel - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().b.a.k; //connection connection channel - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D vec3dObj)) return new Vector(0, 0, 0); - return new Vector(vec3dObj.b, vec3dObj.c, vec3dObj.d); //x, y, z - } -} \ No newline at end of file diff --git a/NMS-v1_18_R2/pom.xml b/NMS-v1_18_R2/pom.xml deleted file mode 100644 index d3f7388..0000000 --- a/NMS-v1_18_R2/pom.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_18_R2 - - - 1.18.2-R0.1-SNAPSHOT - 17 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_18_R2.java b/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_18_R2.java deleted file mode 100644 index dae512a..0000000 --- a/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_18_R2.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.network.protocol.game.PacketPlayOutMap; -import net.minecraft.world.level.saveddata.maps.WorldMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; -import org.bukkit.entity.Player; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; - -import java.util.ArrayList; -import java.util.List; - -public class MapSender_v1_18_R2 { - private static final List sendQueue = new ArrayList<>(); - private static int senderID = -1; - - public static void addToQueue(final int id, final ArrayImage content, final Player player) { - QueuedMap toSend = new QueuedMap(id, content, player); - if (sendQueue.contains(toSend)) return; - sendQueue.add(toSend); - - runSender(); - } - - private static void runSender() { - if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty()) - return; - - senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> { - if (sendQueue.isEmpty()) return; - - for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) { - QueuedMap current = sendQueue.get(0); - if (current == null) return; - - sendMap(current.id, current.image, current.player); - - if (!sendQueue.isEmpty()) sendQueue.remove(0); - } - }, 0, 2); - } - - public static void sendMap(final int id0, final ArrayImage content, final Player player) { - if (player == null || !player.isOnline()) { - List toRemove = new ArrayList<>(); - for (QueuedMap qMap : sendQueue) { - if (qMap == null) continue; - - if (qMap.player == null || !qMap.player.isOnline()) { - toRemove.add(qMap); - } - } - Bukkit.getScheduler().cancelTask(senderID); - sendQueue.removeAll(toRemove); - - return; - } - - final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - WorldMap.b updateData = new WorldMap.b( - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY, //Y size (2nd Y pos) - content.array //Data - ); - - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //Show icons - new ArrayList<>(), //Icons - updateData - ); - - ((CraftPlayer) player).getHandle().b.a(packet); //connection send() - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - record QueuedMap(int id, ArrayImage image, Player player) { - } -} \ No newline at end of file diff --git a/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_18_R2.java b/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_18_R2.java deleted file mode 100644 index 671c86e..0000000 --- a/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_18_R2.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata; -import net.minecraft.network.protocol.game.PacketPlayOutSetSlot; -import net.minecraft.network.syncher.DataWatcher; -import net.minecraft.network.syncher.DataWatcherObject; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.decoration.EntityItemFrame; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_18_R2.CraftWorld; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; -import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; - -import java.util.*; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class MapWrapper_v1_18_R2 extends MapWrapper { - protected MapController controller = new MapController() { - private final Map viewers = new HashMap<>(); - - @Override - public void addViewer(Player player) throws MapLimitExceededException { - if (!isViewing(player)) { - viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player)); - } - } - - @Override - public void removeViewer(OfflinePlayer player) { - viewers.remove(player.getUniqueId()); - } - - @Override - public void clearViewers() { - for (UUID uuid : viewers.keySet()) { - viewers.remove(uuid); - } - } - - @Override - public boolean isViewing(OfflinePlayer player) { - if (player == null) return false; - return viewers.containsKey(player.getUniqueId()); - } - - @Override - public int getMapId(OfflinePlayer player) { - if (isViewing(player)) { - return viewers.get(player.getUniqueId()); - } - return -1; - } - - @Override - public void update(ArrayImage content) { - MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); - if (duplicate != null) { - MapWrapper_v1_18_R2.this.content = duplicate.getContent(); - return; - } - - MapWrapper_v1_18_R2.this.content = content; - - for (UUID id : viewers.keySet()) { - sendContent(Bukkit.getPlayer(id)); - } - } - - @Override - public ArrayImage getContent() { - return MapWrapper_v1_18_R2.this.getContent(); - } - - @Override - public void sendContent(Player player) { - sendContent(player, false); - } - - @Override - public void sendContent(Player player, boolean withoutQueue) { - if (!isViewing(player)) return; - - int id = getMapId(player); - if (withoutQueue) { - MapSender_v1_18_R2.sendMap(id, MapWrapper_v1_18_R2.this.content, player); - } else { - MapSender_v1_18_R2.addToQueue(id, MapWrapper_v1_18_R2.this.content, player); - } - } - - @Override - public void showInInventory(Player player, int slot, boolean force) { - if (!isViewing(player)) return; - - if (player.getGameMode() == GameMode.CREATIVE && !force) return; - - if (slot < 9) { - slot += 36; - } else if (slot > 35 && slot != 45) { - slot = 8 - (slot - 36); - } - - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().bU.j; //inventoryMenu containerId - int stateId = craftPlayer.getHandle().bU.j(); //inventoryMenu getStateId() - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, stateId, slot, nmsStack); - ((CraftPlayer) player).getHandle().b.a(packet); - } - - @Override - public void showInInventory(Player player, int slot) { - showInInventory(player, slot, false); - } - - @Override - public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.FILLED_MAP && !force) return; - showInInventory(player, player.getInventory().getHeldItemSlot(), force); - } - - @Override - public void showInHand(Player player) { - showInHand(player, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame) { - showInFrame(player, frame, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.FILLED_MAP && !force) return; - showInFrame(player, frame.getEntityId()); - } - - @Override - public void showInFrame(Player player, int entityId) { - showInFrame(player, entityId, null); - } - - @Override - public void showInFrame(Player player, int entityId, String debugInfo) { - if (!isViewing(player)) return; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - if (debugInfo != null) { - ItemMeta itemMeta = stack.getItemMeta(); - itemMeta.setDisplayName(debugInfo); - stack.setItemMeta(itemMeta); - } - - Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> { - ItemFrame frame = getItemFrameById(player.getWorld(), entityId); - if (frame != null) { - frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_18_R2.this)); - } - - sendItemFramePacket(player, entityId, stack, getMapId(player)); - }); - } - - @Override - public void clearFrame(Player player, int entityId) { - - } - - @Override - public void clearFrame(Player player, ItemFrame frame) { - - } - - @Override - public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; - - Entity entity = craftWorld.getHandle().a(entityId); - if (entity == null) return null; - - if (entity instanceof ItemFrame) return (ItemFrame) entity; - - return null; - } - - private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - nmsStack.u().a("map", mapId); //getOrCreateTag putInt - - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); - - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "ao"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - ((CraftPlayer) player).getHandle().b.a(packet); - } - }; - - public MapWrapper_v1_18_R2(ArrayImage image) { - super(image); - } - - @Override - public MapController getController() { - return controller; - } -} diff --git a/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_18_R2.java b/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_18_R2.java deleted file mode 100644 index ed14a73..0000000 --- a/NMS-v1_18_R2/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_18_R2.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot; -import net.minecraft.network.protocol.game.PacketPlayInUseEntity; -import net.minecraft.network.protocol.game.PacketPlayOutMap; -import net.minecraft.world.EnumHand; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3D; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_18_R2.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_18_R2.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.*; - -public class PacketListener_v1_18_R2 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap packetPlayOutMap) { - int id = (int) getField(packetPlayOutMap, "a"); - - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity packetPlayInUseEntity) { - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - Object action = getField(packetPlayInUseEntity, "b"); //action - Enum actionEnum = (Enum) getValue(action, "a"); //action type - EnumHand hand = hasField(action, "a") ? (EnumHand) getField(action, "a") : null; //hand - Vec3D pos = hasField(action, "b") ? (Vec3D) getField(action, "b") : null; //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, actionEnum.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot) { - int slot = packetPlayInSetCreativeSlot.b(); - ItemStack item = packetPlayInSetCreativeSlot.c(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().b.a.m.pipeline(); //connection connection channel - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().b.a.m; //connection connection channel - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D vec3dObj)) return new Vector(0, 0, 0); - return new Vector(vec3dObj.b, vec3dObj.c, vec3dObj.d); //x, y, z - } -} diff --git a/NMS-v1_19_R1/pom.xml b/NMS-v1_19_R1/pom.xml deleted file mode 100644 index 6fe4d53..0000000 --- a/NMS-v1_19_R1/pom.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - - - - MapReflectionAPI - tech.sbdevelopment - ${revision} - - 4.0.0 - - MapReflectionAPI-NMS-v1_19_R1 - - - 1.19-R0.1-SNAPSHOT - 17 - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0-SNAPSHOT - - ${jdk.version} - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - - - - - - - - org.bukkit - craftbukkit - ${NMSVersion} - provided - - - tech.sbdevelopment - MapReflectionAPI-API - 1.0-SNAPSHOT - provided - - - \ No newline at end of file diff --git a/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_19_R1.java b/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_19_R1.java deleted file mode 100644 index 3d420c0..0000000 --- a/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_19_R1.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.network.protocol.game.PacketPlayOutMap; -import net.minecraft.world.level.saveddata.maps.WorldMap; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; -import org.bukkit.entity.Player; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; - -import java.util.ArrayList; -import java.util.List; - -public class MapSender_v1_19_R1 { - private static final List sendQueue = new ArrayList<>(); - private static int senderID = -1; - - public static void addToQueue(final int id, final ArrayImage content, final Player player) { - QueuedMap toSend = new QueuedMap(id, content, player); - if (sendQueue.contains(toSend)) return; - sendQueue.add(toSend); - - runSender(); - } - - private static void runSender() { - if (Bukkit.getScheduler().isQueued(senderID) || Bukkit.getScheduler().isCurrentlyRunning(senderID) || sendQueue.isEmpty()) - return; - - senderID = Bukkit.getScheduler().scheduleSyncRepeatingTask(MapReflectionAPI.getInstance(), () -> { - if (sendQueue.isEmpty()) return; - - for (int i = 0; i < Math.min(sendQueue.size(), 10 + 1); i++) { - QueuedMap current = sendQueue.get(0); - if (current == null) return; - - sendMap(current.id, current.image, current.player); - - if (!sendQueue.isEmpty()) sendQueue.remove(0); - } - }, 0, 2); - } - - public static void sendMap(final int id0, final ArrayImage content, final Player player) { - if (player == null || !player.isOnline()) { - List toRemove = new ArrayList<>(); - for (QueuedMap qMap : sendQueue) { - if (qMap == null) continue; - - if (qMap.player == null || !qMap.player.isOnline()) { - toRemove.add(qMap); - } - } - Bukkit.getScheduler().cancelTask(senderID); - sendQueue.removeAll(toRemove); - - return; - } - - final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - WorldMap.b updateData = new WorldMap.b( - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY, //Y size (2nd Y pos) - content.array //Data - ); - - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //Show icons - new ArrayList<>(), //Icons - updateData - ); - - ((CraftPlayer) player).getHandle().b.a(packet); //connection send() - } catch (Exception e) { - e.printStackTrace(); - } - }); - } - - record QueuedMap(int id, ArrayImage image, Player player) { - } -} diff --git a/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_19_R1.java b/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_19_R1.java deleted file mode 100644 index 9267d6f..0000000 --- a/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_19_R1.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import net.minecraft.network.protocol.game.PacketPlayOutEntityMetadata; -import net.minecraft.network.protocol.game.PacketPlayOutSetSlot; -import net.minecraft.network.syncher.DataWatcher; -import net.minecraft.network.syncher.DataWatcherObject; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.decoration.EntityItemFrame; -import org.bukkit.*; -import org.bukkit.craftbukkit.v1_19_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; -import org.bukkit.entity.ItemFrame; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; -import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; - -import java.util.*; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; - -public class MapWrapper_v1_19_R1 extends MapWrapper { - protected MapController controller = new MapController() { - private final Map viewers = new HashMap<>(); - - @Override - public void addViewer(Player player) throws MapLimitExceededException { - if (!isViewing(player)) { - viewers.put(player.getUniqueId(), MapReflectionAPI.getMapManager().getNextFreeIdFor(player)); - } - } - - @Override - public void removeViewer(OfflinePlayer player) { - viewers.remove(player.getUniqueId()); - } - - @Override - public void clearViewers() { - for (UUID uuid : viewers.keySet()) { - viewers.remove(uuid); - } - } - - @Override - public boolean isViewing(OfflinePlayer player) { - if (player == null) return false; - return viewers.containsKey(player.getUniqueId()); - } - - @Override - public int getMapId(OfflinePlayer player) { - if (isViewing(player)) { - return viewers.get(player.getUniqueId()); - } - return -1; - } - - @Override - public void update(ArrayImage content) { - MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); - if (duplicate != null) { - MapWrapper_v1_19_R1.this.content = duplicate.getContent(); - return; - } - - MapWrapper_v1_19_R1.this.content = content; - - for (UUID id : viewers.keySet()) { - sendContent(Bukkit.getPlayer(id)); - } - } - - @Override - public ArrayImage getContent() { - return MapWrapper_v1_19_R1.this.getContent(); - } - - @Override - public void sendContent(Player player) { - sendContent(player, false); - } - - @Override - public void sendContent(Player player, boolean withoutQueue) { - if (!isViewing(player)) return; - - int id = getMapId(player); - if (withoutQueue) { - MapSender_v1_19_R1.sendMap(id, MapWrapper_v1_19_R1.this.content, player); - } else { - MapSender_v1_19_R1.addToQueue(id, MapWrapper_v1_19_R1.this.content, player); - } - } - - @Override - public void showInInventory(Player player, int slot, boolean force) { - if (!isViewing(player)) return; - - if (player.getGameMode() == GameMode.CREATIVE && !force) return; - - if (slot < 9) { - slot += 36; - } else if (slot > 35 && slot != 45) { - slot = 8 - (slot - 36); - } - - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().bT.j; //inventoryMenu containerId - int stateId = craftPlayer.getHandle().bT.j(); //inventoryMenu getStateId() - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, stateId, slot, nmsStack); - ((CraftPlayer) player).getHandle().b.a(packet); - } - - @Override - public void showInInventory(Player player, int slot) { - showInInventory(player, slot, false); - } - - @Override - public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.FILLED_MAP && !force) return; - showInInventory(player, player.getInventory().getHeldItemSlot(), force); - } - - @Override - public void showInHand(Player player) { - showInHand(player, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame) { - showInFrame(player, frame, false); - } - - @Override - public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.FILLED_MAP && !force) return; - showInFrame(player, frame.getEntityId()); - } - - @Override - public void showInFrame(Player player, int entityId) { - showInFrame(player, entityId, null); - } - - @Override - public void showInFrame(Player player, int entityId, String debugInfo) { - if (!isViewing(player)) return; - - ItemStack stack = new ItemStack(Material.FILLED_MAP, 1); - if (debugInfo != null) { - ItemMeta itemMeta = stack.getItemMeta(); - itemMeta.setDisplayName(debugInfo); - stack.setItemMeta(itemMeta); - } - - Bukkit.getScheduler().runTask(MapReflectionAPI.getInstance(), () -> { - ItemFrame frame = getItemFrameById(player.getWorld(), entityId); - if (frame != null) { - frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_19_R1.this)); - } - - sendItemFramePacket(player, entityId, stack, getMapId(player)); - }); - } - - @Override - public void clearFrame(Player player, int entityId) { - - } - - @Override - public void clearFrame(Player player, ItemFrame frame) { - - } - - @Override - public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; - - Entity entity = craftWorld.getHandle().a(entityId); - if (entity == null) return null; - - if (entity instanceof ItemFrame) return (ItemFrame) entity; - - return null; - } - - private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.world.item.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - nmsStack.v().a("map", mapId); //getOrCreateTag putInt - - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); - - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "ao"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; - } - - ((CraftPlayer) player).getHandle().b.a(packet); - } - }; - - public MapWrapper_v1_19_R1(ArrayImage image) { - super(image); - } - - @Override - public MapController getController() { - return controller; - } -} diff --git a/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_19_R1.java b/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_19_R1.java deleted file mode 100644 index 3786d4d..0000000 --- a/NMS-v1_19_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/PacketListener_v1_19_R1.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This file is part of MapReflectionAPI. - * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package tech.sbdevelopment.mapreflectionapi.nms; - -import io.netty.channel.*; -import net.minecraft.network.protocol.game.PacketPlayInSetCreativeSlot; -import net.minecraft.network.protocol.game.PacketPlayInUseEntity; -import net.minecraft.network.protocol.game.PacketPlayOutMap; -import net.minecraft.world.EnumHand; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3D; -import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_19_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_19_R1.inventory.CraftItemStack; -import org.bukkit.entity.Player; -import org.bukkit.util.Vector; -import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; -import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; -import tech.sbdevelopment.mapreflectionapi.listeners.PacketListener; - -import java.util.concurrent.TimeUnit; - -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.*; - -public class PacketListener_v1_19_R1 extends PacketListener { - @Override - protected void injectPlayer(Player p) { - ChannelDuplexHandler channelDuplexHandler = new ChannelDuplexHandler() { - @Override - //On send packet - public void write(ChannelHandlerContext ctx, Object packet, ChannelPromise promise) throws Exception { - if (packet instanceof PacketPlayOutMap packetPlayOutMap) { - int id = (int) getField(packetPlayOutMap, "a"); - - if (id < 0) { - //It's one of our maps, invert ID and let through! - int newId = -id; - setField(packetPlayOutMap, "a", newId); //mapId - } else { - boolean async = !plugin.getServer().isPrimaryThread(); - MapCancelEvent event = new MapCancelEvent(p, id, async); - if (MapReflectionAPI.getMapManager().isIdUsedBy(p, id)) event.setCancelled(true); - if (event.getHandlers().getRegisteredListeners().length > 0) - Bukkit.getPluginManager().callEvent(event); - - if (event.isCancelled()) return; - } - } - - super.write(ctx, packet, promise); - } - - @Override - //On receive packet - public void channelRead(ChannelHandlerContext ctx, Object packet) throws Exception { - if (packet instanceof PacketPlayInUseEntity packetPlayInUseEntity) { - int entityId = (int) getField(packetPlayInUseEntity, "a"); //entityId - Object action = getField(packetPlayInUseEntity, "b"); //action - Enum actionEnum = (Enum) getValue(action, "a"); //action type - EnumHand hand = hasField(action, "a") ? (EnumHand) getField(action, "a") : null; //hand - Vec3D pos = hasField(action, "b") ? (Vec3D) getField(action, "b") : null; //pos - - if (Bukkit.getScheduler().callSyncMethod(plugin, () -> { - boolean async = !plugin.getServer().isPrimaryThread(); - MapInteractEvent event = new MapInteractEvent(p, entityId, actionEnum.ordinal(), pos != null ? vec3DToVector(pos) : null, hand != null ? hand.ordinal() : 0, async); - if (event.getFrame() != null && event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - return event.isCancelled(); - } - return false; - }).get(1, TimeUnit.SECONDS)) return; - } else if (packet instanceof PacketPlayInSetCreativeSlot packetPlayInSetCreativeSlot) { - int slot = packetPlayInSetCreativeSlot.b(); - ItemStack item = packetPlayInSetCreativeSlot.c(); - - boolean async = !plugin.getServer().isPrimaryThread(); - CreateInventoryMapUpdateEvent event = new CreateInventoryMapUpdateEvent(p, slot, CraftItemStack.asBukkitCopy(item), async); - if (event.getMapWrapper() != null) { - Bukkit.getPluginManager().callEvent(event); - if (event.isCancelled()) return; - } - } - - super.channelRead(ctx, packet); - } - }; - - ChannelPipeline pipeline = ((CraftPlayer) p).getHandle().b.b.m.pipeline(); //connection connection channel - pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler); - } - - @Override - public void removePlayer(Player p) { - Channel channel = ((CraftPlayer) p).getHandle().b.b.m; //connection connection channel - channel.eventLoop().submit(() -> channel.pipeline().remove(p.getName())); - } - - @Override - protected Vector vec3DToVector(Object vec3d) { - if (!(vec3d instanceof Vec3D vec3dObj)) return new Vector(0, 0, 0); - return new Vector(vec3dObj.c, vec3dObj.d, vec3dObj.e); //x, y, z - } -} diff --git a/pom.xml b/pom.xml index a575d69..5bff386 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,27 @@ + + @@ -6,69 +29,50 @@ tech.sbdevelopment MapReflectionAPI - pom - ${revision} + 1.1 + jar + + MapReflectionAPI + This API helps developer with viewing images on maps. + https://sbdplugins.nl - 1.0-SNAPSHOT UTF-8 - 11 - - API - Dist - NMS-v1_19_R1 - NMS-v1_18_R2 - NMS-v1_17_R1 - NMS-v1_16_R3 - NMS-v1_15_R1 - NMS-v1_14_R1 - NMS-v1_13_R2 - NMS-v1_12_R1 - - - clean package org.apache.maven.plugins - maven-toolchains-plugin - 3.1.0 + maven-compiler-plugin + 3.9.0-SNAPSHOT + + 11 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.3.1-SNAPSHOT + package - toolchain + shade + + false + - - - - ${jdk.version} - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - ${jdk.version} - - - - - org.apache.maven.plugins - maven-deploy-plugin - 3.0.0-M2 - - true - + + + src/main/resources + true + + @@ -76,6 +80,14 @@ spigot-repo https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + MG-Dev Jenkins CI Maven Repository + https://ci.mg-dev.eu/plugin/repository/everything + + + dmulloy2-repo + https://repo.dmulloy2.net/repository/public/ + @@ -84,5 +96,17 @@ spigot-api 1.19-R0.1-SNAPSHOT + + com.bergerkiller.bukkit + BKCommonLib + 1.19-v1 + provided + + + com.comphenix.protocol + ProtocolLib + 4.8.0 + provided + \ No newline at end of file diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/MapReflectionAPI.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/MapReflectionAPI.java similarity index 87% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/MapReflectionAPI.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/MapReflectionAPI.java index e12d932..7c20b33 100644 --- a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/MapReflectionAPI.java +++ b/src/main/java/tech/sbdevelopment/mapreflectionapi/MapReflectionAPI.java @@ -23,6 +23,8 @@ package tech.sbdevelopment.mapreflectionapi; +import com.comphenix.protocol.ProtocolLibrary; +import com.comphenix.protocol.ProtocolManager; import org.bukkit.Bukkit; import org.bukkit.map.MapView; import org.bukkit.plugin.java.JavaPlugin; @@ -35,7 +37,7 @@ import java.util.logging.Level; public class MapReflectionAPI extends JavaPlugin { private static MapReflectionAPI instance; private static MapManager mapManager; - private static PacketListener packetListener; + private ProtocolManager protocolManager; public static MapReflectionAPI getInstance() { if (instance == null) throw new IllegalStateException("The plugin is not enabled yet!"); @@ -61,14 +63,8 @@ public class MapReflectionAPI extends JavaPlugin { return; } - try { - packetListener = PacketListener.construct(this); - } catch (IllegalStateException e) { - getLogger().log(Level.SEVERE, e.getMessage(), e); - Bukkit.getPluginManager().disablePlugin(this); - return; - } - packetListener.init(this); + protocolManager = ProtocolLibrary.getProtocolManager(); + protocolManager.addPacketListener(new PacketListener(this)); try { mapManager = new MapManager(this); @@ -99,9 +95,6 @@ public class MapReflectionAPI extends JavaPlugin { @Override public void onDisable() { - getLogger().info("Disabling the packet handler..."); - if (packetListener != null) Bukkit.getOnlinePlayers().forEach(p -> packetListener.removePlayer(p)); - getLogger().info("MapReflectionAPI is disabled!"); instance = null; diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/ArrayImage.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/ArrayImage.java similarity index 91% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/ArrayImage.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/ArrayImage.java index 47d0244..b285d54 100644 --- a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/ArrayImage.java +++ b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/ArrayImage.java @@ -71,6 +71,16 @@ public class ArrayImage { this.array = result; } + public BufferedImage toBuffered() { + BufferedImage img = new BufferedImage(width, height, this.imageType); + for (int x = 0; x < width; x++) { + for (int y = 0; y < height; y++) { + img.setRGB(x, y, MapColorPalette.getRealColor(array[y * width + x]).getRGB()); + } + } + return img; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapController.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapController.java similarity index 100% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapController.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapController.java diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapManager.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapManager.java similarity index 100% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapManager.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapManager.java diff --git a/NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_12_R1.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapSender.java similarity index 65% rename from NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_12_R1.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapSender.java index 88f0e6f..89fef87 100644 --- a/NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapSender_v1_12_R1.java +++ b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapSender.java @@ -21,20 +21,19 @@ * SOFTWARE. */ -package tech.sbdevelopment.mapreflectionapi.nms; +package tech.sbdevelopment.mapreflectionapi.api; -import net.minecraft.server.v1_12_R1.PacketPlayOutMap; import org.bukkit.Bukkit; -import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; import org.bukkit.entity.Player; import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; +import tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil; +import tech.sbdevelopment.mapreflectionapi.util.ReflectionUtils; import java.util.ArrayList; import java.util.List; import java.util.Objects; -public class MapSender_v1_12_R1 { +public class MapSender { private static final List sendQueue = new ArrayList<>(); private static int senderID = -1; @@ -80,28 +79,55 @@ public class MapSender_v1_12_R1 { return; } + Class packetClass = ReflectionUtils.getNMSClass("network.protocol.game", "PacketPlayOutMap"); final int id = -id0; - Bukkit.getScheduler().runTaskAsynchronously(MapReflectionAPI.getInstance(), () -> { - try { - PacketPlayOutMap packet = new PacketPlayOutMap( - id, //ID - (byte) 0, //Scale - false, //??? - new ArrayList<>(), //Icons - content.array, //Data - content.minX, //X pos - content.minY, //Y pos - content.maxX, //X size (2nd X pos) - content.maxY //Y size (2nd Y pos) - ); + Object packet; + if (ReflectionUtils.supports(17)) { //1.17+ + Class worldMapClass = ReflectionUtils.getNMSClass("world.level.saveddata.maps", "WorldMap"); + Object updateData = ReflectionUtil.callConstructor(worldMapClass, + content.minX, //X pos + content.minY, //Y pos + content.maxX, //X size (2nd X pos) + content.maxY, //Y size (2nd Y pos) + content.array //Data + ); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); - } catch (Exception e) { - e.printStackTrace(); - } - }); + packet = ReflectionUtil.callConstructor(packetClass, + id, //ID + (byte) 0, //Scale + false, //Show icons + new ArrayList<>(), //Icons + updateData + ); + } else if (ReflectionUtils.supports(14)) { //1.16-1.14 + packet = ReflectionUtil.callConstructor(packetClass, + id, //ID + (byte) 0, //Scale + false, //Tracking position + false, //Locked + new ArrayList<>(), //Icons + content.array, //Data + content.minX, //X pos + content.minY, //Y pos + content.maxX, //X size (2nd X pos) + content.maxY //Y size (2nd Y pos) + ); + } else { //1.13- + packet = ReflectionUtil.callConstructor(packetClass, + id, //ID + (byte) 0, //Scale + false, //??? + new ArrayList<>(), //Icons + content.array, //Data + content.minX, //X pos + content.minY, //Y pos + content.maxX, //X size (2nd X pos) + content.maxY //Y size (2nd Y pos) + ); + } + + ReflectionUtils.sendPacket(player, packet); } - static final class QueuedMap { private final int id; private final ArrayImage image; diff --git a/NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_12_R1.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapWrapper.java similarity index 53% rename from NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_12_R1.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapWrapper.java index 6a38063..41f460d 100644 --- a/NMS-v1_12_R1/src/main/java/tech/sbdevelopment/mapreflectionapi/nms/MapWrapper_v1_12_R1.java +++ b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/MapWrapper.java @@ -21,32 +21,28 @@ * SOFTWARE. */ -package tech.sbdevelopment.mapreflectionapi.nms; +package tech.sbdevelopment.mapreflectionapi.api; -import net.minecraft.server.v1_12_R1.*; -import org.bukkit.Material; -import org.bukkit.World; import org.bukkit.*; -import org.bukkit.craftbukkit.v1_12_R1.CraftWorld; -import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer; -import org.bukkit.craftbukkit.v1_12_R1.inventory.CraftItemStack; import org.bukkit.entity.ItemFrame; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.metadata.FixedMetadataValue; import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; -import tech.sbdevelopment.mapreflectionapi.api.ArrayImage; -import tech.sbdevelopment.mapreflectionapi.api.MapController; -import tech.sbdevelopment.mapreflectionapi.api.MapWrapper; import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException; +import tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil; +import tech.sbdevelopment.mapreflectionapi.util.ReflectionUtils; import java.util.*; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.getField; -import static tech.sbdevelopment.mapreflectionapi.util.ReflectionUtil.setField; +public class MapWrapper { + protected ArrayImage content; + + public MapWrapper(ArrayImage image) { + this.content = image; + } -public class MapWrapper_v1_12_R1 extends MapWrapper { protected MapController controller = new MapController() { private final Map viewers = new HashMap<>(); @@ -87,11 +83,11 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { public void update(ArrayImage content) { MapWrapper duplicate = MapReflectionAPI.getMapManager().getDuplicate(content); if (duplicate != null) { - MapWrapper_v1_12_R1.this.content = duplicate.getContent(); + MapWrapper.this.content = duplicate.getContent(); return; } - MapWrapper_v1_12_R1.this.content = content; + MapWrapper.this.content = content; for (UUID id : viewers.keySet()) { sendContent(Bukkit.getPlayer(id)); @@ -100,7 +96,7 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { @Override public ArrayImage getContent() { - return MapWrapper_v1_12_R1.this.getContent(); + return MapWrapper.this.getContent(); } @Override @@ -114,9 +110,9 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { int id = getMapId(player); if (withoutQueue) { - MapSender_v1_12_R1.sendMap(id, MapWrapper_v1_12_R1.this.content, player); + MapSender.sendMap(id, MapWrapper.this.content, player); } else { - MapSender_v1_12_R1.addToQueue(id, MapWrapper_v1_12_R1.this.content, player); + MapSender.addToQueue(id, MapWrapper.this.content, player); } } @@ -132,14 +128,35 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { slot = 8 - (slot - 36); } - CraftPlayer craftPlayer = (CraftPlayer) player; - int windowId = craftPlayer.getHandle().defaultContainer.windowId; + Object playerHandle = ReflectionUtils.getHandle(player); + Object inventoryMenu = ReflectionUtil.getField(playerHandle, ReflectionUtils.supports(19) ? "bT" : ReflectionUtils.supports(17) ? "bU" : "defaultContainer"); + int windowId = (int) ReflectionUtil.getField(inventoryMenu, ReflectionUtils.supports(17) ? "j" : "windowId"); - ItemStack stack = new ItemStack(Material.MAP, 1); - net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); + ItemStack stack = new ItemStack(ReflectionUtils.supports(13) ? Material.FILLED_MAP : Material.MAP, 1); - PacketPlayOutSetSlot packet = new PacketPlayOutSetSlot(windowId, slot, nmsStack); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + Class craftStackClass = ReflectionUtils.getCraftClass("CraftItemStack"); + Object nmsStack = ReflectionUtil.callMethod(craftStackClass, "asNMSCopy", stack); + + Class setSlotPacketClass = ReflectionUtils.getNMSClass("network.protocol.game", "PacketPlayOutSetSlot"); + Object packet; + if (ReflectionUtils.supports(17)) { //1.17+ + int stateId = (int) ReflectionUtil.callMethod(inventoryMenu, ReflectionUtils.supports(18) ? "j" : "getStateId"); + + packet = ReflectionUtil.callConstructor(setSlotPacketClass, + windowId, + stateId, + slot, + nmsStack + ); + } else { //1.16- + packet = ReflectionUtil.callConstructor(setSlotPacketClass, + windowId, + slot, + nmsStack + ); + } + + ReflectionUtils.sendPacket(player, packet); } @Override @@ -149,7 +166,8 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { @Override public void showInHand(Player player, boolean force) { - if (player.getInventory().getItemInMainHand().getType() != Material.MAP && !force) return; + if (player.getInventory().getItemInMainHand().getType() != (ReflectionUtils.supports(13) ? Material.FILLED_MAP : Material.MAP) && !force) + return; showInInventory(player, player.getInventory().getHeldItemSlot(), force); } @@ -165,7 +183,8 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { @Override public void showInFrame(Player player, ItemFrame frame, boolean force) { - if (frame.getItem().getType() != Material.MAP && !force) return; + if (frame.getItem().getType() != (ReflectionUtils.supports(13) ? Material.FILLED_MAP : Material.MAP) && !force) + return; showInFrame(player, frame.getEntityId()); } @@ -178,7 +197,7 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { public void showInFrame(Player player, int entityId, String debugInfo) { if (!isViewing(player)) return; - ItemStack stack = new ItemStack(Material.MAP, 1); + ItemStack stack = new ItemStack(ReflectionUtils.supports(13) ? Material.FILLED_MAP : Material.MAP, 1); if (debugInfo != null) { ItemMeta itemMeta = stack.getItemMeta(); itemMeta.setDisplayName(debugInfo); @@ -189,7 +208,7 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { ItemFrame frame = getItemFrameById(player.getWorld(), entityId); if (frame != null) { frame.removeMetadata("MAP_WRAPPER_REF", MapReflectionAPI.getInstance()); - frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper_v1_12_R1.this)); + frame.setMetadata("MAP_WRAPPER_REF", new FixedMetadataValue(MapReflectionAPI.getInstance(), MapWrapper.this)); } sendItemFramePacket(player, entityId, stack, getMapId(player)); @@ -208,45 +227,64 @@ public class MapWrapper_v1_12_R1 extends MapWrapper { @Override public ItemFrame getItemFrameById(World world, int entityId) { - CraftWorld craftWorld = (CraftWorld) world; + Object worldHandle = ReflectionUtils.getHandle(world); + Object nmsEntity = ReflectionUtil.callMethod(worldHandle, ReflectionUtils.supports(18) ? "a" : "getEntity"); + if (nmsEntity == null) return null; - Entity entity = craftWorld.getHandle().getEntity(entityId); - if (entity == null) return null; - - org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); - if (bukkitEntity instanceof ItemFrame) return (ItemFrame) bukkitEntity; + if (!ReflectionUtils.supports(17)) { + nmsEntity = ReflectionUtil.callMethod(nmsEntity, "getBukkitEntity"); + } + if (nmsEntity instanceof ItemFrame) return (ItemFrame) nmsEntity; return null; } private void sendItemFramePacket(Player player, int entityId, ItemStack stack, int mapId) { - net.minecraft.server.v1_12_R1.ItemStack nmsStack = CraftItemStack.asNMSCopy(stack); - if (nmsStack.getTag() == null) nmsStack.setTag(new NBTTagCompound()); //No orCreate on 1.12.2! - nmsStack.getTag().setInt("map", mapId); //getTag putInt + Class craftStackClass = ReflectionUtils.getCraftClass("CraftItemStack"); + Object nmsStack = ReflectionUtil.callMethod(craftStackClass, "asNMSCopy", stack); - PacketPlayOutEntityMetadata packet = new PacketPlayOutEntityMetadata(entityId, new DataWatcher(null), true); + Object nbtObject = ReflectionUtil.callMethod(nmsStack, ReflectionUtils.supports(19) ? "v" : ReflectionUtils.supports(18) ? "u" : ReflectionUtils.supports(13) ? "getOrCreateTag" : "getTag"); - try { - List> list = new ArrayList<>(); - DataWatcherObject dataWatcherObject = (DataWatcherObject) getField(EntityItemFrame.class, "c"); - DataWatcher.Item dataWatcherItem = new DataWatcher.Item<>(dataWatcherObject, nmsStack); - list.add(dataWatcherItem); - setField(packet, "b", list); - } catch (Exception e) { - e.printStackTrace(); - return; + if (!ReflectionUtils.supports(13) && nbtObject == null) { //1.12 has no getOrCreate, call create if null! + Class tagCompoundClass = ReflectionUtils.getCraftClass("NBTTagCompound"); + Object tagCompound = ReflectionUtil.callConstructor(tagCompoundClass); + + ReflectionUtil.callMethod(nbtObject, "setTag", tagCompound); } - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + ReflectionUtil.callMethod(nbtObject, ReflectionUtils.supports(18) ? "a" : "setInt", "map", mapId); + + Class entityClass = ReflectionUtils.getNMSClass("world.entity", "Entity"); + + Class dataWatcherClass = ReflectionUtils.getNMSClass("network.syncher", "DataWatcher"); + Object dataWatcher = ReflectionUtil.callConstructor(dataWatcherClass, entityClass.cast(null)); + + Class entityMetadataPacketClass = ReflectionUtils.getNMSClass("network.protocol.game", "PacketPlayOutEntityMetadata"); + Object packet = ReflectionUtil.callConstructor(entityMetadataPacketClass, + entityId, + dataWatcher, //dummy watcher! + true + ); + + List list = new ArrayList<>(); + Class entityItemFrameClass = ReflectionUtils.getNMSClass("world.entity.decoration", "EntityItemFrame"); + Object dataWatcherObject = ReflectionUtil.getDeclaredField(entityItemFrameClass, ReflectionUtils.supports(17) ? "ao" : ReflectionUtils.supports(14) ? "ITEM" : ReflectionUtils.supports(13) ? "e" : "c"); + Class dataWatcherItemClass = ReflectionUtils.getNMSClass("network.syncher", "DataWatcher$Item"); + Object dataWatcherItem = ReflectionUtil.callConstructor(dataWatcherItemClass, dataWatcherObject, nmsStack); + list.add(dataWatcherItem); + ReflectionUtil.setDeclaredField(packet, "b", list); + + ReflectionUtils.sendPacket(player, packet); } }; - public MapWrapper_v1_12_R1(ArrayImage image) { - super(image); + public ArrayImage getContent() { + return content; } - @Override public MapController getController() { return controller; } + + } diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/CreateInventoryMapUpdateEvent.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/CreateInventoryMapUpdateEvent.java similarity index 100% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/CreateInventoryMapUpdateEvent.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/CreateInventoryMapUpdateEvent.java diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapCancelEvent.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapCancelEvent.java similarity index 100% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapCancelEvent.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapCancelEvent.java diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapInteractEvent.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapInteractEvent.java similarity index 100% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapInteractEvent.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/api/events/MapInteractEvent.java diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/exceptions/MapLimitExceededException.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/exceptions/MapLimitExceededException.java similarity index 100% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/exceptions/MapLimitExceededException.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/exceptions/MapLimitExceededException.java diff --git a/API/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/MapListener.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/MapListener.java similarity index 100% rename from API/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/MapListener.java rename to src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/MapListener.java diff --git a/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/PacketListener.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/PacketListener.java new file mode 100644 index 0000000..7e48703 --- /dev/null +++ b/src/main/java/tech/sbdevelopment/mapreflectionapi/listeners/PacketListener.java @@ -0,0 +1,94 @@ +/* + * This file is part of MapReflectionAPI. + * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package tech.sbdevelopment.mapreflectionapi.listeners; + +import com.comphenix.protocol.PacketType; +import com.comphenix.protocol.events.ListenerPriority; +import com.comphenix.protocol.events.PacketAdapter; +import com.comphenix.protocol.events.PacketEvent; +import com.comphenix.protocol.wrappers.EnumWrappers; +import com.comphenix.protocol.wrappers.WrappedEnumEntityUseAction; +import org.bukkit.Bukkit; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.bukkit.util.Vector; +import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI; +import tech.sbdevelopment.mapreflectionapi.api.events.CreateInventoryMapUpdateEvent; +import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent; +import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent; + +public class PacketListener extends PacketAdapter { + public PacketListener(Plugin plugin) { + super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.MAP, PacketType.Play.Client.USE_ENTITY, PacketType.Play.Client.SET_CREATIVE_SLOT); + } + + @Override + public void onPacketSending(PacketEvent event) { + if (event.getPacketType() != PacketType.Play.Server.MAP) return; //Make sure it's the right packet! + + int id = event.getPacket().getIntegers().read(0); //Read first int (a); that's the MAP id + + if (id < 0) { + //It's one of our maps, invert ID and let through! + int newId = -id; + event.getPacket().getIntegers().write(0, newId); //set the MAP id to the reverse + } else { + boolean async = !plugin.getServer().isPrimaryThread(); + MapCancelEvent cancelEvent = new MapCancelEvent(event.getPlayer(), id, async); + if (MapReflectionAPI.getMapManager().isIdUsedBy(event.getPlayer(), id)) cancelEvent.setCancelled(true); + if (cancelEvent.getHandlers().getRegisteredListeners().length > 0) + Bukkit.getPluginManager().callEvent(cancelEvent); + + if (cancelEvent.isCancelled()) event.setCancelled(true); + } + } + + @Override + public void onPacketReceiving(PacketEvent event) { + if (event.getPacketType() == PacketType.Play.Client.USE_ENTITY) { + int entityId = event.getPacket().getIntegers().read(0); //entityId + WrappedEnumEntityUseAction action = event.getPacket().getEnumEntityUseActions().read(0); + EnumWrappers.EntityUseAction actionEnum = action.getAction(); + EnumWrappers.Hand hand = action.getHand(); + Vector pos = action.getPosition(); + + boolean async = !plugin.getServer().isPrimaryThread(); + MapInteractEvent interactEvent = new MapInteractEvent(event.getPlayer(), entityId, actionEnum.ordinal(), pos, hand.ordinal(), async); + if (interactEvent.getFrame() != null && interactEvent.getMapWrapper() != null) { + Bukkit.getPluginManager().callEvent(interactEvent); + if (interactEvent.isCancelled()) event.setCancelled(true); + } + } else if (event.getPacketType() == PacketType.Play.Client.SET_CREATIVE_SLOT) { + int slot = event.getPacket().getIntegers().read(0); + ItemStack item = event.getPacket().getItemModifier().read(0); + + boolean async = !plugin.getServer().isPrimaryThread(); + CreateInventoryMapUpdateEvent updateEvent = new CreateInventoryMapUpdateEvent(event.getPlayer(), slot, item, async); + if (updateEvent.getMapWrapper() != null) { + Bukkit.getPluginManager().callEvent(updateEvent); + if (updateEvent.isCancelled()) event.setCancelled(true); + } + } + } +} diff --git a/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtil.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtil.java new file mode 100644 index 0000000..b6cbfe0 --- /dev/null +++ b/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtil.java @@ -0,0 +1,165 @@ +/* + * This file is part of MapReflectionAPI. + * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package tech.sbdevelopment.mapreflectionapi.util; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; + +/** + * ReflectionUtil - Reflection handler for NMS and CraftBukkit.
+ * Caches the packet related methods and is asynchronous. + *

+ * This class does not handle null checks as most of the requests are from the + * other utility classes that already handle null checks. + *

+ * Clientbound Packets are considered fake + * updates to the client without changing the actual data. Since all the data is handled + * by the server. + * + * @author Crypto Morin, Stijn Bannink + * @version 2.1 + */ +public class ReflectionUtil { + private ReflectionUtil() { + } + + private static Class wrapperToPrimitive(Class clazz) { + if (clazz == Boolean.class) return boolean.class; + if (clazz == Integer.class) return int.class; + if (clazz == Double.class) return double.class; + if (clazz == Float.class) return float.class; + if (clazz == Long.class) return long.class; + if (clazz == Short.class) return short.class; + if (clazz == Byte.class) return byte.class; + if (clazz == Void.class) return void.class; + if (clazz == Character.class) return char.class; + return clazz; + } + + private static Class[] toParamTypes(Object... params) { + return Arrays.stream(params) + .map(obj -> wrapperToPrimitive(obj.getClass())) + .toArray(Class[]::new); + } + + @Nullable + public static Class getClass(@NotNull String name) { + try { + return Class.forName(name); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + return null; + } + } + + @Nullable + public static Object callConstructor(Class clazz, Object... params) { + try { + Constructor con = clazz.getConstructor(toParamTypes(params)); + con.setAccessible(true); + return con.newInstance(params); + } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | + InvocationTargetException ex) { + ex.printStackTrace(); + return null; + } + } + + @Nullable + public static Object callDeclaredConstructor(Class clazz, Object... params) { + try { + Constructor con = clazz.getDeclaredConstructor(toParamTypes(params)); + con.setAccessible(true); + return con.newInstance(params); + } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | + InvocationTargetException ex) { + ex.printStackTrace(); + return null; + } + } + + @Nullable + public static Object callMethod(Object obj, String method, Object... params) { + try { + Method m = obj.getClass().getMethod(method, toParamTypes(params)); + m.setAccessible(true); + return m.invoke(obj, params); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + ex.printStackTrace(); + return null; + } + } + + @Nullable + public static Object callDeclaredMethod(Object obj, String method, Object... params) { + try { + Method m = obj.getClass().getDeclaredMethod(method, toParamTypes(params)); + m.setAccessible(true); + return m.invoke(obj, params); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) { + ex.printStackTrace(); + return null; + } + } + + @Nullable + public static Object getField(Object object, String field) { + try { + Field f = object.getClass().getField(field); + f.setAccessible(true); + return f.get(object); + } catch (NoSuchFieldException | IllegalAccessException ex) { + ex.printStackTrace(); + return null; + } + } + + @Nullable + public static Object getDeclaredField(Object object, String field) { + try { + Field f = object.getClass().getDeclaredField(field); + f.setAccessible(true); + return f.get(object); + } catch (NoSuchFieldException | IllegalAccessException ex) { + ex.printStackTrace(); + return null; + } + } + + public static void setDeclaredField(Object object, String field, Object value) { + try { + Field f = object.getClass().getDeclaredField(field); + f.setAccessible(true); + f.set(object, toParamTypes(value)); + } catch (NoSuchFieldException | IllegalAccessException ex) { + ex.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtils.java b/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtils.java new file mode 100644 index 0000000..0f1c566 --- /dev/null +++ b/src/main/java/tech/sbdevelopment/mapreflectionapi/util/ReflectionUtils.java @@ -0,0 +1,381 @@ +/* + * This file is part of MapReflectionAPI. + * Copyright (c) 2022 inventivetalent / SBDevelopment - All Rights Reserved + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package tech.sbdevelopment.mapreflectionapi.util; + +import org.bukkit.World; +import org.bukkit.entity.Player; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.util.Objects; +import java.util.concurrent.Callable; +import java.util.concurrent.CompletableFuture; + +/** + * ReflectionUtils - Reflection handler for NMS and CraftBukkit.
+ * Caches the packet related methods and is asynchronous. + *

+ * This class does not handle null checks as most of the requests are from the + * other utility classes that already handle null checks. + *

+ * Clientbound Packets are considered fake + * updates to the client without changing the actual data. Since all the data is handled + * by the server. + *

+ * A useful resource used to compare mappings is Mini's Mapping Viewer + * + * @author Crypto Morin + * @version 6.0.1 + */ +public final class ReflectionUtils { + /** + * We use reflection mainly to avoid writing a new class for version barrier. + * The version barrier is for NMS that uses the Minecraft version as the main package name. + *

+ * E.g. EntityPlayer in 1.15 is in the class {@code net.minecraft.server.v1_15_R1} + * but in 1.14 it's in {@code net.minecraft.server.v1_14_R1} + * In order to maintain cross-version compatibility we cannot import these classes. + *

+ * Performance is not a concern for these specific statically initialized values. + */ + public static final String VERSION; + /** + * The raw minor version number. + * E.g. {@code v1_17_R1} to {@code 17} + * + * @since 4.0.0 + */ + public static final int VER = Integer.parseInt(VERSION.substring(1).split("_")[1]); + /** + * Mojang remapped their NMS in 1.17 https://www.spigotmc.org/threads/spigot-bungeecord-1-17.510208/#post-4184317 + */ + public static final String + CRAFTBUKKIT = "org.bukkit.craftbukkit." + VERSION + '.', + NMS = v(17, "net.minecraft.").orElse("net.minecraft.server." + VERSION + '.'); + /** + * A nullable public accessible field only available in {@code EntityPlayer}. + * This can be null if the player is offline. + */ + private static final MethodHandle PLAYER_CONNECTION; + /** + * Responsible for getting the NMS handler {@code EntityPlayer} object for the player. + * {@code CraftPlayer} is simply a wrapper for {@code EntityPlayer}. + * Used mainly for handling packet related operations. + *

+ * This is also where the famous player {@code ping} field comes from! + */ + private static final MethodHandle GET_HANDLE; + private static final MethodHandle GET_HANDLE_WORLD; + /** + * Sends a packet to the player's client through a {@code NetworkManager} which + * is where {@code ProtocolLib} controls packets by injecting channels! + */ + private static final MethodHandle SEND_PACKET; + + static { // This needs to be right below VERSION because of initialization order. + // This package loop is used to avoid implementation-dependant strings like Bukkit.getVersion() or Bukkit.getBukkitVersion() + // which allows easier testing as well. + String found = null; + for (Package pack : Package.getPackages()) { + String name = pack.getName(); + + // .v because there are other packages. + if (name.startsWith("org.bukkit.craftbukkit.v")) { + found = pack.getName().split("\\.")[3]; + + // Just a final guard to make sure it finds this important class. + // As a protection for forge+bukkit implementation that tend to mix versions. + // The real CraftPlayer should exist in the package. + // Note: Doesn't seem to function properly. Will need to separate the version + // handler for NMS and CraftBukkit for softwares like catmc. + try { + Class.forName("org.bukkit.craftbukkit." + found + ".entity.CraftPlayer"); + break; + } catch (ClassNotFoundException e) { + found = null; + } + } + } + if (found == null) + throw new IllegalArgumentException("Failed to parse server version. Could not find any package starting with name: 'org.bukkit.craftbukkit.v'"); + VERSION = found; + } + + static { + Class entityPlayer = getNMSClass("server.level", "EntityPlayer"); + Class worldServer = getNMSClass("server.level", "WorldServer"); + Class craftPlayer = getCraftClass("entity.CraftPlayer"); + Class craftWorld = getCraftClass("CraftWorld"); + Class playerConnection = getNMSClass("server.network", "PlayerConnection"); + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodHandle sendPacket = null, getHandle = null, getHandleWorld = null, connection = null; + + try { + connection = lookup.findGetter(entityPlayer, + v(17, "b").orElse("playerConnection"), playerConnection); + getHandle = lookup.findVirtual(craftPlayer, "getHandle", MethodType.methodType(entityPlayer)); + getHandleWorld = lookup.findVirtual(craftWorld, "getHandle", MethodType.methodType(worldServer)); + sendPacket = lookup.findVirtual(playerConnection, + v(18, "a").orElse("sendPacket"), + MethodType.methodType(void.class, getNMSClass("network.protocol", "Packet"))); + } catch (NoSuchMethodException | NoSuchFieldException | IllegalAccessException ex) { + ex.printStackTrace(); + } + + PLAYER_CONNECTION = connection; + SEND_PACKET = sendPacket; + GET_HANDLE = getHandle; + GET_HANDLE_WORLD = getHandleWorld; + } + + private ReflectionUtils() { + } + + /** + * This method is purely for readability. + * No performance is gained. + * + * @since 5.0.0 + */ + public static VersionHandler v(int version, T handle) { + return new VersionHandler<>(version, handle); + } + + public static CallableVersionHandler v(int version, Callable handle) { + return new CallableVersionHandler<>(version, handle); + } + + /** + * Checks whether the server version is equal or greater than the given version. + * + * @param version the version to compare the server version with. + * @return true if the version is equal or newer, otherwise false. + * @since 4.0.0 + */ + public static boolean supports(int version) { + return VER >= version; + } + + /** + * Get a NMS (net.minecraft.server) class which accepts a package for 1.17 compatibility. + * + * @param newPackage the 1.17 package name. + * @param name the name of the class. + * @return the NMS class or null if not found. + * @since 4.0.0 + */ + @Nullable + public static Class getNMSClass(@Nonnull String newPackage, @Nonnull String name) { + if (supports(17)) name = newPackage + '.' + name; + return getNMSClass(name); + } + + /** + * Get a NMS (net.minecraft.server) class. + * + * @param name the name of the class. + * @return the NMS class or null if not found. + * @since 1.0.0 + */ + @Nullable + public static Class getNMSClass(@Nonnull String name) { + try { + return Class.forName(NMS + name); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + return null; + } + } + + /** + * Sends a packet to the player asynchronously if they're online. + * Packets are thread-safe. + * + * @param player the player to send the packet to. + * @param packets the packets to send. + * @return the async thread handling the packet. + * @see #sendPacketSync(Player, Object...) + * @since 1.0.0 + */ + @Nonnull + public static CompletableFuture sendPacket(@Nonnull Player player, @Nonnull Object... packets) { + return CompletableFuture.runAsync(() -> sendPacketSync(player, packets)) + .exceptionally(ex -> { + ex.printStackTrace(); + return null; + }); + } + + /** + * Sends a packet to the player synchronously if they're online. + * + * @param player the player to send the packet to. + * @param packets the packets to send. + * @see #sendPacket(Player, Object...) + * @since 2.0.0 + */ + public static void sendPacketSync(@Nonnull Player player, @Nonnull Object... packets) { + try { + Object handle = GET_HANDLE.invoke(player); + Object connection = PLAYER_CONNECTION.invoke(handle); + + // Checking if the connection is not null is enough. There is no need to check if the player is online. + if (connection != null) { + for (Object packet : packets) SEND_PACKET.invoke(connection, packet); + } + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + + @Nullable + public static Object getHandle(@Nonnull Player player) { + Objects.requireNonNull(player, "Cannot get handle of null player"); + try { + return GET_HANDLE.invoke(player); + } catch (Throwable throwable) { + throwable.printStackTrace(); + return null; + } + } + + @Nullable + public static Object getHandle(@Nonnull World world) { + Objects.requireNonNull(world, "Cannot get handle of null world"); + try { + return GET_HANDLE_WORLD.invoke(world); + } catch (Throwable throwable) { + throwable.printStackTrace(); + return null; + } + } + + @Nullable + public static Object getConnection(@Nonnull Player player) { + Objects.requireNonNull(player, "Cannot get connection of null player"); + try { + Object handle = GET_HANDLE.invoke(player); + return PLAYER_CONNECTION.invoke(handle); + } catch (Throwable throwable) { + throwable.printStackTrace(); + return null; + } + } + + /** + * Get a CraftBukkit (org.bukkit.craftbukkit) class. + * + * @param name the name of the class to load. + * @return the CraftBukkit class or null if not found. + * @since 1.0.0 + */ + @Nullable + public static Class getCraftClass(@Nonnull String name) { + try { + return Class.forName(CRAFTBUKKIT + name); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + return null; + } + } + + public static Class getArrayClass(String clazz, boolean nms) { + clazz = "[L" + (nms ? NMS : CRAFTBUKKIT) + clazz + ';'; + try { + return Class.forName(clazz); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + return null; + } + } + + public static Class toArrayClass(Class clazz) { + try { + return Class.forName("[L" + clazz.getName() + ';'); + } catch (ClassNotFoundException ex) { + ex.printStackTrace(); + return null; + } + } + + public static final class VersionHandler { + private int version; + private T handle; + + private VersionHandler(int version, T handle) { + if (supports(version)) { + this.version = version; + this.handle = handle; + } + } + + public VersionHandler v(int version, T handle) { + if (version == this.version) + throw new IllegalArgumentException("Cannot have duplicate version handles for version: " + version); + if (version > this.version && supports(version)) { + this.version = version; + this.handle = handle; + } + return this; + } + + public T orElse(T handle) { + return this.version == 0 ? handle : this.handle; + } + } + + public static final class CallableVersionHandler { + private int version; + private Callable handle; + + private CallableVersionHandler(int version, Callable handle) { + if (supports(version)) { + this.version = version; + this.handle = handle; + } + } + + public CallableVersionHandler v(int version, Callable handle) { + if (version == this.version) + throw new IllegalArgumentException("Cannot have duplicate version handles for version: " + version); + if (version > this.version && supports(version)) { + this.version = version; + this.handle = handle; + } + return this; + } + + public T orElse(Callable handle) { + try { + return (this.version == 0 ? handle : this.handle).call(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + } +} \ No newline at end of file diff --git a/API/src/main/resources/plugin.yml b/src/main/resources/plugin.yml similarity index 100% rename from API/src/main/resources/plugin.yml rename to src/main/resources/plugin.yml