diff --git a/CommonCore b/CommonCore index 9ea02eb..89b0c14 160000 --- a/CommonCore +++ b/CommonCore @@ -1 +1 @@ -Subproject commit 9ea02ebcd4620e7baa6980cd88e1a4dabd59e50c +Subproject commit 89b0c14da664589a7c9699d73bf72028cdf9dd0d diff --git a/SpigotCore_Main/src/de/steamwar/entity/REntity.java b/SpigotCore_Main/src/de/steamwar/entity/REntity.java index bc7736e..5d01b40 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 1b85252..e0ea912 100644 --- a/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java +++ b/SpigotCore_Main/src/de/steamwar/entity/REntityServer.java @@ -19,9 +19,11 @@ package de.steamwar.entity; +import com.comphenix.tinyprotocol.Reflection; import com.comphenix.tinyprotocol.TinyProtocol; import de.steamwar.core.Core; import de.steamwar.core.FlatteningWrapper; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -34,7 +36,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; @@ -43,15 +47,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); @@ -65,6 +97,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); } @@ -72,6 +105,7 @@ public class REntityServer implements Listener { } void addEntity(REntity entity) { + entityMap.put(entity.entityId, entity); addEntityToChunk(entity); entity.spawn(packet -> updateEntity(entity, packet)); } @@ -105,6 +139,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) { @@ -227,4 +262,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); + } }