feat: add spectator tab highlight and command loggin

This commit is contained in:
2026-10-04 11:04:17 +02:00
parent 3c72b6e5ea
commit 9324965322
6 changed files with 88 additions and 10 deletions
+1 -1
View File
@@ -48,7 +48,7 @@ public class ChatLogger {
); );
} }
private static String formatPos(ServerPlayer player) { static String formatPos(ServerPlayer player) {
ServerLevel level = player.level(); ServerLevel level = player.level();
// У ResourceKey дістаємо Identifier/ResourceLocation через .identifier(), // У ResourceKey дістаємо Identifier/ResourceLocation через .identifier(),
@@ -0,0 +1,21 @@
package org.examp.john;
import net.minecraft.server.level.ServerPlayer;
/**
* Логує команди, які виконують гравці, в консоль сервера.
* Формат: хто виконав ➔ яка команда ➔ координати гравця.
*/
public class CommandLogger {
public static void logCommand(ServerPlayer player, String command) {
String normalized = command.startsWith("/") ? command : "/" + command;
MSNexus.magicModLog.info(
"[CMD] {} ran: \"{}\" | pos: {}",
player.getName().getString(),
normalized,
ChatLogger.formatPos(player)
);
}
}
@@ -0,0 +1,38 @@
package org.examp.john.mixin;
import com.mojang.brigadier.ParseResults;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.Commands;
import net.minecraft.server.level.ServerPlayer;
import org.examp.john.CommandLogger;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* Логує виконання команд гравцями в консоль сервера.
* Хукає Commands.performCommand — спільну точку виконання всіх команд.
*/
@Mixin(Commands.class)
public class CommandLogMixin {
@Inject(
method = "performCommand(Lcom/mojang/brigadier/ParseResults;Ljava/lang/String;)V",
at = @At("HEAD")
)
private void msnexus$logExecutedCommand(ParseResults<CommandSourceStack> parseResults, String command, CallbackInfo ci) {
try {
CommandSourceStack source = parseResults.getContext().getSource();
if (source == null) {
return;
}
ServerPlayer player = source.getPlayer();
if (player != null) {
CommandLogger.logCommand(player, command);
}
} catch (Exception e) {
org.examp.john.MSNexus.magicModLog.warn("[CMD] Не вдалося залогувати команду: {}", e.getMessage());
}
}
}
@@ -0,0 +1,24 @@
package org.examp.john.mixin;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.GameType;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(ClientboundPlayerInfoUpdatePacket.Entry.class)
public class SpectatorTabMixin {
@Redirect(
method = "<init>(Lnet/minecraft/server/level/ServerPlayer;)V",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/server/level/ServerPlayer;gameMode()Lnet/minecraft/world/level/GameType;"
)
)
private static GameType msnexus$highlightSpectatorsInTab(ServerPlayer player) {
GameType gameMode = player.gameMode();
return gameMode == GameType.SPECTATOR ? GameType.SURVIVAL : gameMode;
}
}
+2 -9
View File
@@ -7,24 +7,17 @@
"authors": [], "authors": [],
"contact": {}, "contact": {},
"license": "All-Rights-Reserved", "license": "All-Rights-Reserved",
"environment": "*", "environment": "server",
"entrypoints": { "entrypoints": {
"fabric-datagen": [ "fabric-datagen": [
"org.examp.john.client.MSNexusDataGenerator" "org.examp.john.client.MSNexusDataGenerator"
], ],
"client": [
"org.examp.john.client.MSNexusClient"
],
"main": [ "main": [
"org.examp.john.MSNexus" "org.examp.john.MSNexus"
] ]
}, },
"mixins": [ "mixins": [
"msnexus.mixins.json", "msnexus.mixins.json"
{
"config": "msnexus.client.mixins.json",
"environment": "client"
}
], ],
"depends": { "depends": {
"fabricloader": ">=${loader_version}", "fabricloader": ">=${loader_version}",
+2
View File
@@ -4,6 +4,8 @@
"package": "org.examp.john.mixin", "package": "org.examp.john.mixin",
"compatibilityLevel": "JAVA_25", "compatibilityLevel": "JAVA_25",
"mixins": [ "mixins": [
"CommandLogMixin",
"SpectatorTabMixin"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1