我正在使用Node.js(使用Discord.js API)创建Discord机器人,并且在运行我的命令之一($$server
)时遇到了一些奇怪的行为。事实是,我正在为机器人使用定制的翻译引擎(实际上是机器人本身的一部分),问题似乎完全是胡说八道。首先,为了简单起见,我不会包含所有代码。如果您想了解整个代码实际上是如何运作的,请转到GitHub repository,我已在其中上传了最新更新。我删除了未使用和不重要的代码以节省空间。
现在,对于这个问题:问题在于,相同的代码(不包括我的调试代码)在不同的Discord语音通道区域中的工作方式不同。除了美国的四个地区(美国西部,东部,中部和南部)以外,所有地区的工作方式几乎都相同。我已经研究了区域ID,它们的解释正确。问题是,当我设置一个美国地区时,它可能找到的第一个翻译(嵌入页脚)突然停止工作。我还尝试设置调试代码(简单的console.log()
函数),事情就是这样。在server.js
中,除了打印出实际的Discord语音区域外,它实际上不做任何其他事情。完全不影响功能。但是,在functions.js
中,调试代码的存在(只是打印出regex
输出的内容,没有其他内容)使代码突然停止在有问题的行中工作(在{{1}中以注释突出显示) }),不仅限于美国地区。
这是functions.js
的内容(删除了不必要的代码):
functions.js
这是/*****************************************
* Joker Discord Bot
* Made by CZghost/Polda18, 2019
* ALPHA v0.0.1
*
* File: functions.js
*****************************************/
const { Permissions } = require("discord.js");
const locales = require("./locales.js");
const literals = require("./literals.js");
const colors = require("colors");
module.exports = {
// ...
// Resolve locale string
resolveLocale: (localeString, localeCode) => {
localeString = localeString.toLowerCase().trim();
// Anything else than #locale{<content>} isn't a locale string
if(!localeString.startsWith('#locale{') || !localeString.endsWith('}')) return localeString;
if(!literals.locales.includes(localeCode)) return null; // Could not recognise locale code
if(Object.prototype.hasOwnProperty.call(literals.locales_map, localeCode))
localeCode = literals.locales_map[localeCode]; // No country code encountered, map to default country
// Check a locale string for any matches
const regex = /#locale\{([a-zA-Z0-9_:]+)\}/g;
// Debug <-- If this is present, the command doesn't work at all, this is where it gets stuck
console.log(regex.exec(localeString));
// Get the content of the brackets and split by colon
let content = regex.exec(localeString)[1].split(':'); // Problematic line - works or not, depends on the region settings - sounds strange, right?
// Get the available locales for this locale string
let availableLocales = content.reduce((o, i) => {
try {
return o[i]; // Decompile string to an object reference
} catch(e) {
console.error(`Cannot find locale string \`${localeString}\` for language \`${localeCode}\`. Perhaps missing?`);
console.error(e);
return undefined; // If reached an unreachable end, return undefined (safe reference)
}
}, locales.locale_strings);
if(!availableLocales || availableLocales.constructor !== Object) return null; // Reached an unreachable reference
// Locale string for this locale code not found => use default locale code
if(!Object.prototype.hasOwnProperty.call(availableLocales, localeCode)) return availableLocales[locales.default_locale];
// Get and return the correct locale string
return availableLocales[localeCode];
},
// ...
}
的内容:
server.js
为澄清起见,这是/*****************************************
* Joker Discord Bot
* Made by CZghost/Polda18, 2019
* ALPHA v0.0.1
*
* File: commands/info/server.js
*****************************************/
const { RichEmbed } = require("discord.js");
const { stripIndents } = require("common-tags");
const { formatDate, createError, resolveLocale } = require("../../functions.js");
const literals = require("../../literals.js");
module.exports = {
name: 'serverinfo',
aliases: [ 'server', 'sinfo' ],
category: 'info',
help: {
description: '#locale{help:command:serverinfo:description}',
args: []
},
run: async (client, message, args) => {
// Check if a locale is set for this guild and fetch that settings
const server_id = message.guild.id;
const localeCode = (Object.prototype.hasOwnProperty.call(client.settings.guilds, server_id))
? client.settings.guilds[server_id].locale
: client.settings.guilds.default.locale
|| client.settings.guilds.default.locale;
// Debug <-- prints out the actual region id to console
console.log(`\`${message.guild.region}\``);
const embed = new RichEmbed()
.setFooter(resolveLocale("#locale{commands:serverinfo:query:footer}", localeCode) // This is where it gets stuck
.replace(/\[author\]/g, message.author.tag.replace(/\$/g, '$$$$')), message.author.displayAvatarURL)
.setTitle(resolveLocale("#locale{commands:serverinfo:query:title}", localeCode))
.setAuthor(message.guild.name, message.guild.iconURL)
.setThumbnail(message.guild.iconURL)
.setColor(literals.region_colors[message.guild.region])
.addField(resolveLocale("#locale{commands:serverinfo:query:basic_info:caption}", localeCode),
stripIndents`
**\\> ${
resolveLocale("#locale{commands:serverinfo:query:basic_info:description:id}", localeCode)
}:** ${server_id}
**\\> ${
resolveLocale("#locale{commands:serverinfo:query:basic_info:description:system_channel}", localeCode)
}:** ${message.guild.systemChannel}
**\\> ${
resolveLocale("#locale{commands:serverinfo:query:basic_info:description:member_count}", localeCode)
}:** ${message.guild.memberCount}
**\\> ${
resolveLocale("#locale{commands:serverinfo:query:basic_info:description:region}", localeCode)
}:** ${literals.region_flags[message.guild.region]} ${resolveLocale(`#locale{regions:${message.guild.region}}`, localeCode)}
`.trim())
embed.setTimestamp();
await message.channel.send(embed);
}
}
的实际内容,用于翻译:
locales.js
这是控制台输出:
/*****************************************
* Joker Discord Bot
* Made by CZghost/Polda18, 2019
* ALPHA v0.0.1
*
* File: locales.js
* Description:
* This file contains locale settings
* for supported languages using ISO 639-1
* language codes with country locale code
*
* Please send me a feature request for
* adding another locale code
*****************************************/
const { stripIndents } = require("common-tags");
// Translations
module.exports = {
default_locale: 'en-US',
supported_locales: {
partially: [],
completely: [
'en-US',
'cs-CZ'
]
},
locale_strings: {
regions: {
'brazil': {
'en-US': 'Brazil',
'cs-CZ': 'Brazílie'
},
'eu-central': {
'en-US': 'Central Europe',
'cs-CZ': 'Střední Evropa'
},
'europe': {
'en-US': 'Europe',
'cs-CZ': 'Evropa'
},
'hongkong': {
'en-US': 'Hong Kong',
'cs-CZ': 'Hong Kong'
},
'india': {
'en-US': 'India',
'cs-CZ': 'Indie'
},
'japan': {
'en-US': 'Japan',
'cs-CZ': 'Japonsko'
},
'russia': {
'en-US': 'Russia',
'cs-CZ': 'Rusko'
},
'singapore': {
'en-US': 'Singapore',
'cs-CZ': 'Singapur'
},
'southafrica': {
'en-US': 'South Africa',
'cs-CZ': 'Jižní Afrika'
},
'sydney': {
'en-US': 'Sydney',
'cs-CZ': 'Sydney'
},
'us-central': {
'en-US': 'U.S. Central',
'cs-CZ': 'Střed USA'
},
'us-east': {
'en-US': 'U.S. East',
'cs-CZ': 'Východ USA'
},
'us-south': {
'en-US': 'U.S. South',
'cs-CZ': 'Jih USA'
},
'us-west': {
'en-US': 'U.S. West',
'cs-CZ': 'Západ USA'
}
},
// ...
commands: {
// ...
serverinfo: {
query: {
footer: {
'en-US': 'Queried by [author]',
'cs-CZ': 'Vyžádal/-a si [author]'
},
title: {
'en-US': 'Server info',
'cs-CZ': 'Informace o serveru'
},
basic_info: {
caption: {
'en-US': 'Basic info',
'cs-CZ': 'Základní informace'
},
description: {
id: {
'en-US': 'Server ID',
'cs-CZ': 'ID serveru'
},
system_channel: {
'en-US': 'System channel',
'cs-CZ': 'Systémový kanál'
},
member_count: {
'en-US': 'Member count',
'cs-CZ': 'Počet členů'
},
region: {
'en-US': 'Region',
'cs-CZ': 'Region'
}
}
}
}
},
// ...
},
help: {
// ...
command: {
// ...
serverinfo: {
description: {
'en-US': 'Returns server information',
'cs-CZ': 'Vrátí informace o serveru'
}
}
}
}
}
}
答案 0 :(得分:0)
好吧,事实证明我没想到语言环境代码中会带有连字符,而我却忘记了它们。没有在regex
中包括它们:D是的,这很愚蠢。
因此,唯一的解决方案是在regex
表达式中包含连字符。