9
0
mirror of https://github.com/Winds-Studio/Leaf.git synced 2025-12-28 19:39:17 +00:00
Files
Leaf/leaf-server/minecraft-patches/features/0130-Improve-Purpur-AFK-system.patch
Dreeam 3c25377465 Drop some unused patches
ClassInstanceMultiMap belongs to Minecraft vanilla entity storage.
And is unused, since replaced by spottedleaf's entity storage (rewrite chunk system).
However these patches might be useful for vanilla entity storage if is used.
2025-07-09 04:20:02 +08:00

198 lines
13 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dreeam <61569423+Dreeam-qwq@users.noreply.github.com>
Date: Sat, 2 Mar 2024 18:22:15 -0500
Subject: [PATCH] Improve Purpur AFK system
AFK command & command cooldown
AFK title message
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 1dc009e85403fe0b6a68daefecfe5cb25ad263cd..de450f9ef03944b101b483126af6a778ae8a4d1d 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -277,6 +277,7 @@ public class Commands {
StopCommand.register(this.dispatcher);
TransferCommand.register(this.dispatcher);
WhitelistCommand.register(this.dispatcher);
+ if (org.dreeam.leaf.config.modules.gameplay.AfkCommand.enabled) org.purpurmc.purpur.command.AFKCommand.register(this.dispatcher); // Leaf - Improve Purpur AFK system
org.purpurmc.purpur.command.CreditsCommand.register(this.dispatcher); // Purpur - Add credits command
org.purpurmc.purpur.command.DemoCommand.register(this.dispatcher); // Purpur - Add demo command
org.purpurmc.purpur.command.PingCommand.register(this.dispatcher); // Purpur - Add ping command
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index 77ca4f505dc0a1aa6292cfcd957b734ab107f657..5f4dcb645670dd1b07ff865d50530b731f0ef769 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -2423,6 +2423,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
// Purpur start - AFK API
private boolean isAfk = false;
+ // Leaf sart - Improve Purpur AFK system
+ public boolean isCommandAfk = false;
+ public boolean commandAfkStatus = false;
+ // Leaf end - Improve Purpur AFK system
@Override
public void setAfk(boolean afk) {
@@ -2460,6 +2464,18 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
String prefix = (split.length > 0 ? split[0] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix, "");
String suffix = (split.length > 1 ? split[1] : "").replace(org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, "");
if (afk) {
+ // Leaf start - Improve Purpur AFK system
+ String[] rawTitle = org.purpurmc.purpur.PurpurConfig.afkTitleAway.split(":");
+ String title = rawTitle[0];
+ String subTitle = rawTitle[1];
+ long fadeInTicks = Long.parseLong(rawTitle[2]);
+ long stayTicks = Long.parseLong(rawTitle[3]);
+ long fadeOutTicks = Long.parseLong(rawTitle[4]);
+
+ net.kyori.adventure.title.Title tile = net.kyori.adventure.title.Title.title(net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(title), net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(subTitle), net.kyori.adventure.title.Title.Times.times(net.kyori.adventure.util.Ticks.duration(fadeInTicks), net.kyori.adventure.util.Ticks.duration(stayTicks), net.kyori.adventure.util.Ticks.duration(fadeOutTicks)));
+ getBukkitEntity().showTitle(tile);
+ // Leaf end - Improve Purpur AFK system
+
getBukkitEntity().setPlayerListName(org.purpurmc.purpur.PurpurConfig.afkTabListPrefix + prefix + scoreboardName + suffix + org.purpurmc.purpur.PurpurConfig.afkTabListSuffix, true);
} else {
getBukkitEntity().setPlayerListName(prefix + scoreboardName + suffix, true);
diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index c6b871037f9dea8c6cbe9d0a2acff2cb2a960c09..b3c138e78552ba348d67c37343c6684d37f2e10f 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2371,6 +2371,7 @@ public class ServerGamePacketListenerImpl
@Override
public void handleChatCommand(ServerboundChatCommandPacket packet) {
+ final boolean isAfkCommandCooldown = this.performAfkCooldown(packet.command()); // Leaf - Improve Purpur AFK system
this.tryHandleChat(packet.command(), () -> {
// CraftBukkit start - SPIGOT-7346: Prevent disconnected players from executing commands
if (this.player.hasDisconnected()) {
@@ -2379,7 +2380,7 @@ public class ServerGamePacketListenerImpl
// CraftBukkit end
this.performUnsignedChatCommand(packet.command());
this.detectRateSpam("/" + packet.command()); // Spigot
- }, true); // CraftBukkit - sync commands
+ }, true, isAfkCommandCooldown); // CraftBukkit - sync commands // Leaf - Improve Purpur AFK system
}
private void performUnsignedChatCommand(String command) {
@@ -2412,6 +2413,7 @@ public class ServerGamePacketListenerImpl
public void handleSignedChatCommand(ServerboundChatCommandSignedPacket packet) {
Optional<LastSeenMessages> optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages());
if (!optional.isEmpty()) {
+ final boolean isAfkCommandCooldown = this.performAfkCooldown(packet.command()); // Leaf - Improve Purpur AFK system
this.tryHandleChat(packet.command(), () -> {
// CraftBukkit start - SPIGOT-7346: Prevent disconnected players from executing commands
if (this.player.hasDisconnected()) {
@@ -2420,7 +2422,7 @@ public class ServerGamePacketListenerImpl
// CraftBukkit end
this.performSignedChatCommand(packet, optional.get());
this.detectRateSpam("/" + packet.command()); // Spigot
- }, true); // CraftBukkit - sync commands
+ }, true, isAfkCommandCooldown); // CraftBukkit - sync commands // Leaf - Improve Purpur AFK system
}
}
@@ -2527,12 +2529,17 @@ public class ServerGamePacketListenerImpl
return dispatcher.parse(command, this.player.createCommandSourceStack());
}
- private void tryHandleChat(String message, Runnable handler, boolean sync) { // CraftBukkit
+ // Leaf start - Improve Purpur AFK system
+ private void tryHandleChat(String message, Runnable handler, boolean sync) {
+ tryHandleChat(message, handler, sync, false);
+ }
+ private void tryHandleChat(String message, Runnable handler, boolean sync, boolean afkCommandCooldown) { // CraftBukkit
+ // Leaf end - Improve Purpur AFK system
if (isChatMessageIllegal(message)) {
this.disconnectAsync(Component.translatable("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add proper async disconnect
} else if (this.player.isRemoved() || this.player.getChatVisibility() == ChatVisiblity.HIDDEN) { // CraftBukkit - dead men tell no tales
this.send(new ClientboundSystemChatPacket(Component.translatable("chat.disabled.options").withStyle(ChatFormatting.RED), false));
- } else if (player.didPlayerJoinEvent) { // Gale - EMC - do not process chat/commands before player has joined
+ } else if (player.didPlayerJoinEvent && !afkCommandCooldown) { // Gale - EMC - do not process chat/commands before player has joined // Leaf - Improve Purpur AFK system - don't process afk command if in cooldown
this.player.resetLastActionTime();
// CraftBukkit start
if (sync) {
@@ -2544,6 +2551,40 @@ public class ServerGamePacketListenerImpl
}
}
+ // Leaf start - Improve Purpur AFK system
+ public static final Map<java.util.UUID, Long> afkCooldown = new it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap<>();
+ private boolean performAfkCooldown(String command) {
+ if (!org.dreeam.leaf.config.modules.gameplay.AfkCommand.enabled || !"afk".equals(command)) {
+ return false;
+ }
+
+ this.player.commandAfkStatus = this.player.isAfk();
+ this.player.isCommandAfk = true;
+
+ if (org.purpurmc.purpur.PurpurConfig.afkCommandCooldown <= 0) {
+ return false;
+ }
+
+ java.util.UUID uuid = this.player.getUUID();
+ Long cooldown = afkCooldown.get(uuid);
+ long currentTime = System.nanoTime();
+
+ if (cooldown != null && (currentTime - cooldown) / 1_000_000_000 <= org.purpurmc.purpur.PurpurConfig.afkCommandCooldown) {
+ String msg = org.purpurmc.purpur.PurpurConfig.afkCooldown;
+
+ if (msg != null && !msg.isEmpty()) {
+ net.kyori.adventure.text.Component message = net.kyori.adventure.text.minimessage.MiniMessage.miniMessage().deserialize(msg.replace("%time%", String.valueOf(org.purpurmc.purpur.PurpurConfig.afkCommandCooldown - (currentTime - cooldown) / 1_000_000_000)));
+ this.player.sendMessage(message);
+ }
+
+ return true;
+ } else {
+ afkCooldown.put(uuid, currentTime);
+ return false;
+ }
+ }
+ // Leaf end - Improve Purpur AFK system
+
private Optional<LastSeenMessages> unpackAndApplyLastSeen(LastSeenMessages.Update update) {
synchronized (this.lastSeenMessages) {
Optional var10000;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index e999ce4ed3a1bba81f61085ead2565f2d3e90cfa..9026b45b6ee7f53f3a3872cda1a8c3f96eb5b2a7 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -676,6 +676,7 @@ public abstract class PlayerList {
org.leavesmc.leaves.protocol.core.LeavesProtocolManager.handlePlayerLeave(player); // Leaves - protocol
// Paper end - Fix kick event leave message not being sent
org.purpurmc.purpur.task.BossBarTask.removeFromAll(player.getBukkitEntity()); // Purpur - Implement TPSBar
+ net.minecraft.server.network.ServerGamePacketListenerImpl.afkCooldown.remove(player.getBukkitEntity().getUniqueId()); // Leaf - Improve Purpur AFK system
ServerLevel serverLevel = player.level();
player.awardStat(Stats.LEAVE_GAME);
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
diff --git a/org/purpurmc/purpur/PurpurConfig.java b/org/purpurmc/purpur/PurpurConfig.java
index 31450de492fbfdd83608ae668072bebd525db566..b83b4536ac756b797f6f2d14886372f01e91145c 100644
--- a/org/purpurmc/purpur/PurpurConfig.java
+++ b/org/purpurmc/purpur/PurpurConfig.java
@@ -175,6 +175,11 @@ public class PurpurConfig {
public static String cannotRideMob = "<red>You cannot mount that mob";
public static String afkBroadcastAway = "<yellow><italic>%s is now AFK";
public static String afkBroadcastBack = "<yellow><italic>%s is no longer AFK";
+ // Leaf start - Improve Purpur AFK system
+ public static String afkTitleAway = "<gold><bold>AFK:<red>You are now AFK...:10:70:20";
+ public static int afkCommandCooldown = 0;
+ public static String afkCooldown = "<gray>You need to wait %time%s to use /afk.";
+ // Leaf end - Improve Purpur AFK system
public static boolean afkBroadcastUseDisplayName = false;
public static String afkTabListPrefix = "[AFK] ";
public static String afkTabListSuffix = "";
@@ -194,6 +199,15 @@ public class PurpurConfig {
cannotRideMob = getString("settings.messages.cannot-ride-mob", cannotRideMob);
afkBroadcastAway = getString("settings.messages.afk-broadcast-away", afkBroadcastAway);
afkBroadcastBack = getString("settings.messages.afk-broadcast-back", afkBroadcastBack);
+ // Leaf start - Improve Purpur AFK system
+ afkTitleAway = getString("settings.messages.afk-title-away", afkTitleAway);
+ if (afkTitleAway.split(":").length != 5) {
+ Bukkit.getLogger().log(Level.SEVERE, "You put wrong format of afk-title-away in PurpurConfig, it should look like <gold><bold>AFK:<red>You are now AFK...:10:70:20");
+ Bukkit.getLogger().log(Level.SEVERE, "'Title:Sub Title:Title Fade In Ticks:Title Stay Ticks:Title Fade Out Ticks', split with :");
+ }
+ afkCommandCooldown = getInt("settings.messages.afk-command-cooldown", afkCommandCooldown);
+ afkCooldown = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-command-cooldown-msg", afkCooldown)));
+ // Leaf end - Improve Purpur AFK system
afkBroadcastUseDisplayName = getBoolean("settings.messages.afk-broadcast-use-display-name", afkBroadcastUseDisplayName);
afkTabListPrefix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-prefix", afkTabListPrefix)));
afkTabListSuffix = MiniMessage.miniMessage().serialize(MiniMessage.miniMessage().deserialize(getString("settings.messages.afk-tab-list-suffix", afkTabListSuffix)));