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.Text; 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.config.ConfigManager; import wtf.hak.survivalfabric.utils.MathUtils; import java.util.Set; @Mixin(PlayerManager.class) public abstract class PlayerManagerMixin { /** * Send join message to joined player */ @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) { if (ConfigManager.getConfig().joinMessageEnabled && !player.getServer().isSingleplayer()) { Text text = Text.literal(String.format(ConfigManager.getConfig().joinMessage, player.getName().getString())); player.sendMessage(text, false); } } /** * Modify join message broadcasted to server */ @ModifyArg(method = {"onPlayerConnect"}, at = @At(value = "INVOKE", target = "Lnet/minecraft/server/PlayerManager;broadcast(Lnet/minecraft/text/Text;Z)V")) private Text onPlayerConnect(Text text) { if (ConfigManager.getConfig().joinMessageEnabled) { String name = text.getString().split(" ")[0]; return Text.literal(String.format(ConfigManager.getConfig().joinMessage, name)); } else return text; } /** * Get player out of specator mode if necessary */ @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); } } /** * Modify chat messages */ @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) { String rawMessage = message.getContent().getString().trim(); boolean isCalcEnabled = ConfigManager.getConfig().chatCalcEnabled; boolean isMsgEnabled = ConfigManager.getConfig().chatMessageEnabled; String processedMessage = rawMessage; if (isCalcEnabled && MathUtils.hasSupportedOperator(rawMessage)) { String expression = rawMessage.endsWith("=") ? rawMessage.substring(0, rawMessage.length() - 1).trim() : rawMessage; try { String result = String.valueOf(MathUtils.evaluateExpression(expression)); StringBuilder sb = new StringBuilder(rawMessage).append("ยง6"); if (rawMessage.contains(" ")) sb.append(" "); if (!rawMessage.endsWith("=")) sb.append("="); if (rawMessage.contains(" ")) sb.append(" "); sb.append(result.endsWith(".0") ? result.substring(0, result.length() - 2) : result); processedMessage = sb.toString(); } catch (Exception ignored) {} } if (isMsgEnabled) { String formatted = String.format(ConfigManager.getConfig().chatMessage, sender.getName().getString(), processedMessage); sender.getServer().getPlayerManager().broadcast(Text.literal(formatted), false); } else if (isCalcEnabled) { String formatted = "<" + sender.getName().getString() + "> " + processedMessage; sender.getServer().getPlayerManager().broadcast(Text.literal(formatted), false); } ci.cancel(); } } }