diff --git a/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore_Main/src/de/steamwar/entity/REntity.java index d6ace1a..2d95c9b 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/REntity.java +++ b/SpigotCore_Main/src/de/steamwar/entity/REntity.java @@ -20,13 +20,17 @@ package de.steamwar.entity; import com.comphenix.tinyprotocol.Reflection; -import de.steamwar.core.*; +import de.steamwar.core.BountifulWrapper; +import de.steamwar.core.Core; +import de.steamwar.core.FlatteningWrapper; +import de.steamwar.core.ProtocolWrapper; import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntList; import lombok.Getter; import org.bukkit.Location; import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; import java.util.*; import java.util.function.Consumer; @@ -214,6 +218,18 @@ public class REntity { } } + public double getX() { + return x; + } + + public double getY() { + return y; + } + + public double getZ() { + return z; + } + private static int spawnPacketOffset() { switch (Core.getVersion()) { case 8: diff --git a/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java b/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java index 70a5fee..a718c41 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java +++ b/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java @@ -19,8 +19,10 @@ package de.steamwar.entity; +import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.core.Core; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -33,7 +35,9 @@ import org.bukkit.event.player.PlayerQuitEvent; import java.util.HashMap; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; +import java.util.function.BiFunction; import java.util.function.Consumer; @@ -42,15 +46,43 @@ public class REntityServer implements Listener { private static final HashSet emptyEntities = new HashSet<>(0); private static final HashSet emptyPlayers = new HashSet<>(0); + private static final Class useEntity = Reflection.getClass("{nms.network.protocol.game}.PacketPlayInUseEntity"); + private static final Reflection.FieldAccessor useEntityTarget = Reflection.getField(useEntity, int.class, 0); + private static final Reflection.FieldAccessor useEntityAction = Reflection.getField(useEntity, int.class, 1); + + private final ConcurrentHashMap entityMap = new ConcurrentHashMap<>(); private final HashMap> entities = new HashMap<>(); private final HashMap> players = new HashMap<>(); private final HashMap lastLocation = new HashMap<>(); private final HashMap viewDistance = new HashMap<>(); + private EntityActionListener callback = null; + + private BiFunction filter = (player, packet) -> { + if (callback == null) return packet; + int target = useEntityTarget.get(packet); + REntity entity = entityMap.get(target); + if (entity == null) return packet; + + EntityAction action = useEntityAction.get(packet) == 1 ? EntityAction.ATTACK : EntityAction.INTERACT; + Bukkit.getScheduler().runTask(Core.getInstance(), () -> { + callback.onAction(player, entity, action); + }); + return null; + }; + public REntityServer() { Core.getInstance().getServer().getPluginManager().registerEvents(this, Core.getInstance()); } + public void setCallback(EntityActionListener callback) { + boolean uninitialized = this.callback == null; + this.callback = callback; + + if(uninitialized) + TinyProtocol.instance.addFilter(useEntity, filter); + } + public void addPlayer(Player player) { Location location = player.getLocation(); lastLocation.put(player, location); @@ -64,6 +96,7 @@ public class REntityServer implements Listener { } public void close() { + TinyProtocol.instance.removeFilter(useEntity, filter); for(Player player : lastLocation.keySet().toArray(new Player[0])) { removePlayer(player); } @@ -71,6 +104,7 @@ public class REntityServer implements Listener { } void addEntity(REntity entity) { + entityMap.put(entity.entityId, entity); addEntityToChunk(entity); entity.spawn(packet -> updateEntity(entity, packet)); } @@ -104,6 +138,7 @@ public class REntityServer implements Listener { void removeEntity(REntity entity) { entity.despawn(packet -> updateEntity(entity, packet)); removeEntityFromChunk(entity); + entityMap.remove(entity.entityId); } private void addEntityToChunk(REntity entity) { @@ -226,4 +261,13 @@ public class REntityServer implements Listener { private long chunkToId(int x, int z) { return ((long) x << 32) + z; } + + public enum EntityAction { + INTERACT, + ATTACK, + } + + public interface EntityActionListener { + void onAction(Player player, REntity entity, EntityAction action); + } }