From 844b876bda3046f794ca2b1172657e6f73e3f3f3 Mon Sep 17 00:00:00 2001 From: iceBear67 Date: Sun, 14 Jul 2024 11:12:26 +0800 Subject: [PATCH] add: broadcast when player is afk --- .../io/ib67/sfcraft/SFCraftInitializer.java | 7 ++--- .../io/ib67/sfcraft/callback/SFCallbacks.java | 7 +++++ .../mixin/server/PlayerEntityMixin.java | 11 ++++++++ .../server/ServerPlayNetworkHandlerMixin.java | 9 ++++++ .../server/bridge/ServerPlayerBridge.java | 11 ++++++++ .../io/ib67/sfcraft/module/AFKModule.java | 28 +++++++++++++++++++ src/main/resources/sfcraft.mixins.json | 3 +- 7 files changed, 70 insertions(+), 6 deletions(-) create mode 100644 src/main/java/io/ib67/sfcraft/mixin/server/bridge/ServerPlayerBridge.java create mode 100644 src/main/java/io/ib67/sfcraft/module/AFKModule.java diff --git a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java index 59b6069..6d7573b 100644 --- a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java +++ b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java @@ -3,6 +3,7 @@ package io.ib67.sfcraft; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.inject.*; +import io.ib67.sfcraft.module.*; import io.ib67.sfcraft.module.chat.ChatPingModule; import io.ib67.sfcraft.module.chat.ChatSendLocModule; import io.ib67.sfcraft.module.randomevt.LongNightModule; @@ -12,10 +13,6 @@ import io.ib67.sfcraft.init.GuiceModInitializer; import io.ib67.sfcraft.geoip.GeoIPService; import io.ib67.sfcraft.geoip.MaxMindGeoIPService; import io.ib67.sfcraft.inject.MinecraftServerSupplier; -import io.ib67.sfcraft.module.MotdModule; -import io.ib67.sfcraft.module.OfflineExemptModule; -import io.ib67.sfcraft.module.PlayLimitModule; -import io.ib67.sfcraft.module.WelcomeModule; import io.ib67.sfcraft.registry.event.RandomEventRegistry; import io.ib67.sfcraft.module.command.BackModule; import io.ib67.sfcraft.module.command.ManagementModule; @@ -46,7 +43,7 @@ public class SFCraftInitializer extends GuiceModInitializer { registerFeature(PlayLimitModule.class); registerFeature(BackModule.class); registerFeature(ManagementModule.class); - + registerFeature(AFKModule.class); registerFeature(ChatPingModule.class); registerFeature(ChatSendLocModule.class); registerFeature(LongNightModule.class); diff --git a/src/main/java/io/ib67/sfcraft/callback/SFCallbacks.java b/src/main/java/io/ib67/sfcraft/callback/SFCallbacks.java index e82989e..5b3bdf7 100644 --- a/src/main/java/io/ib67/sfcraft/callback/SFCallbacks.java +++ b/src/main/java/io/ib67/sfcraft/callback/SFCallbacks.java @@ -8,6 +8,7 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.ClientConnection; import net.minecraft.server.MinecraftServer; import net.minecraft.server.ServerMetadata; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.Unit; import net.minecraft.util.math.BlockPos; @@ -28,6 +29,12 @@ public interface SFCallbacks { l -> (pl, damageSource) -> forEach(l, i -> i.onPlayerDeath(pl, damageSource))); Event MOTD = EventFactory.createArrayBacked(ServerMotdCallback.class, l -> (s, c) -> first(l, t -> t.onMotd(s, c))); + Event PLAYER_IDLE = EventFactory.createArrayBacked(PlayerIdlingCallback.class, + l -> (p, a) -> forEach(l, i -> i.onSwitchIdle(p, a))); + + interface PlayerIdlingCallback { + void onSwitchIdle(ServerPlayerEntity player, boolean afk); + } interface ServerMotdCallback { ServerMetadata onMotd(MinecraftServer server, ClientConnection connection); diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/PlayerEntityMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/PlayerEntityMixin.java index 5d71f64..adec5bb 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/PlayerEntityMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/PlayerEntityMixin.java @@ -8,6 +8,7 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Unit; import net.minecraft.util.math.BlockPos; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -15,6 +16,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(ServerPlayerEntity.class) public class PlayerEntityMixin { + @Shadow + private long lastActionTime; + @Inject(method = "onDeath", at = @At("TAIL")) public void onDeath(DamageSource damageSource, CallbackInfo ci) { SFCallbacks.PLAYER_DEATH.invoker().onPlayerDeath((ServerPlayerEntity) (Object) this, damageSource); @@ -27,4 +31,11 @@ public class PlayerEntityMixin { cir.setReturnValue(result); } } + + @Inject(method = "updateLastActionTime", at = @At("HEAD")) + public void leaveAFK(CallbackInfo ci) { + if (lastActionTime == Long.MAX_VALUE) { + SFCallbacks.PLAYER_IDLE.invoker().onSwitchIdle((ServerPlayerEntity) (Object) this, false); + } + } } diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java index 3bcad07..f792eb0 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/ServerPlayNetworkHandlerMixin.java @@ -1,10 +1,13 @@ package io.ib67.sfcraft.mixin.server; import io.ib67.sfcraft.SFCraft; +import io.ib67.sfcraft.callback.SFCallbacks; +import io.ib67.sfcraft.mixin.server.bridge.ServerPlayerBridge; import io.ib67.sfcraft.registry.chat.SimpleMessageDecorator; import net.minecraft.network.message.MessageDecorator; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.text.Text; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.*; @@ -18,4 +21,10 @@ public abstract class ServerPlayNetworkHandlerMixin { public MessageDecorator getMessageDecorator(MinecraftServer instance) { return SFCraft.getInjector().getInstance(SimpleMessageDecorator.class); } + + @Redirect(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/network/ServerPlayNetworkHandler;disconnect(Lnet/minecraft/text/Text;)V", ordinal = 2)) + public void onPlayerIdling(ServerPlayNetworkHandler instance, Text text) { + ((ServerPlayerBridge) instance.player).setLastActionTime(Long.MAX_VALUE); + SFCallbacks.PLAYER_IDLE.invoker().onSwitchIdle(instance.player,true); + } } diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/bridge/ServerPlayerBridge.java b/src/main/java/io/ib67/sfcraft/mixin/server/bridge/ServerPlayerBridge.java new file mode 100644 index 0000000..a8560f8 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/mixin/server/bridge/ServerPlayerBridge.java @@ -0,0 +1,11 @@ +package io.ib67.sfcraft.mixin.server.bridge; + +import net.minecraft.server.network.ServerPlayerEntity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(ServerPlayerEntity.class) +public interface ServerPlayerBridge { + @Accessor + void setLastActionTime(long time); +} diff --git a/src/main/java/io/ib67/sfcraft/module/AFKModule.java b/src/main/java/io/ib67/sfcraft/module/AFKModule.java new file mode 100644 index 0000000..958b510 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/module/AFKModule.java @@ -0,0 +1,28 @@ +package io.ib67.sfcraft.module; + +import io.ib67.sfcraft.ServerModule; +import io.ib67.sfcraft.callback.SFCallbacks; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Text; +import net.minecraft.util.Colors; + +public class AFKModule extends ServerModule { + @Override + public void onInitialize() { + SFCallbacks.PLAYER_IDLE.register(this::onAFK); + } + + private void onAFK(ServerPlayerEntity player, boolean afk) { + if(afk){ + player.server.getPlayerManager().broadcast( + Text.literal(" * " + player.getName().getLiteralString() + " 正在挂机.").withColor(Colors.LIGHT_GRAY), + false + ); + }else{ + player.server.getPlayerManager().broadcast( + Text.literal(" * " + player.getName().getLiteralString() + " 回来了.").withColor(Colors.LIGHT_GRAY), + false + ); + } + } +} diff --git a/src/main/resources/sfcraft.mixins.json b/src/main/resources/sfcraft.mixins.json index ba72c76..5f3939b 100644 --- a/src/main/resources/sfcraft.mixins.json +++ b/src/main/resources/sfcraft.mixins.json @@ -8,9 +8,10 @@ "client": [ ], "server": [ + "server.bridge.ServerWorldBridge", + "server.bridge.ServerPlayerBridge", "server.MinecraftServerMixin", "server.ServerPlayNetworkHandlerMixin", - "server.bridge.ServerWorldBridge", "server.SleepManagerMixin", "server.ServerWorldMixin", "server.AbstractFurnaceBlockMixin",