From 3096e7c838b1938e68aeb5b2194f5eb6571740aa Mon Sep 17 00:00:00 2001 From: iceBear67 Date: Sat, 18 Jul 2026 14:13:17 +0800 Subject: [PATCH] sevveral fixes and improvements added: inline command: showoff `.item` clicking coordinates open a url to visit that area in web map added sound for player join/leave/death to annoy everyone increased the search radius of /back command. (200 from 100) fix: inline ping is not case-insensitive time does not pass faster when everybody is sleeping code cleanup --- .../io/ib67/sfcraft/SFCraftInitializer.java | 3 + .../mixin/server/ServerWorldMixin.java | 8 ++- .../module/ElytraSpeedMeterModule.java | 2 - .../io/ib67/sfcraft/module/SoundModule.java | 66 +++++++++++++++++++ .../module/chat/decorator/ChatPingModule.java | 7 +- .../chat/decorator/ChatSendLocModule.java | 9 ++- .../chat/decorator/ChatShowoffModule.java | 34 ++++++++++ .../sfcraft/module/command/BackModule.java | 2 +- src/main/resources/sfcraft.mixins.json | 2 +- 9 files changed, 123 insertions(+), 10 deletions(-) create mode 100644 src/main/java/io/ib67/sfcraft/module/SoundModule.java create mode 100644 src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatShowoffModule.java diff --git a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java index f95ba58..5b2aca3 100644 --- a/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java +++ b/src/main/java/io/ib67/sfcraft/SFCraftInitializer.java @@ -7,6 +7,7 @@ import io.ib67.sfcraft.module.*; import io.ib67.sfcraft.module.chat.ChatPrefixModule; import io.ib67.sfcraft.module.chat.decorator.ChatPingModule; import io.ib67.sfcraft.module.chat.decorator.ChatSendLocModule; +import io.ib67.sfcraft.module.chat.decorator.ChatShowoffModule; import io.ib67.sfcraft.module.compat.ModCompatModule; import io.ib67.sfcraft.module.room.CreativeRoomModule; import io.ib67.sfcraft.module.supervisor.WebModule; @@ -61,6 +62,8 @@ public class SFCraftInitializer extends GuiceModInitializer { registerFeature(RoomModule.class); registerFeature(CreativeRoomModule.class); registerFeature(ChatPrefixModule.class); + registerFeature(SoundModule.class); + registerFeature(ChatShowoffModule.class); registerWebModules(); } diff --git a/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java b/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java index a17fe9e..165bc9d 100644 --- a/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java +++ b/src/main/java/io/ib67/sfcraft/mixin/server/ServerWorldMixin.java @@ -9,10 +9,16 @@ import org.spongepowered.asm.mixin.injection.*; @Mixin(ServerLevel.class) public abstract class ServerWorldMixin { + @ModifyArg(method = "tickTime", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/storage/ServerLevelData;setGameTime(J)V")) public long setTimeOfDay(long timeOfDay) { - int i = ((ServerLevel) (Object) this).getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE); + var _this = ((ServerLevel) (Object) this); + int i = _this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE); if (((ServerWorldBridge) this).getSleepStatus().areEnoughSleeping(i)) { + var dt = _this.dimensionTypeRegistration(); + var clock = dt.value().defaultClock(); + if(clock.isEmpty()) return timeOfDay; + _this.clockManager().addTicks(clock.get(), 10); MixinHelper.spedUp = true; return timeOfDay + 10; } diff --git a/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java b/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java index 22e3ef7..0a380b7 100644 --- a/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java +++ b/src/main/java/io/ib67/sfcraft/module/ElytraSpeedMeterModule.java @@ -15,8 +15,6 @@ import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.player.Player; public class ElytraSpeedMeterModule extends ServerModule { - private static final int BAR_LEN = 20; - private static final int MAX_NORMAL_SPEED = 6; private static final int THRESHLD_OF_ELYTRA_FLY = 8; private static final Component[] ELYTRA_DURABILITY = new Component[100]; private final Object2ObjectMap playerFlyMap = new Object2ObjectOpenHashMap<>(); diff --git a/src/main/java/io/ib67/sfcraft/module/SoundModule.java b/src/main/java/io/ib67/sfcraft/module/SoundModule.java new file mode 100644 index 0000000..f4a35a4 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/module/SoundModule.java @@ -0,0 +1,66 @@ +package io.ib67.sfcraft.module; + +import com.google.common.collect.Lists; +import io.ib67.kiwi.RandomHelper; +import io.ib67.sfcraft.ServerModule; +import io.ib67.sfcraft.callback.SFCallbacks; +import io.ib67.sfcraft.inject.MinecraftServerSupplier; +import jakarta.inject.Inject; +import net.fabricmc.fabric.api.networking.v1.PacketSender; +import net.fabricmc.fabric.api.networking.v1.PlayerLookup; +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.ServerGamePacketListenerImpl; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.animal.chicken.ChickenSoundVariants; +import net.minecraft.world.entity.player.Player; + +import java.util.Arrays; +import java.util.List; + +public class SoundModule extends ServerModule { + public static final List DEATH_SOUNDS = Lists.newArrayList( + SoundEvents.BEE_DEATH, + SoundEvents.PLAYER_DEATH + ); + + protected SoundEvent join = SoundEvents.UI_TOAST_IN; + protected SoundEvent leave = SoundEvents.UI_TOAST_OUT; + + protected final MinecraftServerSupplier serverSupplier; + + @Inject + public SoundModule(MinecraftServerSupplier serverSupplier) { + this.serverSupplier = serverSupplier; + } + + @Override + public void onInitialize() { + SFCallbacks.PLAYER_DEATH.register(this::playDeathSound); + ServerPlayConnectionEvents.JOIN.register(this::playJoinSound); + ServerPlayConnectionEvents.DISCONNECT.register(this::playLeaveSound); + } + + @Override + public void onEnable() { + var sounds = SoundEvents.CHICKEN_SOUNDS.get(ChickenSoundVariants.SoundSet.CLASSIC).adultSounds(); + DEATH_SOUNDS.add(sounds.hurtSound().value()); + join = SoundEvents.NOTE_BLOCK_HAT.value(); + join = SoundEvents.NOTE_BLOCK_BASS.value(); + } + + private void playLeaveSound(ServerGamePacketListenerImpl serverGamePacketListener, MinecraftServer minecraftServer) { + PlayerLookup.all(serverSupplier.get()).forEach(it -> it.playSound(leave)); + } + + private void playJoinSound(ServerGamePacketListenerImpl serverGamePacketListener, PacketSender packetSender, MinecraftServer minecraftServer) { + PlayerLookup.all(serverSupplier.get()).forEach(it -> it.playSound(join)); + } + + private void playDeathSound(Player player, DamageSource damageSource) { + var rand = RandomHelper.number(0, DEATH_SOUNDS.size() - 1); + PlayerLookup.all(serverSupplier.get()).forEach(it -> it.playSound(DEATH_SOUNDS.get(rand))); + } +} diff --git a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java index 6e36df0..afdded6 100644 --- a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java +++ b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatPingModule.java @@ -20,9 +20,10 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.util.CommonColors; import net.minecraft.world.entity.player.Player; +import org.jspecify.annotations.NonNull; public class ChatPingModule extends ServerModule implements ChatDecorator { - private static final Pattern PING = Pattern.compile("(@[\\w]+)?"); //todo remove the need of prefix + private static final Pattern PING = Pattern.compile("(@[\\w]+)?"); @Inject MinecraftServerSupplier serverSupplier; @Inject @@ -34,7 +35,7 @@ public class ChatPingModule extends ServerModule implements ChatDecorator { } @Override - public Component decorate(@Nullable ServerPlayer sender, Component message) { + public @NonNull Component decorate(@Nullable ServerPlayer sender, @NonNull Component message) { if (!isEnabled()) { return message; } @@ -69,7 +70,7 @@ public class ChatPingModule extends ServerModule implements ChatDecorator { for (int i = 0; i < match.groupCount(); i++) { var r = match.group(); if (r.isEmpty()) continue; - final var d = r.substring(1); + final var d = r.substring(1).toLowerCase(); return playerNames.stream() .filter(it -> it.toLowerCase().startsWith(d)) .peek(it -> foundPlayers.add(serverSupplier.get().getPlayerList().getPlayerByName(it))) diff --git a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java index 93dc0d0..e47f06b 100644 --- a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java +++ b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatSendLocModule.java @@ -14,6 +14,9 @@ import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.level.Level; import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.NonNull; + +import java.net.URI; public class ChatSendLocModule extends ServerModule implements ChatDecorator { @Inject @@ -25,7 +28,7 @@ public class ChatSendLocModule extends ServerModule implements ChatDecorator { } @Override - public Component decorate(@Nullable ServerPlayer sender, Component message) { + public @NonNull Component decorate(@Nullable ServerPlayer sender, @NonNull Component message) { if (!isEnabled()) return message; if (sender != null) { if (!SFConsts.USE_BROADCAST_LOCATION.hasPermission(sender)) { @@ -46,7 +49,9 @@ public class ChatSendLocModule extends ServerModule implements ChatDecorator { return Component .literal(" " + x + ", " + y + ", " + z + world + " ") .withColor(Helper.fromRgb(63, 254, 254)) - .withStyle(style -> style.withClickEvent(new ClickEvent.RunCommand("/gps " + key + " " + x + " " + y + " " + z))); + .withStyle(style -> style.withClickEvent(new ClickEvent.OpenUrl(URI.create( + "https://mc.sfclub.cc/map/?world=" + key.identifier().toString().replace(':', '_') + "&zoom=5&x=" + x + "&z=" + z + )))); } private static String translate(ResourceKey registryKey) { diff --git a/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatShowoffModule.java b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatShowoffModule.java new file mode 100644 index 0000000..33b5af9 --- /dev/null +++ b/src/main/java/io/ib67/sfcraft/module/chat/decorator/ChatShowoffModule.java @@ -0,0 +1,34 @@ +package io.ib67.sfcraft.module.chat.decorator; + +import com.google.inject.Inject; +import io.ib67.sfcraft.ServerModule; +import io.ib67.sfcraft.registry.chat.SimpleMessageDecorator; +import net.minecraft.network.chat.ChatDecorator; +import net.minecraft.network.chat.Component; +import net.minecraft.server.level.ServerPlayer; +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public class ChatShowoffModule extends ServerModule implements ChatDecorator { + @Inject + SimpleMessageDecorator messageDecorator; + + @Override + public void onInitialize() { + messageDecorator.registerDecorator(this); + } + + @Override + public @NonNull Component decorate(@Nullable ServerPlayer player, Component message) { + if (!isEnabled()) { + return message; + } + + return ReplaceHelper.replace(player, message, ".item", this::generateShowoffText); + } + + private Component generateShowoffText(ServerPlayer serverPlayer) { + var item = serverPlayer.getMainHandItem(); + return item.getDisplayName(); + } +} diff --git a/src/main/java/io/ib67/sfcraft/module/command/BackModule.java b/src/main/java/io/ib67/sfcraft/module/command/BackModule.java index f0b81a9..faef498 100644 --- a/src/main/java/io/ib67/sfcraft/module/command/BackModule.java +++ b/src/main/java/io/ib67/sfcraft/module/command/BackModule.java @@ -39,7 +39,7 @@ public class BackModule extends ServerModule { var wld = player.level().getServer().getLevel(pos.dimension()); var _pos = pos.pos(); if (wld == null) return 0; - var nearby = wld.getNearestPlayer(_pos.getX(), _pos.getY(), _pos.getZ(), 100, true); + var nearby = wld.getNearestPlayer(_pos.getX(), _pos.getY(), _pos.getZ(), 200, true); if (nearby != null) { _pos = nearby.blockPosition(); Helper.teleportSafely(player, wld, _pos.getX(), _pos.getY(), _pos.getZ(),0,0); diff --git a/src/main/resources/sfcraft.mixins.json b/src/main/resources/sfcraft.mixins.json index 6964728..d6741b6 100644 --- a/src/main/resources/sfcraft.mixins.json +++ b/src/main/resources/sfcraft.mixins.json @@ -4,6 +4,7 @@ "package": "io.ib67.sfcraft.mixin", "compatibilityLevel": "JAVA_21", "mixins": [ + "server.ServerWorldMixin" ], "client": [ ], @@ -25,7 +26,6 @@ "server.ServerLoginNetworkHandlerMixin", "server.ServerPlayerEntityMixin", "server.ServerPlayNetworkHandlerMixin", - "server.ServerWorldMixin", "server.SleepManagerMixin", "server.subserver.PlayerListS2CPacket$EntryMixin", "server.subserver.PlayerManagerMixin",