mirror of
https://github.com/System-End/Discord-MC-Chat.git
synced 2026-04-19 16:28:23 +00:00
format
This commit is contained in:
parent
6a9036dbbc
commit
758d1634d2
12 changed files with 83 additions and 61 deletions
|
|
@ -142,7 +142,8 @@ DMCC 在 Client 端提供独立的 `whitelist` 代理命令(默认所需权限
|
||||||
当 DMCC 处于 `standalone + multi_server_client` 架构时,不同子服务器可使用不同 OP 映射策略。
|
当 DMCC 处于 `standalone + multi_server_client` 架构时,不同子服务器可使用不同 OP 映射策略。
|
||||||
|
|
||||||
在 `standalone` 配置的 `user_mappings` 与 `role_mappings` 中,每个条目包含一个顶层 `op_level`(给 Standalone 自身查询使用),以及一个
|
在 `standalone` 配置的 `user_mappings` 与 `role_mappings` 中,每个条目包含一个顶层 `op_level`(给 Standalone 自身查询使用),以及一个
|
||||||
`server_overrides` 列表字典。若 `server_overrides` 中没有某子服务器的对应条目,则该子服务器自动降级使用顶层 `op_level` 作为默认回退值。
|
`server_overrides` 列表字典。若 `server_overrides` 中没有某子服务器的对应条目,则该子服务器自动降级使用顶层 `op_level`
|
||||||
|
作为默认回退值。
|
||||||
|
|
||||||
## 7. 命令列表与权限参考
|
## 7. 命令列表与权限参考
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,14 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public class DiscordEventPacket extends Packet {
|
public class DiscordEventPacket extends Packet {
|
||||||
|
|
||||||
/** The type of Discord event. */
|
/**
|
||||||
|
* The type of Discord event.
|
||||||
|
*/
|
||||||
public EventType type;
|
public EventType type;
|
||||||
|
|
||||||
/** Pre-built rich text segments for the main message line. */
|
/**
|
||||||
|
* Pre-built rich text segments for the main message line.
|
||||||
|
*/
|
||||||
public List<TextSegment> segments;
|
public List<TextSegment> segments;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -67,10 +71,14 @@ public class DiscordEventPacket extends Packet {
|
||||||
* @author Xujiayao
|
* @author Xujiayao
|
||||||
*/
|
*/
|
||||||
public enum EventType {
|
public enum EventType {
|
||||||
/** A regular Discord chat message forwarded to Minecraft. */
|
/**
|
||||||
|
* A regular Discord chat message forwarded to Minecraft.
|
||||||
|
*/
|
||||||
CHAT,
|
CHAT,
|
||||||
|
|
||||||
/** A Discord command execution notification forwarded to Minecraft. */
|
/**
|
||||||
|
* A Discord command execution notification forwarded to Minecraft.
|
||||||
|
*/
|
||||||
COMMAND
|
COMMAND
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,22 +21,34 @@ public class TextSegment implements Serializable {
|
||||||
@Serial
|
@Serial
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/** The display text of this segment. */
|
/**
|
||||||
|
* The display text of this segment.
|
||||||
|
*/
|
||||||
public String text;
|
public String text;
|
||||||
|
|
||||||
/** Whether the text should be rendered in bold. */
|
/**
|
||||||
|
* Whether the text should be rendered in bold.
|
||||||
|
*/
|
||||||
public boolean bold;
|
public boolean bold;
|
||||||
|
|
||||||
/** Whether the text should be rendered in italic. */
|
/**
|
||||||
|
* Whether the text should be rendered in italic.
|
||||||
|
*/
|
||||||
public boolean italic;
|
public boolean italic;
|
||||||
|
|
||||||
/** Whether the text should be rendered with underline. */
|
/**
|
||||||
|
* Whether the text should be rendered with underline.
|
||||||
|
*/
|
||||||
public boolean underlined;
|
public boolean underlined;
|
||||||
|
|
||||||
/** Whether the text should be rendered with strikethrough. */
|
/**
|
||||||
|
* Whether the text should be rendered with strikethrough.
|
||||||
|
*/
|
||||||
public boolean strikethrough;
|
public boolean strikethrough;
|
||||||
|
|
||||||
/** Whether the text should be rendered obfuscated. */
|
/**
|
||||||
|
* Whether the text should be rendered obfuscated.
|
||||||
|
*/
|
||||||
public boolean obfuscated;
|
public boolean obfuscated;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@ import net.dv8tion.jda.api.JDA;
|
||||||
import net.dv8tion.jda.api.JDABuilder;
|
import net.dv8tion.jda.api.JDABuilder;
|
||||||
import net.dv8tion.jda.api.OnlineStatus;
|
import net.dv8tion.jda.api.OnlineStatus;
|
||||||
import net.dv8tion.jda.api.entities.Activity;
|
import net.dv8tion.jda.api.entities.Activity;
|
||||||
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.entities.Webhook;
|
import net.dv8tion.jda.api.entities.Webhook;
|
||||||
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
import net.dv8tion.jda.api.entities.channel.concrete.TextChannel;
|
||||||
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
import net.dv8tion.jda.api.exceptions.InsufficientPermissionException;
|
||||||
|
|
@ -295,7 +297,7 @@ public class DiscordManager {
|
||||||
* @param discordId The Discord user ID.
|
* @param discordId The Discord user ID.
|
||||||
* @return The User object, or null if JDA is not available or user not found.
|
* @return The User object, or null if JDA is not available or user not found.
|
||||||
*/
|
*/
|
||||||
public static net.dv8tion.jda.api.entities.User retrieveUser(String discordId) {
|
public static User retrieveUser(String discordId) {
|
||||||
if (jda == null) return null;
|
if (jda == null) return null;
|
||||||
try {
|
try {
|
||||||
return jda.retrieveUserById(discordId).complete();
|
return jda.retrieveUserById(discordId).complete();
|
||||||
|
|
@ -310,11 +312,11 @@ public class DiscordManager {
|
||||||
* @param discordId The Discord user ID.
|
* @param discordId The Discord user ID.
|
||||||
* @return The Member object, or null if JDA is not available or member not found.
|
* @return The Member object, or null if JDA is not available or member not found.
|
||||||
*/
|
*/
|
||||||
public static net.dv8tion.jda.api.entities.Member retrieveMember(String discordId) {
|
public static Member retrieveMember(String discordId) {
|
||||||
if (jda == null) return null;
|
if (jda == null) return null;
|
||||||
for (var guild : jda.getGuilds()) {
|
for (var guild : jda.getGuilds()) {
|
||||||
try {
|
try {
|
||||||
net.dv8tion.jda.api.entities.Member member = guild.retrieveMemberById(discordId).complete();
|
Member member = guild.retrieveMemberById(discordId).complete();
|
||||||
if (member != null) {
|
if (member != null) {
|
||||||
return member;
|
return member;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.xujiayao.discord_mc_chat.network.packets.events.TextSegment;
|
import com.xujiayao.discord_mc_chat.network.packets.events.TextSegment;
|
||||||
import com.xujiayao.discord_mc_chat.server.linking.LinkedAccountManager;
|
import com.xujiayao.discord_mc_chat.server.linking.LinkedAccountManager;
|
||||||
import com.xujiayao.discord_mc_chat.utils.config.ConfigManager;
|
import com.xujiayao.discord_mc_chat.utils.config.ConfigManager;
|
||||||
import com.xujiayao.discord_mc_chat.utils.config.ModeManager;
|
|
||||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
|
|
@ -370,13 +369,13 @@ public class DiscordMessageParser {
|
||||||
* Parses the raw text content of a Discord message, handling mentions, emojis,
|
* Parses the raw text content of a Discord message, handling mentions, emojis,
|
||||||
* markdown, and hyperlinks inline.
|
* markdown, and hyperlinks inline.
|
||||||
*
|
*
|
||||||
* @param raw The raw content string.
|
* @param raw The raw content string.
|
||||||
* @param message The Discord message (for resolving mentions).
|
* @param message The Discord message (for resolving mentions).
|
||||||
* @param parseMentions Whether to parse mentions.
|
* @param parseMentions Whether to parse mentions.
|
||||||
* @param parseCustomEmojis Whether to parse custom emojis.
|
* @param parseCustomEmojis Whether to parse custom emojis.
|
||||||
* @param parseUnicodeEmojis Whether to parse unicode emojis.
|
* @param parseUnicodeEmojis Whether to parse unicode emojis.
|
||||||
* @param parseMarkdown Whether to parse markdown formatting.
|
* @param parseMarkdown Whether to parse markdown formatting.
|
||||||
* @param parseHyperlinks Whether to parse hyperlinks.
|
* @param parseHyperlinks Whether to parse hyperlinks.
|
||||||
* @return The list of text segments for the raw content.
|
* @return The list of text segments for the raw content.
|
||||||
*/
|
*/
|
||||||
private static List<TextSegment> parseRawContent(String raw, Message message,
|
private static List<TextSegment> parseRawContent(String raw, Message message,
|
||||||
|
|
@ -721,32 +720,6 @@ public class DiscordMessageParser {
|
||||||
return "blue";
|
return "blue";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal record representing a span of raw text that maps to a special token
|
|
||||||
* (mention, emoji, link, etc.).
|
|
||||||
*/
|
|
||||||
private record TokenSpan(int start, int end, TextSegment segment) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal record representing a markdown-formatted span of text.
|
|
||||||
*/
|
|
||||||
private record MarkdownSpan(int start, int end, String innerText, MarkdownType type) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Types of markdown formatting.
|
|
||||||
*/
|
|
||||||
private enum MarkdownType {
|
|
||||||
BOLD,
|
|
||||||
ITALIC,
|
|
||||||
UNDERLINE,
|
|
||||||
STRIKETHROUGH,
|
|
||||||
SPOILER,
|
|
||||||
CODE_BLOCK,
|
|
||||||
INLINE_CODE
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely truncates a string to the given maximum character count without splitting
|
* Safely truncates a string to the given maximum character count without splitting
|
||||||
* surrogate pairs (multi-byte emoji characters).
|
* surrogate pairs (multi-byte emoji characters).
|
||||||
|
|
@ -765,4 +738,30 @@ public class DiscordMessageParser {
|
||||||
}
|
}
|
||||||
return text.substring(0, maxLen);
|
return text.substring(0, maxLen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of markdown formatting.
|
||||||
|
*/
|
||||||
|
private enum MarkdownType {
|
||||||
|
BOLD,
|
||||||
|
ITALIC,
|
||||||
|
UNDERLINE,
|
||||||
|
STRIKETHROUGH,
|
||||||
|
SPOILER,
|
||||||
|
CODE_BLOCK,
|
||||||
|
INLINE_CODE
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal record representing a span of raw text that maps to a special token
|
||||||
|
* (mention, emoji, link, etc.).
|
||||||
|
*/
|
||||||
|
private record TokenSpan(int start, int end, TextSegment segment) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal record representing a markdown-formatted span of text.
|
||||||
|
*/
|
||||||
|
private record MarkdownSpan(int start, int end, String innerText, MarkdownType type) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -142,11 +142,11 @@ public class CoreEvents {
|
||||||
* The handler should convert the pre-built {@link TextSegment} lists into
|
* The handler should convert the pre-built {@link TextSegment} lists into
|
||||||
* Minecraft Components and broadcast them to all online players.
|
* Minecraft Components and broadcast them to all online players.
|
||||||
*
|
*
|
||||||
* @param segments The main message line segments.
|
* @param segments The main message line segments.
|
||||||
* @param replySegments The reply context line segments (may be null or empty).
|
* @param replySegments The reply context line segments (may be null or empty).
|
||||||
* @param mentionNotificationText The mention notification text (may be null).
|
* @param mentionNotificationText The mention notification text (may be null).
|
||||||
* @param mentionNotificationStyle The notification style: "action_bar", "title", or "chat".
|
* @param mentionNotificationStyle The notification style: "action_bar", "title", or "chat".
|
||||||
* @param mentionedPlayerUuids UUIDs of players who should receive mention notifications.
|
* @param mentionedPlayerUuids UUIDs of players who should receive mention notifications.
|
||||||
*/
|
*/
|
||||||
public record DiscordChatMessageEvent(
|
public record DiscordChatMessageEvent(
|
||||||
List<TextSegment> segments,
|
List<TextSegment> segments,
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ account_linking:
|
||||||
user_mappings:
|
user_mappings:
|
||||||
- user: "xujiayao"
|
- user: "xujiayao"
|
||||||
op_level: 4
|
op_level: 4
|
||||||
server_overrides: # 如果该子服务器不需要覆盖上方定义的 OP 等级设置,可以删除该项。此列表可以为空。
|
server_overrides: # 如果该子服务器不需要覆盖上方定义的 OP 等级设置,可以删除该项。此列表可以为空。
|
||||||
- server: "SMP"
|
- server: "SMP"
|
||||||
op_level: 4
|
op_level: 4
|
||||||
- server: "CMP"
|
- server: "CMP"
|
||||||
|
|
@ -163,7 +163,7 @@ account_linking:
|
||||||
# 示例 1:拥有 "Admins" 角色的用户将被视为 OP 3。
|
# 示例 1:拥有 "Admins" 角色的用户将被视为 OP 3。
|
||||||
- role: "Admins"
|
- role: "Admins"
|
||||||
op_level: 3
|
op_level: 3
|
||||||
server_overrides: # 如果该子服务器不需要覆盖上方定义的 OP 等级设置,可以删除该项。此列表可以为空。
|
server_overrides: # 如果该子服务器不需要覆盖上方定义的 OP 等级设置,可以删除该项。此列表可以为空。
|
||||||
- server: "SMP"
|
- server: "SMP"
|
||||||
op_level: 3
|
op_level: 3
|
||||||
- server: "CMP"
|
- server: "CMP"
|
||||||
|
|
@ -171,7 +171,7 @@ account_linking:
|
||||||
# 示例 2:可将基础认证角色映射为 OP 0,使其有权执行无需特殊权限的 DMCC 命令(如委托执行白名单)。
|
# 示例 2:可将基础认证角色映射为 OP 0,使其有权执行无需特殊权限的 DMCC 命令(如委托执行白名单)。
|
||||||
- role: "Players"
|
- role: "Players"
|
||||||
op_level: 0
|
op_level: 0
|
||||||
server_overrides: # 如果该子服务器不需要覆盖上方定义的 OP 等级设置,可以删除该项。此列表可以为空。
|
server_overrides: # 如果该子服务器不需要覆盖上方定义的 OP 等级设置,可以删除该项。此列表可以为空。
|
||||||
- server: "SMP"
|
- server: "SMP"
|
||||||
op_level: 0
|
op_level: 0
|
||||||
- server: "CMP"
|
- server: "CMP"
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ common:
|
||||||
|
|
||||||
discord_to_minecraft:
|
discord_to_minecraft:
|
||||||
mentioned: "{effective_name} mentioned you!"
|
mentioned: "{effective_name} mentioned you!"
|
||||||
response: # 回复其它用户的消息时,原消息的格式
|
response: # 回复其它用户的消息时,原消息的格式
|
||||||
- text: " ┌──── "
|
- text: " ┌──── "
|
||||||
bold: true
|
bold: true
|
||||||
color: "dark_gray"
|
color: "dark_gray"
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ common:
|
||||||
|
|
||||||
discord_to_minecraft:
|
discord_to_minecraft:
|
||||||
mentioned: "{effective_name} 提及了你!"
|
mentioned: "{effective_name} 提及了你!"
|
||||||
response: # 回复其它用户的消息时,原消息的格式
|
response: # 回复其它用户的消息时,原消息的格式
|
||||||
- text: " ┌──── "
|
- text: " ┌──── "
|
||||||
bold: true
|
bold: true
|
||||||
color: "dark_gray"
|
color: "dark_gray"
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
*/
|
*/
|
||||||
public class MinecraftEventHandler {
|
public class MinecraftEventHandler {
|
||||||
|
|
||||||
|
private static final String DEFAULT_MENTION_STYLE = "title";
|
||||||
private static MinecraftServer serverInstance;
|
private static MinecraftServer serverInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -657,7 +658,7 @@ public class MinecraftEventHandler {
|
||||||
* Builds a clickable Component that suggests a command (fills the chat input) when clicked.
|
* Builds a clickable Component that suggests a command (fills the chat input) when clicked.
|
||||||
* Displayed in green with brackets.
|
* Displayed in green with brackets.
|
||||||
*
|
*
|
||||||
* @param command The command to suggest (fill into chat input).
|
* @param command The command to suggest (fill into chat input).
|
||||||
* @return A clickable Component.
|
* @return A clickable Component.
|
||||||
*/
|
*/
|
||||||
private static Component buildSuggestCommand(String command) {
|
private static Component buildSuggestCommand(String command) {
|
||||||
|
|
@ -805,8 +806,6 @@ public class MinecraftEventHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String DEFAULT_MENTION_STYLE = "title";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a mention notification to a player using the configured style.
|
* Sends a mention notification to a player using the configured style.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import com.xujiayao.discord_mc_chat.utils.StringUtils;
|
||||||
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
import com.xujiayao.discord_mc_chat.utils.i18n.I18nManager;
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.chat.contents.TranslatableContents;
|
import net.minecraft.network.chat.contents.TranslatableContents;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.packs.PackResources;
|
import net.minecraft.server.packs.PackResources;
|
||||||
import net.minecraft.server.packs.PackType;
|
import net.minecraft.server.packs.PackType;
|
||||||
|
|
@ -245,7 +246,7 @@ public class TranslationManager {
|
||||||
packResources1.getNamespaces(PackType.CLIENT_RESOURCES).forEach(namespace -> {
|
packResources1.getNamespaces(PackType.CLIENT_RESOURCES).forEach(namespace -> {
|
||||||
IoSupplier<InputStream> supplier = packResources1.getResource(
|
IoSupplier<InputStream> supplier = packResources1.getResource(
|
||||||
PackType.CLIENT_RESOURCES,
|
PackType.CLIENT_RESOURCES,
|
||||||
net.minecraft.resources.ResourceLocation.fromNamespaceAndPath(namespace, "lang/" + language + ".json")
|
ResourceLocation.fromNamespaceAndPath(namespace, "lang/" + language + ".json")
|
||||||
);
|
);
|
||||||
|
|
||||||
if (supplier != null) {
|
if (supplier != null) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue