Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ It was originally created to connect to Minecraft's RCON server.
## Installation

npm:

$ npm install rcon
$ npm install rcon

## Usage

Expand Down Expand Up @@ -52,21 +51,27 @@ If your application may leave the connection idle for a long time, you can eithe
new Rcon instance (and connection) each time you need it, or you can send a ping command
periodically to keep the connection alive.

```javascript
setInterval(() => {
rcon.send('');
}, 30000)
```

## Events

The connection emits the following events:

- .emit('auth')
- .emit('authenticated')

This is sent in response to an authentication request that was successful.

- .emit('end')

The connection was closed from any reason
The connection was closed from any reason.

- .emit('response', str)

There was a response returned to a command/message sent to the server
There was a response returned to a command/message sent to the server.

- .emit('server', str)

Expand Down
32 changes: 16 additions & 16 deletions examples/basic.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
// This minimal example connects and runs the "help" command.
// This minimal example connects and runs the 'help' command.

var Rcon = require('../node-rcon');
const RCON = require('../');

var conn = new Rcon('localhost', 1234, 'password');
const rcon = new RCON('localhost', 25575, 'password');

conn.on('auth', function() {
rcon.on('authenticated', () => {
// You must wait until this event is fired before sending any commands,
// otherwise those commands will fail.
console.log("Authenticated");
console.log("Sending command: help")
conn.send("help");
}).on('response', function(str) {
console.log("Response: " + str);
}).on('error', function(err) {
console.log("Error: " + err);
}).on('end', function() {
console.log("Connection closed");
process.exit();
console.log('Authenticated');
console.log('Sending command: help')
rcon.send('help');
}).on('response', response => {
console.log('Response: ' + response);
}).on('error', error => {
console.error('Error:', error);
}).on('end', () => {
console.log('Connection closed');
process.exit(0);
});

conn.connect();
rcon.connect();

// connect() will return immediately.
//
// If you try to send a command here, it will fail since the connection isn't
// authenticated yet. Wait for the 'auth' event.
// authenticated yet. Wait for the 'authenticated' event.
77 changes: 22 additions & 55 deletions examples/stdio.js
Original file line number Diff line number Diff line change
@@ -1,64 +1,31 @@
// This example reads commands from stdin and sends them on enter key press.
// You need to run `npm install keypress` for this example to work.

var Rcon = require('../node-rcon');
var keypress = require('keypress');
const RCON = require('../');

var conn = new Rcon('localhost', 1234, 'password');
var authenticated = false;
var queuedCommands = [];
const rcon = new RCON('localhost', 1234, 'password');

conn.on('auth', function() {
console.log("Authenticated");
authenticated = true;
rcon.on('authenticated', () => {
console.log('Authenticated');

// 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.
process.stdin.on('data', inputBuffer => {
// Convert buffer to string and take out last 2 characters- return character.
const inputString = inputBuffer.toString().slice(0, -2);

for (var i = 0; i < queuedCommands.length; i++) {
conn.send(queuedCommands[i]);
}
queuedCommands = [];

}).on('response', function(str) {
console.log("Response: " + str);
}).on('error', function(err) {
console.log("Error: " + err);
}).on('end', function() {
console.log("Connection closed");
process.exit();
});

conn.connect();

keypress(process.stdin);
process.stdin.setRawMode(true);
process.stdin.resume();

var buffer = "";
if (inputString === 'disconnect') {
console.log('Disconnecting from the server');
return rcon.disconnect();
}

process.stdin.on('keypress', function(chunk, key) {
if (key && key.ctrl && (key.name == 'c' || key.name == 'd')) {
conn.disconnect();
return;
}
process.stdout.write(chunk);
rcon.send(inputString);
});

if (key && (key.name == 'enter' || key.name == 'return')) {
if (authenticated) {
conn.send(buffer);
} else {
queuedCommands.push(buffer);
}
buffer = "";
process.stdout.write("\n");
} else if (key && key.name == 'backspace') {
buffer = buffer.slice(0, -1);
process.stdout.write("\033[K"); // Clear to end of line
} else {
buffer += chunk;
}
}).on('response', response => {
console.log('Response: ' + response);
}).on('error', error => {
console.error('Error:', error);
}).on('end', () => {
console.log('Connection closed');
process.exit(0);
});

rcon.connect();
104 changes: 104 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import { EventEmitter } from 'events';
import net from 'net';
import dgram from 'dgram';

export enum PacketType {
COMMAND = 0x02,
AUTH = 0x03,
RESPONSE_VALUE = 0x00,
RESPONSE_AUTH = 0x02,
};

export type RCONOptions = {
id?: number;
} & ({
useTcp?: true;
} | {
useTcp: false;
challenge?: boolean
});

interface RCONClientEvents {
authenticated: [];
debug: [string, Buffer?];
response: [string];
server: [string];
error: [Error];
end: []
}

export default class RCON extends EventEmitter<RCONClientEvents> {
private _outstandingData: Buffer | null;
private _challengeToken?: string;
private _tcpSocket?: net.Socket;
private _udpSocket?: dgram.Socket;

/**
* The RCON id - you'll likely not need to change this
*/
public id: number;
/**
* Whether the RCON is authenticated
*/
public authenticated: boolean;
/**
* Whether we are using a TCP connection or not. (the other connection type is UDP)
*/
public useTcp: boolean;
/**
* Whether we are using the challenge authentication method.
* (only in UDP connections)
*/
public challenge: boolean;

/**
* Make a new RCON connection.
* @param host The IP address of the server.
* @param port The port of the server.
* @param password The password.
* @param options Options - if you want to use a UDP connection for example.
*
* @example
* const RCON = require('node-rcon');
* const rcon = new RCON('localhost', 25575, 'password');
*
* rcon.on('authenticated', () => console.log('Authenticated'));
*
* rcon.connect();
*/
public constructor(public host: string, public port: number, public password: string, options?: RCONOptions);

private _sendData(data: Buffer): void;
private _dataReceived(data: Buffer): void;
private _onConnect(): void;
private _onClose(): void;

/**
* Connect to the server.
*
* @example
* const rcon = new RCON('localhost', 25575, 'password');
* rcon.on('authenticated', () => console.log('authenticated with the server.'));
* rcon.connect();
*/
public connect(): void;
/**
* Send data to the server.
* @param data The data to send.
* @param packetType The type of packet - you'll likely not need to change this
* @param id The RCON ID - you'll likely not need to change this
*
* @example
* RCON.send('say hi');
*/
public send(data: string, packetType?: PacketType, id?: number): void;
/**
* Disconnect the server;
* @example
* RCON.disconnect();
* process.exit(0);
*/
public disconnect(): void;
}

export = RCON;
Loading