mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
Upstream has released updates that appears to apply and compile correctly Paper Changes: cb15cfa4 Improve Async Login so pending connections dont get exposed f275e9cb Optimize Hoppers - Major Boost - Got2GoFast! 0106485c Improvements to watchdog changes 65934b1f Fix build for last commit. 5am commits are great 3f436029 Don't process watchdog until server has fully started and ticked. 938bd972 Don't fire BlockFade on worldgen threads - Fixes #3208 509a828e Fix loading spawn chunks when async chunks is off 8a91bfd2 Improvements to async login bf698865 Revert "Re-track players that dismount from other players" 82b98418 Fix some issues with async login as well another source of sync loads aa241d2b Allow multiple callbacks to schedule for Callback Executor a2064a41 Add PlayerAttackEntityCooldownResetEvent This event is called when processing a player's attack on an entity right before their attack strength cd is reset, there are no existing events that fire within this period of time so it was impossible to capture the players attack strength via API prior to this commit. f48d4299 Allow sleeping players to float eeb2f67d Fix Bed respawn deviating too far from vanilla (#3195) 68a7b9fe Move player to spawn point if spawn in unloaded world
304 lines
14 KiB
Diff
304 lines
14 KiB
Diff
From abb33f41016157ea033dade6e81f3e7a87afe74e Mon Sep 17 00:00:00 2001
|
|
From: William Blake Galbreath <blake.galbreath@gmail.com>
|
|
Date: Thu, 8 Aug 2019 15:29:15 -0500
|
|
Subject: [PATCH] Implement AFK API
|
|
|
|
---
|
|
.../java/net/minecraft/server/Entity.java | 1 +
|
|
.../net/minecraft/server/EntityHuman.java | 9 ++++
|
|
.../net/minecraft/server/EntityPlayer.java | 43 +++++++++++++++++++
|
|
.../net/minecraft/server/IEntityAccess.java | 34 ++++++---------
|
|
.../net/minecraft/server/IEntitySelector.java | 2 +
|
|
.../minecraft/server/PlayerConnection.java | 10 +++++
|
|
.../net/minecraft/server/WorldServer.java | 4 +-
|
|
.../net/pl3x/purpur/PurpurWorldConfig.java | 11 +++++
|
|
.../craftbukkit/entity/CraftPlayer.java | 17 ++++++++
|
|
.../java/org/spigotmc/ActivationRange.java | 1 +
|
|
src/main/resources/purpur.lang | 4 +-
|
|
11 files changed, 111 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java
|
|
index c211073e..9ff3e68e 100644
|
|
--- a/src/main/java/net/minecraft/server/Entity.java
|
|
+++ b/src/main/java/net/minecraft/server/Entity.java
|
|
@@ -1420,6 +1420,7 @@ public abstract class Entity implements INamableTileEntity, ICommandListener, Ke
|
|
return MathHelper.c(f * f + f1 * f1 + f2 * f2);
|
|
}
|
|
|
|
+ public double getDistanceSquared(double x, double y, double z) { return g(x, y, z); } // Purpur - OBFHELPER
|
|
public double g(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 16ccabfd..5ac3c464 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityHuman.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityHuman.java
|
|
@@ -86,6 +86,15 @@ public abstract class EntityHuman extends EntityLiving {
|
|
}
|
|
// CraftBukkit end
|
|
|
|
+ // Purpur start
|
|
+ public void setAfk(boolean setAfk){
|
|
+ }
|
|
+
|
|
+ public boolean isAfk() {
|
|
+ return false;
|
|
+ }
|
|
+ // Purpur end
|
|
+
|
|
public EntityHuman(World world, GameProfile gameprofile) {
|
|
super(EntityTypes.PLAYER, world);
|
|
this.bV = ItemStack.a;
|
|
diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
index 51933a49..a021c111 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
@@ -1622,8 +1622,51 @@ public class EntityPlayer extends EntityHuman implements ICrafting {
|
|
|
|
public void resetIdleTimer() {
|
|
this.cj = SystemUtils.getMonotonicMillis();
|
|
+ setAfk(false); // Purpur
|
|
}
|
|
|
|
+ // Purpur start
|
|
+ private boolean isAfk = false;
|
|
+
|
|
+ @Override
|
|
+ public void setAfk(boolean setAfk) {
|
|
+ if (this.isAfk == setAfk) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ net.pl3x.purpur.event.PlayerAFKEvent event = new net.pl3x.purpur.event.PlayerAFKEvent(getBukkitEntity(), setAfk, world.purpurConfig.idleTimeoutKick, LocaleLanguage.getInstance().translateKey("idle.timeout.broadcast." + (setAfk ? "away" : "back")), !Bukkit.isPrimaryThread());
|
|
+ if (!event.callEvent() || event.shouldKick()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ this.isAfk = setAfk;
|
|
+
|
|
+ if (!setAfk) {
|
|
+ resetIdleTimer();
|
|
+ }
|
|
+
|
|
+ if (event.getBroadcastMsg() != null && !event.getBroadcastMsg().isEmpty()) {
|
|
+ server.getPlayerList().sendAll(new PacketPlayOutChat(new ChatMessage(event.getBroadcastMsg(), getScoreboardDisplayName())));
|
|
+ }
|
|
+
|
|
+ if (world.purpurConfig.idleTimeoutUpdateTabList) {
|
|
+ getBukkitEntity().setPlayerListName((setAfk ? "[AFK] " : "") + getName());
|
|
+ }
|
|
+
|
|
+ ((WorldServer) world).everyoneSleeping();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isAfk() {
|
|
+ return isAfk;
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public boolean isCollidable(boolean ignoreClimbing) {
|
|
+ return !isAfk() && super.isCollidable(ignoreClimbing);
|
|
+ }
|
|
+ // Purpur end
|
|
+
|
|
public ServerStatisticManager getStatisticManager() {
|
|
return this.serverStatisticManager;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/IEntityAccess.java b/src/main/java/net/minecraft/server/IEntityAccess.java
|
|
index 89961900..d9f246b8 100644
|
|
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
|
|
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
|
|
@@ -125,28 +125,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.g(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.getDistanceSquared(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 e1fdee27..4665671e 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<Entity> a = Entity::isAlive;
|
|
+ public static Predicate<EntityLiving> isLivingAlive() { return b; } // Purpur - OBFHELPER
|
|
public static final Predicate<EntityLiving> b = EntityLiving::isAlive;
|
|
public static final Predicate<Entity> c = (entity) -> {
|
|
return entity.isAlive() && !entity.isVehicle() && !entity.isPassenger();
|
|
@@ -24,6 +25,7 @@ public final class IEntitySelector {
|
|
return !entity.isSpectator();
|
|
};
|
|
public static Predicate<EntityHuman> isInsomniac = (player) -> MathHelper.clamp(((EntityPlayer) player).getStatisticManager().getStatisticValue(StatisticList.CUSTOM.b(StatisticList.TIME_SINCE_REST)), 1, Integer.MAX_VALUE) >= 72000; // Purpur
|
|
+ public static Predicate<EntityHuman> notAfk = (player) -> !player.isAfk(); // Purpur
|
|
|
|
public static Predicate<Entity> 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 3c37d032..c1a4697a 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
@@ -224,6 +224,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]));
|
|
}
|
|
@@ -440,6 +446,8 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
|
this.lastYaw = to.getYaw();
|
|
this.lastPitch = to.getPitch();
|
|
|
|
+ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ()) this.player.resetIdleTimer(); // Purpur
|
|
+
|
|
// Skip the first time we do this
|
|
if (true) { // Spigot - don't skip any move events
|
|
Location oldTo = to.clone();
|
|
@@ -1109,6 +1117,8 @@ public class PlayerConnection implements PacketListenerPlayIn {
|
|
this.lastYaw = to.getYaw();
|
|
this.lastPitch = to.getPitch();
|
|
|
|
+ if (!to.getWorld().getUID().equals(from.getWorld().getUID()) || to.getBlockX() != from.getBlockX() || to.getBlockY() != from.getBlockY() || to.getBlockZ() != from.getBlockZ()) 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/minecraft/server/WorldServer.java b/src/main/java/net/minecraft/server/WorldServer.java
|
|
index fe81529a..9b873948 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -393,7 +393,7 @@ public class WorldServer extends World {
|
|
}
|
|
|
|
if (this.everyoneSleeping && this.players.stream().noneMatch((entityplayer) -> {
|
|
- return !entityplayer.isSpectator() && !entityplayer.isDeeplySleeping() && !entityplayer.fauxSleeping; // CraftBukkit
|
|
+ return !entityplayer.isSpectator() && !entityplayer.isDeeplySleeping() && !entityplayer.fauxSleeping && !(purpurConfig.idleTimeoutCountAsSleeping && entityplayer.isAfk()); // CraftBukkit // Purpur
|
|
})) {
|
|
// CraftBukkit start
|
|
long l = this.worldData.getDayTime() + 24000L;
|
|
@@ -714,7 +714,7 @@ public class WorldServer extends World {
|
|
while (iterator.hasNext()) {
|
|
EntityPlayer entityplayer = (EntityPlayer) iterator.next();
|
|
|
|
- if (entityplayer.isSpectator() || (entityplayer.fauxSleeping && !entityplayer.isSleeping())) { // CraftBukkit
|
|
+ if (entityplayer.isSpectator() || (entityplayer.fauxSleeping && !entityplayer.isSleeping()) || (purpurConfig.idleTimeoutCountAsSleeping && entityplayer.isAfk())) { // CraftBukkit // Purpur
|
|
++i;
|
|
} else if (entityplayer.isSleeping()) {
|
|
++j;
|
|
diff --git a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
index c6bf9395..76f8c8fe 100644
|
|
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
@@ -138,6 +138,17 @@ public class PurpurWorldConfig {
|
|
disableDropsOnCrammingDeath = getBoolean("gameplay-mechanics.disable-drops-on-cramming-death", disableDropsOnCrammingDeath);
|
|
}
|
|
|
|
+ public boolean idleTimeoutKick = true;
|
|
+ public boolean idleTimeoutTickNearbyEntities = true;
|
|
+ public boolean idleTimeoutCountAsSleeping = false;
|
|
+ public boolean idleTimeoutUpdateTabList = false;
|
|
+ private void idleTimeoutSettings() {
|
|
+ idleTimeoutKick = getBoolean("gameplay-mechanics.player.idle-timeout.kick-if-idle", idleTimeoutKick);
|
|
+ idleTimeoutTickNearbyEntities = getBoolean("gameplay-mechanics.player.idle-timeout.tick-nearby-entities", idleTimeoutTickNearbyEntities);
|
|
+ idleTimeoutCountAsSleeping = getBoolean("gameplay-mechanics.player.idle-timeout.count-as-sleeping", idleTimeoutCountAsSleeping);
|
|
+ idleTimeoutUpdateTabList = getBoolean("gameplay-mechanics.player.idle-timeout.update-tab-list", idleTimeoutUpdateTabList);
|
|
+ }
|
|
+
|
|
public boolean batRidable = false;
|
|
public boolean batRidableInWater = false;
|
|
public boolean batRequireShiftToMount = true;
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
index b76379a1..b7571d08 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -2079,4 +2079,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
|
return spigot;
|
|
}
|
|
// Spigot end
|
|
+
|
|
+ // Purpur start
|
|
+ @Override
|
|
+ public boolean isAfk() {
|
|
+ return getHandle().isAfk();
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void setAfk(boolean setAfk) {
|
|
+ getHandle().setAfk(setAfk);
|
|
+ }
|
|
+
|
|
+ @Override
|
|
+ public void resetIdleTimer() {
|
|
+ getHandle().resetIdleTimer();
|
|
+ }
|
|
+ // Purpur end
|
|
}
|
|
diff --git a/src/main/java/org/spigotmc/ActivationRange.java b/src/main/java/org/spigotmc/ActivationRange.java
|
|
index 79581717..17c4d7ec 100644
|
|
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
|
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
|
@@ -146,6 +146,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 );
|
|
diff --git a/src/main/resources/purpur.lang b/src/main/resources/purpur.lang
|
|
index 7125c047..e925e137 100644
|
|
--- a/src/main/resources/purpur.lang
|
|
+++ b/src/main/resources/purpur.lang
|
|
@@ -1,3 +1,5 @@
|
|
{
|
|
- "cannot.ride.mob": "You cannot mount that mob"
|
|
+ "cannot.ride.mob": "You cannot mount that mob",
|
|
+ "idle.timeout.broadcast.away": "§e§o%s is now AFK",
|
|
+ "idle.timeout.broadcast.back": "§e§o%s is no longer AFK"
|
|
}
|
|
--
|
|
2.24.0
|
|
|