mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2024-11-14 19:04:59 -05:00
Merge pull request #257 from rom1504/static_cross_version
enable cross version with an option in createClient and createServer
This commit is contained in:
commit
8d9f37c2ba
16 changed files with 737 additions and 678 deletions
|
@ -7,7 +7,7 @@ Parse and serialize minecraft packets, plus authentication and encryption.
|
|||
|
||||
## Features
|
||||
|
||||
* Supports Minecraft version 1.8.8
|
||||
* Supports Minecraft version 1.8.8 and 1.9
|
||||
* Parses all packets and emits events with packet fields as JavaScript
|
||||
objects.
|
||||
* Send a packet by supplying fields as a JavaScript object.
|
||||
|
@ -121,8 +121,7 @@ See [doc](doc/README.md)
|
|||
## Testing
|
||||
|
||||
* Ensure your system has the `java` executable in `PATH`.
|
||||
* Download the appropriate version of `minecraft_server.jar`.
|
||||
* `MC_SERVER_JAR=path/to/minecraft_server.jar MC_USERNAME=email@example.com MC_PASSWORD=password npm test`
|
||||
* `MC_SERVER_JAR_DIR=some/path/to/store/minecraft/server/ MC_USERNAME=email@example.com MC_PASSWORD=password npm test`
|
||||
|
||||
## Debugging
|
||||
|
||||
|
|
10
circle.yml
10
circle.yml
|
@ -1,12 +1,10 @@
|
|||
machine:
|
||||
environment:
|
||||
MC_SERVER_JAR: /home/ubuntu/node-minecraft-protocol/minecraft-server/minecraft_server.jar
|
||||
MC_SERVER_JAR_DIR: /home/ubuntu/node-minecraft-protocol/minecraft-server/
|
||||
node:
|
||||
version: 0.10.28
|
||||
java:
|
||||
version: openjdk7
|
||||
test:
|
||||
override:
|
||||
- mkdir -p /home/ubuntu/node-minecraft-protocol/minecraft-server/
|
||||
- node_modules/.bin/downloadMinecraft `node -e 'console.log(require("./src/version").minecraftVersion)'` $MC_SERVER_JAR
|
||||
- npm test
|
||||
dependencies:
|
||||
pre:
|
||||
- mkdir minecraft-server
|
||||
|
|
|
@ -84,6 +84,7 @@ Returns a `Client` instance and perform login.
|
|||
* clientToken : generated if a password is given
|
||||
* accessToken : generated if a password is given
|
||||
* keepAlive : send keep alive packets : default to true
|
||||
* version : 1.8 or 1.9
|
||||
|
||||
## Client
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ var mc = require('../../');
|
|||
|
||||
var states = mc.states;
|
||||
function printHelpAndExit(exitCode) {
|
||||
console.log("usage: node proxy.js [<options>...] <target_srv> <user> [<password>]");
|
||||
console.log("usage: node proxy.js [<options>...] <target_srv> <user> [<password>] [<version>]");
|
||||
console.log("options:");
|
||||
console.log(" --dump name");
|
||||
console.log(" print to stdout messages with the specified name.");
|
||||
|
@ -37,6 +37,7 @@ var host;
|
|||
var port = 25565;
|
||||
var user;
|
||||
var passwd;
|
||||
var version;
|
||||
|
||||
var printAllNames = false;
|
||||
var printNameWhitelist = {};
|
||||
|
@ -59,10 +60,11 @@ var printNameBlacklist = {};
|
|||
printHelpAndExit(1);
|
||||
}
|
||||
}
|
||||
if(!(i + 2 <= args.length && args.length <= i + 3)) printHelpAndExit(1);
|
||||
if(!(i + 2 <= args.length && args.length <= i + 4)) printHelpAndExit(1);
|
||||
host = args[i++];
|
||||
user = args[i++];
|
||||
passwd = args[i++];
|
||||
version = args[i++];
|
||||
})();
|
||||
|
||||
if(host.indexOf(':') != -1) {
|
||||
|
@ -73,7 +75,8 @@ if(host.indexOf(':') != -1) {
|
|||
var srv = mc.createServer({
|
||||
'online-mode': false,
|
||||
port: 25566,
|
||||
keepAlive: false
|
||||
keepAlive: false,
|
||||
version:version
|
||||
});
|
||||
srv.on('login', function(client) {
|
||||
var addr = client.socket.remoteAddress;
|
||||
|
@ -98,7 +101,8 @@ srv.on('login', function(client) {
|
|||
username: user,
|
||||
password: passwd,
|
||||
'online-mode': passwd != null ? true : false,
|
||||
keepAlive:false
|
||||
keepAlive:false,
|
||||
version:version
|
||||
});
|
||||
client.on('packet', function(data, meta) {
|
||||
if(targetClient.state == states.PLAY && meta.state == states.PLAY) {
|
||||
|
@ -128,8 +132,8 @@ srv.on('login', function(client) {
|
|||
targetClient.on('raw', function(buffer, meta) {
|
||||
if(client.state != states.PLAY || meta.state != states.PLAY)
|
||||
return;
|
||||
var packetData = mc.parsePacketData(buffer, meta.state, false, {"packet": 1}).data;
|
||||
var packetBuff = mc.createPacketBuffer(meta.name, meta.state, packetData, true);
|
||||
var packetData = targetClient.deserializer.parsePacketData(buffer).data;
|
||||
var packetBuff = client.serializer.createPacketBuffer(meta.name, packetData);
|
||||
if(buffertools.compare(buffer, packetBuff) != 0) {
|
||||
console.log("client<-server: Error in packet " + state + "." + meta.name);
|
||||
console.log(buffer.toString('hex'));
|
||||
|
@ -148,8 +152,8 @@ srv.on('login', function(client) {
|
|||
client.on('raw', function(buffer, meta) {
|
||||
if(meta.state != states.PLAY || targetClient.state != states.PLAY)
|
||||
return;
|
||||
var packetData = mc.parsePacketData(buffer, meta.state, true, {"packet": 1}).data;
|
||||
var packetBuff = mc.createPacketBuffer(meta.name, meta.state, packetData, false);
|
||||
var packetData = client.deserializer.parsePacketData(buffer).data;
|
||||
var packetBuff = targetClient.serializer.createPacketBuffer(meta.name, packetData);
|
||||
if(buffertools.compare(buffer, packetBuff) != 0) {
|
||||
console.log("client->server: Error in packet " + state + "." + meta.name);
|
||||
console.log(buffer.toString('hex'));
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
"gulp-plumber": "^1.0.1",
|
||||
"gulp-sourcemaps": "^1.3.0",
|
||||
"intelli-espower-loader": "^1.0.0",
|
||||
"mocha": "~1.8.2",
|
||||
"mocha": "~2.3.3",
|
||||
"power-assert": "^1.0.0",
|
||||
"source-map-support": "^0.3.2",
|
||||
"minecraft-wrap": "~0.5.4"
|
||||
|
|
|
@ -1,19 +1,10 @@
|
|||
var version = require('./version');
|
||||
var packets = require('minecraft-data')(version.majorVersion).protocol.states;
|
||||
var readPackets = require("./packets").readPackets;
|
||||
var packetIndexes = readPackets(packets, states);
|
||||
var utils = require("./utils");
|
||||
var serializer = require("./transforms/serializer");
|
||||
|
||||
module.exports = {
|
||||
Client: require('./client'),
|
||||
protocol: require('./protocol'),
|
||||
createPacketBuffer: serializer.createPacketBuffer,
|
||||
parsePacketData: serializer.parsePacketData,
|
||||
packetFields: packetIndexes.packetFields,
|
||||
packetNames: packetIndexes.packetNames,
|
||||
packetIds: packetIndexes.packetIds,
|
||||
packetStates: packetIndexes.packetStates,
|
||||
types: serializer.types,
|
||||
get: serializer.get,
|
||||
readPackets:readPackets,
|
||||
supportedVersions:require("./version").supportedVersions
|
||||
};
|
||||
|
|
|
@ -5,10 +5,6 @@ var compression = require('./transforms/compression');
|
|||
var framing = require('./transforms/framing');
|
||||
var crypto = require('crypto');
|
||||
var states = serializer.states;
|
||||
var version = require('./version');
|
||||
var packets = require('minecraft-data')(version.majorVersion).protocol.states;
|
||||
var readPackets = require("./packets").readPackets;
|
||||
var packetIndexes = readPackets(packets, states);
|
||||
|
||||
|
||||
class Client extends EventEmitter
|
||||
|
@ -24,11 +20,16 @@ class Client extends EventEmitter
|
|||
deserializer;
|
||||
isServer;
|
||||
|
||||
constructor(isServer) {
|
||||
constructor(isServer,version) {
|
||||
super();
|
||||
|
||||
this.serializer = serializer.createSerializer({ isServer });
|
||||
this.deserializer = serializer.createDeserializer({ isServer, packetsToParse: this.packetsToParse });
|
||||
var mcData=require("minecraft-data")(version);
|
||||
var packets = mcData.protocol.states;
|
||||
var readPackets = require("./packets").readPackets;
|
||||
var packetIndexes = readPackets(packets, states);
|
||||
|
||||
this.serializer = serializer.createSerializer({ isServer, version:version});
|
||||
this.deserializer = serializer.createDeserializer({ isServer, packetsToParse: this.packetsToParse, version:version});
|
||||
this.isServer = !!isServer;
|
||||
|
||||
this.on('newListener', function(event, listener) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
var mcHexDigest=require("./mcHexDigest");
|
||||
var ursa=require("./ursa");
|
||||
var version = require("./version");
|
||||
var net = require('net');
|
||||
var dns = require('dns');
|
||||
var Client = require('./client');
|
||||
|
@ -42,8 +41,12 @@ function createClient(options) {
|
|||
var haveCredentials = options.password != null || (clientToken != null && accessToken != null);
|
||||
var keepAlive = options.keepAlive == null ? true : options.keepAlive;
|
||||
|
||||
var optVersion = options.version || require("./version").defaultVersion;
|
||||
var mcData=require("minecraft-data")(optVersion);
|
||||
var version = mcData.version;
|
||||
|
||||
var client = new Client(false);
|
||||
|
||||
var client = new Client(false,version.majorVersion);
|
||||
client.on('connect', onConnect);
|
||||
if(keepAlive) client.on('keep_alive', onKeepAlive);
|
||||
client.once('encryption_begin', onEncryptionKeyRequest);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
var mcHexDigest=require("./mcHexDigest");
|
||||
var ursa=require("./ursa");
|
||||
var version = require("./version");
|
||||
var crypto = require('crypto');
|
||||
var Yggdrasil = require('./yggdrasil.js');
|
||||
var validateSession = Yggdrasil.validateSession;
|
||||
|
@ -28,9 +27,13 @@ function createServer(options) {
|
|||
|
||||
var enableKeepAlive = options.keepAlive == null ? true : options.keepAlive;
|
||||
|
||||
var optVersion = options.version || require("./version").defaultVersion;
|
||||
var mcData=require("minecraft-data")(optVersion);
|
||||
var version = mcData.version;
|
||||
|
||||
var serverKey = ursa.generatePrivateKey(1024);
|
||||
|
||||
var server = new Server(options);
|
||||
var server = new Server(version.majorVersion);
|
||||
server.motd = options.motd || "A Minecraft server";
|
||||
server.maxPlayers = options['max-players'] || 20;
|
||||
server.playerCount = 0;
|
||||
|
|
17
src/index.js
17
src/index.js
|
@ -3,10 +3,7 @@ var Server = require('./server');
|
|||
var Yggdrasil = require('./yggdrasil.js');
|
||||
var serializer = require("./transforms/serializer");
|
||||
var utils = require("./utils");
|
||||
var version = require("./version");
|
||||
var packets = require('minecraft-data')(version.majorVersion).protocol.states;
|
||||
var readPackets = require("./packets").readPackets;
|
||||
var packetIndexes = readPackets(packets, serializer.states);
|
||||
var createClient = require("./createClient");
|
||||
var createServer = require("./createServer");
|
||||
|
||||
|
@ -16,16 +13,10 @@ module.exports = {
|
|||
Client: Client,
|
||||
Server: Server,
|
||||
states: serializer.states,
|
||||
createPacketBuffer: serializer.createPacketBuffer,
|
||||
parsePacketData: serializer.parsePacketData,
|
||||
packetFields: packetIndexes.packetFields,
|
||||
packetNames: packetIndexes.packetNames,
|
||||
packetIds: packetIndexes.packetIds,
|
||||
packetStates: packetIndexes.packetStates,
|
||||
types: serializer.types,
|
||||
get: serializer.get,
|
||||
createSerializer:serializer.createSerializer,
|
||||
createDeserializer:serializer.createDeserializer,
|
||||
readPackets:readPackets,
|
||||
ping: require('./ping'),
|
||||
yggdrasil: Yggdrasil,
|
||||
version: version.version,
|
||||
minecraftVersion: version.minecraftVersion
|
||||
supportedVersions:require("./version").supportedVersions
|
||||
};
|
||||
|
|
12
src/ping.js
12
src/ping.js
|
@ -1,15 +1,17 @@
|
|||
var net = require('net')
|
||||
, Client = require('./client')
|
||||
, states = require('./transforms/serializer').states;
|
||||
var version = require('./version');
|
||||
var net = require('net');
|
||||
var Client = require('./client');
|
||||
var states = require('./transforms/serializer').states;
|
||||
|
||||
module.exports = ping;
|
||||
|
||||
function ping(options, cb) {
|
||||
var host = options.host || 'localhost';
|
||||
var port = options.port || 25565;
|
||||
var optVersion = options.version || require("./version").defaultVersion;
|
||||
var mcData=require("minecraft-data")(optVersion);
|
||||
var version = mcData.version;
|
||||
|
||||
var client = new Client();
|
||||
var client = new Client(false,version.majorVersion);
|
||||
client.on('error', function(err) {
|
||||
cb(err);
|
||||
});
|
||||
|
|
|
@ -10,16 +10,17 @@ class Server extends EventEmitter
|
|||
decipher=null;
|
||||
clients={};
|
||||
|
||||
constructor() {
|
||||
constructor(version) {
|
||||
super();
|
||||
this.version=version;
|
||||
}
|
||||
|
||||
listen(port, host) {
|
||||
var self = this;
|
||||
var nextId = 0;
|
||||
self.socketServer = net.createServer();
|
||||
self.socketServer.on('connection', function(socket) {
|
||||
var client = new Client(true);
|
||||
self.socketServer.on('connection', socket => {
|
||||
var client = new Client(true,this.version);
|
||||
client._end = client.end;
|
||||
client.end = function end(endReason) {
|
||||
endReason='{"text":"'+endReason+'"}';
|
||||
|
|
|
@ -13,9 +13,6 @@ module.exports.createDeserializer = function(obj) {
|
|||
return new Deserializer(obj);
|
||||
};
|
||||
|
||||
module.exports.createPacketBuffer=createPacketBuffer;
|
||||
module.exports.parsePacketData=parsePacketData;
|
||||
|
||||
// This is really just for the client.
|
||||
var states = {
|
||||
"HANDSHAKING": "handshaking",
|
||||
|
@ -25,137 +22,81 @@ var states = {
|
|||
};
|
||||
module.exports.states = states;
|
||||
|
||||
module.exports.get = get;
|
||||
|
||||
|
||||
|
||||
var NMProtocols = require("../protocol");
|
||||
|
||||
var numeric = require("../datatypes/numeric");
|
||||
var utils = require("../datatypes/utils");
|
||||
var minecraft = require("../datatypes/minecraft");
|
||||
var structures = require("../datatypes/structures");
|
||||
var conditional = require("../datatypes/conditional");
|
||||
|
||||
var proto = new NMProtocols();
|
||||
proto.addTypes(numeric);
|
||||
proto.addTypes(utils);
|
||||
proto.addTypes(minecraft);
|
||||
proto.addTypes(structures);
|
||||
proto.addTypes(conditional);
|
||||
|
||||
module.exports.types = proto.types;
|
||||
|
||||
var version = require('../version');
|
||||
var packets = require('minecraft-data')(version.majorVersion).protocol;
|
||||
proto.addTypes(packets.types);
|
||||
|
||||
var readPackets = require("../packets").readPackets;
|
||||
var packetIndexes = readPackets(packets.states, states);
|
||||
|
||||
var packetFields = packetIndexes.packetFields;
|
||||
var packetNames = packetIndexes.packetNames;
|
||||
var packetIds = packetIndexes.packetIds;
|
||||
var packetStates = packetIndexes.packetStates;
|
||||
|
||||
|
||||
// TODO : This does NOT contain the length prefix anymore.
|
||||
function createPacketBuffer(packetName, state, params, isServer) {
|
||||
var direction = !isServer ? 'toServer' : 'toClient';
|
||||
var packetId = packetIds[state][direction][packetName];
|
||||
assert.notEqual(packetId, undefined, `${state}.${isServer}.${packetName} : ${packetId}`);
|
||||
var packet = get(packetName, state, !isServer);
|
||||
assert.notEqual(packet, null);
|
||||
|
||||
var length = utils.varint[2](packetId);
|
||||
tryCatch(() => {
|
||||
length += structures.container[2].call(proto, params, packet, {});
|
||||
//length += proto.sizeOf(params, ["container", packet], {});
|
||||
}, (e) => {
|
||||
e.field = [state, direction, packetName, e.field].join(".");
|
||||
e.message = `SizeOf error for ${e.field} : ${e.message}`;
|
||||
throw e;
|
||||
});
|
||||
|
||||
var buffer = new Buffer(length);
|
||||
var offset = utils.varint[1](packetId, buffer, 0);
|
||||
tryCatch(() => {
|
||||
offset = structures.container[1].call(proto, params, buffer, offset, packet, {});
|
||||
//offset = proto.write(params, buffer, offset, ["container", packet], {});
|
||||
}, (e) => {
|
||||
e.field = [state, direction, packetName, e.field].join(".");
|
||||
e.message = `Write error for ${e.field} : ${e.message}`;
|
||||
throw e;
|
||||
});
|
||||
return buffer;
|
||||
function createProtocol(types)
|
||||
{
|
||||
var proto = new NMProtocols();
|
||||
proto.addTypes(numeric);
|
||||
proto.addTypes(utils);
|
||||
proto.addTypes(minecraft);
|
||||
proto.addTypes(structures);
|
||||
proto.addTypes(conditional);
|
||||
proto.addTypes(types);
|
||||
return proto;
|
||||
}
|
||||
|
||||
|
||||
function get(packetName, state, toServer) {
|
||||
var direction = toServer ? "toServer" : "toClient";
|
||||
var packetInfo = packetFields[state][direction][packetName];
|
||||
if(!packetInfo) {
|
||||
return null;
|
||||
}
|
||||
return packetInfo;
|
||||
}
|
||||
|
||||
function parsePacketData(buffer, state, isServer, packetsToParse = {"packet": true}) {
|
||||
var { value: packetId, size: cursor } = utils.varint[0](buffer, 0);
|
||||
|
||||
var direction = isServer ? "toServer" : "toClient";
|
||||
var packetName = packetNames[state][direction][packetId];
|
||||
var results = {
|
||||
metadata: {
|
||||
name: packetName,
|
||||
id: packetId,
|
||||
state
|
||||
},
|
||||
data: {},
|
||||
buffer
|
||||
};
|
||||
|
||||
// Only parse the packet if there is a need for it, AKA if there is a listener
|
||||
// attached to it.
|
||||
var shouldParse =
|
||||
(packetsToParse.hasOwnProperty(packetName) && packetsToParse[packetName] > 0) ||
|
||||
(packetsToParse.hasOwnProperty("packet") && packetsToParse["packet"] > 0);
|
||||
if (!shouldParse)
|
||||
return results;
|
||||
|
||||
var packetInfo = get(packetName, state, isServer);
|
||||
if(packetInfo === null)
|
||||
throw new Error("Unrecognized packetId: " + packetId + " (0x" + packetId.toString(16) + ")")
|
||||
else
|
||||
debug("read packetId " + state + "." + packetName + " (0x" + packetId.toString(16) + ")");
|
||||
|
||||
var res;
|
||||
tryCatch(() => {
|
||||
res = proto.read(buffer, cursor, ["container", packetInfo], {});
|
||||
}, (e) => {
|
||||
e.field = [state, direction, packetName, e.field].join(".");
|
||||
e.message = `Read error for ${e.field} : ${e.message}`;
|
||||
throw e;
|
||||
});
|
||||
results.data = res.value;
|
||||
cursor += res.size;
|
||||
if(buffer.length > cursor)
|
||||
throw new Error(`Read error for ${packetName} : Packet data not entirely read :
|
||||
${JSON.stringify(results)}`);
|
||||
debug(results);
|
||||
return results;
|
||||
}
|
||||
|
||||
class Serializer extends Transform {
|
||||
constructor({ state = states.HANDSHAKING, isServer = false } = {}) {
|
||||
constructor({ state = states.HANDSHAKING, isServer = false , version} = {}) {
|
||||
super({ writableObjectMode: true });
|
||||
this.protocolState = state;
|
||||
this.isServer = isServer;
|
||||
this.version = version;
|
||||
|
||||
var mcData=require("minecraft-data")(version);
|
||||
var packets = mcData.protocol.states;
|
||||
var packetIndexes = readPackets(packets, states);
|
||||
|
||||
this.proto=createProtocol(mcData.protocol.types);
|
||||
|
||||
this.packetFields = packetIndexes.packetFields;
|
||||
this.packetIds = packetIndexes.packetIds;
|
||||
}
|
||||
|
||||
// TODO : This does NOT contain the length prefix anymore.
|
||||
createPacketBuffer(packetName, params) {
|
||||
var direction = !this.isServer ? 'toServer' : 'toClient';
|
||||
var packetId = this.packetIds[this.protocolState][direction][packetName];
|
||||
assert.notEqual(packetId, undefined, `${this.protocolState}.${direction}.${packetName} : ${packetId}`);
|
||||
var packet = this.packetFields[this.protocolState][direction][packetName];
|
||||
packet=packet ? packet : null;
|
||||
|
||||
assert.notEqual(packet, null);
|
||||
|
||||
var length = utils.varint[2](packetId);
|
||||
tryCatch(() => {
|
||||
length += structures.container[2].call(this.proto, params, packet, {});
|
||||
//length += proto.sizeOf(params, ["container", packet], {});
|
||||
}, (e) => {
|
||||
e.field = [this.protocolState, direction, packetName, e.field].join(".");
|
||||
e.message = `SizeOf error for ${e.field} : ${e.message}`;
|
||||
throw e;
|
||||
});
|
||||
|
||||
var buffer = new Buffer(length);
|
||||
var offset = utils.varint[1](packetId, buffer, 0);
|
||||
tryCatch(() => {
|
||||
offset = structures.container[1].call(this.proto, params, buffer, offset, packet, {});
|
||||
//offset = proto.write(params, buffer, offset, ["container", packet], {});
|
||||
}, (e) => {
|
||||
e.field = [this.protocolState, direction, packetName, e.field].join(".");
|
||||
e.message = `Write error for ${e.field} : ${e.message}`;
|
||||
throw e;
|
||||
});
|
||||
return buffer;
|
||||
}
|
||||
|
||||
_transform(chunk, enc, cb) {
|
||||
try {
|
||||
var buf = createPacketBuffer(chunk.packetName, this.protocolState, chunk.params, this.isServer);
|
||||
var buf = this.createPacketBuffer(chunk.packetName, chunk.params);
|
||||
this.push(buf);
|
||||
return cb();
|
||||
} catch (e) {
|
||||
|
@ -165,17 +106,76 @@ class Serializer extends Transform {
|
|||
}
|
||||
|
||||
class Deserializer extends Transform {
|
||||
constructor({ state = states.HANDSHAKING, isServer = false, packetsToParse = {"packet": true} } = {}) {
|
||||
constructor({ state = states.HANDSHAKING, isServer = false, packetsToParse = {"packet": true}, version } = {}) {
|
||||
super({ readableObjectMode: true });
|
||||
this.protocolState = state;
|
||||
this.isServer = isServer;
|
||||
this.packetsToParse = packetsToParse;
|
||||
this.version = version;
|
||||
|
||||
|
||||
var mcData=require("minecraft-data")(version);
|
||||
var packets = mcData.protocol.states;
|
||||
var packetIndexes = readPackets(packets, states);
|
||||
|
||||
this.proto=createProtocol(mcData.protocol.types);
|
||||
|
||||
this.packetFields = packetIndexes.packetFields;
|
||||
this.packetNames = packetIndexes.packetNames;
|
||||
}
|
||||
|
||||
parsePacketData(buffer) {
|
||||
var { value: packetId, size: cursor } = utils.varint[0](buffer, 0);
|
||||
|
||||
var direction = this.isServer ? "toServer" : "toClient";
|
||||
var packetName = this.packetNames[this.protocolState][direction][packetId];
|
||||
var results = {
|
||||
metadata: {
|
||||
name: packetName,
|
||||
id: packetId,
|
||||
state:this.protocolState
|
||||
},
|
||||
data: {},
|
||||
buffer
|
||||
};
|
||||
|
||||
// Only parse the packet if there is a need for it, AKA if there is a listener
|
||||
// attached to it.
|
||||
var shouldParse =
|
||||
(this.packetsToParse.hasOwnProperty(packetName) && this.packetsToParse[packetName] > 0) ||
|
||||
(this.packetsToParse.hasOwnProperty("packet") && this.packetsToParse["packet"] > 0);
|
||||
if (!shouldParse)
|
||||
return results;
|
||||
|
||||
var packetInfo = this.packetFields[this.protocolState][direction][packetName];
|
||||
packetInfo=packetInfo ? packetInfo : null;
|
||||
if(packetInfo === null)
|
||||
throw new Error("Unrecognized packetId: " + packetId + " (0x" + packetId.toString(16) + ")")
|
||||
else
|
||||
debug("read packetId " + this.protocolState + "." + packetName + " (0x" + packetId.toString(16) + ")");
|
||||
|
||||
var res;
|
||||
tryCatch(() => {
|
||||
res = this.proto.read(buffer, cursor, ["container", packetInfo], {});
|
||||
}, (e) => {
|
||||
e.field = [this.protocolState, direction, packetName, e.field].join(".");
|
||||
e.message = `Read error for ${e.field} : ${e.message}`;
|
||||
throw e;
|
||||
});
|
||||
results.data = res.value;
|
||||
cursor += res.size;
|
||||
if(buffer.length > cursor)
|
||||
throw new Error(`Read error for ${packetName} : Packet data not entirely read :
|
||||
${JSON.stringify(results)}`);
|
||||
debug(results);
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
_transform(chunk, enc, cb) {
|
||||
var packet;
|
||||
try {
|
||||
packet = parsePacketData(chunk, this.protocolState, this.isServer, this.packetsToParse);
|
||||
packet = this.parsePacketData(chunk);
|
||||
} catch (e) {
|
||||
return cb(e);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
var majorVersion='1.8';
|
||||
var mcData=require("minecraft-data")(majorVersion);
|
||||
module.exports=mcData.version;
|
||||
module.exports={
|
||||
defaultVersion:'1.8',
|
||||
supportedVersions:['1.8','1.9']
|
||||
};
|
||||
|
|
|
@ -11,21 +11,24 @@ var testDataWrite = [
|
|||
// TODO: add more packets for better quality data
|
||||
];
|
||||
|
||||
var inputData = [];
|
||||
|
||||
var start, i, j;
|
||||
console.log('Beginning write test');
|
||||
start = Date.now();
|
||||
for(i = 0; i < ITERATIONS; i++) {
|
||||
for(j = 0; j < testDataWrite.length; j++) {
|
||||
inputData.push(mc.createPacketBuffer(testDataWrite[j].name, states.PLAY, testDataWrite[j].params, false));
|
||||
mc.supportedVersions.forEach(function(supportedVersion){
|
||||
var inputData = [];
|
||||
var serializer=new mc.createSerializer({state:states.PLAY,isServer:false,version:supportedVersion});
|
||||
var start, i, j;
|
||||
console.log('Beginning write test for '+supportedVersion);
|
||||
start = Date.now();
|
||||
for(i = 0; i < ITERATIONS; i++) {
|
||||
for(j = 0; j < testDataWrite.length; j++) {
|
||||
inputData.push(serializer.createPacketBuffer(testDataWrite[j].name, testDataWrite[j].params));
|
||||
}
|
||||
}
|
||||
}
|
||||
console.log('Finished write test in ' + (Date.now() - start) / 1000 + ' seconds');
|
||||
console.log('Finished write test in ' + (Date.now() - start) / 1000 + ' seconds');
|
||||
|
||||
console.log('Beginning read test');
|
||||
start = Date.now();
|
||||
for (j = 0; j < inputData.length; j++) {
|
||||
mc.parsePacketData(inputData[j], states.PLAY, true);
|
||||
}
|
||||
console.log('Finished read test in ' + (Date.now() - start) / 1000 + ' seconds');
|
||||
var deserializer=new mc.createDeserializer({state:states.PLAY,isServer:true,version:supportedVersion});
|
||||
console.log('Beginning read test for '+supportedVersion);
|
||||
start = Date.now();
|
||||
for (j = 0; j < inputData.length; j++) {
|
||||
deserializer.parsePacketData(inputData[j]);
|
||||
}
|
||||
console.log('Finished read test in ' + (Date.now() - start) / 1000 + ' seconds');
|
||||
});
|
||||
|
|
1025
test/test.js
1025
test/test.js
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue