mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2025-05-08 20:30:28 -04:00
test all packets
This commit is contained in:
parent
5df31e4d88
commit
10cb3e0100
6 changed files with 173 additions and 26 deletions
8
index.js
8
index.js
|
@ -24,6 +24,7 @@ function createServer(options) {
|
|||
options['server-port'] != null ?
|
||||
options['server-port'] :
|
||||
25565 ;
|
||||
var maxPlayers = options['max-players'] || 20;
|
||||
var host = options.host || '0.0.0.0';
|
||||
var kickTimeout = options.kickTimeout || 10 * 1000;
|
||||
var checkTimeoutInterval = options.checkTimeoutInterval || 4 * 1000;
|
||||
|
@ -32,6 +33,7 @@ function createServer(options) {
|
|||
assert.ok(! onlineMode, "online mode for servers is not yet supported");
|
||||
|
||||
var server = new Server(options);
|
||||
server.maxPlayers = maxPlayers;
|
||||
server.on("connection", function(client) {
|
||||
client.once(0xfe, onPing);
|
||||
client.on(0x02, onHandshake);
|
||||
|
@ -87,7 +89,7 @@ function createServer(options) {
|
|||
protocol.minecraftVersion,
|
||||
motd,
|
||||
server.playerCount,
|
||||
server.maxPlayers,
|
||||
maxPlayers,
|
||||
].join('\u0000')
|
||||
});
|
||||
}
|
||||
|
@ -118,9 +120,7 @@ function createClient(options) {
|
|||
var email = options.email;
|
||||
var password = options.password;
|
||||
|
||||
var client = new Client({
|
||||
isServer: false
|
||||
});
|
||||
var client = new Client(false);
|
||||
client.username = options.username;
|
||||
client.on('connect', function() {
|
||||
client.write(0x02, {
|
||||
|
|
|
@ -7,12 +7,10 @@ var net = require('net')
|
|||
|
||||
module.exports = Client;
|
||||
|
||||
function Client(options) {
|
||||
function Client(isServer) {
|
||||
EventEmitter.call(this);
|
||||
|
||||
options = options || {};
|
||||
|
||||
this.isServer = !!options.isServer;
|
||||
this.isServer = !!isServer;
|
||||
this.socket = null;
|
||||
this.encryptionEnabled = false;
|
||||
this.cipher = null;
|
||||
|
|
|
@ -2,15 +2,6 @@ var assert = require('assert');
|
|||
|
||||
var STRING_MAX_LENGTH = 240;
|
||||
|
||||
module.exports = {
|
||||
version: 51,
|
||||
minecraftVersion: '1.4.7',
|
||||
sessionVersion: 13,
|
||||
parsePacket: parsePacket,
|
||||
createPacketBuffer: createPacketBuffer,
|
||||
STRING_MAX_LENGTH: STRING_MAX_LENGTH,
|
||||
};
|
||||
|
||||
var packets = {
|
||||
0x00: [
|
||||
{ name: "keepAliveId", type: "int" }
|
||||
|
@ -459,10 +450,10 @@ var types = {
|
|||
'double': [readDouble, DoubleWriter],
|
||||
'float': [readFloat, FloatWriter],
|
||||
'slot': [readSlot, SlotWriter],
|
||||
'long': [readLong, LongWriter],
|
||||
'ascii': [readAscii, AsciiWriter],
|
||||
|
||||
'ascii': [readAscii],
|
||||
'byteArray32': [readByteArray32],
|
||||
'long': [readLong],
|
||||
'slotArray': [readSlotArray],
|
||||
'mapChunkBulk': [readMapChunkBulk],
|
||||
'entityMetadata': [readEntityMetadata],
|
||||
|
@ -886,6 +877,22 @@ StringWriter.prototype.write = function(buffer, offset) {
|
|||
}
|
||||
};
|
||||
|
||||
function AsciiWriter(value) {
|
||||
this.value = value;
|
||||
this.size = 2 + value.length;
|
||||
}
|
||||
|
||||
AsciiWriter.prototype.write = function(buffer, offset) {
|
||||
var cursor = offset;
|
||||
buffer.writeInt16BE(this.value.length, cursor);
|
||||
cursor += 2;
|
||||
|
||||
for (var i = 0; i < this.value.length; ++i) {
|
||||
buffer.writeUInt8(this.value.charCodeAt(i), cursor);
|
||||
cursor += 1;
|
||||
}
|
||||
};
|
||||
|
||||
function ByteArray16Writer(value) {
|
||||
assert.ok(Buffer.isBuffer(value), "non buffer passed to ByteArray16Writer");
|
||||
this.value = value;
|
||||
|
@ -969,6 +976,16 @@ IntWriter.prototype.write = function(buffer, offset) {
|
|||
buffer.writeInt32BE(this.value, offset);
|
||||
}
|
||||
|
||||
function LongWriter(value) {
|
||||
this.value = value;
|
||||
this.size = 8;
|
||||
}
|
||||
|
||||
LongWriter.prototype.write = function(buffer, offset) {
|
||||
buffer.writeInt32BE(this.value[0], offset);
|
||||
buffer.writeInt32BE(this.value[1], offset + 4);
|
||||
}
|
||||
|
||||
function get(packetId, toServer) {
|
||||
var packetInfo = packets[packetId];
|
||||
return Array.isArray(packetInfo) ?
|
||||
|
@ -1025,3 +1042,14 @@ function parsePacket(buffer, isServer) {
|
|||
results: results,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
version: 51,
|
||||
minecraftVersion: '1.4.7',
|
||||
sessionVersion: 13,
|
||||
parsePacket: parsePacket,
|
||||
createPacketBuffer: createPacketBuffer,
|
||||
STRING_MAX_LENGTH: STRING_MAX_LENGTH,
|
||||
packets: packets,
|
||||
get: get,
|
||||
};
|
||||
|
|
|
@ -6,10 +6,9 @@ var net = require('net')
|
|||
|
||||
module.exports = Server;
|
||||
|
||||
function Server(options) {
|
||||
function Server() {
|
||||
EventEmitter.call(this);
|
||||
|
||||
this.maxPlayers = options['max-players'] || 20;
|
||||
this.playerCount = 0
|
||||
|
||||
this.socketServer = null;
|
||||
|
@ -24,9 +23,7 @@ Server.prototype.listen = function(port, host) {
|
|||
var nextId = 0;
|
||||
self.socketServer = net.createServer();
|
||||
self.socketServer.on('connection', function(socket) {
|
||||
var client = new Client({
|
||||
isServer: true,
|
||||
});
|
||||
var client = new Client(true);
|
||||
client.id = nextId++;
|
||||
self.clients[client.id] = client;
|
||||
client.on('error', function(err) {
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
"devDependencies": {
|
||||
"mocha": "~1.7.4",
|
||||
"mkdirp": "~0.3.4",
|
||||
"rimraf": "~2.1.1"
|
||||
"rimraf": "~2.1.1",
|
||||
"zfill": "0.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ursa": "~0.8.0",
|
||||
|
|
125
test/test.js
125
test/test.js
|
@ -1,12 +1,16 @@
|
|||
var mc = require('../')
|
||||
, protocol = require('../lib/protocol')
|
||||
, protocol = mc.protocol
|
||||
, Client = mc.Client
|
||||
, Server = mc.Server
|
||||
, spawn = require('child_process').spawn
|
||||
, path = require('path')
|
||||
, fs = require('fs')
|
||||
, net = require('net')
|
||||
, assert = require('assert')
|
||||
, mkdirp = require('mkdirp')
|
||||
, rimraf = require('rimraf')
|
||||
, Batch = require('batch')
|
||||
, zfill = require('zfill')
|
||||
, MC_SERVER_JAR = process.env.MC_SERVER_JAR
|
||||
, SURVIVE_TIME = 10000
|
||||
, MC_SERVER_PATH = path.join(__dirname, 'server')
|
||||
|
@ -41,6 +45,125 @@ var defaultServerProps = {
|
|||
'motd': 'A Minecraft Server',
|
||||
};
|
||||
|
||||
var values = {
|
||||
'int': Math.floor(Math.random() * Math.pow(2, 16)),
|
||||
'short': Math.floor(Math.random() * Math.pow(2, 8)),
|
||||
'ushort': Math.floor(Math.random() * Math.pow(2, 16)),
|
||||
'byte': Math.floor(Math.random() * Math.pow(2, 4)),
|
||||
'ubyte': Math.floor(Math.random() * Math.pow(2, 8)),
|
||||
'string': "hi hi this is my string",
|
||||
'byteArray16': new Buffer(8),
|
||||
'bool': Math.random() < 0.5,
|
||||
'double': Math.random() * Math.pow(2, 64),
|
||||
'float': Math.random() * Math.pow(2, 32),
|
||||
'slot': {
|
||||
id: 5,
|
||||
itemCount: 56,
|
||||
itemDamage: 2,
|
||||
nbtData: new Buffer(90),
|
||||
},
|
||||
|
||||
'ascii': "hello",
|
||||
'byteArray32': new Buffer(10),
|
||||
'long': [0, 1],
|
||||
'slotArray': [{
|
||||
id: 41,
|
||||
itemCount: 2,
|
||||
itemDamage: 3,
|
||||
nbtData: new Buffer(0),
|
||||
}],
|
||||
'mapChunkBulk': {
|
||||
skyLightSent: true,
|
||||
compressedChunkData: new Buffer(1234),
|
||||
meta: [{
|
||||
x: 23,
|
||||
z: 64,
|
||||
bitMap: 3,
|
||||
addBitMap: 10,
|
||||
}],
|
||||
},
|
||||
'entityMetadata': {},
|
||||
'objectData': {
|
||||
intField: 9,
|
||||
velocityX: 1,
|
||||
velocityY: 2,
|
||||
velocityZ: 3,
|
||||
},
|
||||
'intArray8': [1, 2, 3, 4],
|
||||
'intVector': {x: 1, y: 2, z: 3},
|
||||
'byteVector': {x: 1, y: 2, z: 3},
|
||||
'byteVectorArray': [{x: 1, y: 2, z: 3}],
|
||||
}
|
||||
|
||||
describe("packets", function() {
|
||||
var client, server, serverClient;
|
||||
before(function(done) {
|
||||
server = new Server();
|
||||
server.once('listening', function() {
|
||||
server.once('connection', function(c) {
|
||||
serverClient = c;
|
||||
done();
|
||||
});
|
||||
client = new Client();
|
||||
client.setSocket(net.connect(25565, 'localhost'));
|
||||
});
|
||||
server.listen(25565, 'localhost');
|
||||
});
|
||||
after(function(done) {
|
||||
client.on('end', function() {
|
||||
server.on('close', done);
|
||||
server.close();
|
||||
});
|
||||
client.end();
|
||||
});
|
||||
var packetId, packetInfo, field;
|
||||
for(packetId in protocol.packets) {
|
||||
packetId = parseInt(packetId, 10);
|
||||
packetInfo = protocol.packets[packetId];
|
||||
it("0x" + zfill(parseInt(packetId, 10).toString(16), 2), callTestPacket(packetId, packetInfo));
|
||||
}
|
||||
function callTestPacket(packetId, packetInfo) {
|
||||
return function(done) {
|
||||
var batch = new Batch();
|
||||
batch.push(function(done) {
|
||||
testPacket(packetId, protocol.get(packetId, false), done);
|
||||
});
|
||||
batch.push(function(done) {
|
||||
testPacket(packetId, protocol.get(packetId, true), done);
|
||||
});
|
||||
batch.end(done);
|
||||
};
|
||||
}
|
||||
function testPacket(packetId, packetInfo, done) {
|
||||
// empty object uses default values
|
||||
var packet = {};
|
||||
packetInfo.forEach(function(field) {
|
||||
var value = field.type;
|
||||
packet[field.name] = values[field.type];
|
||||
});
|
||||
serverClient.once(packetId, function(receivedPacket) {
|
||||
delete receivedPacket.id;
|
||||
assertPacketsMatch(packet, receivedPacket);
|
||||
client.once(packetId, function(clientReceivedPacket) {
|
||||
delete clientReceivedPacket.id;
|
||||
assertPacketsMatch(receivedPacket, clientReceivedPacket);
|
||||
done();
|
||||
});
|
||||
serverClient.write(packetId, receivedPacket);
|
||||
});
|
||||
client.write(packetId, packet);
|
||||
}
|
||||
function assertPacketsMatch(p1, p2) {
|
||||
var field;
|
||||
for (field in p1) {
|
||||
assert.ok(field in p2, "field " + field + " missing in p2")
|
||||
}
|
||||
for (field in p2) {
|
||||
assert.ok(field in p1, "field " + field + " missing in p1");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe("client", function() {
|
||||
this.timeout(20000);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue