This commit is contained in:
2025-06-15 13:42:56 +09:00
parent 740dffcbaf
commit e46b697a33
4 changed files with 65 additions and 26 deletions

View File

@@ -21,9 +21,29 @@ class LibreTranslateAPI {
return response.json(); 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}`);}} async init() {
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}`);}} try {
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}`);}} 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}`);
}
}
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 = ['zh-Hant', 'en']) { async translate(query, targetLanguages = ['zh-Hant', 'en']) {
console.log(query); console.log(query);
@@ -48,7 +68,9 @@ class LibreTranslateAPI {
} }
return result; return result;
} catch (err) {this.logger.error(`[Chat Sync] translation failed:\n${err.stack}`);} } catch (err) {
this.logger.error(`[Chat Sync] translation failed:\n${err.stack}`);
}
} }
} }
@@ -68,7 +90,7 @@ class ControllerPlugin extends BaseControllerPlugin {
} }
async connect() { async connect() {
await this.clientDestroy() await this.clientDestroy();
if (!this.controller.config.get('ClusterChatSync.discord_bot_token')) { if (!this.controller.config.get('ClusterChatSync.discord_bot_token')) {
this.logger.error('[Chat Sync] Discord bot token not configured.'); this.logger.error('[Chat Sync] Discord bot token not configured.');
@@ -78,9 +100,7 @@ class ControllerPlugin extends BaseControllerPlugin {
this.client = new Discord.Client({intents: [Discord.GatewayIntentBits.Guilds, Discord.GatewayIntentBits.GuildMessages, Discord.GatewayIntentBits.MessageContent]}); this.client = new Discord.Client({intents: [Discord.GatewayIntentBits.Guilds, Discord.GatewayIntentBits.GuildMessages, Discord.GatewayIntentBits.MessageContent]});
this.logger.info('[Chat Sync] Logging into Discord.'); this.logger.info('[Chat Sync] Logging into Discord.');
try { try {await this.client.login(this.controller.config.get('ClusterChatSync.discord_bot_token'))} catch (err) {
await this.client.login(this.controller.config.get('ClusterChatSync.discord_bot_token'));
} catch (err) {
this.logger.error(`[Chat Sync] Discord login error:\n${err.stack}`); this.logger.error(`[Chat Sync] Discord login error:\n${err.stack}`);
await this.clientDestroy() await this.clientDestroy()
return; return;

11
info.js
View File

@@ -13,8 +13,15 @@ class InstanceActionEvent {
this.content = content; this.content = content;
} }
static jsonSchema = {type: 'object', required: ['instanceName', 'action', 'content'], properties: {'instanceName': {type: 'string'}, 'action': {type: 'string'}, 'content': {type: 'string'}}}; static jsonSchema = {
static fromJSON(json) {return new this(json.instanceName, json.action, json.content);} type: 'object',
required: ['instanceName', 'action', 'content'],
properties: {'instanceName': {type: 'string'}, 'action': {type: 'string'}, 'content': {type: 'string'}}
}
static fromJSON(json) {
return new this(json.instanceName, json.action, json.content);
}
} }
const plugin = { const plugin = {

View File

@@ -4,18 +4,30 @@ const {BaseInstancePlugin} = require("@clusterio/host");
const {InstanceActionEvent} = require("./info.js"); const {InstanceActionEvent} = require("./info.js");
class InstancePlugin extends BaseInstancePlugin { class InstancePlugin extends BaseInstancePlugin {
async init() {this.messageQueue = [];} async init() {
this.messageQueue = [];
}
onControllerConnectionEvent(event) { onControllerConnectionEvent(event) {
if (event === 'connect') { if (event === 'connect') {
for (const [action, content] of this.messageQueue) {try {this.instance.sendTo('controller', new InstanceActionEvent(this.instance.name, action, content))} catch (err) {this.messageQueue.push([output.action, output.message])}} for (const [action, content] of this.messageQueue) {
try {
this.instance.sendTo('controller', new InstanceActionEvent(this.instance.name, action, content));
} catch (err) {
this.messageQueue.push([output.action, output.message]);
}
}
this.messageQueue = []; this.messageQueue = [];
} }
} }
async onOutput(output) { async onOutput(output) {
if (output.type !== 'action') return; if (output.type !== 'action') return;
if (this.host.connector.connected) {this.instance.sendTo('controller', new InstanceActionEvent(this.instance.name, output.action, output.message))} else {this.messageQueue.push([output.action, output.message])} if (this.host.connector.connected) {
this.instance.sendTo('controller', new InstanceActionEvent(this.instance.name, output.action, output.message));
} else {
this.messageQueue.push([output.action, output.message]);
}
} }
} }

View File

@@ -1,27 +1,27 @@
"use strict"; 'use strict';
const path = require("path"); const path = require('path');
const webpack = require("webpack"); const webpack = require('webpack');
const { merge } = require("webpack-merge"); const { merge } = require('webpack-merge');
const common = require("@clusterio/web_ui/webpack.common"); const common = require('@clusterio/web_ui/webpack.common');
module.exports = (env = {}) => merge(common(env), { module.exports = (env = {}) => merge(common(env), {
context: __dirname, context: __dirname,
entry: "./web/index.jsx", entry: './web/index.jsx',
output: { output: {
path: path.resolve(__dirname, "dist", "web"), path: path.resolve(__dirname, 'dist', 'web'),
}, },
plugins: [ plugins: [
new webpack.container.ModuleFederationPlugin({ new webpack.container.ModuleFederationPlugin({
name: "ClusterChatSync", name: 'ClusterChatSync',
library: { type: "var", name: "plugin_ClusterChatSync" }, library: {type: 'var', name: 'plugin_ClusterChatSync' },
exposes: { exposes: {
"./": "./info.js", './': './info.js',
"./package.json": "./package.json", './package.json': './package.json',
}, },
shared: { shared: {
"@clusterio/lib": { import: false }, '@clusterio/lib': {import: false},
"@clusterio/web_ui": { import: false }, '@clusterio/web_ui': {import: false},
}, },
}), }),
], ],