New way to handle conditional fields in packets

Some packets have conditional fields. The previous way to handle
those was to provide a single condition for each packet type
which determined if additional fields are appended to the packet.
Unfortunately this is not enough for some packets: They have
complex conditions that cannot be expressed this way.

This diff changes the way conditional fields are handled: For
each field in each packet there is a new optional 'condition'
function which will be called with the packet data. Only if
the 'condition' function returns true, the field is de/encoded.

This diff also adds new (previously missing) conditions.
This commit is contained in:
Florian Wesch 2013-08-26 13:00:28 +02:00
parent 65fc158d97
commit 170566d700

View File

@ -360,7 +360,10 @@ var packets = {
{ name: "inventoryType", type: "byte" },
{ name: "windowTitle", type: "string" },
{ name: "slotCount", type: "byte" },
{ name: "useProvidedTitle", type: "bool" }
{ name: "useProvidedTitle", type: "bool" },
{ name: "entityId", type: "int", condition: function(field_values) {
return field_values['inventoryType'] == 11;
} }
],
0x65: [
{ name: "windowId", type: "byte" }
@ -462,8 +465,12 @@ var packets = {
0xcf: [
{ name: "itemName", type: "string" },
{ name: "remove", type: "bool" },
{ name: "scoreName", type: "string" },
{ name: "value", type: "int" }
{ name: "scoreName", type: "string", condition: function(field_values) {
return !field_values['remove']
} },
{ name: "value", type: "int", condition: function(field_values) {
return !field_values['remove']
} }
],
0xd0: [
{ name: "position", type: "byte" },
@ -472,11 +479,21 @@ var packets = {
0xd1: [
{ name: "team", type: "string" },
{ name: "mode", type: "byte" },
{ name: "name", type: "string" },
{ name: "prefix", type: "string" },
{ name: "suffix", type: "string" },
{ name: "friendlyFire", type: "byte" },
{ name: "players", type: "stringArray" }
{ name: "name", type: "string", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 2;
} },
{ name: "prefix", type: "string", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 2;
} },
{ name: "suffix", type: "string", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 2;
} },
{ name: "friendlyFire", type: "byte", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 2;
} },
{ name: "players", type: "stringArray", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 3 || field_values['mode'] == 4;
} }
],
0xfa: [
{ name: "channel", type: "string" },
@ -505,17 +522,6 @@ var packets = {
]
};
packet_optional_fields = {
0x64: {
condition: function(field_values) {
return field_values["inventoryType"] === 11;
},
fields: [
{ name: "entityId", type: "int" }
]
}
};
var types = {
'int': [readInt, writeInt, 4],
'short': [readShort, writeShort, 2],
@ -1393,18 +1399,17 @@ function createPacketBuffer(packetId, params, isServer) {
var packet = get(packetId, !isServer);
assert.notEqual(packet, null);
packet.forEach(function(fieldInfo) {
var condition = fieldInfo.condition;
if (typeof condition != "undefined" && !condition(params))
return;
size += sizeOf(fieldInfo.type, params[fieldInfo.name]);
});
var optionalFields, i;
if (packet_optional_fields[packetId] && packet_optional_fields[packetId].condition && packet_optional_fields[packetId].condition(params)) {
optionalFields = packet_optional_fields[packetId].fields;
for (i = 0; i < optionalFields.length; ++i) {
size += sizeOf(optionalFields[i].type, params[optionalFields[i].name]);
}
}
var buffer = new Buffer(size);
var offset = writeUByte(packetId, buffer, 0);
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;
@ -1444,6 +1449,9 @@ function parsePacket(buffer, 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))
continue;
readResults = readPacketField(fieldInfo);
if (!readResults || readResults.error) {
return readResults;
@ -1451,17 +1459,6 @@ function parsePacket(buffer, isServer) {
results[fieldInfo.name] = readResults.value;
size += readResults.size;
}
if (packet_optional_fields[packetId] && packet_optional_fields[packetId].condition(results)) {
for (i = 0; i < packet_optional_fields[packetId].fields.length; ++i) {
fieldInfo = packet_optional_fields[packetId].fields[i];
readResults = readPacketField(fieldInfo);
if (!readResults || readResults.error) {
return readResults;
}
results[fieldInfo.name] = readResults.value;
size += readResults.size;
}
}
debug(results);
return {
size: size,