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
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.

View file

@ -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) {

View file

@ -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);