use recent raknet and add basic example

This commit is contained in:
Romain Beaumont 2016-04-02 23:50:28 +02:00
commit ff54ec47c0
6 changed files with 34 additions and 256 deletions

27
examples/server.js Normal file
View file

@ -0,0 +1,27 @@
var pmp = require('../');
if(process.argv.length !=4) {
console.log("Usage: node server.js <host> <port>");
process.exit(1);
}
var server = pmp.createServer({
host: process.argv[2],
port: parseInt(process.argv[3])
});
server.on('connection', function(client) {
client.on('unconnected_ping', function(packet) {
console.log(packet);
client.write('unconnected_pong', {
pingID: packet.pingID,
serverID: 0,
magic: 0,
serverName: 'MCPE;numerous-alpaca test server!;45 45;0.0.1;0;20'
});
});
client.on('error', function(err) {
// ignore it
});
});

View file

@ -1,110 +0,0 @@
'use strict';
var EventEmitter = require('events').EventEmitter;
var debug = require('./debug');
var createSerializer = require("./transforms/serializer").createSerializer;
var createDeserializer = require("./transforms/serializer").createDeserializer;
class Client extends EventEmitter {
constructor(isServer) {
super();
this.isServer = !!isServer;
}
setSerializer() {
this.serializer = createSerializer(this.isServer);
this.deserializer = createDeserializer(this.isServer);
this.serializer.on('error', (e) => {
var parts = e.field.split(".");
parts.shift();
e.message = `Serialization error for ${e.message}`;
this.emit('error', e);
});
this.deserializer.on('error', (e) => {
var parts = e.field.split(".");
parts.shift();
e.message = `Deserialization error for ${e.message}`;
this.emit('error', e);
});
this.deserializer.on('data', (parsed) => {
parsed.metadata.name = parsed.data.name;
parsed.data = parsed.data.params;
this.emit('packet', parsed.data, parsed.metadata);
debug("reading packet " + "." + parsed.metadata.name);
debug(parsed.data);
this.emit(parsed.metadata.name, parsed.data, parsed.metadata);
this.emit('raw.' + parsed.metadata.name, parsed.buffer, parsed.metadata);
this.emit('raw', parsed.buffer, parsed.metadata);
});
}
setSocket(socket) {
var ended = false;
var endSocket = function() {
if (ended) return;
ended = true;
this.socket.removeListener('close', endSocket);
this.socket.removeListener('end', endSocket);
this.socket.removeListener('timeout', endSocket);
this.emit('end', this._endReason);
};
var onFatalError = function(err) {
this.emit('error', err);
endSocket();
};
var onError = function(err) {
this.emit('error', err);
}
this.socket = socket;
if (this.socket.setNoDelay) {
this.socket.setNoDelay(true);
}
this.socket.on('connect', function() {
this.emit('connect');
});
this.socket.on('error', onFatalError);
this.socket.on('close', endSocket);
this.socket.on('end', endSocket);
this.socket.on('timeout', endSocket);
this.setSerializer();
this.socket.pipe(this.deserializer);
this.serializer.pipe(this.socket);
}
end(reason) {
this._endReason = reason;
if (this.socket)
this.socket.end();
}
write(name, params) {
debug("writing packet " + "." + name);
debug(params);
this.serializer.write({
name,
params
});
}
writeRaw(buffer) {
this.socket.write(buffer);
}
}
module.exports = Client;

View file

@ -1,26 +1,6 @@
'use strict';
var net = require('net');
var dns = require('dns');
var Client = require('./client');
var assert = require('assert');
module.exports = createClient;
Client.prototype.connect = function(port, host) {
var self = this;
if(port == 19132 && net.isIP(host) === 0) {
dns.resolveSrv(host, function(err, addresses) {
if(addresses && addresses.length > 0) {
self.setSocket(net.connect(addresses[0].port, addresses[0].name));
} else {
self.setSocket(net.connect(port, host));
}
});
} else {
self.setSocket(net.connect(port, host));
}
};
const assert = require('assert');
const raknet = require('raknet');
function createClient(options) {
assert.ok(options, "options is required");
@ -30,13 +10,10 @@ function createClient(options) {
assert.ok(options.username, "username is required");
var client = new Client(false);
client.on('connect', onConnect);
var client=raknet.createClient(options);
client.username = options.username;
client.connect(port, host);
function onConnect() {
// we should probably implement the login protocol for the client here
}
return client;
}
module.exports = createClient;

View file

@ -1,4 +1,4 @@
var Server = require('./server');
const raknet = require('raknet');
function createServer(options) {
options = options || {};
@ -8,60 +8,18 @@ function createServer(options) {
options['server-port'] :
19132;
var host = options.host || '0.0.0.0';
var kickTimeout = options.kickTimeout || 10 * 1000;
var checkTimeoutInterval = options.checkTimeoutInterval || 4 * 1000;
var onlineMode = options['online-mode'] == null ? true : options['online-mode'];
var beforePing = options.beforePing || null;
var enablePing = options.ping == null ? true : options.ping;
var server = new Server();
var server = raknet.createServer(options);
server.name = options.name || "Minecraft Server";
server.motd = options.motd || "A Minecraft server";
server.maxPlayers = options['max-players'] || 20;
server.playerCount = 0;
server.onlineModeExceptions = {};
server.on("connection", function (client) {
client.once('player_identification', onLogin);
client.on('end', onEnd);
var ping = true;
var pingTimer = null;
function pingLoop() {
client.write('ping', {});
}
function startPing() {
pingTimer = setInterval(pingLoop, checkTimeoutInterval);
}
function onEnd() {
clearInterval(pingTimer);
}
function onLogin(packet) {
client.username=packet.username;
client.identification_byte=packet.unused;
if(options.handshake)
{
options.handshake(function(){
continueLogin();
})
}
else
continueLogin();
}
function continueLogin() {
// we should probably implement the login protocol here
server.emit('login', client);
startPing();
}
});
server.listen(port, host);
return server;
}

View file

@ -1,16 +0,0 @@
var util = require('util')
var debug;
if(process.env.NODE_DEBUG) {
var pid = process.pid;
debug = function(x) {
if(!console.error)
return;
console.error('MCPE-PROTO: %d', pid,
util.format.apply(util, arguments));
};
} else {
debug = function() {}
}
module.exports = debug;

View file

@ -1,58 +0,0 @@
'use strict';
var net = require('net');
var EventEmitter = require('events').EventEmitter;
var Client = require('./client');
class Server extends EventEmitter {
constructor() {
super();
}
listen(port, host) {
var self = this;
var nextId = 0;
self.socketServer = net.createServer();
self.socketServer.on('connection', socket => {
var client = new Client(true);
// client._end = client.end;
// client.end = function end(endReason) {
// client.write('disconnect_player', {
// disconnect_reason: endReason
// });
// client._end(endReason);
// };
client.id = nextId++;
self.clients[client.id] = client;
client.on('end', function () {
delete self.clients[client.id];
});
client.setSocket(socket);
self.emit('connection', client);
});
self.socketServer.on('error', function (err) {
self.emit('error', err);
});
self.socketServer.on('close', function () {
self.emit('close');
});
self.socketServer.on('listening', function () {
self.emit('listening');
});
self.socketServer.listen(port, host);
}
close() {
var client;
for (var clientId in this.clients) {
if (!this.clients.hasOwnProperty(clientId)) continue;
client = this.clients[clientId];
client.end('ServerShutdown');
}
this.socketServer.close();
}
}
module.exports = Server;