I am trying to test somehow the rcon connection, but I don't know how normally do you check if the connection is valid and successful.
I mean there isn't really a persistent connection, but how could I ensure the RCON password is valid and the server received without doing anything particular on the server.
Right now this is how I send a command:
Could someone point me to the right direction, please?
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
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
const dgram = require('dgram');
class RCON {
static sendCommand(ip, port, password, command) {
return new Promise((resolve, reject) => {
console.log(`\nSending RCON command to ${ip}:${port}`);
console.log(`Command: ${command}`);
const client = dgram.createSocket('udp4');
const header = Buffer.from([0x01, 0x00, 0xF2]);
const passwordLength = Buffer.from([password.length]);
const commandLength = Buffer.alloc(2);
const commandBuffer = Buffer.from(command, 'latin1');
commandLength.writeUInt16LE(commandBuffer.length, 0);
const packet = Buffer.concat([
header,
passwordLength,
Buffer.from(password),
commandLength,
commandBuffer
]);
const operationTimeout = setTimeout(() => {
if (client) {
client.close();
}
console.log('Operation timed out - No response from server');
reject(new Error('RCON request timed out'));
}, 2000);
client.on('error', (err) => {
console.error('RCON socket error:', err);
clearTimeout(operationTimeout);
if (client) {
client.close();
}
reject(err);
});
client.on('message', (msg) => {
clearTimeout(operationTimeout);
const responseHeader = msg.slice(0, 3);
if (msg.length === 7) {
const responseType = msg[4];
if (responseType === 0x33) { // "3" - Server is blocking us
console.log('Server is blocking RCON commands - Too many failed attempts');
client.close();
reject(new Error('RCON blocked - Too many failed attempts'));
return;
}
if (responseType === 0x34) { // "4" - Wrong password
console.log('Wrong RCON password');
client.close();
reject(new Error('Wrong RCON password'));
return;
}
}
let responseContent;
if (msg.length > 5) {
const contentBuffer = msg.slice(5);
responseContent = contentBuffer.toString('utf16le').replace(/\u0000/g, '');
} else {
responseContent = msg.slice(3).toString('latin1');
}
console.log('\nResponse:', responseContent);
client.close();
resolve({ success: true, response: responseContent });
});
client.bind(() => {
client.send(packet, 0, packet.length, port, ip, (err) => {
if (err) {
console.error('Error sending RCON command:', err);
clearTimeout(operationTimeout);
if (client) {
client.close();
}
reject(err);
} else {
console.log('Command sent successfully, waiting for response...');
}
});
});
});
}
}
module.exports = RCON;