✨ Added packet listener
This commit is contained in:
parent
515d27c15c
commit
45aa955771
22 changed files with 1408 additions and 8 deletions
|
@ -24,6 +24,7 @@
|
||||||
package tech.sbdevelopment.mapreflectionapi;
|
package tech.sbdevelopment.mapreflectionapi;
|
||||||
|
|
||||||
import org.bukkit.OfflinePlayer;
|
import org.bukkit.OfflinePlayer;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.ItemFrame;
|
import org.bukkit.entity.ItemFrame;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
import tech.sbdevelopment.mapreflectionapi.exceptions.MapLimitExceededException;
|
||||||
|
@ -170,4 +171,13 @@ public interface MapController {
|
||||||
* @param frame {@link ItemFrame} to clear
|
* @param frame {@link ItemFrame} to clear
|
||||||
*/
|
*/
|
||||||
void clearFrame(Player player, ItemFrame frame);
|
void clearFrame(Player player, ItemFrame frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an {@link ItemFrame} by its entity ID
|
||||||
|
*
|
||||||
|
* @param world The world the {@link ItemFrame} is in
|
||||||
|
* @param entityId Entity-ID of the {@link ItemFrame}
|
||||||
|
* @return The found {@link ItemFrame}, or <code>null</code>
|
||||||
|
*/
|
||||||
|
ItemFrame getItemFrameById(World world, int entityId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||||
public class MapReflectionAPI extends JavaPlugin {
|
public class MapReflectionAPI extends JavaPlugin {
|
||||||
private static MapReflectionAPI instance;
|
private static MapReflectionAPI instance;
|
||||||
private static MapManager mapManager;
|
private static MapManager mapManager;
|
||||||
|
private static PacketListener packetListener;
|
||||||
|
|
||||||
public static MapReflectionAPI getInstance() {
|
public static MapReflectionAPI getInstance() {
|
||||||
if (instance == null) throw new IllegalStateException("The plugin is not enabled yet!");
|
if (instance == null) throw new IllegalStateException("The plugin is not enabled yet!");
|
||||||
|
@ -50,6 +51,9 @@ public class MapReflectionAPI extends JavaPlugin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packetListener = PacketListener.construct();
|
||||||
|
packetListener.init(this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mapManager = new MapManager();
|
mapManager = new MapManager();
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
|
@ -63,6 +67,7 @@ public class MapReflectionAPI extends JavaPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisable() {
|
public void onDisable() {
|
||||||
|
Bukkit.getOnlinePlayers().forEach(p -> packetListener.removePlayer(p));
|
||||||
instance = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public abstract class PacketListener implements Listener {
|
||||||
|
protected JavaPlugin plugin;
|
||||||
|
|
||||||
|
protected static PacketListener construct() {
|
||||||
|
String packageName = Bukkit.getServer().getClass().getPackage().getName();
|
||||||
|
String version = packageName.substring(packageName.lastIndexOf('.') + 1);
|
||||||
|
|
||||||
|
try {
|
||||||
|
final Class<?> clazz = Class.forName("tech.sbdevelopment.mapreflectionapi.nms.MapWrapper_" + version);
|
||||||
|
if (MapWrapper.class.isAssignableFrom(clazz)) {
|
||||||
|
return (PacketListener) clazz.getDeclaredConstructor().newInstance();
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException("Plugin corrupted! Detected invalid MapWrapper class.");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new IllegalStateException("This Spigot 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);
|
||||||
|
|
||||||
|
protected 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Object getField(Object packet, String field) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field f = packet.getClass().getDeclaredField(field);
|
||||||
|
f.setAccessible(true);
|
||||||
|
return f.get(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setField(Object packet, String field, Object value) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field f = packet.getClass().getDeclaredField(field);
|
||||||
|
f.setAccessible(true);
|
||||||
|
f.set(packet, value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* 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.events;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
|
||||||
|
public class CreateInventoryMapUpdateEvent extends Event implements Cancellable {
|
||||||
|
private static final HandlerList handlerList = new HandlerList();
|
||||||
|
private final Player player;
|
||||||
|
private final int slot;
|
||||||
|
private final ItemStack item;
|
||||||
|
private MapWrapper mapWrapper;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
public CreateInventoryMapUpdateEvent(Player player, int slot, ItemStack item) {
|
||||||
|
this.player = player;
|
||||||
|
this.slot = slot;
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CreateInventoryMapUpdateEvent(Player player, int slot, ItemStack item, boolean isAsync) {
|
||||||
|
super(isAsync);
|
||||||
|
this.player = player;
|
||||||
|
this.slot = slot;
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSlot() {
|
||||||
|
return slot;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemStack getItem() {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapWrapper getMapWrapper() {
|
||||||
|
if (mapWrapper == null) {
|
||||||
|
if (item == null) return null;
|
||||||
|
if (item.getType() != Material.MAP) return null;
|
||||||
|
MapReflectionAPI.getMapManager().getWrapperForId(player, item.getDurability());
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean b) {
|
||||||
|
this.cancelled = b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* 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.events;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
|
||||||
|
public class MapCancelEvent extends Event implements Cancellable {
|
||||||
|
private static final HandlerList handlerList = new HandlerList();
|
||||||
|
private final Player player;
|
||||||
|
private final int id;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
public MapCancelEvent(Player player, int id) {
|
||||||
|
this.player = player;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapCancelEvent(Player player, int id, boolean isAsync) {
|
||||||
|
super(isAsync);
|
||||||
|
this.player = player;
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean b) {
|
||||||
|
this.cancelled = b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* 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.events;
|
||||||
|
|
||||||
|
import org.bukkit.entity.ItemFrame;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.MapWrapper;
|
||||||
|
|
||||||
|
public class MapInteractEvent extends Event implements Cancellable {
|
||||||
|
private static final HandlerList handlerList = new HandlerList();
|
||||||
|
private final Player player;
|
||||||
|
private final int entityID;
|
||||||
|
private final int action;
|
||||||
|
private final Vector vector;
|
||||||
|
private final int hand;
|
||||||
|
private ItemFrame frame;
|
||||||
|
private MapWrapper mapWrapper;
|
||||||
|
private boolean cancelled;
|
||||||
|
|
||||||
|
public MapInteractEvent(Player player, int entityID, int action, Vector vector, int hand) {
|
||||||
|
this.player = player;
|
||||||
|
this.entityID = entityID;
|
||||||
|
this.action = action;
|
||||||
|
this.vector = vector;
|
||||||
|
this.hand = hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapInteractEvent(Player player, int entityID, int action, Vector vector, int hand, boolean isAsync) {
|
||||||
|
super(isAsync);
|
||||||
|
this.player = player;
|
||||||
|
this.entityID = entityID;
|
||||||
|
this.action = action;
|
||||||
|
this.vector = vector;
|
||||||
|
this.hand = hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HandlerList getHandlerList() {
|
||||||
|
return handlerList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getEntityID() {
|
||||||
|
return entityID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Vector getVector() {
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHand() {
|
||||||
|
return hand;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ItemFrame getFrame() {
|
||||||
|
if (frame == null) {
|
||||||
|
frame = getMapWrapper().getController().getItemFrameById(player.getWorld(), entityID);
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MapWrapper getMapWrapper() {
|
||||||
|
if (mapWrapper == null) {
|
||||||
|
mapWrapper = MapReflectionAPI.getMapManager().getWrapperForId(player, entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mapWrapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean b) {
|
||||||
|
this.cancelled = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HandlerList getHandlers() {
|
||||||
|
return handlerList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -207,7 +207,8 @@ public class MapWrapper_v1_12_R1 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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(packet, "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
|
||||||
|
protected 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -207,7 +207,8 @@ public class MapWrapper_v1_13_R2 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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(packet, "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
|
||||||
|
protected 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -207,7 +207,8 @@ public class MapWrapper_v1_14_R1 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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(packet, "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
|
||||||
|
protected 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -207,7 +207,8 @@ public class MapWrapper_v1_15_R1 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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(packet, "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
|
||||||
|
protected 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -207,7 +207,8 @@ public class MapWrapper_v1_16_R3 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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(packet, "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
|
||||||
|
protected 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -212,7 +212,8 @@ public class MapWrapper_v1_17_R1 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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 = packetPlayOutMap.b();
|
||||||
|
|
||||||
|
if (id < 0) {
|
||||||
|
//It's one of our maps, invert ID and let through!
|
||||||
|
int newId = -id;
|
||||||
|
setField(packet, "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
|
||||||
|
Enum<?> action = (Enum<?>) getField(packetPlayInUseEntity, "b"); //action
|
||||||
|
EnumHand hand = (EnumHand) getField(action, "a"); //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, 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) {
|
||||||
|
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().connection.connection.channel.pipeline();
|
||||||
|
pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void removePlayer(Player p) {
|
||||||
|
Channel channel = ((CraftPlayer) p).getHandle().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.x, vec3dObj.y, vec3dObj.z);
|
||||||
|
}
|
||||||
|
}
|
|
@ -212,7 +212,8 @@ public class MapWrapper_v1_18_R2 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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 = packetPlayOutMap.getMapId();
|
||||||
|
|
||||||
|
if (id < 0) {
|
||||||
|
//It's one of our maps, invert ID and let through!
|
||||||
|
int newId = -id;
|
||||||
|
setField(packet, "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
|
||||||
|
Enum<?> action = (Enum<?>) getField(packetPlayInUseEntity, "b"); //action
|
||||||
|
EnumHand hand = (EnumHand) getField(action, "a"); //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, 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) {
|
||||||
|
int slot = packetPlayInSetCreativeSlot.getSlotNum();
|
||||||
|
ItemStack item = packetPlayInSetCreativeSlot.getItem();
|
||||||
|
|
||||||
|
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().connection.connection.channel.pipeline();
|
||||||
|
pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void removePlayer(Player p) {
|
||||||
|
Channel channel = ((CraftPlayer) p).getHandle().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.x, vec3dObj.y, vec3dObj.z);
|
||||||
|
}
|
||||||
|
}
|
|
@ -212,7 +212,8 @@ public class MapWrapper_v1_19_R1 implements MapWrapper {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ItemFrame getItemFrameById(World world, int entityId) {
|
@Override
|
||||||
|
public ItemFrame getItemFrameById(World world, int entityId) {
|
||||||
CraftWorld craftWorld = (CraftWorld) world;
|
CraftWorld craftWorld = (CraftWorld) world;
|
||||||
|
|
||||||
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
Entity entity = craftWorld.getHandle().getEntity(entityId);
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
* 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.PacketListener;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.CreateInventoryMapUpdateEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapCancelEvent;
|
||||||
|
import tech.sbdevelopment.mapreflectionapi.events.MapInteractEvent;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
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 = packetPlayOutMap.getMapId();
|
||||||
|
|
||||||
|
if (id < 0) {
|
||||||
|
//It's one of our maps, invert ID and let through!
|
||||||
|
int newId = -id;
|
||||||
|
setField(packet, "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
|
||||||
|
Enum<?> action = (Enum<?>) getField(packetPlayInUseEntity, "b"); //action
|
||||||
|
EnumHand hand = (EnumHand) getField(action, "a"); //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, 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) {
|
||||||
|
int slot = packetPlayInSetCreativeSlot.getSlotNum();
|
||||||
|
ItemStack item = packetPlayInSetCreativeSlot.getItem();
|
||||||
|
|
||||||
|
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().connection.connection.channel.pipeline();
|
||||||
|
pipeline.addBefore("packet_handler", p.getName(), channelDuplexHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void removePlayer(Player p) {
|
||||||
|
Channel channel = ((CraftPlayer) p).getHandle().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.x, vec3dObj.y, vec3dObj.z);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue