forked from garrettjoecox/scriptserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
115 lines (96 loc) · 2.73 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const EventsEmitter = require('events');
const { spawn } = require('child_process');
const defaultsDeep = require('lodash.defaultsdeep');
const get = require('lodash.get');
const Rcon = require('./Rcon');
const defaultConfig = {
flavor: 'vanilla',
core: {
jar: 'minecraft_server.jar',
args: ['-Xmx2G'],
pipeIO: true,
spawnOpts: {
stdio: ['pipe', 'pipe', 'inherit'],
},
rcon: {
host: 'localhost',
port: '25575',
password: '0000',
buffer: 50,
},
flavorSpecific: {
default: {
rconRunning: /^\[[\d:]{8}\] \[RCON Listener #1\/INFO\]: RCON running/i,
},
spigot: {
rconRunning: /^\[[\d:]{8} INFO\]: RCON running/i,
},
sponge: {
rconRunning: /^\[[\d:]{8} INFO\]: RCON running/i,
},
glowstone: {
rconRunning: /^[\d:]{8} \[INFO\] Successfully bound rcon/i,
},
},
},
};
class ScriptServer extends EventsEmitter {
constructor(config = {}) {
super();
this.config = defaultsDeep({}, config, defaultConfig);
this.modules = [];
// RCON
this.rcon = new Rcon(this.config.core.rcon);
this.on('console', (l) => {
if (this.rcon.state !== 'connected') {
const rconRunning = get(this.config.core, `flavorSpecific.${this.config.flavor}.rconRunning`, this.config.core.flavorSpecific.default.rconRunning);
if (l.match(rconRunning)) this.rcon.connect();
}
});
process.on('exit', () => this.stop());
process.on('close', () => this.stop());
}
start() {
if (this.spawn) throw new Error('Server already started');
const args = this.config.core.args.concat('-jar', this.config.core.jar, 'nogui');
this.spawn = spawn('java', args, this.config.core.spawnOpts);
if (this.config.core.pipeIO) {
this.spawn.stdout.pipe(process.stdout);
process.stdin.pipe(this.spawn.stdin);
}
this.spawn.stdout.on('data', (d) => {
// Emit console
d.toString().split('\n').forEach((l) => {
if (l) this.emit('console', l.trim());
});
});
return this;
}
stop() {
if (this.spawn) {
this.rcon.disconnect();
this.spawn.kill();
this.spawn = null;
}
return this;
}
use(module) {
if (typeof module !== 'function') throw new Error('A module must be a function');
if (this.modules.filter(m => m === module).length === 0) {
this.modules.push(module);
module.call(this);
}
return this;
}
send(command) {
return new Promise((resolve) => {
this.rcon.exec(command, result => resolve(result));
});
}
sendConsole(command) {
return new Promise((resolve) => {
this.spawn.stdin.write(`${command}\n`, () => resolve());
});
}
}
module.exports = ScriptServer;