This commit is contained in:
Xujiayao 2026-03-22 16:51:41 +08:00
parent 968cdd2858
commit ce2aee857d
11 changed files with 119 additions and 65 deletions

View file

@ -5,6 +5,7 @@ import com.xujiayao.discord_mc_chat.commands.impl.StatsCommand;
import com.xujiayao.discord_mc_chat.network.NetworkManager;
import com.xujiayao.discord_mc_chat.network.packets.events.DiscordEventPacket;
import com.xujiayao.discord_mc_chat.network.packets.events.TextSegment;
import com.xujiayao.discord_mc_chat.server.message.DiscordMessageParser;
import com.xujiayao.discord_mc_chat.utils.LogFileUtils;
import com.xujiayao.discord_mc_chat.utils.config.ConfigManager;
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;

View file

@ -1,4 +1,4 @@
package com.xujiayao.discord_mc_chat.server.discord;
package com.xujiayao.discord_mc_chat.server.message;
import com.fasterxml.jackson.databind.JsonNode;
import com.xujiayao.discord_mc_chat.network.packets.events.TextSegment;
@ -1631,7 +1631,7 @@ public class DiscordMessageParser {
* @param member The Discord member (may be null).
* @return The hex color string (e.g. "#FF0000"), or "white" if no role color.
*/
static String getRoleColorHex(Member member) {
public static String getRoleColorHex(Member member) {
if (member == null) {
return "white";
}

View file

@ -0,0 +1,9 @@
package com.xujiayao.discord_mc_chat.server.message;
/**
* TODO
*
* @author Xujiayao
*/
public class MinecraftMessageParser {
}

View file

@ -87,11 +87,11 @@ message_parsing:
mentions: true
hyperlinks: true
timestamps: true
# Once enabled, ci.cancel() [PlayerChat, SourceSay, SourceTellRaw, SourceMsg, SourceMe]
# Once enabled, ci.cancel() [PlayerChat, SourceSay, SourceMsg, SourceMe]
# to prevent the original message from being processed by Minecraft, and instead broadcast
# the parsed message back (including the sender's own client).
# ---
# So, enabling this = enabling [player.chat, source.say, source.tell_raw, source.msg, source.me]
# So, enabling this = enabling [player.chat, source.say, source.msg, source.me]
# for the source DMCC client.
overwrite_minecraft_source_messages: false

View file

@ -121,11 +121,11 @@ message_parsing:
mentions: true
hyperlinks: true
timestamps: true
# Once enabled, ci.cancel() [PlayerChat, SourceSay, SourceTellRaw, SourceMsg, SourceMe]
# Once enabled, ci.cancel() [PlayerChat, SourceSay, SourceMsg, SourceMe]
# to prevent the original message from being processed by Minecraft, and instead broadcast
# the parsed message back (including the sender's own client).
# ---
# So, enabling this = enabling [player.chat, source.say, source.tell_raw, source.msg, source.me]
# So, enabling this = enabling [player.chat, source.say, source.msg, source.me]
# for the source DMCC client.
overwrite_minecraft_source_messages: false

View file

@ -34,18 +34,37 @@ xxxxx_to_minecraft: # for both discord_to_minecraft and minecraft_to_minecraft
bold: false
color: "gray"
single_server_overwrite:
user_message:
- text: "<{effective_name}> "
bold: false
color: "{role_color}"
- text: "{message}"
bold: false
color: "gray"
system_message:
- text: "{message}"
bold: false
color: "gray"
overwrite:
standalone:
user_message:
- text: "[{server}] "
bold: true
color: "{server_color}"
- text: "<{display_name}> "
bold: false
color: "{role_color}"
- text: "{message}"
bold: false
color: "white"
system_message:
- text: "[{server}] "
bold: true
color: "{server_color}"
- text: "{message}"
bold: false
color: "white"
single_server:
user_message:
- text: "<{display_name}> "
bold: false
color: "{role_color}"
- text: "{message}"
bold: false
color: "white"
system_message:
- text: "{message}"
bold: false
color: "white"
discord_to_minecraft:
mentioned: "{effective_name} mentioned you!"

View file

@ -34,18 +34,37 @@ xxxxx_to_minecraft: # for both discord_to_minecraft and minecraft_to_minecraft
bold: false
color: "gray"
single_server_overwrite:
user_message:
- text: "<{effective_name}> "
bold: false
color: "{role_color}"
- text: "{message}"
bold: false
color: "gray"
system_message:
- text: "{message}"
bold: false
color: "gray"
overwrite:
standalone:
user_message:
- text: "[{server}] "
bold: true
color: "{server_color}"
- text: "<{display_name}> "
bold: false
color: "{role_color}"
- text: "{message}"
bold: false
color: "white"
system_message:
- text: "[{server}] "
bold: true
color: "{server_color}"
- text: "{message}"
bold: false
color: "white"
single_server:
user_message:
- text: "<{display_name}> "
bold: false
color: "{role_color}"
- text: "{message}"
bold: false
color: "white"
system_message:
- text: "{message}"
bold: false
color: "white"
discord_to_minecraft:
mentioned: "{effective_name} 提及了你!"

View file

@ -33,9 +33,9 @@ commands:
dmcc_not_supported: "Executing DMCC commands through \"console\" command is not supported. Please use \"execute\" command."
server_not_ready: "Minecraft Server is not ready yet."
no_response: |
No response received from DMCC Client.
This can be normal for certain Minecraft commands. If you expected a response, please check the Minecraft server log by executing "{}" command.
No response received from DMCC Client.
This can be normal for certain Minecraft commands. If you expected a response, please check the Minecraft server log by executing "{}" command.
help:
description: "Show a list of available commands"

View file

@ -153,7 +153,7 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.PlayerJoin.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.serverPlayer().getName().getString(),
"player_name", event.serverPlayer().getName().getString(),
"display_name", event.serverPlayer().getDisplayName().getString()
);
NetworkManager.sendPacketToServer(new MinecraftEventPacket(MinecraftEventPacket.MessageType.PLAYER_JOIN, placeholders));
@ -166,7 +166,7 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.PlayerQuit.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.serverPlayer().getName().getString(),
"player_name", event.serverPlayer().getName().getString(),
"display_name", event.serverPlayer().getDisplayName().getString()
);
NetworkManager.sendPacketToServer(new MinecraftEventPacket(MinecraftEventPacket.MessageType.PLAYER_QUIT, placeholders));
@ -174,7 +174,7 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.PlayerDie.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.serverPlayer().getName().getString(),
"player_name", event.serverPlayer().getName().getString(),
"display_name", event.serverPlayer().getDisplayName().getString(),
"death_message", TranslationManager.get(event.serverPlayer().getCombatTracker().getDeathMessage())
);
@ -195,7 +195,7 @@ public class MinecraftEventHandler {
Map<String, String> placeholders = Map.of(
"type", type,
"user_name", event.serverPlayer().getName().getString(),
"player_name", event.serverPlayer().getName().getString(),
"display_name", event.serverPlayer().getDisplayName().getString(),
"title", TranslationManager.get(displayInfo.getTitle()),
"description", TranslationManager.get(displayInfo.getDescription())
@ -207,7 +207,7 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.PlayerChangeGameMode.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.serverPlayer().getName().getString(),
"player_name", event.serverPlayer().getName().getString(),
"display_name", event.serverPlayer().getDisplayName().getString(),
"mode", TranslationManager.get(event.gameType().getLongDisplayName())
);
@ -216,7 +216,8 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.PlayerChat.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.serverPlayer().getName().getString(),
"player_uuid", event.serverPlayer().getStringUUID(),
"player_name", event.serverPlayer().getName().getString(),
"display_name", event.serverPlayer().getDisplayName().getString(),
"message", TranslationManager.get(event.playerChatMessage().decoratedContent())
);
@ -225,7 +226,8 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.PlayerCommand.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.serverPlayer().getName().getString(),
"player_uuid", event.serverPlayer().getStringUUID(),
"player_name", event.serverPlayer().getName().getString(),
"display_name", event.serverPlayer().getDisplayName().getString(),
"command", "/" + event.command()
);
@ -234,7 +236,8 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.SourceSay.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.commandContext().getSource().getTextName(),
"player_uuid", event.commandContext().getSource().getEntity() instanceof ServerPlayer player ? player.getStringUUID() : "",
"player_name", event.commandContext().getSource().getTextName(),
"display_name", event.commandContext().getSource().getDisplayName().getString(),
"message", TranslationManager.get(event.playerChatMessage().decoratedContent())
);
@ -242,19 +245,13 @@ public class MinecraftEventHandler {
});
EventManager.register(MinecraftEvents.SourceTellRaw.class, event -> {
String input = event.commandContext().getInput();
String rawMessage = input.substring("tellraw @a ".length());
Map<String, String> placeholders = Map.of(
"user_name", event.commandContext().getSource().getTextName(),
"display_name", event.commandContext().getSource().getDisplayName().getString(),
"message", rawMessage
);
NetworkManager.sendPacketToServer(new MinecraftEventPacket(MinecraftEventPacket.MessageType.SOURCE_TELL_RAW, placeholders));
// TODO Rewrite
});
EventManager.register(MinecraftEvents.SourceMsg.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.commandContext().getSource().getTextName(),
"player_uuid", event.commandContext().getSource().getEntity() instanceof ServerPlayer player ? player.getStringUUID() : "",
"player_name", event.commandContext().getSource().getTextName(),
"display_name", event.commandContext().getSource().getDisplayName().getString(),
"message", TranslationManager.get(event.playerChatMessage().decoratedContent())
);
@ -263,7 +260,7 @@ public class MinecraftEventHandler {
EventManager.register(MinecraftEvents.SourceMe.class, event -> {
Map<String, String> placeholders = Map.of(
"user_name", event.commandContext().getSource().getTextName(),
"player_name", event.commandContext().getSource().getTextName(),
"display_name", event.commandContext().getSource().getDisplayName().getString(),
"action", TranslationManager.get(event.playerChatMessage().decoratedContent())
);

View file

@ -6,6 +6,7 @@ import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.advancements.AdvancementProgress;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.network.Connection;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.PlayerChatMessage;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerPlayer;
@ -116,7 +117,8 @@ public class MinecraftEvents {
* Posted when the /tellraw command is used.
*/
public record SourceTellRaw(
CommandContext<CommandSourceStack> commandContext
CommandContext<CommandSourceStack> commandContext,
Component component
) {
}
@ -124,9 +126,9 @@ public class MinecraftEvents {
* Posted when the /msg, /tell, /w command is used.
*/
public record SourceMsg(
CommandContext<CommandSourceStack> commandContext,
PlayerChatMessage playerChatMessage
) {
CommandContext<CommandSourceStack> commandContext,
PlayerChatMessage playerChatMessage
) {
}
/**

View file

@ -1,17 +1,22 @@
package com.xujiayao.discord_mc_chat.minecraft.mixins;
import com.mojang.brigadier.context.CommandContext;
import com.xujiayao.discord_mc_chat.Constants;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.xujiayao.discord_mc_chat.minecraft.events.MinecraftEvents;
import com.xujiayao.discord_mc_chat.utils.events.EventManager;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.ComponentArgument;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.network.chat.Component;
import net.minecraft.server.commands.TellRawCommand;
import net.minecraft.server.level.ServerPlayer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Optional;
import java.util.regex.Pattern;
/**
@ -23,17 +28,19 @@ public class MixinTellRawCommand {
@Unique
private static final Pattern TELLRAW_PATTERN = Pattern.compile("^tellraw @a .*");
@Inject(method = "lambda$register$0", at = @At("HEAD"), cancellable = true)
private static void lambda$register$0(CommandContext<CommandSourceStack> commandContext, CallbackInfoReturnable<Integer> cir) {
@Inject(method = "lambda$register$0", at = @At("HEAD"))
private static void lambda$register$0(CommandContext<CommandSourceStack> commandContext, CallbackInfoReturnable<Integer> cir) throws CommandSyntaxException {
if (TELLRAW_PATTERN.matcher(commandContext.getInput()).matches()) {
// SourceTellRaw Event
EventManager.post(new MinecraftEvents.SourceTellRaw(
commandContext
));
Optional<ServerPlayer> optional = EntityArgument.getPlayers(commandContext, "targets").stream().findFirst();
if (optional.isPresent()) {
ServerPlayer player = optional.get();
Component component = ComponentArgument.getResolvedComponent(commandContext, "message", player);
if (Constants.OVERWRITE_MINECRAFT_SOURCE_MESSAGES.get()) {
cir.setReturnValue(1);
cir.cancel();
// SourceTellRaw Event
EventManager.post(new MinecraftEvents.SourceTellRaw(
commandContext,
component
));
}
}
}