diff --git a/lib/protocol.js b/lib/protocol.js index 4d86f5e..a349b3b 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -633,20 +633,21 @@ var packetStates = {toClient: {}, toServer: {}}; var types = { - 'int': [readInt, writeInt, 4], - 'short': [readShort, writeShort, 2], - 'ushort': [readUShort, writeUShort, 2], 'byte': [readByte, writeByte, 1], 'ubyte': [readUByte, writeUByte, 1], - 'string': [readString, writeString, sizeOfString], - 'ustring': [readString, writeString, sizeOfUString], - 'byteArray16': [readByteArray16, writeByteArray16, sizeOfByteArray16], - 'bool': [readBool, writeBool, 1], - 'double': [readDouble, writeDouble, 8], - 'float': [readFloat, writeFloat, 4], - 'slot': [readSlot, writeSlot, sizeOfSlot], + 'short': [readShort, writeShort, 2], + 'ushort': [readUShort, writeUShort, 2], + 'int': [readInt, writeInt, 4], 'long': [readLong, writeLong, 8], 'varint': [readVarInt, writeVarInt, sizeOfVarInt], + 'float': [readFloat, writeFloat, 4], + 'double': [readDouble, writeDouble, 8], + 'bool': [readBool, writeBool, 1], + 'string': [readString, writeString, sizeOfString], + 'ustring': [readString, writeString, sizeOfUString], // TODO : remove ustring + // TODO : remove type-specific, replace with generic containers and arrays. + 'slot': [readSlot, writeSlot, sizeOfSlot], + 'byteArray16': [readByteArray16, writeByteArray16, sizeOfByteArray16], 'ascii': [readAscii, writeAscii, sizeOfAscii], 'entityMetadata': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata], 'byteArray32': [readByteArray32, writeByteArray32, sizeOfByteArray32], @@ -728,7 +729,7 @@ function sizeOfEntityMetadata(value) { var item; for (var i = 0; i < value.length; ++i) { item = value[i]; - size += sizeOf(item.type, item.value); + size += sizeOf(item.value, { type: item.type }, {}); } return size; } @@ -1599,6 +1600,50 @@ function writeMatchArray(value, buffer, offset) { return offset; } +function read(buffer, cursor, fieldInfo, rootNodes) { + if (fieldInfo.condition && !fieldInfo.condition(rootNodes)) { + return null; + } + var type = types[fieldInfo.type]; + if (!type) { + return { + error: new Error("missing data type: " + fieldInfo.type) + }; + } + var readResults = type[0](buffer, cursor, fieldInfo.typeArgs, rootNodes); + if (readResults.error) return { error: readResults.error }; + + return readResults; +} + +function write(value, buffer, offset, fieldInfo, rootNodes) { + if (fieldInfo.condition && !fieldInfo.condition(rootNodes)) { + return null; + } + var type = types[fieldInfo.type]; + if (!type) { + return { + error: new Error("missing data type: " + fieldInfo.type) + }; + } + return type[1](value, buffer, offset, fieldInfo.typeArgs); +} + +function sizeOf(value, fieldInfo, rootNodes) { + if (fieldInfo.condition && !fieldInfo.condition(rootNodes)) { + return 0; + } + var type = types[fieldInfo.type]; + if (!type) { + throw new Error("missing data type: " + fieldInfo.type); + } + if (typeof type[2] === 'function') { + return type[2](value, fieldInfo.typeArgs); + } else { + return type[2]; + } +} + function get(packetId, state, toServer) { var direction = toServer ? "toServer" : "toClient"; var packetInfo = packetFields[state][direction][packetId]; @@ -1608,17 +1653,6 @@ function get(packetId, state, toServer) { return packetInfo; } -function sizeOf(type, value) { - var dataType = types[type]; - assert.ok(dataType, "unknown data type " + type); - var size = dataType[2]; - if (typeof size === "function") { - return size(value); - } else { - return size; - } -} - function createPacketBuffer(packetId, state, params, isServer) { var length = 0; if (typeof packetId === 'string' && typeof state !== 'string' && !params) { @@ -1632,10 +1666,7 @@ function createPacketBuffer(packetId, state, params, isServer) { var packet = get(packetId, state, !isServer); assert.notEqual(packet, null); packet.forEach(function(fieldInfo) { - var condition = fieldInfo.condition; - if (typeof condition != "undefined" && !condition(params)) - return; - length += sizeOf(fieldInfo.type, params[fieldInfo.name]); + length += sizeOf(params[fieldInfo.name], fieldInfo, params); }); length += sizeOfVarInt(packetId); var size = length + sizeOfVarInt(length); @@ -1643,32 +1674,14 @@ function createPacketBuffer(packetId, state, params, isServer) { var offset = writeVarInt(length, buffer, 0); offset = writeVarInt(packetId, buffer, offset); packet.forEach(function(fieldInfo) { - var condition = fieldInfo.condition; - if (typeof condition != "undefined" && !condition(params)) - return; - var write = types[fieldInfo.type][1]; var value = params[fieldInfo.name]; - if(typeof value === "undefined") value = 0; - offset = write(value, buffer, offset); + if(typeof value === "undefined") value = 0; // TODO : Why ? + offset = write(value, buffer, offset, fieldInfo, params); }); return buffer; } function parsePacket(buffer, state, isServer) { - - function readPacketField(fieldInfo) { - var read = types[fieldInfo.type][0]; - if (!read) { - return { - error: new Error("missing reader for data type: " + fieldInfo.type) - } - } - var readResults = read(buffer, cursor); - if (! readResults) return null; // buffer needs to be more full - if (readResults.error) return { error: readResults.error }; - - return readResults; - } if (state == null) state == states.PLAY; var cursor = 0; var lengthField = readVarInt(buffer, 0); @@ -1697,13 +1710,10 @@ function parsePacket(buffer, state, isServer) { var i, fieldInfo, readResults; for (i = 0; i < packetInfo.length; ++i) { fieldInfo = packetInfo[i]; - var condition = fieldInfo.condition; - if (typeof condition != "undefined" && !condition(results)) { - results[fieldInfo.name] = null; - continue; - } - readResults = readPacketField(fieldInfo); - if (!!!readResults) { + readResults = read(buffer, cursor, fieldInfo, results); + /* A deserializer cannot return null anymore. Besides, read() returns + * null when the condition is not fulfilled. + if (!!!readResults) { var error = new Error("A deserializer returned null"); error.packetId = packetId; error.fieldInfo = fieldInfo.name; @@ -1712,7 +1722,8 @@ function parsePacket(buffer, state, isServer) { error: error, results: results }; - } + }*/ + if (readResults === null) continue; if (readResults.error) { return readResults; } diff --git a/test/test.js b/test/test.js index ff74845..8923326 100644 --- a/test/test.js +++ b/test/test.js @@ -164,7 +164,9 @@ describe("packets", function() { // empty object uses default values var packet = {}; packetInfo.forEach(function(field) { - packet[field.name] = values[field.type]; + if (!field.hasOwnProperty("condition") || field.condition(packet)) { + packet[field.name] = values[field.type]; + } }); if (toServer) { serverClient.once([state, packetId], function(receivedPacket) {