-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrcon.js
executable file
·300 lines (289 loc) · 12 KB
/
rcon.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.rconConsole = void 0;
process.title = 'rcon';
const commander = require('commander');
const Rcon = require('rcon');
const child_process = require("child_process");
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
});
const fs = require('fs');
const semver = require('semver');
const latestVersion = semver.clean(child_process.execSync('npm view rcon-console version').toString());
const version = semver.clean(require('./package.json').version);
const outOfDate = semver.lt(version, latestVersion);
const versionDiff = semver.diff(version, latestVersion);
const ora = require("ora");
var versionHandler = ora({ discardStdin: false, color: "red" });
var authenticate = ora({ text: 'Authenticating...', discardStdin: false, color: "yellow" });
var command = ora({ text: "Something went wrong, please try again", discardStdin: false, color: "cyan" });
var action = ora({ discardStdin: false, color: "green" });
//var credentials = require('./credentials.json');
var actionArguments;
const defaultConfig = require('./lib/lock/default_config.json');
var configExists = fs.existsSync('./lib/config.json');
var config = configExists ? require('./lib/config.json') : addConfig();
const questions = require('./lib/lock/configuration_questions.json');
var question = 1;
const { emit, stdin } = require('process');
var authenticated = false;
var queuedCommands = [];
config.options.tcp = config.options.protocol.toLowerCase() === "tcp" ? true : false;
const rcon = new Rcon(config.host, config.port, config.password, config.options);
var configuring = false;
class rconConsole {
constructor() {
versionHandler.start("Checking for updates...");
try {
if (outOfDate) {
if (versionDiff == "prerelease" && config.betaUpdates) {
versionHandler.warn('you are a' + versionDiff + ' version behind, run `rcon update` to update to version ' + latestVersion);
} else {
versionHandler.warn('you are a' + versionDiff + ' version behind, run `rcon update` to update to version ' + latestVersion);
}
}
} catch (error) {
versionHandler.fail("Error while checking for updates\n" + error);
}
commander
.showHelpAfterError()
.showSuggestionAfterError()
.version(version)
.arguments('[reset|uninstall|rebuild|help|config]')
.addHelpText('after', `
Please provide a command:
[command] command to run once connected (put qotations if more than two words)
uninstall uninstall the program from your device
rebuild rebuild rcon-console (use if crashing)
update updates rcon-console
config view your config.json
config edit edit your config.json
config reset reset your the configuration
See the wiki for help: https://github.com/bloomkd46/rcon-console/wiki
`)
.option('-H, --host <host>', 'This is the host that the Rcon will connect to (default: ' + config.host + ")", (p) => cache("host", p))
.option('-P, --port <port>', 'This is the port that the Rcon connection will be established on (default: ' + config.port + ")", (p) => cache("port", p))
.option('-p, --password <password>', 'specify the rcon password (default: ' + config.password + ")", (p) => cache("password", p))
.option('--protocol <protocol>', 'choose which rcon protocol, TCP or UDP (default: ' + config.options.protocol + ")", (p) => cache("options", p.toLocaleLowerCase ? true : false, "tcp"))
.option('-C, --challenge <true/false>', 'choose wether to use the rcon challenge protocal (default: ' + config.options.challenge + ")", (p) => cache("options", p, "challenge"))
.option('-S, --save', 'save your port, host, and password to the config.json', () => updateConfig())
.action((cmd, cmdArgs) => {
console.log(cmd);
this.action = cmd;
actionArguments = cmdArgs;
})
.parse();
switch (this.action) {
case 'uninstall': {
action.start("Uninstalling...");
child_process.exec('npm uninstall rcon-console', (error) => {
if (error) {
action.fail("Error: Unable to uninstall rcon-console\n" + error);
return;
} else {
action.succeed("Successfully uninstalled rcon-console");
}
});
process.exit(1);
}
case 'rebuild': {
action.start('Rebuilding...');
child_process.exec('npm install -g rcon-console@' + version, (error) => {
if (error) {
action.fail(`exec error: ${error}`);
return;
}
action.succeed(`successfully rebuilt rcon-console`);
process.exit(1);
});
break;
}
case 'update': {
action.start("Updating from v" + version + " to v" + latestVersion);
if (outOfDate) {
child_process.exec('npm install -g rcon-console@' + latestVersion, (error) => {
if (error) {
action.fail(`exec error: ${error}`);
return;
}
action.succeed(`successfully updated rcon-console to v` + latestVersion);
process.exit(1);
});
} else {
action.fail("Already Up-To-Date with v" + version);
}
process.exit(1);
}
case 'help': {
commander.outputHelp();
break;
}
case 'config': {
if (actionArguments === "edit") {
configuring = true;
action.info("Entering configuration mode, type nothing to use the default value");
action.info(questions[question + "-description"] + " (default: " + defaultConfig[questions[question]] + ")");
} else if (actionArguments === "reset") {
action.start("Reseting configuration...");
try {
fs.writeFileSync('./lib/config.json', JSON.stringify(require('./lib/lock/default_config.json'), null, 2));
action.succeed("configuration successfully reset");
} catch (error) {
action.fail("Error: Unable to reset configuration\n" + error);
}
process.exit(0);
} else {
action.start("Loading configuration...");
try {
action.succeed(JSON.stringify(config, null, 2))
} catch (error) {
action.fail("Error loading configuration " + error)
}
}
break;
}
default: {
authenticate.start("Authenticating...");
rcon.connect();
if (this.action) {
command.start(actionArguments != null ? this.action + " " + actionArguments : this.action);
if (authenticated) rcon.send(actionArguments != null ? this.action + " " + actionArguments : this.action); else queuedCommands.push(actionArguments != null ? this.action + " " + actionArguments : this.action);
}
break;
}
}
}
}
readline.on('line', (content) => {
//console.log(`Received: ${content}`);
if (configuring && question < questions.length) {
configure(question, content);
question++;
} else if (configuring) {
updateConfig();
configuring = false;
authenticate.start("Authenticating...");
rcon.connect();
} else {
command.start(content);
if (authenticated) rcon.send(content); else queuedCommands.push(content);
}
/*if (question > 6 && configuring) { configuring = false; updateConfig(); authenticate.start("Authenticating..."); rcon.connect() }
if (configuring) {
if (question > 3) {
cache("options", content, questions[question + 1]);
if (question == 5) {
action.info("Would you like to enable keepAlive? (true/false)");
} else if (question == 4) action.info("would you like to use the challenge protocal? (true/false)");
} else {
cache(questions[question], content);
if (question == 3) action.info("would you like to use TCP or UDP? (true for TCP, false for UDP)"); else action.info("what would you like to set the " + questions[question + 1] + " to?");
}
question++;
}*/
}).on('SIGINT', () => {
authenticate.start("Shutting Down...");
setTimeout(() => {
try {
rcon.disconnect();
authenticate.succeed("Successfully shut down");
} catch (error) {
authenticate.fail("Error while trying to shut down\n" + error);
}
process.exit(1);
}, 500);
});
rcon.on('auth', function () {
authenticate.succeed('Authenticated');
authenticated = true;
// You must wait until this event is fired before sending any commands,
// otherwise those commands will fail.
//
// This example buffers any commands sent before auth finishes, and sends
// them all once the connection is available.
for (var i = 0; i < queuedCommands.length; i++) {
command.start(queuedCommands[i]);
rcon.send(queuedCommands[i]);
}
queuedCommands = [];
}).on('response', function (str) {
if (str.includes("Unknown or incomplete command, see below for error")) command.fail("Unknown or incomplete command, see below for error\n" + str.slice(50)); else command.succeed(str);
}).on('error', function (err) {
if (!authenticated) authenticate.fail("Authentication failed\n" + JSON.stringify(err, null, 2)); else command.fail("Error encountered: " + err);
}).on('end', function () {
console.log("Connection closed, Reconnecting...");
authenticated = false;
if (config.keepAlive) {
authenticate.start("Authenticating...");
rcon.connect();
} else {
process.exit(1);
}
});
function cache(key, value, _key2) {
action.start("Setting " + key + " to " + value);
try {
if (_key2) {
config[key][_key2] = value;
rcon[key + "." + _key2] = value;
action.succeed("Successfully set " + key + "." + _key2 + " to " + value);
config.options.tcp = config.options.protocol.toLocaleLowerCase === "tcp" ? true : false;
} else {
config[key] = value;
rcon[key] = value;
action.succeed("Successfully set " + key + " to " + value);
}
} catch (error) {
if (_key2) {
action.fail("Failed to set " + key + "." + _key2 + " to " + value + "\n" + error);
} else {
action.fail("Failed to set " + key + " to " + value + "\n" + error);
}
}
}
function updateConfig() {
action.start("Reseting configuration...");
try {
config.options.tcp = config.options.protocol.toLocaleLowerCase === "tcp" ? true : false;
fs.writeFileSync('./lib/config.json', JSON.stringify(require('./lib/lock/default_config.json'), null, 2));
action.succeed("configuration successfully reset");
//this.action = 'reset';
} catch (error) {
action.fail("Error: Unable to reset configuration\n" + error);
}
action.start("Updating Configuration...");
try {
fs.writeFileSync('./lib/config.json', JSON.stringify(config, null, 2));
config = require('./lib/config.json');
action.succeed("Successfully updated your configuration");
} catch (error) {
action.fail("Failed to update configuration, " + error);
}
}
function configure(questionn, response) {
if (questionn > questions["options-after"]) {
cache("options", response != " " ? response : defaultConfig[questionn], questions[questionn]);
config.options.tcp = config.options.protocol.toLocaleLowerCase === "tcp" ? true : false;
} else {
cache(questions[questionn], response != "" ? response : defaultConfig[questions[questionn]]);
}
action.info(questions[(questionn + 1) + "-description"] + " (default: " + defaultConfig[questions[questionn + 1]] + ")");
}
function addConfig() {
action.start("Adding configuration...");
try {
fs.writeFileSync('./lib/config.json', JSON.stringify(require('./lib/lock/default_config.json'), null, 2));
action.succeed("configuration successfully added");
return require('./lib/config.json');
} catch (error) {
action.fail("Error: Unable to add configuration\n" + error);
}
}
exports.rconConsole = rconConsole;
function bootstrap() {
return new rconConsole();
}
bootstrap();