C# Discord Bot JSON本地化示例及全局本地化实现请求
C# Discord Bot JSON本地化实现方案
一、JSON本地化文件模板
在项目中创建Localization目录,存放多语言JSON文件,结构统一包含命令、通用消息两类节点:
en-US.json
{ "commands": { "Ping": { "name": "ping", "description": "Check the bot's response latency" }, "Help": { "name": "help", "description": "Get a list of available commands" } }, "strings": { "PingResponse": "Pong! Latency: {0}ms", "HelpHeader": "Available Commands:", "CommandNotFound": "Sorry, that command doesn't exist. Use {0} to see all commands." } }
zh-CN.json
{ "commands": { "Ping": { "name": "心跳", "description": "检查机器人的响应延迟" }, "Help": { "name": "帮助", "description": "获取可用命令列表" } }, "strings": { "PingResponse": "咚!延迟:{0}毫秒", "HelpHeader": "可用命令:", "CommandNotFound": "抱歉,该命令不存在。使用{0}查看所有命令。" } }
二、本地化加载与管理类
编写静态类负责读取JSON文件、缓存内容,支持按语言切换:
using System; using System.Collections.Generic; using System.IO; using System.Text.Json; public static class LocalizationManager { private static readonly Dictionary<string, LocalizationData> _cache = new(); private const string _dir = "Localization"; static LocalizationManager() { foreach (var file in Directory.GetFiles(_dir, "*.json")) { var langCode = Path.GetFileNameWithoutExtension(file); var json = File.ReadAllText(file); var data = JsonSerializer.Deserialize<LocalizationData>(json); _cache[langCode] = data; } } // 默认回退到en-US public static LocalizationData Get(string langCode = "en-US") { return _cache.TryGetValue(langCode, out var data) ? data : _cache["en-US"]; } public class LocalizationData { public Dictionary<string, CommandLoc> Commands { get; set; } public Dictionary<string, string> Strings { get; set; } } public class CommandLoc { public string Name { get; set; } public string Description { get; set; } } }
三、Discord.NET命令本地化配置
通过实现ICommandLocalizer接口,将JSON内容对接至命令服务:
1. 自定义本地化提供者
using Discord.Commands; public class JsonCommandLocalizer : ICommandLocalizer { // 此处可替换为从用户设置/数据库获取语言的逻辑 private string GetUserLang(ICommandContext context) => context.Guild.PreferredLocale; public LocalizedString GetName(ICommandInfo command, ICommandContext context) { var loc = LocalizationManager.Get(GetUserLang(context)); return loc.Commands.TryGetValue(command.Name, out var cmd) ? new LocalizedString(cmd.Name, cmd.Name) : new LocalizedString(command.Name, command.Name); } public LocalizedString GetDescription(ICommandInfo command, ICommandContext context) { var loc = LocalizationManager.Get(GetUserLang(context)); return loc.Commands.TryGetValue(command.Name, out var cmd) ? new LocalizedString(cmd.Description, cmd.Description) : new LocalizedString(command.Description, command.Description); } // 按需实现参数本地化 public LocalizedString GetParameterName(IParameterInfo parameter, ICommandContext context) { return new LocalizedString(parameter.Name, parameter.Name); } }
2. 注册命令服务时绑定本地化
using Discord; using Discord.Commands; using Discord.WebSocket; var clientConfig = new DiscordSocketConfig { GatewayIntents = GatewayIntents.AllUnprivileged | GatewayIntents.MessageContent }; var client = new DiscordSocketClient(clientConfig); var commandConfig = new CommandServiceConfig { Localizer = new JsonCommandLocalizer(), CaseSensitiveCommands = false }; var commandService = new CommandService(commandConfig); // 后续注册命令、启动客户端逻辑...
四、复用本地化到机器人消息
发送消息时直接从本地化缓存中取值,支持参数格式化:
[Command("ping")] public async Task Ping() { var lang = Context.Guild.PreferredLocale; var loc = LocalizationManager.Get(lang); await ReplyAsync(string.Format(loc.Strings["PingResponse"], Context.Client.Latency)); } public async Task HandleUnknownCommand() { var lang = Context.Guild.PreferredLocale; var loc = LocalizationManager.Get(lang); await ReplyAsync(string.Format(loc.Strings["CommandNotFound"], loc.Commands["Help"].Name)); }
附:Discord.NET官方JSON本地化Schema与.resx对比
官方JSON Schema
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "commands": { "type": "object", "patternProperties": { "^[a-zA-Z0-9_]+$": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "parameters": { "type": "object", "patternProperties": { "^[a-zA-Z0-9_]+$": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" } }, "required": ["name"] } } } }, "required": ["name", "description"] } } }, "strings": { "type": "object", "patternProperties": { "^[a-zA-Z0-9_]+$": { "type": "string" } } } }, "required": ["commands", "strings"] }
传统.resx示例(参考)
<!-- Resources.en-US.resx --> <root> <data name="PingCommandName" xml:space="preserve"> <value>ping</value> </data> <data name="PingCommandDescription" xml:space="preserve"> <value>Check the bot's response latency</value> </data> <data name="PingResponse" xml:space="preserve"> <value>Pong! Latency: {0}ms</value> </data> </root>
内容的提问来源于stack exchange,提问作者LinesinRows
相关产品推荐
相关产品推荐

