This commit is contained in:
2025-09-25 16:05:42 +09:00
parent effd713f54
commit e6cba1d7ad
2 changed files with 0 additions and 110 deletions

View File

@@ -5,77 +5,6 @@ const {BaseControllerPlugin} = require('@clusterio/controller');
const {InstanceActionEvent} = require('./info.js');
const MAX_DISCORD_MESSAGE_LENGTH = 1950;
const MIN_CONFIDENCE_SCORE = 10.0;
class LibreTranslateAPI {
constructor(url, apiKey, logger = console) {
if (!url || !apiKey) this.logger.error('[Chat Sync] LibreTranslate API configuration is incomplete.');
try {new URL(url);} catch { this.logger.error('[Chat Sync] LibreTranslate url is invalid'); }
this.url = url.endsWith('/') ? url : url + '/';
this.apiKey = apiKey;
this.logger = logger;
}
async handleResponse(response) {
if (!response.ok) this.logger.error(`[Chat Sync] API Request got HTTP ${response.status}`);
return response.json();
}
async init() {
try {
this.allowedLanguages = (await this.handleResponse(
await fetch(`${this.url}languages?api_key=${this.apiKey}`, {method: 'GET'})
))?.[0]?.targets || [];
} catch (err) {
this.logger.error(`[Chat Sync] failed to initialize languages:\n${err.stack}`);
throw err; // Re-throw to handle it upstream
}
}
async translateRequest(q, source, target) {
try {
return (await this.handleResponse(await fetch(`${this.url}translate`, {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({q: q, api_key: this.apiKey, source: source, target: target})})))?.translatedText;
} catch (err) {
this.logger.error(`[Chat Sync] Translation failed:\n${err.stack}`);
}
}
async detectLanguage(q) {
try {
return (await this.handleResponse(await fetch(`${this.url}detect`, {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({q: q, api_key: this.apiKey})})))?.[0];
} catch (err) {
this.logger.error(`[Chat Sync] Detection failed:\n${err.stack}`);
}
}
async translate(query, targetLanguages) {
console.log(query);
const result = {action: false, passage: []};
try {
const detection = await this.detectLanguage(query);
if (!detection || typeof detection !== 'object' || !detection.confidence || !detection.language) {
this.logger.warn('[Chat Sync] Invalid language detection result:', detection);
return result;
}
if (detection.confidence > MIN_CONFIDENCE_SCORE) {
for (const targetLang of targetLanguages) {
if (!((detection.language === 'zh-Hans' || detection.language === 'zh-Hant') && (targetLang === 'zh-Hans' || targetLang === 'zh-Hant')) && detection.language !== targetLang && this.allowedLanguages.includes(detection.language) && this.allowedLanguages.includes(targetLang)) {
result.action = true;
const translated = await this.translateRequest(query, detection.language, targetLang);
result.passage.push(`[${detection.language} -> ${targetLang}] ${translated}`);
}
}
}
return result;
} catch (err) {
this.logger.error(`[Chat Sync] translation failed:\n${err.stack}`);
}
}
}
class ControllerPlugin extends BaseControllerPlugin {
async init() {
@@ -118,12 +47,6 @@ class ControllerPlugin extends BaseControllerPlugin {
}
this.logger.info('[Chat Sync] Logged in Discord successfully.');
if (this.controller.config.get('ClusterChatSync.use_libretranslate')) {
this.translator = new LibreTranslateAPI(this.controller.config.get('ClusterChatSync.libretranslate_url'), this.controller.config.get('ClusterChatSync.libretranslate_key'), this.logger);
await this.translator.init();
this.translator_language = this.controller.config.get('ClusterChatSync.libretranslate_language').trim().split(/\s+/) || ['zh-Hant', 'en'];
}
}
async onShutdown() {
@@ -179,15 +102,6 @@ class ControllerPlugin extends BaseControllerPlugin {
const nrc_username = nrc.substring(0, nrc_index);
const nrc_message = nrc.substring(nrc_index + 1).trim();
await this.sendMessage(request, `**\`${nrc_username}\`**: ${nrc_message}`);
if (this.controller.config.get('ClusterChatSync.use_libretranslate')) {
const result = await this.translator.translate(nrc_message, this.translator_language);
if (result && result.action) {
await this.sendMessage(request, `**\`${nrc_username}\`**: ${result.passage}`);
this.controller.sendTo(src, new lib.InstanceSendRconRequest(`[color=255,255,255]\`${nrc_username}\`: ${result.passage}[/color]`));
}
}
}
}
}