diff --git a/package.json b/package.json index 0190e52..f51dbf1 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "readable-stream": "^1.1.0", "superagent": "~0.10.0", "ursa-purejs": "0.0.3", - "minecraft-data": "0.6.0" + "minecraft-data": "0.7.0" }, "optionalDependencies": { "ursa": "~0.8.0" diff --git a/src/browser.js b/src/browser.js index 686c1b3..1d3a9a3 100644 --- a/src/browser.js +++ b/src/browser.js @@ -16,5 +16,4 @@ module.exports = { packetStates: packetIndexes.packetStates, types: serializer.types, get: serializer.get, - evalCondition: utils.evalCondition, }; diff --git a/src/datatypes/conditional.js b/src/datatypes/conditional.js index 2bb82b3..679fdd2 100644 --- a/src/datatypes/conditional.js +++ b/src/datatypes/conditional.js @@ -1,25 +1,41 @@ -var evalCondition = require("../utils").evalCondition; +var { getField, getFieldInfo } = require('../utils'); module.exports = { - 'condition': [readCondition, writeCondition, sizeOfCondition] + 'switch': [readSwitch, writeSwitch, sizeOfSwitch], }; -function readCondition(buffer, offset, typeArgs, rootNode) { - if(!evalCondition(typeArgs, rootNode)) - return {value: null, size: 0}; - return this.read(buffer, offset, typeArgs.type, rootNode); +function readSwitch(buffer, offset, typeArgs, rootNode) { + var compareTo = getField(typeArgs.compareTo, rootNode); + var fieldInfo; + if (typeof typeArgs.fields[compareTo] === 'undefined' && typeof typeArgs.default === "undefined") + throw new Error(compareTo + " has no associated fieldInfo in switch"); + else if (typeof typeArgs.fields[compareTo] === 'undefined') + fieldInfo = getFieldInfo(typeArgs.default); + else + fieldInfo = getFieldInfo(typeArgs.fields[compareTo]); + return this.read(buffer, offset, fieldInfo, rootNode); } -function writeCondition(value, buffer, offset, typeArgs, rootNode) { - if(!evalCondition(typeArgs, rootNode)) - return offset; - - return this.write(value, buffer, offset, typeArgs.type, rootNode); +function writeSwitch(value, buffer, offset, typeArgs, rootNode) { + var compareTo = getField(typeArgs.compareTo, rootNode); + var fieldInfo; + if (typeof typeArgs.fields[compareTo] === 'undefined' && typeof typeArgs.default === "undefined") + throw new Error(compareTo + " has no associated fieldInfo in switch"); + else if (typeof typeArgs.fields[compareTo] === 'undefined') + fieldInfo = getFieldInfo(typeArgs.default); + else + fieldInfo = getFieldInfo(typeArgs.fields[compareTo]); + return this.write(value, buffer, offset, fieldInfo, rootNode); } -function sizeOfCondition(value, typeArgs, rootNode) { - if(!evalCondition(typeArgs, rootNode)) - return 0; - - return this.sizeOf(value, typeArgs.type, rootNode); +function sizeOfSwitch(value, typeArgs, rootNode) { + var compareTo = getField(typeArgs.compareTo, rootNode); + var fieldInfo; + if (typeof typeArgs.fields[compareTo] === 'undefined' && typeof typeArgs.default === "undefined") + throw new Error(compareTo + " has no associated fieldInfo in switch"); + else if (typeof typeArgs.fields[compareTo] === 'undefined') + fieldInfo = getFieldInfo(typeArgs.default); + else + fieldInfo = getFieldInfo(typeArgs.fields[compareTo]); + return this.sizeOf(value, fieldInfo, rootNode); } diff --git a/src/datatypes/structures.js b/src/datatypes/structures.js index 2aac73b..453bc51 100644 --- a/src/datatypes/structures.js +++ b/src/datatypes/structures.js @@ -1,6 +1,5 @@ var getField = require("../utils").getField; var debug = require("../debug"); -var evalCondition = require("../utils").evalCondition; module.exports = { 'array': [readArray, writeArray, sizeOfArray], diff --git a/src/datatypes/utils.js b/src/datatypes/utils.js index d4c7c52..d7c8097 100644 --- a/src/datatypes/utils.js +++ b/src/datatypes/utils.js @@ -6,7 +6,8 @@ module.exports = { 'varint': [readVarInt, writeVarInt, sizeOfVarInt], 'bool': [readBool, writeBool, 1], 'string': [readString, writeString, sizeOfString], - 'buffer': [readBuffer, writeBuffer, sizeOfBuffer] + 'buffer': [readBuffer, writeBuffer, sizeOfBuffer], + 'void': [readVoid, writeVoid, 0], }; function readVarInt(buffer, offset) { @@ -131,3 +132,14 @@ function sizeOfBuffer(value, typeArgs, rootNode) { } return size + value.length; } + +function readVoid() { + return { + value: undefined, + size: 0, + }; +} + +function writeVoid(value, buffer, offset) { + return offset; +} diff --git a/src/index.js b/src/index.js index 368905e..7b4169a 100644 --- a/src/index.js +++ b/src/index.js @@ -24,7 +24,6 @@ module.exports = { packetStates: packetIndexes.packetStates, types: serializer.types, get: serializer.get, - evalCondition: utils.evalCondition, ping: require('./ping'), yggdrasil: Yggdrasil, version: version.version, diff --git a/src/transforms/serializer.js b/src/transforms/serializer.js index 181d462..6b6c406 100644 --- a/src/transforms/serializer.js +++ b/src/transforms/serializer.js @@ -47,7 +47,6 @@ proto.addTypes(conditional); module.exports.types = proto.types; -var evalCondition = require("../utils").evalCondition; var version = require('../version'); var packets = require('minecraft-data')(version.majorVersion).protocol; var readPackets = require("../packets").readPackets; @@ -88,8 +87,8 @@ function createPacketBuffer(packetId, state, params, isServer) { offset = utils.varint[1](packetId, buffer, offset); packet.forEach(function(fieldInfo) { var value = params[fieldInfo.name]; - // TODO : A better check is probably needed - if(typeof value === "undefined" && fieldInfo.type != "count" && (fieldInfo.type != "condition" || evalCondition(fieldInfo.typeArgs, params))) + // TODO : This check belongs to the respective datatype. + if(typeof value === "undefined" && fieldInfo.type != "count") debug(new Error("Missing Property " + fieldInfo.name).stack); offset = proto.write(value, buffer, offset, fieldInfo.type, params); }); diff --git a/src/utils.js b/src/utils.js index 3d1dc3b..6ca36fb 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,7 +1,6 @@ module.exports = { getField: getField, getFieldInfo: getFieldInfo, - evalCondition: evalCondition }; function getField(countField, rootNode) { @@ -23,14 +22,3 @@ function getFieldInfo(fieldInfo) { else throw new Error("Not a fieldinfo"); } - -function evalCondition(condition, field_values) { - var field_value_to_test = "this" in condition && condition["this"] ? field_values["this"][condition.field] : field_values[condition.field]; - var b = condition.values.some(function(value) { - return field_value_to_test === value; - }); - if("different" in condition && condition["different"]) - return !b; - else - return b; -} diff --git a/test/test.js b/test/test.js index ad3ff76..5a955d4 100644 --- a/test/test.js +++ b/test/test.js @@ -15,7 +15,7 @@ var mc = require('../') , SURVIVE_TIME = 10000 , MC_SERVER_PATH = path.join(__dirname, 'server') , getFieldInfo = require('../dist/utils').getFieldInfo - , evalCondition = require('../dist/utils').evalCondition + , getField = require('../dist/utils').getField ; var defaultServerProps = { @@ -62,30 +62,16 @@ var values = { 'ubyte': 8, 'string': "hi hi this is my client string", 'buffer': new Buffer(8), - 'array': function(_typeArgs, packet) { - var typeArgs = getFieldInfo(_typeArgs.type) - if(typeof values[typeArgs.type] === "undefined") { - throw new Error("No data type for " + typeArgs.type); - } - if(typeof values[typeArgs.type] === "function") { - return [values[typeArgs.type](typeArgs.typeArgs, packet)]; - } - return [values[typeArgs.type]]; + 'array': function(typeArgs, packet) { + return [getValue(typeArgs.type, packet)]; }, 'container': function(typeArgs, packet) { var results = {}; for(var index in typeArgs) { - if(typeof values[getFieldInfo(typeArgs[index].type).type] === "undefined") { - throw new Error("No data type for " + typeArgs[index].type); - } - if(typeof values[getFieldInfo(typeArgs[index].type).type] === "function") { - var backupThis = packet.this; - packet.this = results; - results[typeArgs[index].name] = values[getFieldInfo(typeArgs[index].type).type](getFieldInfo(typeArgs[index].type).typeArgs, packet); - packet.this = backupThis; - } else { - results[typeArgs[index].name] = values[getFieldInfo(typeArgs[index].type).type]; - } + var backupThis = packet.this; + packet.this = results; + results[typeArgs[index].name] = getValue(typeArgs[index].type, packet); + packet.this = backupThis; } return results; }, @@ -127,16 +113,25 @@ var values = { 'UUID': "00112233-4455-6677-8899-aabbccddeeff", 'position': {x: 12, y: 332, z: 4382821}, 'restBuffer': new Buffer(0), - 'condition': function(typeArgs, packet) { - if (evalCondition(typeArgs, packet)) { - if (typeof values[getFieldInfo(typeArgs.type).type] === "function") - return values[getFieldInfo(typeArgs.type).type](getFieldInfo(typeArgs.type).typeArgs, packet); - else - return values[getFieldInfo(typeArgs.type).type]; - } - } + 'switch': function(typeArgs, packet) { + var i = typeArgs.fields[getField(typeArgs.compareTo, packet)]; + if (typeof i === "undefined") + return getValue(typeArgs.default, packet); + else + return getValue(i, packet); + }, }; +function getValue(_type, packet) { + var fieldInfo = getFieldInfo(_type); + if (typeof values[fieldInfo.type] === "function") + return values[fieldInfo.type](fieldInfo.typeArgs, packet); + else if (values[fieldInfo.type] !== "undefined") + return values[fieldInfo.type]; + else if (fieldInfo.type !== "void") + throw new Error("No value for type " + fieldInfo.type); +} + describe("packets", function() { var client, server, serverClient; before(function(done) { @@ -188,14 +183,7 @@ describe("packets", function() { // empty object uses default values var packet = {}; packetInfo.forEach(function(field) { - var fieldVal = values[getFieldInfo(field.type).type]; - if(typeof fieldVal === "undefined") { - throw new Error("No value for type " + field.type); - } - if(typeof fieldVal === "function") { - fieldVal = fieldVal(getFieldInfo(field.type).typeArgs, packet); - } - packet[field.name] = fieldVal; + packet[field.name] = getValue(field.type, packet); }); if(toServer) { serverClient.once([state, packetId], function(receivedPacket) {