From 8ac3484c5416bc198d9efcefeedec9153e728b77 Mon Sep 17 00:00:00 2001 From: Hedzer Kuijlman Date: Tue, 18 Mar 2025 14:23:02 +0100 Subject: [PATCH] Restored original mod --- .../hak/survivalfabric/SurvivalFabric.java | 11 +-- .../commands/SpectatorCommand.java | 77 +++++++++++++++++++ .../survivalfabric/mixin/ExampleMixin.java | 15 ---- .../mixin/PlayerManagerMixin.java | 55 +++++++++++++ .../mixin/ServerPlayNetworkHandlerMixin.java | 18 +++++ .../hak/survivalfabric/utils/Messages.java | 9 +++ src/main/resources/survivalfabric.mixins.json | 3 +- 7 files changed, 164 insertions(+), 24 deletions(-) create mode 100644 src/main/java/wtf/hak/survivalfabric/commands/SpectatorCommand.java delete mode 100644 src/main/java/wtf/hak/survivalfabric/mixin/ExampleMixin.java create mode 100644 src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java create mode 100644 src/main/java/wtf/hak/survivalfabric/mixin/ServerPlayNetworkHandlerMixin.java create mode 100644 src/main/java/wtf/hak/survivalfabric/utils/Messages.java diff --git a/src/main/java/wtf/hak/survivalfabric/SurvivalFabric.java b/src/main/java/wtf/hak/survivalfabric/SurvivalFabric.java index a804680..5fa917b 100644 --- a/src/main/java/wtf/hak/survivalfabric/SurvivalFabric.java +++ b/src/main/java/wtf/hak/survivalfabric/SurvivalFabric.java @@ -2,23 +2,18 @@ package wtf.hak.survivalfabric; import net.fabricmc.api.ModInitializer; +import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import wtf.hak.survivalfabric.commands.SpectatorCommand; public class SurvivalFabric implements ModInitializer { public static final String MOD_ID = "survivalfabric"; - // This logger is used to write text to the console and the log file. - // It is considered best practice to use your mod id as the logger's name. - // That way, it's clear which mod wrote info, warnings, and errors. public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); @Override public void onInitialize() { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. - - LOGGER.info("Hello Fabric world!"); + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> SpectatorCommand.register(dispatcher, new String[] { "spectator", "s", "S", "camera", "c", "C", })); } } \ No newline at end of file diff --git a/src/main/java/wtf/hak/survivalfabric/commands/SpectatorCommand.java b/src/main/java/wtf/hak/survivalfabric/commands/SpectatorCommand.java new file mode 100644 index 0000000..85d45b7 --- /dev/null +++ b/src/main/java/wtf/hak/survivalfabric/commands/SpectatorCommand.java @@ -0,0 +1,77 @@ +package wtf.hak.survivalfabric.commands; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.context.CommandContext; +import net.minecraft.server.command.CommandManager; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.text.Text; +import net.minecraft.world.GameMode; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class SpectatorCommand { + + public static final Map spectating = new HashMap<>(); + + public static void register(CommandDispatcher dispatcher, String... aliases) { + for (String str : aliases) + dispatcher.register(CommandManager.literal(str) // Ensure correct method name + .executes(SpectatorCommand::execute)); + } + + private static int execute(CommandContext context) { + ServerCommandSource source = context.getSource(); + if (source.getEntity() == null) { // Ensure correct method name + source.sendMessage(Text.literal("Console cannot go into spectator mode!")); + return 0; + } + ServerPlayerEntity player = (ServerPlayerEntity) source.getEntity(); // Ensure correct method name + if (spectating.containsKey(player)) { + LocationData data = spectating.get(player); + player.teleport(data.world, data.x, data.y, data.z, Set.of(), data.yaw, data.pitch, false); + player.changeGameMode(GameMode.SURVIVAL); + spectating.remove(player); + } else { + + spectating.put(player, new LocationData(player + .getX(), player + .getY(), player + .getZ(), player + .getYaw(), player + .getPitch(), player + .getServerWorld())); + player.changeGameMode(GameMode.SPECTATOR); + } + return 1; + } + + + public static class LocationData { + + public final double x; + + public final double y; + + public final double z; + + public final float yaw; + + public final float pitch; + + public final ServerWorld world; + + LocationData(double x, double y, double z, float yaw, float pitch, ServerWorld world) { + this.x = x; + this.y = y; + this.z = z; + this.yaw = yaw; + this.pitch = pitch; + this.world = world; + } + } + +} diff --git a/src/main/java/wtf/hak/survivalfabric/mixin/ExampleMixin.java b/src/main/java/wtf/hak/survivalfabric/mixin/ExampleMixin.java deleted file mode 100644 index 69248f7..0000000 --- a/src/main/java/wtf/hak/survivalfabric/mixin/ExampleMixin.java +++ /dev/null @@ -1,15 +0,0 @@ -package wtf.hak.survivalfabric.mixin; - -import net.minecraft.server.MinecraftServer; -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; - -@Mixin(MinecraftServer.class) -public class ExampleMixin { - @Inject(at = @At("HEAD"), method = "loadWorld") - private void init(CallbackInfo info) { - // This code is injected into the start of MinecraftServer.loadWorld()V - } -} \ No newline at end of file diff --git a/src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java b/src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java new file mode 100644 index 0000000..c454e62 --- /dev/null +++ b/src/main/java/wtf/hak/survivalfabric/mixin/PlayerManagerMixin.java @@ -0,0 +1,55 @@ +package wtf.hak.survivalfabric.mixin; + +import net.minecraft.network.ClientConnection; +import net.minecraft.network.message.MessageType; +import net.minecraft.network.message.SignedMessage; +import net.minecraft.server.PlayerManager; +import net.minecraft.server.network.ConnectedClientData; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.text.TextContent; +import net.minecraft.world.GameMode; +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.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import wtf.hak.survivalfabric.commands.SpectatorCommand; +import wtf.hak.survivalfabric.utils.Messages; + +import java.util.Set; + +@Mixin(PlayerManager.class) +public abstract class PlayerManagerMixin { + + @Inject(method = {"onPlayerConnect"}, at = {@At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V")}) + public void onPlayerConnect(ClientConnection connection, ServerPlayerEntity player, ConnectedClientData clientData, CallbackInfo ci) { + Text text = Text.literal(String.format(Messages.JOIN_MESSAGE, player.getName().getString())); + player.sendMessage(text, false); + } + + @ModifyArg(method = {"onPlayerConnect"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V")) + private Text onPlayerConnect(Text text) { + String name = text.getString().split(" ")[0]; + return Text.literal(String.format(Messages.JOIN_MESSAGE, name)); + } + + @Inject(method = {"remove"}, at = {@At("HEAD")}) + public void onPlayerLeave(ServerPlayerEntity player, CallbackInfo ci) { + if(SpectatorCommand.spectating.containsKey(player)) { + SpectatorCommand.LocationData loc = SpectatorCommand.spectating.remove(player); + player.teleport(loc.world, loc.x,loc.y,loc.z, Set.of(), loc.yaw, loc.pitch, false); + player.changeGameMode(GameMode.SURVIVAL); + } + } + + @Inject(method = {"broadcast(Lnet/minecraft/network/message/SignedMessage;Lnet/minecraft/server/network/ServerPlayerEntity;Lnet/minecraft/network/message/MessageType$Parameters;)V"}, at = {@At("HEAD")}, cancellable = true) + private void onBroadcast(SignedMessage message, ServerPlayerEntity sender, MessageType.Parameters parameters, CallbackInfo ci) { + if(sender != null) { + Text text = Text.literal(String.format(Messages.CHAT_FORMAT, sender.getName().getString(), message.getContent().getString())); + sender.getServer().getPlayerManager().broadcast(text, false); + ci.cancel(); + } + } +} diff --git a/src/main/java/wtf/hak/survivalfabric/mixin/ServerPlayNetworkHandlerMixin.java b/src/main/java/wtf/hak/survivalfabric/mixin/ServerPlayNetworkHandlerMixin.java new file mode 100644 index 0000000..2c97b99 --- /dev/null +++ b/src/main/java/wtf/hak/survivalfabric/mixin/ServerPlayNetworkHandlerMixin.java @@ -0,0 +1,18 @@ +package wtf.hak.survivalfabric.mixin; + +import net.minecraft.server.network.ServerPlayNetworkHandler; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import wtf.hak.survivalfabric.utils.Messages; + +@Mixin(ServerPlayNetworkHandler.class) +public abstract class ServerPlayNetworkHandlerMixin { + + @ModifyArg(method = {"cleanUp"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V")) + private Text quitMessage(Text text) { + String name = text.getString().split(" ")[0]; + return Text.literal(String.format(Messages.QUIT_MESSAGE, name)); + } +} diff --git a/src/main/java/wtf/hak/survivalfabric/utils/Messages.java b/src/main/java/wtf/hak/survivalfabric/utils/Messages.java new file mode 100644 index 0000000..80f26f8 --- /dev/null +++ b/src/main/java/wtf/hak/survivalfabric/utils/Messages.java @@ -0,0 +1,9 @@ +package wtf.hak.survivalfabric.utils; + +public class Messages { + public static final String JOIN_MESSAGE = "§8[§a+§8] §7%s"; + + public static final String QUIT_MESSAGE = "§8[§c-§8] §7%s"; + + public static final String CHAT_FORMAT = "§7%s§8:§f %s"; +} \ No newline at end of file diff --git a/src/main/resources/survivalfabric.mixins.json b/src/main/resources/survivalfabric.mixins.json index 3a8747e..57d04b9 100644 --- a/src/main/resources/survivalfabric.mixins.json +++ b/src/main/resources/survivalfabric.mixins.json @@ -3,7 +3,8 @@ "package": "wtf.hak.survivalfabric.mixin", "compatibilityLevel": "JAVA_21", "mixins": [ - "ExampleMixin" + "PlayerManagerMixin", + "ServerPlayNetworkHandlerMixin" ], "injectors": { "defaultRequire": 1