From d2bfaf541ef41249d32971b8757ec8545197c9c6 Mon Sep 17 00:00:00 2001 From: Keuin Date: Sun, 22 Aug 2021 19:04:38 +0800 Subject: Logs end gateway teleporting. --- src/main/java/com/keuin/blame/Blame.java | 2 ++ src/main/java/com/keuin/blame/EventHandler.java | 9 ++++++- .../adapter/handler/EndGatewayTeleportHandler.java | 17 ++++++++++++ .../java/com/keuin/blame/data/LogEntryFactory.java | 19 ++++++++++++++ .../com/keuin/blame/data/enums/ActionType.java | 3 ++- .../keuin/blame/mixin/EndGatewayTeleportMixin.java | 27 +++++++++++++++++++ src/main/java/com/keuin/blame/util/EntityUtil.java | 30 ++++++++++++++++++++++ 7 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/keuin/blame/adapter/handler/EndGatewayTeleportHandler.java create mode 100644 src/main/java/com/keuin/blame/mixin/EndGatewayTeleportMixin.java create mode 100644 src/main/java/com/keuin/blame/util/EntityUtil.java (limited to 'src/main/java') diff --git a/src/main/java/com/keuin/blame/Blame.java b/src/main/java/com/keuin/blame/Blame.java index ead8dce..acd9b45 100644 --- a/src/main/java/com/keuin/blame/Blame.java +++ b/src/main/java/com/keuin/blame/Blame.java @@ -2,6 +2,7 @@ package com.keuin.blame; import com.google.gson.Gson; import com.keuin.blame.adapter.*; +import com.keuin.blame.adapter.handler.EndGatewayTeleportHandler; import com.keuin.blame.adapter.handler.PlaceBlockHandler; import com.keuin.blame.command.BlameBlockCommand; import com.keuin.blame.command.BlameLimitCommand; @@ -86,6 +87,7 @@ public class Blame implements ModInitializer { UseBlockCallback.EVENT.register(new UseBlockAdapter(EventHandler.INSTANCE)); UseEntityCallback.EVENT.register(new UseEntityAdapter(EventHandler.INSTANCE)); UseItemCallback.EVENT.register(new UseItemAdapter(EventHandler.INSTANCE)); + EndGatewayTeleportHandler.EVENT.register(EventHandler.INSTANCE); // initialize PrintUtil ServerLifecycleEvents.SERVER_STARTED.register(PrintUtil.INSTANCE); diff --git a/src/main/java/com/keuin/blame/EventHandler.java b/src/main/java/com/keuin/blame/EventHandler.java index 5209fee..7dfd4c9 100644 --- a/src/main/java/com/keuin/blame/EventHandler.java +++ b/src/main/java/com/keuin/blame/EventHandler.java @@ -7,7 +7,9 @@ import com.keuin.blame.data.enums.ActionType; import com.keuin.blame.util.MinecraftUtil; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; +import net.minecraft.block.entity.EndGatewayBlockEntity; import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Hand; import net.minecraft.util.hit.BlockHitResult; @@ -19,7 +21,7 @@ import org.jetbrains.annotations.Nullable; import java.util.Objects; -public class EventHandler implements AttackEntityHandler, PlaceBlockHandler, BreakBlockHandler, UseBlockHandler, UseEntityHandler, UseItemHandler { +public class EventHandler implements AttackEntityHandler, PlaceBlockHandler, BreakBlockHandler, UseBlockHandler, UseEntityHandler, UseItemHandler, EndGatewayTeleportHandler { public static final EventHandler INSTANCE = new EventHandler(); @@ -166,4 +168,9 @@ public class EventHandler implements AttackEntityHandler, PlaceBlockHandler, Bre // TODO: 增加cool down,过滤掉两个相邻重复事件(时间间隔大概为20ms+) } + @Override + public void onEndGatewayTeleport(EndGatewayBlockEntity gatewayBlockEntity, Entity teleportedEntity) { + var entry = LogEntryFactory.endGatewayTeleported(teleportedEntity, gatewayBlockEntity); + SubmitWorker.INSTANCE.submit(entry); + } } diff --git a/src/main/java/com/keuin/blame/adapter/handler/EndGatewayTeleportHandler.java b/src/main/java/com/keuin/blame/adapter/handler/EndGatewayTeleportHandler.java new file mode 100644 index 0000000..12d39c0 --- /dev/null +++ b/src/main/java/com/keuin/blame/adapter/handler/EndGatewayTeleportHandler.java @@ -0,0 +1,17 @@ +package com.keuin.blame.adapter.handler; + +import net.fabricmc.fabric.api.event.Event; +import net.fabricmc.fabric.api.event.EventFactory; +import net.minecraft.block.entity.EndGatewayBlockEntity; +import net.minecraft.entity.Entity; + +public interface EndGatewayTeleportHandler { + Event EVENT = EventFactory.createArrayBacked(EndGatewayTeleportHandler.class, + (listeners) -> (gatewayBlockEntity, teleportedEntity) -> { + for (var listener : listeners) { + listener.onEndGatewayTeleport(gatewayBlockEntity, teleportedEntity); + } + }); + + void onEndGatewayTeleport(EndGatewayBlockEntity gatewayBlockEntity, Entity teleportedEntity); +} diff --git a/src/main/java/com/keuin/blame/data/LogEntryFactory.java b/src/main/java/com/keuin/blame/data/LogEntryFactory.java index f21fc7b..e511ddf 100644 --- a/src/main/java/com/keuin/blame/data/LogEntryFactory.java +++ b/src/main/java/com/keuin/blame/data/LogEntryFactory.java @@ -56,4 +56,23 @@ public class LogEntryFactory { WorldPos.NULL_POS ); } + + + @SuppressWarnings("ConstantConditions") + public static LogEntry endGatewayTeleported(Entity entity, EndGatewayBlockEntity gatewayBlockEntity) { + var world = gatewayBlockEntity.hasWorld() ? gatewayBlockEntity.getWorld() : Objects.requireNonNull(entity.world); + var worldName = MinecraftUtil.worldToString(world); + var gatewayPos = gatewayBlockEntity.getPos(); + var itemId = Registry.ITEM.getId(gatewayBlockEntity.getCachedState().getBlock().asItem()).toString(); + return new LogEntry( + System.currentTimeMillis(), + entity.getName().asString(), + entity.getUuid(), + new WorldPos(worldName, entity.getX(), entity.getY(), entity.getZ()), + ActionType.TELEPORTED_BY, + ObjectType.BLOCK, + itemId, + new WorldPos(worldName, gatewayPos.getX(), gatewayPos.getY(), gatewayPos.getZ()) + ); + } } diff --git a/src/main/java/com/keuin/blame/data/enums/ActionType.java b/src/main/java/com/keuin/blame/data/enums/ActionType.java index 58c4a56..c900895 100644 --- a/src/main/java/com/keuin/blame/data/enums/ActionType.java +++ b/src/main/java/com/keuin/blame/data/enums/ActionType.java @@ -8,7 +8,8 @@ public enum ActionType implements IntegerEnum { BLOCK_USE(3, "USE_BLOCK"), ENTITY_ATTACK(4, "ATTACK_ENTITY"), ENTITY_USE(5, "USE_ENTITY"), - ITEM_USE(6, "USE_ITEM"); + ITEM_USE(6, "USE_ITEM"), + TELEPORTED_BY(7, "TELEPORTED_BY"); private final int value; private final String typeString; diff --git a/src/main/java/com/keuin/blame/mixin/EndGatewayTeleportMixin.java b/src/main/java/com/keuin/blame/mixin/EndGatewayTeleportMixin.java new file mode 100644 index 0000000..095e396 --- /dev/null +++ b/src/main/java/com/keuin/blame/mixin/EndGatewayTeleportMixin.java @@ -0,0 +1,27 @@ +package com.keuin.blame.mixin; + +import com.keuin.blame.adapter.handler.EndGatewayTeleportHandler; +import com.keuin.blame.util.EntityUtil; +import net.minecraft.block.entity.EndGatewayBlockEntity; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(EndGatewayBlockEntity.class) +public class EndGatewayTeleportMixin { + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;teleport(DDD)V"), + method = "tryTeleportingEntity") + public void teleportEntity(Entity entity, CallbackInfo ci) { + // all teleported entities, including all passengers + var entitySet = EntityUtil.getEntityRidingRelationClosure(entity.getRootVehicle()); + var gatewayBlockEntity = (EndGatewayBlockEntity) (Object) this; + for (Entity e : entitySet) { + EndGatewayTeleportHandler.EVENT + .invoker() + .onEndGatewayTeleport(gatewayBlockEntity, e); + } + } +} diff --git a/src/main/java/com/keuin/blame/util/EntityUtil.java b/src/main/java/com/keuin/blame/util/EntityUtil.java new file mode 100644 index 0000000..31eb55f --- /dev/null +++ b/src/main/java/com/keuin/blame/util/EntityUtil.java @@ -0,0 +1,30 @@ +package com.keuin.blame.util; + +import net.minecraft.entity.Entity; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +public class EntityUtil { + /** + * Get passengers and passengers of passengers and so on. i.e. get the closure of 'riding' relation on given entity. + * @param entity The entity to start from. + * @return the closure. Note that the set contains the root entity. + */ + public static Set getEntityRidingRelationClosure(Entity entity) { + Objects.requireNonNull(entity); + Set set = new HashSet<>(); + set.add(entity); + bfs(entity, set); + return Collections.unmodifiableSet(set); + } + + private static void bfs(Entity entity, Set set) { + for (var sub : entity.getPassengerList()) { + set.add(sub); + bfs(sub, set); + } + } +} -- cgit v1.2.3