use recent raknet and add basic example
This commit is contained in:
parent
1b23ccfcf6
commit
ff54ec47c0
6 changed files with 34 additions and 256 deletions
27
examples/server.js
Normal file
27
examples/server.js
Normal 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
|
||||
});
|
||||
});
|
||||
110
src/client.js
110
src/client.js
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
16
src/debug.js
16
src/debug.js
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
Loading…
Add table
Add a link
Reference in a new issue