mirror of
https://github.com/PHIDIAS0303/ClusterChatSync.git
synced 2025-12-27 03:05:21 +09:00
.
This commit is contained in:
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# npm stuff
|
||||||
|
/node_modules/
|
||||||
|
/package-lock.json
|
||||||
|
/dist
|
||||||
0
.npmignore
Normal file
0
.npmignore
Normal file
6
CHANGELOG.md
Normal file
6
CHANGELOG.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## v1.0.0
|
||||||
|
|
||||||
|
- Initial
|
||||||
|
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
# ClusterChatSync
|
Cluster Chat Sync
|
||||||
Clusterio plugin - One way discord chat sync
|
========================
|
||||||
|
|
||||||
|
This is a custom chat sync, one-way only at this time.
|
||||||
|
|||||||
102
controller.js
Normal file
102
controller.js
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
"use strict";
|
||||||
|
const Discord = require("discord.js");
|
||||||
|
const { BaseControllerPlugin } = require("@clusterio/controller");
|
||||||
|
const { InstanceActionEvent } = require("./info.js");
|
||||||
|
|
||||||
|
class ControllerPlugin extends BaseControllerPlugin {
|
||||||
|
async init() {
|
||||||
|
this.controller.config.on("fieldChanged", (field, curr, prev) => {
|
||||||
|
if (field === "chat_sync.discord_bot_token") {
|
||||||
|
this.connect().catch(err => { this.logger.error(`Unexpected error:\n${err.stack}`); });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.controller.handle(InstanceActionEvent, this.handleInstanceAction.bind(this));
|
||||||
|
this.client = null;
|
||||||
|
await this.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
async connect() {
|
||||||
|
if (this.client) {
|
||||||
|
this.client.destroy();
|
||||||
|
this.client = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let token = this.controller.config.get("chat_sync.discord_bot_token");
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
this.logger.warn("chat sync bot token not configured, so chat is offline");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client = new Discord.Client({
|
||||||
|
intents: [
|
||||||
|
Discord.GatewayIntentBits.Guilds,
|
||||||
|
Discord.GatewayIntentBits.GuildMessages,
|
||||||
|
Discord.GatewayIntentBits.MessageContent,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.logger.info("chat sync is logging in to Discord");
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.client.login(this.controller.config.get("chat_sync.discord_bot_token"));
|
||||||
|
} catch (err) {
|
||||||
|
this.logger.error(`chat sync have error logging in to discord, chat is offline:\n${err.stack}`);
|
||||||
|
this.client.destroy();
|
||||||
|
this.client = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logger.info("chat sync have successfully logged in");
|
||||||
|
}
|
||||||
|
|
||||||
|
async onShutdown() {
|
||||||
|
if (this.client) {
|
||||||
|
this.client.destroy();
|
||||||
|
this.client = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async handleInstanceAction(request, src) {
|
||||||
|
if (request.action === "CHAT" || request.action === "SHOUT") {
|
||||||
|
const channel_id = this.controller.config.get("chat_sync.discord_channel_mapping")[this.controller.instances.get(src.id) ?? ""];
|
||||||
|
let channel = null;
|
||||||
|
|
||||||
|
if (!channel_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
channel = await this.client.channels.fetch(channel_id);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code !== 10003) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (channel === null) {
|
||||||
|
this.logger.error(`chat sync discord hannel ID ${channel_id} was not found`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const nrc = request.content.replace(/\[special-item=.*?\]/g, '<blueprint>').replace(/<@/g, '<@\u200c>');
|
||||||
|
const nrc_index = nrc.indexOf(":");
|
||||||
|
const nrc_username = nrc.substring(0, nrc_index);
|
||||||
|
const nrc_message = nrc.substring(nrc_index + 1).trim();
|
||||||
|
const nrc_msg = `**\`${nrc_username}\`** ${nrc_message}`
|
||||||
|
|
||||||
|
if (this.controller.config.get("chat_sync.datetime_on_message")) {
|
||||||
|
let now = new Date();
|
||||||
|
let dt = `${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}${String(now.getMinutes()).padStart(2, '0')}${String(now.getSeconds()).padStart(2, '0')}`;
|
||||||
|
await channel.send(`${dt} ${nrc_msg}`, { allowedMentions: { parse: [] }});
|
||||||
|
} else {
|
||||||
|
await channel.send(nrc_msg, { allowedMentions: { parse: [] }});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
ControllerPlugin
|
||||||
|
};
|
||||||
70
info.js
Normal file
70
info.js
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
"use strict";
|
||||||
|
const lib = require("@clusterio/lib");
|
||||||
|
|
||||||
|
class InstanceActionEvent {
|
||||||
|
static type = "event";
|
||||||
|
static src = "instance";
|
||||||
|
static dst = "controller";
|
||||||
|
static plugin = "chat_sync";
|
||||||
|
|
||||||
|
constructor(instanceName, action, content) {
|
||||||
|
this.instanceName = instanceName;
|
||||||
|
this.action = action;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
static jsonSchema = {
|
||||||
|
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 = {
|
||||||
|
name: "chat_sync",
|
||||||
|
title: "Chat Sync",
|
||||||
|
description: "One way chat sync.",
|
||||||
|
instanceEntrypoint: "instance",
|
||||||
|
controllerEntrypoint: "controller",
|
||||||
|
controllerConfigFields: {
|
||||||
|
"chat_sync.discord_bot_token": {
|
||||||
|
title: "Discord Bot Token",
|
||||||
|
description: "API Token",
|
||||||
|
type: "string",
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
"chat_sync.datetime_on_message": {
|
||||||
|
title: "Message Datetime",
|
||||||
|
description: "Append datetime in front",
|
||||||
|
type: "boolean",
|
||||||
|
initialValue: true,
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
"chat_sync.discord_channel_mapping": {
|
||||||
|
title: "Channels",
|
||||||
|
description: "Putting the discord channel id and instance relations here",
|
||||||
|
type: "object",
|
||||||
|
initialValue: {
|
||||||
|
"S1": "123",
|
||||||
|
"S2": "123",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
messages: [
|
||||||
|
InstanceActionEvent
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
plugin,
|
||||||
|
InstanceActionEvent
|
||||||
|
};
|
||||||
19
instance.js
Normal file
19
instance.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
"use strict";
|
||||||
|
const lib = require("@clusterio/lib");
|
||||||
|
const { BaseInstancePlugin } = require("@clusterio/host");
|
||||||
|
|
||||||
|
class InstancePlugin extends BaseInstancePlugin {
|
||||||
|
async init() {
|
||||||
|
this.messageQueue = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
async onOutput(output) {
|
||||||
|
if (output.type == "action") {
|
||||||
|
this.messageQueue.push([output.action, output.message]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
InstancePlugin
|
||||||
|
};
|
||||||
41
package.json
Normal file
41
package.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "@phidias0303/chat_sync",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "One way chat sync",
|
||||||
|
"main": "info.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"prepare": "webpack-cli --env production"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/PHIDIAS0303"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"clusterio",
|
||||||
|
"factorio",
|
||||||
|
"discord"
|
||||||
|
],
|
||||||
|
"author": "PHIDIAS <github@aperx.org>",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/PHIDIAS0303/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/PHIDIAS0303#readme",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@clusterio/lib": "^2.0.0-alpha.14"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@clusterio/lib": "^2.0.0-alpha.14",
|
||||||
|
"@clusterio/web_ui": "^2.0.0-alpha.14",
|
||||||
|
"webpack": "^5.88.2",
|
||||||
|
"webpack-cli": "^5.1.4",
|
||||||
|
"webpack-merge": "^5.9.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"discord.js": "^14.14.1"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
}
|
||||||
|
}
|
||||||
0
web/index.jsx
Normal file
0
web/index.jsx
Normal file
28
webpack.config.js
Normal file
28
webpack.config.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
"use strict";
|
||||||
|
const path = require("path");
|
||||||
|
const webpack = require("webpack");
|
||||||
|
const { merge } = require("webpack-merge");
|
||||||
|
|
||||||
|
const common = require("@clusterio/web_ui/webpack.common");
|
||||||
|
|
||||||
|
module.exports = (env = {}) => merge(common(env), {
|
||||||
|
context: __dirname,
|
||||||
|
entry: "./web/index.jsx",
|
||||||
|
output: {
|
||||||
|
path: path.resolve(__dirname, "dist", "web"),
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.container.ModuleFederationPlugin({
|
||||||
|
name: "chat_sync",
|
||||||
|
library: { type: "var", name: "plugin_chat_sync" },
|
||||||
|
exposes: {
|
||||||
|
"./": "./info.js",
|
||||||
|
"./package.json": "./package.json",
|
||||||
|
},
|
||||||
|
shared: {
|
||||||
|
"@clusterio/lib": { import: false },
|
||||||
|
"@clusterio/web_ui": { import: false },
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user