From 0aa52864df1495daa94a59ef8bbd4fe6f3a9de3a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 8 Jan 2013 02:44:17 -0500 Subject: [PATCH] simplify and fix entityMetadata parsing and serializing --- README.md | 17 +++-------------- lib/protocol.js | 47 +++++++++++++++++++++++++++++------------------ test/test.js | 11 +++++------ 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 7db1a03..79d0567 100644 --- a/README.md +++ b/README.md @@ -112,27 +112,16 @@ server.on('login', function(client) { #### entityMetadata -When *writing* a packet with an entityMetadata data type field, the structure -looks like this: +Value looks like this: ```js [ - {type: 'slot', value: slot}, - {type: 'int', value: value}, + {type: 'slot', value: slot, key: 3}, + {type: 'int', value: value, key: 4}, ... ] ``` -When *receiving* a packet with an entityMetadata data type field, the structure -looks like this: - -```js -{ - 1: value, - 3: value, -} -``` - Where the key is the numeric metadata key and the value is the value of the correct data type. diff --git a/lib/protocol.js b/lib/protocol.js index b6e04ac..0d2f984 100644 --- a/lib/protocol.js +++ b/lib/protocol.js @@ -510,30 +510,33 @@ for (var n in entityMetadataTypes) { function EntityMetadataWriter(value) { this.value = []; - this.size = 1; - value.forEach(function(item) { - this.size += 1; - var Writer = types[item.type][1]; + this.size = 1 + value.length; + var item, Writer, writer, dataType; + for (var i = 0; i < value.length; ++i) { + item = value[i]; + dataType = types[item.type]; + assert.ok(dataType, "unknown data type " + dataType); + Writer = dataType[1]; assert.ok(Writer, "missing writer for data type " + item.type); - var writer = new Writer(item.value); + writer = new Writer(item.value); this.size += writer.size; this.value.push({ writer: writer, key: item.key, type: entityMetadataTypeBytes[item.type], }); - }); + } } EntityMetadataWriter.prototype.write = function(buffer, offset) { this.value.forEach(function(item) { - var headerByte = (item.type << 5) & item.key; - buffer.write(headerByte, offset); + var headerByte = (item.type << 5) | item.key; + buffer.writeUInt8(headerByte, offset); offset += 1; item.writer.write(buffer, offset); offset += item.writer.size; }); - buffer.writeUInt8(127, offset); + buffer.writeUInt8(0x7f, offset); } function ObjectDataWriter(value) { @@ -708,26 +711,34 @@ function readIntVector(buffer, offset) { function readEntityMetadata(buffer, offset) { var cursor = offset; - var metadata = {}; - var item, key, type, results, reader; + var metadata = []; + var item, key, type, results, reader, typeName, dataType; while (true) { if (cursor + 1 > buffer.length) return null; item = buffer.readUInt8(cursor); cursor += 1; - if (item === 0x7f) break; + if (item === 0x7f) { + return { + value: metadata, + size: cursor - offset, + }; + } key = item & 0x1f; type = item >> 5; - reader = types[entityMetadataTypes[type]][0]; + typeName = entityMetadataTypes[type]; + dataType = types[typeName]; + assert.ok(dataType, "unrecognized entity metadata type " + type); + reader = dataType[0]; assert.ok(reader, "missing reader for entity metadata type " + type); results = reader(buffer, cursor); if (! results) return null; - metadata[key] = results.value; + metadata.push({ + key: key, + value: results.value, + type: typeName, + }); cursor += results.size; } - return { - value: metadata, - size: cursor - offset, - }; } function readObjectData(buffer, offset) { diff --git a/test/test.js b/test/test.js index 8146067..5c0de89 100644 --- a/test/test.js +++ b/test/test.js @@ -86,7 +86,11 @@ var values = { addBitMap: 10, }], }, ok], - 'entityMetadata': [[], ok], + 'entityMetadata': [[{ + type: 'int', + key: 3, + value: 100, + }], ok], 'objectData': [{ intField: 9, velocityX: 1, @@ -153,11 +157,6 @@ describe("packets", function() { assertPacketsMatch(receivedPacket, clientReceivedPacket); done(); }); - // entityMetadata does not have the same format sending and receiving - // we skip the test. - if (receivedPacket.metadata) { - return done(); - } serverClient.write(packetId, receivedPacket); }); client.write(packetId, packet);