mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 08:27:43 +01:00
Upstream has released updates that appears to apply and compile correctly Paper Changes: d63075df Pass fireworks through vanished players (#3021) 4d991f19 [CI-SKIP] Rebuild patches 26070a0e Indicate ticking status in entity list command (#2856) 2ff7b480 Optimise Chunk#getFluid (#2860) c23ebb78 Optimise ticklistserver (#2957)
283 lines
14 KiB
Diff
283 lines
14 KiB
Diff
From bfec24048fcbf8603ebc427e8f8a018c38248df4 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
|
|
|
|
---
|
|
.../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 | 15 +++++++
|
|
.../craftbukkit/entity/CraftPlayer.java | 17 ++++++++
|
|
.../java/org/spigotmc/ActivationRange.java | 1 +
|
|
9 files changed, 111 insertions(+), 24 deletions(-)
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java
|
|
index de22cad764..9d26bd1e4c 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 24ce25ba60..4694edc5de 100644
|
|
--- a/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
+++ b/src/main/java/net/minecraft/server/EntityPlayer.java
|
|
@@ -1653,8 +1653,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, setAfk ? world.purpurConfig.idleTimeoutBroadcastAway : world.purpurConfig.idleTimeoutBroadcastBack);
|
|
+ if (!event.callEvent() || event.shouldKick()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ this.isAfk = setAfk;
|
|
+
|
|
+ if (!setAfk) {
|
|
+ resetIdleTimer();
|
|
+ }
|
|
+
|
|
+ if (event.getBroadcastMsg() != null && !event.getBroadcastMsg().isEmpty()) {
|
|
+ ((WorldServer) world).getMinecraftServer().server.broadcastMessage(event.getBroadcastMsg().replace("{player}", getName()));
|
|
+ }
|
|
+
|
|
+ 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 9622615b50..e0d011a2d8 100644
|
|
--- a/src/main/java/net/minecraft/server/IEntityAccess.java
|
|
+++ b/src/main/java/net/minecraft/server/IEntityAccess.java
|
|
@@ -121,28 +121,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 e1fdee2794..4665671ef6 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 67afa457e8..2659da1881 100644
|
|
--- a/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
+++ b/src/main/java/net/minecraft/server/PlayerConnection.java
|
|
@@ -279,6 +279,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]));
|
|
}
|
|
@@ -495,6 +501,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();
|
|
@@ -1164,6 +1172,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 8eae813adc..baa0f885e5 100644
|
|
--- a/src/main/java/net/minecraft/server/WorldServer.java
|
|
+++ b/src/main/java/net/minecraft/server/WorldServer.java
|
|
@@ -746,7 +746,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;
|
|
@@ -1051,7 +1051,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 2bbbf30c0d..95f1dcf0d7 100644
|
|
--- a/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
+++ b/src/main/java/net/pl3x/purpur/PurpurWorldConfig.java
|
|
@@ -147,6 +147,21 @@ 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;
|
|
+ public String idleTimeoutBroadcastAway = "&e&o{player} is now AFK";
|
|
+ public String idleTimeoutBroadcastBack = "&e&o{player} is no longer AFK";
|
|
+ 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);
|
|
+ idleTimeoutBroadcastAway = org.bukkit.ChatColor.translateAlternateColorCodes('&', getString("gameplay-mechanics.player.idle-timeout.broadcast.away", idleTimeoutBroadcastAway));
|
|
+ idleTimeoutBroadcastBack = org.bukkit.ChatColor.translateAlternateColorCodes('&', getString("gameplay-mechanics.player.idle-timeout.broadcast.back", idleTimeoutBroadcastBack));
|
|
+ }
|
|
+
|
|
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 516a016480..7451e120cd 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
|
@@ -2125,4 +2125,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 e160f03c1e..11fb146129 100644
|
|
--- a/src/main/java/org/spigotmc/ActivationRange.java
|
|
+++ b/src/main/java/org/spigotmc/ActivationRange.java
|
|
@@ -142,6 +142,7 @@ public class ActivationRange
|
|
final int maxRange = Math.min( ( ( player instanceof net.minecraft.server.EntityPlayer ? ((net.minecraft.server.EntityPlayer)player).getEffectiveViewDistance(((WorldServer)world).getChunkProvider().playerChunkMap) : world.spigotConfig.viewDistance ) << 4 ) - 8, maxRangeTemp );
|
|
// Tuinity end - per player view distance
|
|
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.24.0
|
|
|