simplify and fix entityMetadata parsing and serializing

This commit is contained in:
Andrew Kelley 2013-01-08 02:44:17 -05:00
parent 5b44fdfdf8
commit 0aa52864df
3 changed files with 37 additions and 38 deletions

View file

@ -112,27 +112,16 @@ server.on('login', function(client) {
#### entityMetadata #### entityMetadata
When *writing* a packet with an entityMetadata data type field, the structure Value looks like this:
looks like this:
```js ```js
[ [
{type: 'slot', value: slot}, {type: 'slot', value: slot, key: 3},
{type: 'int', value: value}, {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 Where the key is the numeric metadata key and the value is the value of the
correct data type. correct data type.

View file

@ -510,30 +510,33 @@ for (var n in entityMetadataTypes) {
function EntityMetadataWriter(value) { function EntityMetadataWriter(value) {
this.value = []; this.value = [];
this.size = 1; this.size = 1 + value.length;
value.forEach(function(item) { var item, Writer, writer, dataType;
this.size += 1; for (var i = 0; i < value.length; ++i) {
var Writer = types[item.type][1]; 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); 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.size += writer.size;
this.value.push({ this.value.push({
writer: writer, writer: writer,
key: item.key, key: item.key,
type: entityMetadataTypeBytes[item.type], type: entityMetadataTypeBytes[item.type],
}); });
}); }
} }
EntityMetadataWriter.prototype.write = function(buffer, offset) { EntityMetadataWriter.prototype.write = function(buffer, offset) {
this.value.forEach(function(item) { this.value.forEach(function(item) {
var headerByte = (item.type << 5) & item.key; var headerByte = (item.type << 5) | item.key;
buffer.write(headerByte, offset); buffer.writeUInt8(headerByte, offset);
offset += 1; offset += 1;
item.writer.write(buffer, offset); item.writer.write(buffer, offset);
offset += item.writer.size; offset += item.writer.size;
}); });
buffer.writeUInt8(127, offset); buffer.writeUInt8(0x7f, offset);
} }
function ObjectDataWriter(value) { function ObjectDataWriter(value) {
@ -708,26 +711,34 @@ function readIntVector(buffer, offset) {
function readEntityMetadata(buffer, offset) { function readEntityMetadata(buffer, offset) {
var cursor = offset; var cursor = offset;
var metadata = {}; var metadata = [];
var item, key, type, results, reader; var item, key, type, results, reader, typeName, dataType;
while (true) { while (true) {
if (cursor + 1 > buffer.length) return null; if (cursor + 1 > buffer.length) return null;
item = buffer.readUInt8(cursor); item = buffer.readUInt8(cursor);
cursor += 1; cursor += 1;
if (item === 0x7f) break; if (item === 0x7f) {
return {
value: metadata,
size: cursor - offset,
};
}
key = item & 0x1f; key = item & 0x1f;
type = item >> 5; 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); assert.ok(reader, "missing reader for entity metadata type " + type);
results = reader(buffer, cursor); results = reader(buffer, cursor);
if (! results) return null; if (! results) return null;
metadata[key] = results.value; metadata.push({
key: key,
value: results.value,
type: typeName,
});
cursor += results.size; cursor += results.size;
} }
return {
value: metadata,
size: cursor - offset,
};
} }
function readObjectData(buffer, offset) { function readObjectData(buffer, offset) {

View file

@ -86,7 +86,11 @@ var values = {
addBitMap: 10, addBitMap: 10,
}], }],
}, ok], }, ok],
'entityMetadata': [[], ok], 'entityMetadata': [[{
type: 'int',
key: 3,
value: 100,
}], ok],
'objectData': [{ 'objectData': [{
intField: 9, intField: 9,
velocityX: 1, velocityX: 1,
@ -153,11 +157,6 @@ describe("packets", function() {
assertPacketsMatch(receivedPacket, clientReceivedPacket); assertPacketsMatch(receivedPacket, clientReceivedPacket);
done(); done();
}); });
// entityMetadata does not have the same format sending and receiving
// we skip the test.
if (receivedPacket.metadata) {
return done();
}
serverClient.write(packetId, receivedPacket); serverClient.write(packetId, receivedPacket);
}); });
client.write(packetId, packet); client.write(packetId, packet);