omegga 0.1.74 → 0.1.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.yml +2 -0
- package/.prettierrc +7 -0
- package/README.md +1 -1
- package/package.json +3 -2
- package/src/omegga/matchers/chat.js +11 -13
- package/src/omegga/matchers/version.js +22 -5
- package/src/omegga/plugin/plugin_node_safe/proxyOmegga.js +43 -25
- package/src/omegga/plugin/plugin_node_safe/worker.js +30 -23
- package/src/omegga/server.js +121 -63
- package/src/omegga/wrapper.js +0 -2
- package/src/softconfig.js +1 -0
package/.eslintrc.yml
CHANGED
|
@@ -4,6 +4,7 @@ env:
|
|
|
4
4
|
extends:
|
|
5
5
|
- eslint:recommended
|
|
6
6
|
parser: "@babel/eslint-parser"
|
|
7
|
+
plugins: [prettier]
|
|
7
8
|
parserOptions:
|
|
8
9
|
ecmaVersion: 12
|
|
9
10
|
requireConfigFile: false
|
|
@@ -11,6 +12,7 @@ globals:
|
|
|
11
12
|
Omegga: readonly
|
|
12
13
|
VERBOSE: readonly
|
|
13
14
|
rules:
|
|
15
|
+
prettier/prettier: warn
|
|
14
16
|
indent:
|
|
15
17
|
- error
|
|
16
18
|
- 2
|
package/.prettierrc
ADDED
package/README.md
CHANGED
|
@@ -676,7 +676,7 @@ Register custom `/commands` by returning `{registeredCommands: ['foo', 'bar']}`
|
|
|
676
676
|
| `line` | [brickadiaLog string] | A brickadia console log | |
|
|
677
677
|
| `start` | [{map}] | Run when the brickadia server starts | |
|
|
678
678
|
| `host` | [{name, id}] | Run when the brickadia server detects the host | |
|
|
679
|
-
| `version` | [
|
|
679
|
+
| `version` | [-1 or the CL number] | Run when the brickadia server detects the version | |
|
|
680
680
|
| `unauthorized` | _none_ | Run when the brickadia server fails an auth check | |
|
|
681
681
|
| `join` | [{name, id, state, controller}] | Run when a player joins | |
|
|
682
682
|
| `leave` | [{name, id, state, controller}] | Run when a player leaves | |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omegga",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.75",
|
|
4
4
|
"description": "Brickadia server installer, manager, wrapper, configurator, and automator",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"socket.io": "^2.3.0",
|
|
39
39
|
"strip-ansi": "^6.0.0",
|
|
40
40
|
"update-notifier": "^5.0.0",
|
|
41
|
-
"vm2": "
|
|
41
|
+
"vm2": "3.9.2 || >3.9.4",
|
|
42
42
|
"vue-grid-layout": "^2.3.9"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"eslint-plugin-vue": "^7.0.1",
|
|
54
54
|
"file-loader": "^6.1.0",
|
|
55
55
|
"jsdoc-to-markdown": "^7.0.1",
|
|
56
|
+
"prettier-eslint": "^13.0.0",
|
|
56
57
|
"mini-css-extract-plugin": "^1.0.0",
|
|
57
58
|
"sass": "^1.42.1",
|
|
58
59
|
"sass-loader": "^12.1.0",
|
|
@@ -5,14 +5,15 @@ module.exports = omegga => {
|
|
|
5
5
|
|
|
6
6
|
const exists = name => omegga.players.some(p => p.name === name);
|
|
7
7
|
|
|
8
|
-
const sanitizeMsg = msg =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
const sanitizeMsg = msg =>
|
|
9
|
+
msg
|
|
10
|
+
.toString()
|
|
11
|
+
.replace(/>/g, '>')
|
|
12
|
+
.replace(/&und;/g, '_')
|
|
13
|
+
.replace(/</g, '<')
|
|
14
|
+
.replace(/&scl;/g, ';');
|
|
13
15
|
|
|
14
|
-
const sanitizeName = name => name.toString()
|
|
15
|
-
.replace(/&und;/g, '_');
|
|
16
|
+
const sanitizeName = name => name.toString().replace(/&und;/g, '_');
|
|
16
17
|
|
|
17
18
|
return {
|
|
18
19
|
// listen for chat messages
|
|
@@ -31,10 +32,8 @@ module.exports = omegga => {
|
|
|
31
32
|
if (chatMatch) {
|
|
32
33
|
let { name, message } = chatMatch.groups;
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
message = sanitizeMsg(message);
|
|
37
|
-
}
|
|
35
|
+
name = sanitizeName(name);
|
|
36
|
+
message = sanitizeMsg(message);
|
|
38
37
|
|
|
39
38
|
// no player has this name. probably a bug
|
|
40
39
|
if (!exists(name)) return;
|
|
@@ -51,7 +50,6 @@ module.exports = omegga => {
|
|
|
51
50
|
|
|
52
51
|
return { type: 'kick', name, kicker, reason };
|
|
53
52
|
}
|
|
54
|
-
|
|
55
53
|
},
|
|
56
54
|
// when there's a match, emit the chat message event
|
|
57
55
|
callback({ type, name, kicker, message, reason }) {
|
|
@@ -71,4 +69,4 @@ module.exports = omegga => {
|
|
|
71
69
|
}
|
|
72
70
|
},
|
|
73
71
|
};
|
|
74
|
-
};
|
|
72
|
+
};
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const softconfig = require('../../softconfig');
|
|
4
|
+
|
|
1
5
|
module.exports = omegga => {
|
|
2
6
|
const versionRegExp = /^Using libcurl (?<curlversion>.+)$/;
|
|
3
|
-
let
|
|
7
|
+
let version;
|
|
4
8
|
return {
|
|
5
9
|
pattern(_line, logMatch) {
|
|
6
10
|
// if the version has already been found - ignore this matcher
|
|
7
|
-
if (
|
|
11
|
+
if (version || !logMatch) return;
|
|
8
12
|
|
|
9
13
|
const { generator, data } = logMatch.groups;
|
|
10
14
|
|
|
@@ -13,10 +17,23 @@ module.exports = omegga => {
|
|
|
13
17
|
|
|
14
18
|
const match = data.match(versionRegExp);
|
|
15
19
|
|
|
20
|
+
const branch = omegga.config.server.branch ?? 'main-server';
|
|
21
|
+
const configPath = path.join(
|
|
22
|
+
softconfig.BRICKADIA_INSTALLS,
|
|
23
|
+
branch.substring(Math.max(0, branch.indexOf(':') + 1)) + '.json'
|
|
24
|
+
);
|
|
25
|
+
|
|
16
26
|
// base game version on curl version
|
|
17
27
|
if (match) {
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
try {
|
|
29
|
+
version = Number(
|
|
30
|
+
JSON.parse(fs.readFileSync(configPath)).version.substring(2)
|
|
31
|
+
);
|
|
32
|
+
} catch (e) {
|
|
33
|
+
console.error('!>'.red, 'Unable to read branch config file: ', e);
|
|
34
|
+
version = -1;
|
|
35
|
+
}
|
|
36
|
+
return version;
|
|
20
37
|
}
|
|
21
38
|
},
|
|
22
39
|
// when there's a match, emit the chat message event
|
|
@@ -25,4 +42,4 @@ module.exports = omegga => {
|
|
|
25
42
|
omegga.version = version;
|
|
26
43
|
},
|
|
27
44
|
};
|
|
28
|
-
};
|
|
45
|
+
};
|
|
@@ -6,30 +6,46 @@ const Omegga = require('../../server.js');
|
|
|
6
6
|
const commandInjector = require('../../commandInjector.js');
|
|
7
7
|
|
|
8
8
|
// bootstrap the proxy with initial omegga data
|
|
9
|
-
const bootstrap =
|
|
9
|
+
const bootstrap = omegga => ({
|
|
10
10
|
'plugin:players:raw': [omegga.players.map(p => p.raw())],
|
|
11
|
-
bootstrap: [
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
11
|
+
bootstrap: [
|
|
12
|
+
{
|
|
13
|
+
host: Object.freeze({ ...omegga.host }),
|
|
14
|
+
version: omegga.version,
|
|
15
|
+
verbose: global.VERBOSE,
|
|
16
|
+
savePath: omegga.savePath,
|
|
17
|
+
path: omegga.path,
|
|
18
|
+
configPath: omegga.configPath,
|
|
19
|
+
starting: omegga.starting,
|
|
20
|
+
started: omegga.started,
|
|
21
|
+
config: omegga.config,
|
|
22
|
+
currentMap: omegga.currentMap
|
|
23
|
+
}
|
|
24
|
+
]
|
|
23
25
|
});
|
|
24
26
|
|
|
25
27
|
// prototypes that can be directly stolen from omegga
|
|
26
28
|
const STEAL_PROTOTYPES = [
|
|
27
|
-
'broadcast',
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'
|
|
32
|
-
'
|
|
29
|
+
'broadcast',
|
|
30
|
+
'whisper',
|
|
31
|
+
'getPlayer',
|
|
32
|
+
'getPlayers',
|
|
33
|
+
'findPlayerByName',
|
|
34
|
+
'getHostId',
|
|
35
|
+
'clearBricks',
|
|
36
|
+
'clearAllBricks',
|
|
37
|
+
'loadBricks',
|
|
38
|
+
'saveBricks',
|
|
39
|
+
'getSavePath',
|
|
40
|
+
'getSaves',
|
|
41
|
+
'writeSaveData',
|
|
42
|
+
'readSaveData',
|
|
43
|
+
'loadSaveData',
|
|
44
|
+
'getSaveData',
|
|
45
|
+
'getRoleSetup',
|
|
46
|
+
'getRoleAssignments',
|
|
47
|
+
'getBanList',
|
|
48
|
+
'getNameCache',
|
|
33
49
|
'changeMap'
|
|
34
50
|
];
|
|
35
51
|
|
|
@@ -46,7 +62,7 @@ class ProxyOmegga extends EventEmitter {
|
|
|
46
62
|
|
|
47
63
|
this.writeln = exec;
|
|
48
64
|
|
|
49
|
-
this.version =
|
|
65
|
+
this.version = -1;
|
|
50
66
|
|
|
51
67
|
this.players = [];
|
|
52
68
|
|
|
@@ -69,12 +85,14 @@ class ProxyOmegga extends EventEmitter {
|
|
|
69
85
|
});
|
|
70
86
|
|
|
71
87
|
// data synchronization
|
|
72
|
-
this.on('host', host => this.host = host);
|
|
73
|
-
this.on('version', version => this.version = version);
|
|
88
|
+
this.on('host', host => (this.host = host));
|
|
89
|
+
this.on('version', version => (this.version = version));
|
|
74
90
|
|
|
75
91
|
// create players from raw constructor data
|
|
76
|
-
this.on(
|
|
77
|
-
|
|
92
|
+
this.on(
|
|
93
|
+
'plugin:players:raw',
|
|
94
|
+
players => (this.players = players.map(p => new Player(this, ...p)))
|
|
95
|
+
);
|
|
78
96
|
|
|
79
97
|
this.on('start', ({ map }) => {
|
|
80
98
|
this.started = true;
|
|
@@ -96,4 +114,4 @@ for (const fn of STEAL_PROTOTYPES) {
|
|
|
96
114
|
ProxyOmegga.prototype[fn] = Omegga.prototype[fn];
|
|
97
115
|
}
|
|
98
116
|
|
|
99
|
-
module.exports = { ProxyOmegga, bootstrap };
|
|
117
|
+
module.exports = { ProxyOmegga, bootstrap };
|
|
@@ -20,11 +20,11 @@ let messageCounter = 0;
|
|
|
20
20
|
const parent = new EventEmitter();
|
|
21
21
|
|
|
22
22
|
// handle message passing
|
|
23
|
-
parentPort.on('message', ({action, args}) => parent.emit(action, ...args));
|
|
23
|
+
parentPort.on('message', ({ action, args }) => parent.emit(action, ...args));
|
|
24
24
|
|
|
25
25
|
// emit a message to the parent port - async wait for a reponse
|
|
26
26
|
const emit = (action, ...args) => {
|
|
27
|
-
const messageId = 'message:' +
|
|
27
|
+
const messageId = 'message:' + messageCounter++;
|
|
28
28
|
|
|
29
29
|
let rejectFn;
|
|
30
30
|
// promise waits for the message to resolve
|
|
@@ -35,7 +35,7 @@ const emit = (action, ...args) => {
|
|
|
35
35
|
|
|
36
36
|
try {
|
|
37
37
|
// post the message
|
|
38
|
-
parentPort.postMessage({action, args: [messageId, ...args]});
|
|
38
|
+
parentPort.postMessage({ action, args: [messageId, ...args] });
|
|
39
39
|
} catch (err) {
|
|
40
40
|
rejectFn(err);
|
|
41
41
|
}
|
|
@@ -51,7 +51,7 @@ const exec = cmd => emit('exec', cmd);
|
|
|
51
51
|
const omegga = new ProxyOmegga(exec);
|
|
52
52
|
|
|
53
53
|
// add plugin fetcher
|
|
54
|
-
omegga.getPlugin = async
|
|
54
|
+
omegga.getPlugin = async name => {
|
|
55
55
|
let plugin = await emit('getPlugin', name);
|
|
56
56
|
if (plugin) {
|
|
57
57
|
plugin.emit = async (ev, ...args) => {
|
|
@@ -70,7 +70,7 @@ const store = {
|
|
|
70
70
|
delete: key => emit('store.delete', key),
|
|
71
71
|
wipe: () => emit('store.wipe'),
|
|
72
72
|
count: () => emit('store.count'),
|
|
73
|
-
keys: () => emit('store.keys')
|
|
73
|
+
keys: () => emit('store.keys')
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
// generic brickadia events are forwarded to the proxy omegga
|
|
@@ -78,15 +78,14 @@ parent.on('brickadiaEvent', (type, ...args) => {
|
|
|
78
78
|
if (!vm) return;
|
|
79
79
|
try {
|
|
80
80
|
omegga.emit(type, ...args);
|
|
81
|
-
} catch(e) {
|
|
82
|
-
console.log('error in brickadia event', e);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
console.log('error in brickadia event', e?.stack ?? e.toString());
|
|
83
83
|
}
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
// create the node vm
|
|
87
|
-
function createVm(pluginPath, {builtin=['*'], external=true}={}) {
|
|
88
|
-
if (vm !== undefined)
|
|
89
|
-
return [false, 'vm is already created'];
|
|
87
|
+
function createVm(pluginPath, { builtin = ['*'], external = true } = {}) {
|
|
88
|
+
if (vm !== undefined) return [false, 'vm is already created'];
|
|
90
89
|
|
|
91
90
|
// create the vm
|
|
92
91
|
vm = new NodeVM({
|
|
@@ -95,12 +94,13 @@ function createVm(pluginPath, {builtin=['*'], external=true}={}) {
|
|
|
95
94
|
require: {
|
|
96
95
|
external,
|
|
97
96
|
builtin,
|
|
98
|
-
root: pluginPath
|
|
97
|
+
root: pluginPath
|
|
99
98
|
}
|
|
100
99
|
});
|
|
101
100
|
|
|
102
101
|
// plugin log generator function
|
|
103
|
-
const ezLog = (logFn, name, symbol) => (...args) =>
|
|
102
|
+
const ezLog = (logFn, name, symbol) => (...args) =>
|
|
103
|
+
console[logFn](name.underline, symbol, ...args);
|
|
104
104
|
|
|
105
105
|
// special formatting for stdout
|
|
106
106
|
vm.on('console.log', ezLog('log', pluginName, '>>'.green));
|
|
@@ -120,8 +120,8 @@ function createVm(pluginPath, {builtin=['*'], external=true}={}) {
|
|
|
120
120
|
try {
|
|
121
121
|
pluginCode = fs.readFileSync(file);
|
|
122
122
|
} catch (e) {
|
|
123
|
-
emit('error', 'failed to read plugin source: ' + e.toString());
|
|
124
|
-
throw 'failed to read plugin source: ' + e.toString();
|
|
123
|
+
emit('error', 'failed to read plugin source: ' + e?.stack ?? e.toString());
|
|
124
|
+
throw 'failed to read plugin source: ' + e?.stack ?? e.toString();
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
// proxy the plugin out of the vm
|
|
@@ -131,10 +131,14 @@ function createVm(pluginPath, {builtin=['*'], external=true}={}) {
|
|
|
131
131
|
} catch (e) {
|
|
132
132
|
emit('error', 'plugin failed to init');
|
|
133
133
|
console.log(e);
|
|
134
|
-
throw 'plugin failed to init: ' + e.toString();
|
|
134
|
+
throw 'plugin failed to init: ' + e?.stack ?? e.toString();
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
-
if (
|
|
137
|
+
if (
|
|
138
|
+
!PluginClass ||
|
|
139
|
+
typeof PluginClass !== 'function' ||
|
|
140
|
+
typeof PluginClass.prototype !== 'object'
|
|
141
|
+
) {
|
|
138
142
|
PluginClass = undefined;
|
|
139
143
|
emit('error', 'plugin does not export a class');
|
|
140
144
|
throw 'plugin does not export a class';
|
|
@@ -154,7 +158,7 @@ function createVm(pluginPath, {builtin=['*'], external=true}={}) {
|
|
|
154
158
|
}
|
|
155
159
|
|
|
156
160
|
// kill this plugin
|
|
157
|
-
parent.on('kill',
|
|
161
|
+
parent.on('kill', resp => {
|
|
158
162
|
emit(resp);
|
|
159
163
|
process.exit(0);
|
|
160
164
|
});
|
|
@@ -168,7 +172,7 @@ parent.on('name', (resp, name) => {
|
|
|
168
172
|
});
|
|
169
173
|
|
|
170
174
|
// get memory usage for this plugin
|
|
171
|
-
parent.on('mem',
|
|
175
|
+
parent.on('mem', resp => emit(resp, 'mem', process.memoryUsage()));
|
|
172
176
|
|
|
173
177
|
// create the vm
|
|
174
178
|
parent.on('load', (resp, pluginPath, options) => {
|
|
@@ -176,7 +180,7 @@ parent.on('load', (resp, pluginPath, options) => {
|
|
|
176
180
|
createVm(pluginPath, options);
|
|
177
181
|
emit(resp, true);
|
|
178
182
|
} catch (err) {
|
|
179
|
-
console.error('error creating vm', err);
|
|
183
|
+
console.error('error creating vm', err?.stack ?? err.toString());
|
|
180
184
|
emit(resp, false);
|
|
181
185
|
}
|
|
182
186
|
});
|
|
@@ -190,16 +194,19 @@ parent.on('start', async (resp, config) => {
|
|
|
190
194
|
const result = await pluginInstance.init();
|
|
191
195
|
// if a plugin init returns a list of strings, treat them as the list of commands
|
|
192
196
|
if (typeof result === 'object' && result) {
|
|
193
|
-
|
|
194
197
|
// if registeredCommands is in the results, register the provided strings as commands
|
|
195
198
|
const cmds = result.registeredCommands;
|
|
196
|
-
if (
|
|
199
|
+
if (
|
|
200
|
+
cmds &&
|
|
201
|
+
cmds instanceof Array &&
|
|
202
|
+
cmds.every(i => typeof i === 'string')
|
|
203
|
+
) {
|
|
197
204
|
emit('command.registers', JSON.stringify(cmds));
|
|
198
205
|
}
|
|
199
206
|
}
|
|
200
207
|
emit(resp, true);
|
|
201
208
|
} catch (err) {
|
|
202
|
-
emit('error', 'error starting plugin', JSON.stringify(err));
|
|
209
|
+
emit('error', 'error starting plugin', err?.stack ?? JSON.stringify(err));
|
|
203
210
|
emit(resp, false);
|
|
204
211
|
console.error(err);
|
|
205
212
|
}
|
|
@@ -214,7 +221,7 @@ parent.on('stop', async resp => {
|
|
|
214
221
|
pluginInstance = undefined;
|
|
215
222
|
emit(resp, true);
|
|
216
223
|
} catch (err) {
|
|
217
|
-
emit('error', 'error stopping plugin', err
|
|
224
|
+
emit('error', 'error stopping plugin', err?.stack ?? toString());
|
|
218
225
|
emit(resp, false);
|
|
219
226
|
}
|
|
220
227
|
});
|
package/src/omegga/server.js
CHANGED
|
@@ -14,7 +14,8 @@ const Terminal = require('../cli/terminal.js');
|
|
|
14
14
|
require('colors');
|
|
15
15
|
|
|
16
16
|
const DEFAULT_COMMANDS = require('../info/default_commands.json');
|
|
17
|
-
const MISSING_CMD =
|
|
17
|
+
const MISSING_CMD =
|
|
18
|
+
'"Command not found. Type <color=\\"ffff00\\">/help</> for a list of commands or <color=\\"ffff00\\">/plugins</> for plugin information."';
|
|
18
19
|
|
|
19
20
|
const MATCHERS = [
|
|
20
21
|
require('./matchers/join.js'),
|
|
@@ -42,7 +43,7 @@ const MATCHERS = [
|
|
|
42
43
|
require('./matchers/init.js'),
|
|
43
44
|
// watch loginit for any funny business
|
|
44
45
|
|
|
45
|
-
require('./matchers/mapChange.js')
|
|
46
|
+
require('./matchers/mapChange.js')
|
|
46
47
|
// 'mapchange' event
|
|
47
48
|
];
|
|
48
49
|
|
|
@@ -50,10 +51,8 @@ const MATCHERS = [
|
|
|
50
51
|
|
|
51
52
|
const verboseLog = (...args) => {
|
|
52
53
|
if (!global.VERBOSE) return;
|
|
53
|
-
if (Omegga.log)
|
|
54
|
-
|
|
55
|
-
else
|
|
56
|
-
console.log('V>'.magenta, ...args);
|
|
54
|
+
if (Omegga.log) Omegga.log('V>'.magenta, ...args);
|
|
55
|
+
else console.log('V>'.magenta, ...args);
|
|
57
56
|
};
|
|
58
57
|
|
|
59
58
|
class Omegga extends OmeggaWrapper {
|
|
@@ -72,40 +71,47 @@ class Omegga extends OmeggaWrapper {
|
|
|
72
71
|
* send a console log to the readline terminal or stdout
|
|
73
72
|
* @param {...args} - things to print out
|
|
74
73
|
*/
|
|
75
|
-
static log(...args) {
|
|
74
|
+
static log(...args) {
|
|
75
|
+
(Omegga.terminal || console).log(...args);
|
|
76
|
+
}
|
|
76
77
|
|
|
77
78
|
/**
|
|
78
79
|
* send a console error to the readline terminal or stderr
|
|
79
80
|
* @param {...args} - things to print out
|
|
80
81
|
*/
|
|
81
|
-
static error(...args) {
|
|
82
|
+
static error(...args) {
|
|
83
|
+
(Omegga.terminal || console).error(...args);
|
|
84
|
+
}
|
|
82
85
|
|
|
83
86
|
/**
|
|
84
87
|
* send a console warn to the readline terminal or stdout
|
|
85
88
|
* @param {...args} - things to print out
|
|
86
89
|
*/
|
|
87
|
-
static warn(...args) {
|
|
90
|
+
static warn(...args) {
|
|
91
|
+
(Omegga.terminal || console).warn(...args);
|
|
92
|
+
}
|
|
88
93
|
|
|
89
94
|
/**
|
|
90
95
|
* send a console log when omegga is launched when --verbose
|
|
91
96
|
* @param {...args} message to print
|
|
92
97
|
*/
|
|
93
|
-
static verbose(...args) {
|
|
98
|
+
static verbose(...args) {
|
|
99
|
+
verboseLog(...args);
|
|
100
|
+
}
|
|
94
101
|
|
|
95
102
|
/**
|
|
96
103
|
* send a console log to the readline terminal or console
|
|
97
104
|
* @param {terminal} - readline terminal instance
|
|
98
105
|
*/
|
|
99
106
|
static setTerminal(term) {
|
|
100
|
-
if (term instanceof Terminal)
|
|
101
|
-
Omegga.terminal = term;
|
|
107
|
+
if (term instanceof Terminal) Omegga.terminal = term;
|
|
102
108
|
}
|
|
103
109
|
|
|
104
110
|
/**
|
|
105
111
|
* Omegga instance
|
|
106
112
|
* @constructor
|
|
107
113
|
*/
|
|
108
|
-
constructor(serverPath, cfg, options={}) {
|
|
114
|
+
constructor(serverPath, cfg, options = {}) {
|
|
109
115
|
super(serverPath, cfg);
|
|
110
116
|
this.verbose = global.VERBOSE;
|
|
111
117
|
|
|
@@ -144,7 +150,10 @@ class Omegga extends OmeggaWrapper {
|
|
|
144
150
|
if (!options.noplugin) {
|
|
145
151
|
verboseLog('Creating plugin loader');
|
|
146
152
|
// create the pluginloader
|
|
147
|
-
this.pluginLoader = new PluginLoader(
|
|
153
|
+
this.pluginLoader = new PluginLoader(
|
|
154
|
+
path.join(this.path, soft.PLUGIN_PATH),
|
|
155
|
+
this
|
|
156
|
+
);
|
|
148
157
|
|
|
149
158
|
verboseLog('Creating loading plugins');
|
|
150
159
|
// load all the plugin formats in
|
|
@@ -158,7 +167,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
158
167
|
this.host = undefined;
|
|
159
168
|
|
|
160
169
|
/** @type {String} current game version - may later be turned into CL#### versions */
|
|
161
|
-
this.version =
|
|
170
|
+
this.version = -1;
|
|
162
171
|
|
|
163
172
|
/** @type {Boolean} whether server has started */
|
|
164
173
|
this.started = false;
|
|
@@ -171,7 +180,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
171
180
|
// add all the matchers to the server
|
|
172
181
|
verboseLog('Adding matchers');
|
|
173
182
|
for (const matcher of MATCHERS) {
|
|
174
|
-
const {pattern, callback} = matcher(this);
|
|
183
|
+
const { pattern, callback } = matcher(this);
|
|
175
184
|
this.addMatcher(pattern, callback);
|
|
176
185
|
}
|
|
177
186
|
|
|
@@ -182,7 +191,11 @@ class Omegga extends OmeggaWrapper {
|
|
|
182
191
|
if (this.webserver && this.webserver.database) {
|
|
183
192
|
this.webserver.database.addChatLog('server', {}, 'Server error');
|
|
184
193
|
}
|
|
185
|
-
try {
|
|
194
|
+
try {
|
|
195
|
+
await this.stop();
|
|
196
|
+
} catch (e) {
|
|
197
|
+
Omegga.error(e);
|
|
198
|
+
}
|
|
186
199
|
process.exit();
|
|
187
200
|
});
|
|
188
201
|
|
|
@@ -201,17 +214,18 @@ class Omegga extends OmeggaWrapper {
|
|
|
201
214
|
|
|
202
215
|
// when the process closes, emit the exit signal and stop
|
|
203
216
|
this.on('closed', () => {
|
|
204
|
-
if (this.started)
|
|
205
|
-
|
|
206
|
-
if (!this.stopping)
|
|
207
|
-
this.stop();
|
|
217
|
+
if (this.started) this.emit('exit');
|
|
218
|
+
if (!this.stopping) this.stop();
|
|
208
219
|
});
|
|
209
220
|
|
|
210
221
|
// detect when a missing command is sent
|
|
211
222
|
this.on('cmd', (cmd, name) => {
|
|
212
223
|
// if it's not in the default commands and it's not registered to a plugin,
|
|
213
224
|
// it's okay to send the missing command message
|
|
214
|
-
if (
|
|
225
|
+
if (
|
|
226
|
+
!DEFAULT_COMMANDS.includes(cmd) &&
|
|
227
|
+
(!this.pluginLoader || !this.pluginLoader.isCommand(cmd))
|
|
228
|
+
) {
|
|
215
229
|
this.whisper(name, MISSING_CMD);
|
|
216
230
|
}
|
|
217
231
|
});
|
|
@@ -248,7 +262,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
248
262
|
*/
|
|
249
263
|
async stop() {
|
|
250
264
|
if (!this.started && !this.starting) {
|
|
251
|
-
verboseLog(
|
|
265
|
+
verboseLog("Stop called while server wasn't started or was starting");
|
|
252
266
|
return;
|
|
253
267
|
}
|
|
254
268
|
|
|
@@ -265,8 +279,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
265
279
|
}
|
|
266
280
|
verboseLog('Stopping server');
|
|
267
281
|
super.stop();
|
|
268
|
-
if (this.stopping)
|
|
269
|
-
this.emit('server:stopped');
|
|
282
|
+
if (this.stopping) this.emit('server:stopped');
|
|
270
283
|
this.stopping = false;
|
|
271
284
|
this.started = false;
|
|
272
285
|
this.starting = false;
|
|
@@ -312,8 +325,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
312
325
|
//
|
|
313
326
|
whisper(target, ...messages) {
|
|
314
327
|
// find the target player
|
|
315
|
-
if (typeof target !== 'object')
|
|
316
|
-
target = this.getPlayer(target);
|
|
328
|
+
if (typeof target !== 'object') target = this.getPlayer(target);
|
|
317
329
|
|
|
318
330
|
// whisper the messages to that player
|
|
319
331
|
messages
|
|
@@ -326,31 +338,45 @@ class Omegga extends OmeggaWrapper {
|
|
|
326
338
|
* get a list of players
|
|
327
339
|
* @return {players} - list of players {id: uuid, name: name} objects
|
|
328
340
|
*/
|
|
329
|
-
getPlayers() {
|
|
341
|
+
getPlayers() {
|
|
342
|
+
return this.players.map(p => ({ ...p }));
|
|
343
|
+
}
|
|
330
344
|
|
|
331
345
|
/**
|
|
332
346
|
* Get up-to-date role setup from RoleSetup.json
|
|
333
347
|
* @return {object}
|
|
334
348
|
*/
|
|
335
|
-
getRoleSetup() {
|
|
349
|
+
getRoleSetup() {
|
|
350
|
+
return file.readWatchedJSON(path.join(this.configPath, 'RoleSetup.json'));
|
|
351
|
+
}
|
|
336
352
|
|
|
337
353
|
/**
|
|
338
354
|
* Get up-to-date role assignments from RoleAssignment.json
|
|
339
355
|
* @return {object}
|
|
340
356
|
*/
|
|
341
|
-
getRoleAssignments() {
|
|
357
|
+
getRoleAssignments() {
|
|
358
|
+
return file.readWatchedJSON(
|
|
359
|
+
path.join(this.configPath, 'RoleAssignments.json')
|
|
360
|
+
);
|
|
361
|
+
}
|
|
342
362
|
|
|
343
363
|
/**
|
|
344
364
|
* Get up-to-date ban list from BanList.json
|
|
345
365
|
* @return {object}
|
|
346
366
|
*/
|
|
347
|
-
getBanList() {
|
|
367
|
+
getBanList() {
|
|
368
|
+
return file.readWatchedJSON(path.join(this.configPath, 'BanList.json'));
|
|
369
|
+
}
|
|
348
370
|
|
|
349
371
|
/**
|
|
350
372
|
* Get up-to-date name cache from PlayerNameCache.json
|
|
351
373
|
* @return {object}
|
|
352
374
|
*/
|
|
353
|
-
getNameCache() {
|
|
375
|
+
getNameCache() {
|
|
376
|
+
return file.readWatchedJSON(
|
|
377
|
+
path.join(this.configPath, 'PlayerNameCache.json')
|
|
378
|
+
);
|
|
379
|
+
}
|
|
354
380
|
|
|
355
381
|
/**
|
|
356
382
|
* find a player by name, id, controller, or state
|
|
@@ -358,7 +384,13 @@ class Omegga extends OmeggaWrapper {
|
|
|
358
384
|
* @return {Player}
|
|
359
385
|
*/
|
|
360
386
|
getPlayer(arg) {
|
|
361
|
-
return this.players.find(
|
|
387
|
+
return this.players.find(
|
|
388
|
+
p =>
|
|
389
|
+
p.name === arg ||
|
|
390
|
+
p.id === arg ||
|
|
391
|
+
p.controller === arg ||
|
|
392
|
+
p.state === arg
|
|
393
|
+
);
|
|
362
394
|
}
|
|
363
395
|
|
|
364
396
|
/**
|
|
@@ -369,27 +401,29 @@ class Omegga extends OmeggaWrapper {
|
|
|
369
401
|
findPlayerByName(name) {
|
|
370
402
|
name = name.toLowerCase();
|
|
371
403
|
const exploded = pattern.explode(name);
|
|
372
|
-
return
|
|
373
|
-
|
|
374
|
-
|
|
404
|
+
return (
|
|
405
|
+
this.players.find(p => p.name === name) || // find by exact match
|
|
406
|
+
this.players.find(p => p.name.indexOf(name) > -1) || // find by rough match
|
|
407
|
+
this.players.find(p => p.name.match(exploded))
|
|
408
|
+
); // find by exploded regex match (ck finds cake, tbp finds TheBlackParrot)
|
|
375
409
|
}
|
|
376
410
|
|
|
377
411
|
/**
|
|
378
412
|
* get the host's ID
|
|
379
413
|
* @return {String} - Host Id
|
|
380
414
|
*/
|
|
381
|
-
getHostId() {
|
|
415
|
+
getHostId() {
|
|
416
|
+
return this.host ? this.host.id : '';
|
|
417
|
+
}
|
|
382
418
|
|
|
383
419
|
/**
|
|
384
420
|
* clear a user's bricks (by uuid, name, controller, or player object)
|
|
385
421
|
* @param {String|Object} - player or player identifier
|
|
386
422
|
* @param {Boolean} - quietly clear bricks
|
|
387
423
|
*/
|
|
388
|
-
clearBricks(target, quiet=false) {
|
|
424
|
+
clearBricks(target, quiet = false) {
|
|
389
425
|
// target is a player object, just use that id
|
|
390
|
-
if (typeof target === 'object' && target.id)
|
|
391
|
-
target = target.id;
|
|
392
|
-
|
|
426
|
+
if (typeof target === 'object' && target.id) target = target.id;
|
|
393
427
|
// if the target isn't a uuid already, find the player by name or controller and use that uuid
|
|
394
428
|
else if (typeof target === 'string' && !uuid.match(target)) {
|
|
395
429
|
// only set the target if the player exists
|
|
@@ -397,8 +431,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
397
431
|
target = player && player.id;
|
|
398
432
|
}
|
|
399
433
|
|
|
400
|
-
if (!target)
|
|
401
|
-
return;
|
|
434
|
+
if (!target) return;
|
|
402
435
|
|
|
403
436
|
this.writeln(`Bricks.Clear ${target} ${quiet ? 1 : ''}`);
|
|
404
437
|
}
|
|
@@ -407,7 +440,9 @@ class Omegga extends OmeggaWrapper {
|
|
|
407
440
|
* Clear all bricks on the server
|
|
408
441
|
* @param {Boolean} - quietly clear bricks
|
|
409
442
|
*/
|
|
410
|
-
clearAllBricks(quiet=false) {
|
|
443
|
+
clearAllBricks(quiet = false) {
|
|
444
|
+
this.writeln(`Bricks.ClearAll ${quiet ? 1 : ''}`);
|
|
445
|
+
}
|
|
411
446
|
|
|
412
447
|
/**
|
|
413
448
|
* Save bricks under a name
|
|
@@ -415,8 +450,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
415
450
|
*/
|
|
416
451
|
saveBricks(name) {
|
|
417
452
|
// add quotes around the filename if it doesn't have them (backwards compat w/ plugins)
|
|
418
|
-
if (!(name.startsWith('"') && name.endsWith('"')))
|
|
419
|
-
name = `"${name}"`;
|
|
453
|
+
if (!(name.startsWith('"') && name.endsWith('"'))) name = `"${name}"`;
|
|
420
454
|
this.writeln(`Bricks.Save ${name}`);
|
|
421
455
|
}
|
|
422
456
|
|
|
@@ -428,19 +462,24 @@ class Omegga extends OmeggaWrapper {
|
|
|
428
462
|
* @param {Number} - world Z offset
|
|
429
463
|
* @param {Boolean} - quiet mode
|
|
430
464
|
*/
|
|
431
|
-
loadBricks(name, {offX=0, offY=0, offZ=0, quiet=false}={}) {
|
|
465
|
+
loadBricks(name, { offX = 0, offY = 0, offZ = 0, quiet = false } = {}) {
|
|
432
466
|
// add quotes around the filename if it doesn't have them (backwards compat w/ plugins)
|
|
433
|
-
if (!(name.startsWith('"') && name.endsWith('"')))
|
|
434
|
-
name = `"${name}"`;
|
|
467
|
+
if (!(name.startsWith('"') && name.endsWith('"'))) name = `"${name}"`;
|
|
435
468
|
|
|
436
|
-
this.writeln(
|
|
469
|
+
this.writeln(
|
|
470
|
+
`Bricks.Load ${name} ${offX} ${offY} ${offZ} ${quiet ? 1 : ''}`
|
|
471
|
+
);
|
|
437
472
|
}
|
|
438
473
|
|
|
439
474
|
/**
|
|
440
475
|
* get all saves in the save folder and child folders
|
|
441
476
|
* @return {Array<String>}
|
|
442
477
|
*/
|
|
443
|
-
getSaves() {
|
|
478
|
+
getSaves() {
|
|
479
|
+
return fs.existsSync(this.savePath)
|
|
480
|
+
? glob.sync(this.savePath + '/**/*.brs')
|
|
481
|
+
: [];
|
|
482
|
+
}
|
|
444
483
|
|
|
445
484
|
/**
|
|
446
485
|
* Checks if a save exists and returns an absolute path
|
|
@@ -448,7 +487,10 @@ class Omegga extends OmeggaWrapper {
|
|
|
448
487
|
* @return {String} - Path to string
|
|
449
488
|
*/
|
|
450
489
|
getSavePath(name) {
|
|
451
|
-
const file = path.join(
|
|
490
|
+
const file = path.join(
|
|
491
|
+
this.savePath,
|
|
492
|
+
name.endsWith('.brs') ? name : name + '.brs'
|
|
493
|
+
);
|
|
452
494
|
return fs.existsSync(file) ? file : undefined;
|
|
453
495
|
}
|
|
454
496
|
|
|
@@ -473,14 +515,18 @@ class Omegga extends OmeggaWrapper {
|
|
|
473
515
|
* @param {Boolean} - only read save header data
|
|
474
516
|
* @return {SaveData} - BRS JS Save Data
|
|
475
517
|
*/
|
|
476
|
-
readSaveData(name, nobricks=false) {
|
|
518
|
+
readSaveData(name, nobricks = false) {
|
|
477
519
|
if (typeof name !== 'string')
|
|
478
520
|
throw 'expected name argument for readSaveData';
|
|
479
521
|
|
|
480
522
|
const file = this.getSavePath(name);
|
|
481
523
|
if (!file || !file.startsWith(this.savePath))
|
|
482
524
|
throw 'save file not in Saved/Builds directory';
|
|
483
|
-
if (file)
|
|
525
|
+
if (file)
|
|
526
|
+
return brs.read(fs.readFileSync(file), {
|
|
527
|
+
preview: false,
|
|
528
|
+
bricks: !nobricks
|
|
529
|
+
});
|
|
484
530
|
}
|
|
485
531
|
|
|
486
532
|
/**
|
|
@@ -492,8 +538,12 @@ class Omegga extends OmeggaWrapper {
|
|
|
492
538
|
* @param {Boolean} - quiet mode
|
|
493
539
|
* @return {Promise}
|
|
494
540
|
*/
|
|
495
|
-
async loadSaveData(
|
|
496
|
-
|
|
541
|
+
async loadSaveData(
|
|
542
|
+
data,
|
|
543
|
+
{ offX = 0, offY = 0, offZ = 0, quiet = false } = {}
|
|
544
|
+
) {
|
|
545
|
+
const saveFile =
|
|
546
|
+
this._tempSavePrefix + Date.now() + '_' + this._tempSaveCounter++;
|
|
497
547
|
// write savedata to file
|
|
498
548
|
this.writeSaveData(saveFile, data);
|
|
499
549
|
|
|
@@ -521,7 +571,8 @@ class Omegga extends OmeggaWrapper {
|
|
|
521
571
|
* @return {Promise<SaveData>} - BRS JS Save Data
|
|
522
572
|
*/
|
|
523
573
|
async getSaveData() {
|
|
524
|
-
const saveFile =
|
|
574
|
+
const saveFile =
|
|
575
|
+
this._tempSavePrefix + Date.now() + '_' + this._tempSaveCounter++;
|
|
525
576
|
|
|
526
577
|
// wait for the server to save the file
|
|
527
578
|
await this.watchLogChunk(
|
|
@@ -529,10 +580,13 @@ class Omegga extends OmeggaWrapper {
|
|
|
529
580
|
/^(LogBrickSerializer|LogTemp): (.+)$/,
|
|
530
581
|
{
|
|
531
582
|
first: match => match[0].endsWith(saveFile + '.brs...'),
|
|
532
|
-
last: match =>
|
|
583
|
+
last: match =>
|
|
584
|
+
match[2].match(
|
|
585
|
+
/Saved .+ bricks and .+ components from .+ owners|Error: No bricks in grid!/
|
|
586
|
+
),
|
|
533
587
|
afterMatchDelay: 0,
|
|
534
588
|
timeoutDelay: 30000
|
|
535
|
-
}
|
|
589
|
+
}
|
|
536
590
|
);
|
|
537
591
|
|
|
538
592
|
// read the save file
|
|
@@ -557,8 +611,7 @@ class Omegga extends OmeggaWrapper {
|
|
|
557
611
|
* @return {Promise}
|
|
558
612
|
*/
|
|
559
613
|
async changeMap(map) {
|
|
560
|
-
if(!map)
|
|
561
|
-
return;
|
|
614
|
+
if (!map) return;
|
|
562
615
|
|
|
563
616
|
// ServerTravel requires /Game/Maps/Plate/Plate instead of Plate
|
|
564
617
|
const brName = mapUtils.n2brn(map);
|
|
@@ -569,9 +622,14 @@ class Omegga extends OmeggaWrapper {
|
|
|
569
622
|
{
|
|
570
623
|
timeoutDelay: 30000,
|
|
571
624
|
exec: () => this.writeln(`ServerTravel ${brName}`)
|
|
572
|
-
}
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
const success = !!(
|
|
628
|
+
match &&
|
|
629
|
+
match[0] &&
|
|
630
|
+
match[0].groups &&
|
|
631
|
+
match[0].groups.map
|
|
573
632
|
);
|
|
574
|
-
const success = !!(match && match[0] && match[0].groups && match[0].groups.map);
|
|
575
633
|
return success;
|
|
576
634
|
}
|
|
577
635
|
|
package/src/omegga/wrapper.js
CHANGED
|
@@ -20,8 +20,6 @@ class OmeggaWrapper extends EventEmitter {
|
|
|
20
20
|
this.dataPath = path.join(this.path, soft.DATA_PATH);
|
|
21
21
|
this.#server = new BrickadiaServer(this.dataPath, cfg);
|
|
22
22
|
|
|
23
|
-
this.version = 'a4';
|
|
24
|
-
|
|
25
23
|
// log wrangler wrangles logs... it reads brickadia logs and clumps them together
|
|
26
24
|
this.logWrangler = new LogWrangler(this);
|
|
27
25
|
this.#server.on('line', this.logWrangler.callback);
|
package/src/softconfig.js
CHANGED
|
@@ -20,6 +20,7 @@ module.exports = {
|
|
|
20
20
|
// home directory for omegga config
|
|
21
21
|
PROJECT_NAME,
|
|
22
22
|
CONFIG_HOME,
|
|
23
|
+
BRICKADIA_INSTALLS: path.join(os.homedir(), '.local/share/brickadia-launcher/brickadia-installs'),
|
|
23
24
|
LOCAL_LAUNCHER: path.join(CONFIG_HOME, 'launcher/brickadia-launcher/main-brickadia-launcher'),
|
|
24
25
|
|
|
25
26
|
// path to auth files
|