From 656498e3c9121548d4057b1cf12b083899ac4685 Mon Sep 17 00:00:00 2001 From: Flemmli97 Date: Wed, 12 May 2021 13:29:29 +0200 Subject: [PATCH] claim yeeting. maybe. idk --- .../flan/api/PermissionRegistry.java | 1 + .../com/flemmli97/flan/claim/Benchmark.java | 38 +++++++++ .../flan/event/EntityInteractEvents.java | 79 +++++++++++++++++++ .../flan/mixin/PlayerClaimMixin.java | 16 ++++ .../flan/player/IPlayerClaimImpl.java | 7 ++ 5 files changed, 141 insertions(+) create mode 100644 src/main/java/com/flemmli97/flan/claim/Benchmark.java diff --git a/src/main/java/com/flemmli97/flan/api/PermissionRegistry.java b/src/main/java/com/flemmli97/flan/api/PermissionRegistry.java index 28ba88d..f9a7739 100644 --- a/src/main/java/com/flemmli97/flan/api/PermissionRegistry.java +++ b/src/main/java/com/flemmli97/flan/api/PermissionRegistry.java @@ -66,6 +66,7 @@ public class PermissionRegistry { public static ClaimPermission BREAKNONLIVING = register(new ClaimPermission("BREAKNONLIVING", () -> new ItemStack(Items.COMMAND_BLOCK_MINECART), "Permission to break things like minecarts or armor stands")); public static ClaimPermission DROP = register(new ClaimPermission("DROP", () -> new ItemStack(Items.BOWL), true, "Allow the drop of items")); public static ClaimPermission PICKUP = register(new ClaimPermission("PICKUP", () -> new ItemStack(Items.BRICK), true, "Allow the pickup of items")); + public static ClaimPermission CANSTAY = register(new ClaimPermission("CANSTAY", () -> new ItemStack(Items.PAPER), true, "Allow player to enter your claim")); public static ClaimPermission HURTPLAYER = global(new ClaimPermission("HURTPLAYER", () -> new ItemStack(Items.DIAMOND_SWORD), "Permission to hurt other players")); public static ClaimPermission EXPLOSIONS = global(new ClaimPermission("EXPLOSIONS", () -> new ItemStack(Items.TNT), "Toggle explosions in claim")); public static ClaimPermission WITHER = global(new ClaimPermission("WITHER", () -> new ItemStack(Items.WITHER_SKELETON_SKULL), "Toggle wither breaking blocks in claim")); diff --git a/src/main/java/com/flemmli97/flan/claim/Benchmark.java b/src/main/java/com/flemmli97/flan/claim/Benchmark.java new file mode 100644 index 0000000..2049972 --- /dev/null +++ b/src/main/java/com/flemmli97/flan/claim/Benchmark.java @@ -0,0 +1,38 @@ +package com.flemmli97.flan.claim; + +import org.apache.commons.lang3.time.StopWatch; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +public class Benchmark { + + private final StopWatch stopWatch = new StopWatch(); + private final List times = new LinkedList<>(); + + public Benchmark() { + } + public void start() { + stopWatch.start(); + } + + public void stop() { + stopWatch.stop(); + times.add(stopWatch.getNanoTime()); + stopWatch.reset(); + } + + public void reset(){ + times.clear(); + stopWatch.reset(); + } + + public long getAverage() { + return times.stream().reduce(0L, Long::sum)/times.size(); + } + + public long worstCase() { + return times.stream().max(Long::compareTo).orElse(-1L); + } +} diff --git a/src/main/java/com/flemmli97/flan/event/EntityInteractEvents.java b/src/main/java/com/flemmli97/flan/event/EntityInteractEvents.java index a4b665c..ea5bb64 100644 --- a/src/main/java/com/flemmli97/flan/event/EntityInteractEvents.java +++ b/src/main/java/com/flemmli97/flan/event/EntityInteractEvents.java @@ -2,11 +2,14 @@ package com.flemmli97.flan.event; import com.flemmli97.flan.api.ClaimPermission; import com.flemmli97.flan.api.PermissionRegistry; +import com.flemmli97.flan.claim.Benchmark; +import com.flemmli97.flan.claim.Claim; import com.flemmli97.flan.claim.ClaimStorage; import com.flemmli97.flan.claim.IPermissionContainer; import com.flemmli97.flan.claim.ObjectToPermissionMap; import com.flemmli97.flan.mixin.IPersistentProjectileVars; import com.flemmli97.flan.player.IOwnedItem; +import com.flemmli97.flan.player.IPlayerClaimImpl; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; @@ -36,13 +39,18 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvents; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.Pair; import net.minecraft.util.collection.DefaultedList; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.hit.HitResult; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import org.apache.commons.lang3.time.StopWatch; + +import java.util.function.Consumer; public class EntityInteractEvents { @@ -252,4 +260,75 @@ public class EntityInteractEvents { } return true; } + + public static final Benchmark benchmark = new Benchmark(); + + public static void updateClaim(ServerPlayerEntity player, Consumer cons) { + benchmark.start(); + if(player.age % 5 == 0) { + ClaimStorage storage = ClaimStorage.get(player.getServerWorld()); + Vec3d pos = player.getPos(); + BlockPos.Mutable bPos = new BlockPos(pos).mutableCopy(); + Claim claim = storage.getClaimAt(bPos); + cons.accept(claim); + if(!player.isSpectator()) { + if (claim != null && !claim.canInteract(player, PermissionRegistry.CANSTAY, bPos, true)) { + Vec3d tp = getTeleportPos(player, pos, storage, claim.getDimensions(), bPos); + player.teleport(tp.getX(), tp.getY(), tp.getZ()); + } + } + } + benchmark.stop(); + System.out.println(String.format("Average: %d, Worst: %d", benchmark.getAverage(), benchmark.worstCase())); + } + + private static Vec3d getTeleportPos(ServerPlayerEntity player, Vec3d playerPos, ClaimStorage storage, int [] dim, BlockPos.Mutable bPos) { + Pair pos = nearestOutside(dim, playerPos); + bPos.set(pos.getRight().getX(), pos.getRight().getY(), pos.getRight().getZ()); + Claim claim = storage.getClaimAt(bPos); + if(claim == null || claim.canInteract(player, PermissionRegistry.CANSTAY, bPos, false)) + return pos.getRight(); + int[] newDim = claim.getDimensions(); + switch (pos.getLeft()){ + case NORTH: + dim[2] = newDim[2]; + break; + case SOUTH: + dim[3] = newDim[3]; + break; + case EAST: + dim[1] = newDim[1]; + break; + default: + dim[0] = newDim[0]; + break; + } + return getTeleportPos(player, playerPos, storage, dim, bPos); + } + + + private static Pair nearestOutside(int[] dim, Vec3d from) { + double northDist = Math.abs(from.getZ() - dim[2]); + double southDist = Math.abs(dim[3] - from.getZ()); + double westDist = Math.abs(from.getX() - dim[0]); + double eastDist = Math.abs(dim[1] - from.getX()); + if(northDist > southDist) { + if(eastDist > westDist) { + if(southDist > westDist) + return new Pair<>(Direction.WEST, new Vec3d(dim[0] - 1.5, from.getY(), from.getZ())); + return new Pair<>(Direction.SOUTH, new Vec3d(from.getX(), from.getY(), dim[3] + 1.5)); + } + if(southDist > eastDist) + return new Pair<>(Direction.EAST, new Vec3d(dim[1] + 1.5, from.getY(), from.getZ())); + return new Pair<>(Direction.SOUTH, new Vec3d(from.getX(), from.getY(), dim[3]+1.5)); + } + if(eastDist > westDist) { + if(northDist > westDist) + return new Pair<>(Direction.WEST, new Vec3d(dim[0] - 1.5, from.getY(), from.getZ())); + return new Pair<>(Direction.NORTH, new Vec3d(from.getX(), from.getY(), dim[2] - 1.5)); + } + if(northDist > eastDist) + return new Pair<>(Direction.EAST, new Vec3d(dim[1] + 1.5, from.getY(), from.getZ())); + return new Pair<>(Direction.NORTH, new Vec3d(from.getX(), from.getY(), dim[2]-1.5)); + } } diff --git a/src/main/java/com/flemmli97/flan/mixin/PlayerClaimMixin.java b/src/main/java/com/flemmli97/flan/mixin/PlayerClaimMixin.java index f79e34f..b81d6cc 100644 --- a/src/main/java/com/flemmli97/flan/mixin/PlayerClaimMixin.java +++ b/src/main/java/com/flemmli97/flan/mixin/PlayerClaimMixin.java @@ -1,5 +1,8 @@ package com.flemmli97.flan.mixin; +import com.flemmli97.flan.claim.Claim; +import com.flemmli97.flan.claim.ClaimStorage; +import com.flemmli97.flan.event.EntityInteractEvents; import com.flemmli97.flan.player.IPlayerClaimImpl; import com.flemmli97.flan.player.PlayerClaimData; import net.minecraft.nbt.CompoundTag; @@ -18,6 +21,9 @@ public abstract class PlayerClaimMixin implements IPlayerClaimImpl { @Unique private PlayerClaimData claimData; + @Unique + private Claim currentClaim; + @Shadow private MinecraftServer server; @@ -46,8 +52,18 @@ public abstract class PlayerClaimMixin implements IPlayerClaimImpl { this.claimData.clone(PlayerClaimData.get(oldPlayer)); } + @Inject(method = "tick", at = @At("HEAD")) + private void canStay(CallbackInfo info) { + EntityInteractEvents.updateClaim((ServerPlayerEntity)(Object)this, claim->this.currentClaim = claim); + } + @Override public PlayerClaimData get() { return this.claimData; } + + @Override + public Claim getCurrentClaim() { + return this.currentClaim; + } } diff --git a/src/main/java/com/flemmli97/flan/player/IPlayerClaimImpl.java b/src/main/java/com/flemmli97/flan/player/IPlayerClaimImpl.java index 696fcc7..d8784d4 100644 --- a/src/main/java/com/flemmli97/flan/player/IPlayerClaimImpl.java +++ b/src/main/java/com/flemmli97/flan/player/IPlayerClaimImpl.java @@ -1,6 +1,13 @@ package com.flemmli97.flan.player; +import com.flemmli97.flan.claim.Claim; + public interface IPlayerClaimImpl { PlayerClaimData get(); + + /** + * @return Gets the current claim the player is in. Can be null if not in a claim. + */ + Claim getCurrentClaim(); }