mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 15:14:52 +09:00
Add clusterio module with API for lua code
Add a shared API for lua code through a module named clusterio.
This commit is contained in:
1 parent
221dc855f4
commit
66aa7e1e43
9 files changed
+139
-43
No files matched your search
@@ -11,6 +11,7 @@ const link = require("lib/link");
|
||||
const plugin = require("lib/plugin");
|
||||
const errors = require("lib/errors");
|
||||
const prometheus = require('lib/prometheus');
|
||||
const luaTools = require('lib/luaTools');
|
||||
|
||||
|
||||
/**
|
||||
@@ -175,7 +176,7 @@ class Instance extends link.Link{
|
||||
|
||||
module = Object.assign({
|
||||
version: plugin.info.version,
|
||||
dependencies: {},
|
||||
dependencies: { 'clusterio': '*' },
|
||||
path: modulePath,
|
||||
load: [],
|
||||
require: [],
|
||||
@@ -203,7 +204,7 @@ class Instance extends link.Link{
|
||||
|
||||
module = Object.assign({
|
||||
path: path.join('modules', entry.name),
|
||||
dependencies: {},
|
||||
dependencies: { 'clusterio': '*' },
|
||||
load: [],
|
||||
require: [],
|
||||
}, module);
|
||||
@@ -218,12 +219,22 @@ class Instance extends link.Link{
|
||||
});
|
||||
|
||||
await this.server.start(saveName);
|
||||
await this.server.disableAchievements()
|
||||
await this.updateInstanceData();
|
||||
|
||||
for (let pluginInstance of this.plugins.values()) {
|
||||
await pluginInstance.onStart();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update instance information on the Factorio side
|
||||
*/
|
||||
async updateInstanceData() {
|
||||
let name = luaTools.escapeString(this.config.name);
|
||||
await this.server.sendRcon(`/sc clusterio_private.update_instance(${this.config.id}, "${name}")`, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the instance
|
||||
*/
|
||||
|
||||
@@ -223,7 +223,8 @@ The following entries are supported in the module.json file:
|
||||
node-semver package for a full description of what operators are
|
||||
supported. The events for dependencies is invoked before the events
|
||||
of the dependent, and starting an instance will fail if the
|
||||
dependencies cannot be satisfied.
|
||||
dependencies cannot be satisfied. If not specified it will default
|
||||
to depending on `clusterio`.
|
||||
- `require`:
|
||||
Lua files to require in `control.lua`. This should only really be
|
||||
needed if you want to make a global function available for use in
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Escapes a string for inclusion into a lua string
|
||||
*/
|
||||
function escapeString(content) {
|
||||
return content
|
||||
.replace(/\\/g, "\\\\")
|
||||
.replace(/"/g, '\\"')
|
||||
.replace(/'/g, "\\'")
|
||||
.replace(/\0/g, "\\0")
|
||||
.replace(/\n/g, "\\n")
|
||||
.replace(/\r/g, "\\r")
|
||||
;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
escapeString,
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
local api = {}
|
||||
|
||||
|
||||
-- Table of events raised by clusterio
|
||||
api.events = {
|
||||
-- Raised after the name and id of an instance has been updated
|
||||
-- This may occur even if the id and name didn't change.
|
||||
|
||||
-- Event data:
|
||||
-- instance_id: The id of the instance.
|
||||
-- instance_name: the name of the instance.
|
||||
on_instance_updated = script.generate_event_name(),
|
||||
}
|
||||
|
||||
|
||||
return api
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
local api = require('modules/clusterio/api')
|
||||
|
||||
|
||||
local impl = {}
|
||||
|
||||
local function init()
|
||||
if not global.clusterio then
|
||||
global.clusterio = {
|
||||
instance_id = nil,
|
||||
instance_name = nil,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
-- Internal API
|
||||
clusterio_private = {}
|
||||
function clusterio_private.update_instance(new_id, new_name)
|
||||
init()
|
||||
global.clusterio.instance_id = new_id
|
||||
global.clusterio.instance_name = new_name
|
||||
script.raise_event(api.events.on_instance_updated, {
|
||||
instance_id = new_id,
|
||||
instance_name = new_name,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
function impl.add_remote_interface()
|
||||
remote.add_interface('clusterio_api', {
|
||||
-- Returns a table of events raised by clusterio
|
||||
get_events = function()
|
||||
return api.events
|
||||
end,
|
||||
|
||||
-- Returns the instance id the game is run under
|
||||
-- This may change over time and/or be nil.
|
||||
get_instance_id = function()
|
||||
init()
|
||||
return global.clusterio.instance_id
|
||||
end,
|
||||
|
||||
-- Returns the name of the instance the game runs under.
|
||||
-- This may change over time and/or be nil.
|
||||
get_instance_name = function()
|
||||
init()
|
||||
return global.clusterio.instance_name
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
return impl
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "clusterio",
|
||||
"version": "0.0.0",
|
||||
"dependencies": {},
|
||||
"load": ["impl.lua"]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
const plugin = require("lib/plugin");
|
||||
const luaTools = require("lib/luaTools");
|
||||
|
||||
|
||||
/**
|
||||
@@ -8,20 +9,6 @@ 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);
|
||||
@@ -34,7 +21,7 @@ class InstancePlugin extends plugin.BaseInstancePlugin {
|
||||
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)}')`, true);
|
||||
await this.instance.server.sendRcon(`/sc game.print('${luaTools.escapeString(content)}')`, true);
|
||||
}
|
||||
|
||||
async onOutput(output) {
|
||||
@@ -54,5 +41,4 @@ module.exports = {
|
||||
|
||||
// For testing only
|
||||
_removeTags: removeTags,
|
||||
_escapeLuaString: escapeLuaString,
|
||||
}
|
||||
@@ -19,30 +19,6 @@ describe("global_chat plugin", function() {
|
||||
});
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
const assert = require('assert').strict;
|
||||
|
||||
const luaTools = require('lib/luaTools');
|
||||
|
||||
|
||||
describe("lib/luaTools", function() {
|
||||
describe("escapeString()", function() {
|
||||
it("should escape backslashes", function() {
|
||||
assert.equal(luaTools.escapeString("\\a"), "\\\\a");
|
||||
});
|
||||
it("should escape double quotes", function() {
|
||||
assert.equal(luaTools.escapeString('"a"'), '\\"a\\"');
|
||||
});
|
||||
it("should escape single quotes", function() {
|
||||
assert.equal(luaTools.escapeString("'a'"), "\\'a\\'");
|
||||
});
|
||||
it("should escape nul bytes", function() {
|
||||
assert.equal(luaTools.escapeString("a\0b"), "a\\0b");
|
||||
});
|
||||
it("should escape newlines", function() {
|
||||
assert.equal(luaTools.escapeString("a\nb"), "a\\nb");
|
||||
});
|
||||
it("should escape carriage return", function() {
|
||||
assert.equal(luaTools.escapeString("a\rb"), "a\\rb");
|
||||
});
|
||||
it("should escape all combined", function() {
|
||||
assert.equal(luaTools.escapeString("a\\b\"c'd\0e\nf\rg"), "a\\\\b\\\"c\\'d\\0e\\nf\\rg");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user