Port globalChat to new plugin system

Port the globalChat plugin to the new plugin system.  Since there's no
config system yet the config options for it is removed.
This commit is contained in:
Hornwitser committed 2019-12-14 17:51:54 +01:00
1 parent bcceae687f
commit b71c392b32
10 files changed
+199 -70

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
let link = require("lib/link");
let plugin = require("lib/plugin");
module.exports = {
name: "global_chat",
title: "Global Chat",
description: "Forwards chat between instances.",
version: "2.0.0-alpha",
instanceEntrypoint: "instance",
messages: {
chat: new link.Event({
type: 'global_chat:chat',
links: ['instance-slave', 'slave-master', 'master-slave', 'slave-instance'],
forwardTo: 'master',
broadcastTo: 'instance',
eventProperties: {
"instance_name": { type: "string" },
"content": { type: "string" },
},
}),
},
}
+58
View File
@@ -0,0 +1,58 @@
const plugin = require("lib/plugin");
/**
* Removes gps and train tags from messags
*/
function removeTags(content) {
return content.replace(/(\[gps=-?\d+,-?\d+\]|\[train=\d+\])/g, "");
}
/**
* Escapes a string for inclusion into a lua string
*/
function escapeLuaString(content) {
return content
.replace(/\\/g, "\\\\")
.replace(/"/g, '\\"')
.replace(/'/g, "\\'")
.replace(/\0/g, "\\0")
.replace(/\n/g, "\\n")
.replace(/\r/g, "\\r")
;
}
class InstancePlugin extends plugin.BaseInstancePlugin {
constructor(...args) {
super(...args);
}
async init() {
// XXX Nothing?
}
async chatEventHandler(message) {
// TODO check if cross server chat is enabled
let content = `[${message.data.instance_name}] ${removeTags(message.data.content)}`;
await this.instance.server.sendRcon(`/sc game.print('${escapeLuaString(content)}')`);
}
async onOutput(output) {
if (output.type === "action" && output.action === "CHAT") {
this.info.messages.chat.send(this.instance, {
instance_name: this.instance.name,
content: output.message,
});
}
}
// TODO implement info command in lua?
}
module.exports = {
InstancePlugin,
// For testing only
_removeTags: removeTags,
_escapeLuaString: escapeLuaString,
}
+91
View File
@@ -0,0 +1,91 @@
const assert = require('assert').strict;
const mock = require('../../../test/mock');
const lines = require('../../../test/lib/factorio/lines');
const instance = require('../instance');
const info = require('../info');
describe("global_chat plugin", function() {
describe("removeTags()", function() {
it("should pass through an ordinary string", function() {
assert.equal(instance._removeTags("string"), "string");
});
it("should strip out gps tag", function() {
assert.equal(instance._removeTags("Look at [gps=12,-4]"), "Look at ");
});
it("should strip out train tag", function() {
assert.equal(instance._removeTags("Train [train=1235]"), "Train ");
});
});
describe("escapeLuaSrting", function() {
it("should escape backslashes", function() {
assert.equal(instance._escapeLuaString("\\a"), "\\\\a");
});
it("should escape double quotes", function() {
assert.equal(instance._escapeLuaString('"a"'), '\\"a\\"');
});
it("should escape single quotes", function() {
assert.equal(instance._escapeLuaString("'a'"), "\\'a\\'");
});
it("should escape nul bytes", function() {
assert.equal(instance._escapeLuaString("a\0b"), "a\\0b");
});
it("should escape newlines", function() {
assert.equal(instance._escapeLuaString("a\nb"), "a\\nb");
});
it("should escape carriage return", function() {
assert.equal(instance._escapeLuaString("a\rb"), "a\\rb");
});
it("should escape all combined", function() {
assert.equal(instance._escapeLuaString("a\\b\"c'd\0e\nf\rg"), "a\\\\b\\\"c\\'d\\0e\\nf\\rg");
});
});
describe("class InstancePlugin", function() {
let instancePlugin;
before(async function() {
instancePlugin = new instance.InstancePlugin(info, new mock.MockInstance());
await instancePlugin.init();
});
describe(".chatEventHandler()", function() {
it("should send received chat as command", async function() {
instancePlugin.instance.server.rconCommands = [];
await instancePlugin.chatEventHandler({ data: { instance_name: "test", content: "User: message" } });
assert.deepEqual(
instancePlugin.instance.server.rconCommands,
["/sc game.print('[test] User: message')"],
);
});
});
describe(".onOutput()", function() {
it("should forward chat", async function() {
let count = 0;
for (let [_, output] of lines.testLines) {
if (output.type === "action" && output.action === "CHAT") {
instancePlugin.instance.connector.sentMessages = [];
await instancePlugin.onOutput(output);
assert(instancePlugin.instance.connector.sentMessages.length, "message was not sent");
count++;
}
}
assert(count > 0, "no lines were tested");
});
it("should ignore regular output", async function() {
let count = 0;
for (let [_, output] of lines.testLines) {
if (output.type !== "action" || output.action !== "CHAT") {
instancePlugin.instance.connector.sentMessages = [];
await instancePlugin.onOutput(output);
assert(!instancePlugin.instance.connector.sentMessages.length, "message was sent");
count++;
}
}
assert(count > 0, "no lines were tested");
});
})
});
});