From 1129007b4b28ee14349f7018ef4de740543895e8 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Thu, 8 Aug 2019 15:29:15 -0500 Subject: [PATCH] Implement AFK options --- .../java/net/minecraft/server/Entity.java | 1 + .../net/minecraft/server/EntityHuman.java | 24 +++++++++++++ .../net/minecraft/server/EntityPlayer.java | 1 + .../net/minecraft/server/IEntityAccess.java | 34 +++++++------------ .../net/minecraft/server/IEntitySelector.java | 2 ++ .../minecraft/server/PlayerConnection.java | 10 ++++++ .../net/pl3x/purpur/PurpurWorldConfig.java | 12 +++++++ .../java/org/spigotmc/ActivationRange.java | 1 + 8 files changed, 63 insertions(+), 22 deletions(-) diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java index 770d21468..2ff5a12d8 100644 --- a/src/main/java/net/minecraft/server/Entity.java +++ b/src/main/java/net/minecraft/server/Entity.java @@ -1396,6 +1396,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke return MathHelper.c(f * f + f1 * f1 + f2 * f2); } + public double getDistanceSq(double x, double y, double z) { return e(x, y, z); } // Purpur - OBFHELPER public double e(double d0, double d1, double d2) { double d3 = this.locX - d0; double d4 = this.locY - d1; diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java index 2a943f316..c396bf2e2 100644 --- a/src/main/java/net/minecraft/server/EntityHuman.java +++ b/src/main/java/net/minecraft/server/EntityHuman.java @@ -75,6 +75,30 @@ public abstract class EntityHuman extends EntityLiving { public boolean affectsSpawning = true; // Paper end + // Purpur start + private boolean isAfk = false; + + public void setAfk(boolean isAfk) { + if (!world.purpurConfig.idleTimeoutKick) { // do not broadcast if going to kick + if (!world.purpurConfig.idleTimeoutBroadcastAway.isEmpty() && !this.isAfk && isAfk) { + getMinecraftServer().server.broadcastMessage(world.purpurConfig.idleTimeoutBroadcastAway.replace("{player}", getName())); + } else if (!world.purpurConfig.idleTimeoutBroadcastBack.isEmpty() && this.isAfk && !isAfk) { + getMinecraftServer().server.broadcastMessage(world.purpurConfig.idleTimeoutBroadcastBack.replace("{player}", getName())); + } + } + this.isAfk = isAfk; + } + + public boolean isAfk() { + return isAfk; + } + + @Override + public boolean isCollidable(boolean ignoreClimbing) { + return !isAfk && super.isCollidable(ignoreClimbing); + } + // Purpur end + // CraftBukkit start public boolean fauxSleeping; public String spawnWorld = ""; diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java index 622899d8f..f7694545e 100644 --- a/src/main/java/net/minecraft/server/EntityPlayer.java +++ b/src/main/java/net/minecraft/server/EntityPlayer.java @@ -1593,6 +1593,7 @@ public class EntityPlayer extends EntityHuman implements ICrafting { public void resetIdleTimer() { this.cm = SystemUtils.getMonotonicMillis(); + setAfk(false); // Purpur } public ServerStatisticManager getStatisticManager() { diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java index 9aaa75e95..70fe85279 100644 --- a/src/main/java/net/minecraft/server/IEntityAccess.java +++ b/src/main/java/net/minecraft/server/IEntityAccess.java @@ -116,28 +116,18 @@ public interface IEntityAccess { return entityhuman; } - default boolean isPlayerNearby(double d0, double d1, double d2, double d3) { - Iterator iterator = this.getPlayers().iterator(); - - double d4; - - do { - EntityHuman entityhuman; - - do { - do { - if (!iterator.hasNext()) { - return false; - } - - entityhuman = (EntityHuman) iterator.next(); - } while (!IEntitySelector.f.test(entityhuman)); - } while (!IEntitySelector.b.test(entityhuman)); - - d4 = entityhuman.e(d0, d1, d2); - } while (d3 >= 0.0D && d4 >= d3 * d3); - - return true; + // Purpur start + default boolean isPlayerNearby(double x, double y, double z, double distance) { + double distanceSq = distance * distance; + for (EntityHuman player : getPlayers()) { + if (IEntitySelector.notSpectator().test(player) && IEntitySelector.isLivingAlive().test(player) && IEntitySelector.notAfk.test(player)) { + if (distance < 0.0D || player.getDistanceSq(x, y, z) < distanceSq) { + return true; + } + } + } + return false; + // Purpur end } @Nullable diff --git a/src/main/java/net/minecraft/server/IEntitySelector.java b/src/main/java/net/minecraft/server/IEntitySelector.java index 7ef7fe228..915be1a9a 100644 --- a/src/main/java/net/minecraft/server/IEntitySelector.java +++ b/src/main/java/net/minecraft/server/IEntitySelector.java @@ -7,6 +7,7 @@ import javax.annotation.Nullable; public final class IEntitySelector { public static final Predicate a = Entity::isAlive; + public static Predicate isLivingAlive() { return b; } // Purpur - OBFHELPER public static final Predicate b = EntityLiving::isAlive; public static final Predicate c = (entity) -> { return entity.isAlive() && !entity.isVehicle() && !entity.isPassenger(); @@ -22,6 +23,7 @@ public final class IEntitySelector { public static final Predicate f = (entity) -> { return !entity.isSpectator(); }; + public static Predicate notAfk = (player) -> !player.isAfk(); // Purpur public static Predicate a(double d0, double d1, double d2, double d3) { double d4 = d3 * d3; diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java index 8aa8a672d..7d4369887 100644 --- a/src/main/java/net/minecraft/server/PlayerConnection.java +++ b/src/main/java/net/minecraft/server/PlayerConnection.java @@ -274,6 +274,12 @@ public class PlayerConnection implements PacketListenerPlayIn { } if (this.player.F() > 0L && this.minecraftServer.getIdleTimeout() > 0 && SystemUtils.getMonotonicMillis() - this.player.F() > (long) (this.minecraftServer.getIdleTimeout() * 1000 * 60)) { + // Purpur start + this.player.setAfk(true); + if (!this.player.world.purpurConfig.idleTimeoutKick) { + return; + } + // Purpur end this.player.resetIdleTimer(); // CraftBukkit - SPIGOT-854 this.disconnect(new ChatMessage("multiplayer.disconnect.idling", new Object[0])); } @@ -490,6 +496,8 @@ public class PlayerConnection implements PacketListenerPlayIn { this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); + if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getX() != from.getX() || to.getY() != from.getY() || to.getZ() != from.getZ()) this.player.resetIdleTimer(); // Purpur + // Skip the first time we do this if (true) { // Spigot - don't skip any move events Location oldTo = to.clone(); @@ -1150,6 +1158,8 @@ public class PlayerConnection implements PacketListenerPlayIn { this.lastYaw = to.getYaw(); this.lastPitch = to.getPitch(); + if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getX() != from.getX() || to.getY() != from.getY() || to.getZ() != from.getZ()) this.player.resetIdleTimer(); // Purpur + // Skip the first time we do this if (from.getX() != Double.MAX_VALUE) { Location oldTo = to.clone(); diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java index b1dcb5f8d..69fac757d 100644 --- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java +++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java @@ -1,6 +1,7 @@ package net.pl3x.purpur; import com.destroystokyo.paper.PaperWorldConfig; +import org.bukkit.ChatColor; import org.bukkit.configuration.file.YamlConfiguration; import org.spigotmc.SpigotWorldConfig; @@ -131,6 +132,17 @@ public class PurpurWorldConfig { limitVillagerIronGolemSpawns = getInt("limit-villager-iron-golem-spawns", limitVillagerIronGolemSpawns); } + public boolean idleTimeoutKick = true; + public boolean idleTimeoutTickNearbyEntities = false; + public String idleTimeoutBroadcastAway = "&e&o{player} is now AFK"; + public String idleTimeoutBroadcastBack = "&e&o{player} is no longer AFK"; + private void playerIdleTimeoutSettings() { + idleTimeoutKick = getBoolean("idle-timeout.kick-if-idle", idleTimeoutKick); + idleTimeoutTickNearbyEntities = getBoolean("idle-timeout.tick-nearby-entities", idleTimeoutTickNearbyEntities); + idleTimeoutBroadcastAway = ChatColor.translateAlternateColorCodes('&', getString("idle-timeout.broadcast.away", idleTimeoutBroadcastAway)); + idleTimeoutBroadcastBack = ChatColor.translateAlternateColorCodes('&', getString("idle-timeout.broadcast.back", idleTimeoutBroadcastBack)); + } + public int elytraDamagePerSecond = 1; public double elytraDamageMultiplyBySpeed = 0; public boolean elytraIgnoreUnbreaking = false; diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java index 92601c581..185717c80 100644 --- a/src/main/java/org/spigotmc/ActivationRange.java +++ b/src/main/java/org/spigotmc/ActivationRange.java @@ -128,6 +128,7 @@ public class ActivationRange { player.activatedTick = MinecraftServer.currentTick; + if (!player.world.purpurConfig.idleTimeoutTickNearbyEntities && player.isAfk()) continue; // Purpur maxBB = player.getBoundingBox().grow( maxRange, 256, maxRange ); ActivationType.MISC.boundingBox = player.getBoundingBox().grow( miscActivationRange, 256, miscActivationRange ); ActivationType.RAIDER.boundingBox = player.getBoundingBox().grow( raiderActivationRange, 256, raiderActivationRange ); -- 2.20.1