From 78e70dad8e732ab121e0c44f18dca371095b6039 Mon Sep 17 00:00:00 2001 From: Romain Beaumont Date: Wed, 13 May 2015 14:47:28 +0200 Subject: [PATCH] reorganize code a bit : debug code going to debug.js, put packets reading code in a function, add types using a addTypes function --- src/client.js | 2 +- src/datatypes/minecraft.js | 1 + src/debug.js | 17 ++++ src/protocol.js | 177 +++++++++++++++++-------------------- 4 files changed, 102 insertions(+), 95 deletions(-) create mode 100644 src/debug.js diff --git a/src/client.js b/src/client.js index 35fdca1..1627309 100644 --- a/src/client.js +++ b/src/client.js @@ -11,7 +11,7 @@ var EventEmitter = require('events').EventEmitter , packetIds = protocol.packetIds , packetNames = protocol.packetNames , states = protocol.states - , debug = protocol.debug + , debug = require('./debug') ; module.exports = Client; diff --git a/src/datatypes/minecraft.js b/src/datatypes/minecraft.js index 8a56c20..d43ddb3 100644 --- a/src/datatypes/minecraft.js +++ b/src/datatypes/minecraft.js @@ -2,6 +2,7 @@ var nbt = require('prismarine-nbt'); var utils = require("./utils"); var numeric = require("./numeric"); +// TODO : remove type-specific, replace with generic containers and arrays. module.exports = { 'UUID': [readUUID, writeUUID, 16], 'position': [readPosition, writePosition, 8], diff --git a/src/debug.js b/src/debug.js new file mode 100644 index 0000000..f9b9b6a --- /dev/null +++ b/src/debug.js @@ -0,0 +1,17 @@ +var util = require('util') + +var debug; +if (process.env.NODE_DEBUG && /(minecraft-protocol|mc-proto)/.test(process.env.NODE_DEBUG)) { + var pid = process.pid; + debug = function(x) { + // if console is not set up yet, then skip this. + if (!console.error) + return; + console.error('MC-PROTO: %d', pid, + util.format.apply(util, arguments).slice(0, 500)); + }; +} else { + debug = function() { }; +} + +module.exports = debug; diff --git a/src/protocol.js b/src/protocol.js index 05d05f1..51b6ad7 100644 --- a/src/protocol.js +++ b/src/protocol.js @@ -1,110 +1,88 @@ var assert = require('assert'); -var util = require('util'); var zlib = require('zlib'); var evalCondition= require("./utils").evalCondition; var STRING_MAX_LENGTH = 240; + +function readPackets(packets,states) +{ + var packetFields = {}; + var packetNames = {}; + var packetIds = {}; + var packetStates = {toClient: {}, toServer: {}}; + for (var stateName in states) { + var state = states[stateName]; + + packetFields[state] = {toClient: [], toServer: []}; + packetNames[state] = {toClient: [], toServer: []}; + packetIds[state] = {toClient: [], toServer: []}; + + ['toClient', 'toServer'].forEach(function(direction) { + for (var name in packets[state][direction]) { + var info = packets[state][direction][name]; + var id = parseInt(info.id); + var fields = info.fields; + + assert(id !== undefined, 'missing id for packet '+name); + assert(fields !== undefined, 'missing fields for packet '+name); + assert(!packetNames[state][direction].hasOwnProperty(id), 'duplicate packet id '+id+' for '+name); + assert(!packetIds[state][direction].hasOwnProperty(name), 'duplicate packet name '+name+' for '+id); + assert(!packetFields[state][direction].hasOwnProperty(id), 'duplicate packet id '+id+' for '+name); + assert(!packetStates[direction].hasOwnProperty(name), 'duplicate packet name '+name+' for '+id+', must be unique across all states'); + + packetNames[state][direction][id] = name; + packetIds[state][direction][name] = id; + packetFields[state][direction][id] = fields; + packetStates[direction][name] = state; + } + }); + } + return { + packetFields:packetFields, + packetNames:packetNames, + packetIds:packetIds, + packetStates:packetStates + }; +} + // This is really just for the client. var states = { - "HANDSHAKING": "handshaking", - "STATUS": "status", - "LOGIN": "login", - "PLAY": "play" + "HANDSHAKING": "handshaking", + "STATUS": "status", + "LOGIN": "login", + "PLAY": "play" }; - var packets=require("../protocol/protocol"); +var packetIndexes=readPackets(packets,states); -var packetFields = {}; -var packetNames = {}; -var packetIds = {}; -var packetStates = {toClient: {}, toServer: {}}; -(function() { - for (var stateName in states) { - var state = states[stateName]; - - packetFields[state] = {toClient: [], toServer: []}; - packetNames[state] = {toClient: [], toServer: []}; - packetIds[state] = {toClient: [], toServer: []}; - - ['toClient', 'toServer'].forEach(function(direction) { - for (var name in packets[state][direction]) { - var info = packets[state][direction][name]; - var id = parseInt(info.id); - var fields = info.fields; - - assert(id !== undefined, 'missing id for packet '+name); - assert(fields !== undefined, 'missing fields for packet '+name); - assert(!packetNames[state][direction].hasOwnProperty(id), 'duplicate packet id '+id+' for '+name); - assert(!packetIds[state][direction].hasOwnProperty(name), 'duplicate packet name '+name+' for '+id); - assert(!packetFields[state][direction].hasOwnProperty(id), 'duplicate packet id '+id+' for '+name); - assert(!packetStates[direction].hasOwnProperty(name), 'duplicate packet name '+name+' for '+id+', must be unique across all states'); - - packetNames[state][direction][id] = name; - packetIds[state][direction][name] = id; - packetFields[state][direction][id] = fields; - packetStates[direction][name] = state; - } - }); - } -})(); - -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 types = { - 'byte': numeric.byte, - 'ubyte':numeric.ubyte, - 'short': numeric.short, - 'ushort': numeric.ushort, - 'int': numeric.int, - 'long': numeric.long, - 'varint': utils.varint, - 'float': numeric.float, - 'double': numeric.double, - 'bool': utils.bool, - 'string': utils.string, - 'ustring': utils.ustring, - 'container': structures.container, - 'array':structures.array, - 'buffer': utils.buffer, - 'count': structures.count, - 'condition': conditional.condition, - // TODO : remove type-specific, replace with generic containers and arrays. - 'restBuffer': minecraft.restBuffer, - 'UUID': minecraft.UUID, - 'position': minecraft.position, - 'slot': minecraft.slot, - 'nbt': minecraft.nbt, - 'entityMetadata': minecraft.entityMetadata -}; - - -var debug; -if (process.env.NODE_DEBUG && /(minecraft-protocol|mc-proto)/.test(process.env.NODE_DEBUG)) { - var pid = process.pid; - debug = function(x) { - // if console is not set up yet, then skip this. - if (!console.error) - return; - console.error('MC-PROTO: %d', pid, - util.format.apply(util, arguments).slice(0, 500)); - }; -} else { - debug = function() { }; -} +var packetFields = packetIndexes.packetFields; +var packetNames = packetIndexes.packetNames; +var packetIds = packetIndexes.packetIds; +var packetStates = packetIndexes.packetStates; function NMProtocols() { - + this.types={}; } +NMProtocols.prototype.addType = function(name,functions) +{ + this.types[name]=functions; +}; + +NMProtocols.prototype.addTypes = function(types) +{ + var self=this; + Object.keys(types).forEach(function(name){ + self.addType(name,types[name]); + }); +}; + + NMProtocols.prototype.read = function(buffer, cursor, fieldInfo, rootNodes) { - var type = types[fieldInfo.type]; + var type = this.types[fieldInfo.type]; if (!type) { return { error: new Error("missing data type: " + fieldInfo.type) @@ -119,7 +97,7 @@ NMProtocols.prototype.read = function(buffer, cursor, fieldInfo, rootNodes) { }; NMProtocols.prototype.write = function(value, buffer, offset, fieldInfo, rootNode) { - var type = types[fieldInfo.type]; + var type = this.types[fieldInfo.type]; if (!type) { return { error: new Error("missing data type: " + fieldInfo.type) @@ -129,7 +107,7 @@ NMProtocols.prototype.write = function(value, buffer, offset, fieldInfo, rootNod }; NMProtocols.prototype.sizeOf = function(value, fieldInfo, rootNode) { - var type = types[fieldInfo.type]; + var type = this.types[fieldInfo.type]; if (!type) { throw new Error("missing data type: " + fieldInfo.type); } @@ -140,7 +118,19 @@ NMProtocols.prototype.sizeOf = function(value, fieldInfo, rootNode) { } }; + +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); function get(packetId, state, toServer) { var direction = toServer ? "toServer" : "toClient"; @@ -282,7 +272,7 @@ function parsePacket(buffer, state, isServer, packetsToParse) { if (state == null) state = states.PLAY; var cursor = 0; var lengthField = utils.varint[0](buffer, 0); - if (!!!lengthField) return null; + if (!lengthField) return null; var length = lengthField.value; cursor += lengthField.size; if (length + lengthField.size > buffer.length) return null; // fail early @@ -324,9 +314,8 @@ module.exports = { packetNames: packetNames, packetFields: packetFields, packetStates: packetStates, - types: types, + types: proto.types, states: states, get: get, - debug: debug, evalCondition:evalCondition };