transform condition functions into objects

This commit is contained in:
Romain Beaumont 2015-05-08 03:08:30 +02:00
parent e47feb1cf6
commit bf8a7899ae
3 changed files with 69 additions and 150 deletions

View file

@ -119,9 +119,23 @@ for (var n in entityMetadataTypes) {
entityMetadataTypeBytes[entityMetadataTypes[n].type] = n; entityMetadataTypeBytes[entityMetadataTypes[n].type] = n;
} }
function evalCondition(condition,arg) function isFunction(functionToCheck) {
var getType = {};
return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}
function evalCondition(condition,field_values)
{ {
return condition(arg); if(!isFunction(condition))
{
var field_value_to_test="this" in condition && condition["this"] ? field_values["this"][condition.field] : field_values[condition.field];
var b=condition.values.some(function(value) {return field_value_to_test===value;});
if("different" in condition && condition["different"])
return !b;
else
return b;
}
return condition(field_values);
} }
function sizeOfEntityMetadata(value) { function sizeOfEntityMetadata(value) {
@ -869,4 +883,5 @@ module.exports = {
states: states, states: states,
get: get, get: get,
debug: debug, debug: debug,
evalCondition:evalCondition
}; };

View file

@ -147,15 +147,9 @@ module.exports= {
{ name: "yaw", type: "byte" }, { name: "yaw", type: "byte" },
{ name: "objectData", type: "container", typeArgs: { fields: [ { name: "objectData", type: "container", typeArgs: { fields: [
{ name: "intField", type: "int" }, { name: "intField", type: "int" },
{ name: "velocityX", type: "short", condition: function(field_values) { { name: "velocityX", type: "short", condition: {"field":"intField","values":[0],"different":true,"this":true}},
return field_values['this']['intField'] != 0; { name: "velocityY", type: "short", condition: {"field":"intField","values":[0],"different":true,"this":true}},
}}, { name: "velocityZ", type: "short", condition: {"field":"intField","values":[0],"different":true,"this":true}}
{ name: "velocityY", type: "short", condition: function(field_values) {
return field_values['this']['intField'] != 0;
}},
{ name: "velocityZ", type: "short", condition: function(field_values) {
return field_values['this']['intField'] != 0;
}}
]}} ]}}
]}, ]},
spawn_entity_living: {id: 0x0f, fields: [ spawn_entity_living: {id: 0x0f, fields: [
@ -389,9 +383,7 @@ module.exports= {
{ name: "inventoryType", type: "string" }, { name: "inventoryType", type: "string" },
{ name: "windowTitle", type: "string" }, { name: "windowTitle", type: "string" },
{ name: "slotCount", type: "ubyte" }, { name: "slotCount", type: "ubyte" },
{ name: "entityId", type: "int", condition: function(field_values) { { name: "entityId", type: "int", condition: {"field":"inventoryType","values":[11]}}
return field_values['inventoryType'] == 11;
} }
]}, ]},
close_window: {id: 0x2e, fields: [ close_window: {id: 0x2e, fields: [
{ name: "windowId", type: "ubyte" } { name: "windowId", type: "ubyte" }
@ -433,21 +425,11 @@ module.exports= {
{ name: "y", type: "byte" } { name: "y", type: "byte" }
]}}}, ]}}},
{ name: "columns", type: "byte" }, { name: "columns", type: "byte" },
{ name: "rows", type: "byte", condition: function(field_values) { { name: "rows", type: "byte", condition: {"field":"columns","values":[0],"different":true}},
return field_values["columns"] !== 0; { name: "x", type: "byte", condition: {"field":"columns","values":[0],"different":true}},
}}, { name: "y", type: "byte", condition: {"field":"columns","values":[0],"different":true}},
{ name: "x", type: "byte", condition: function(field_values) { { name: "dataLength", type: "count", typeArgs: { countFor: "data", type: "varint" }, condition: {"field":"columns","values":[0],"different":true}},
return field_values["columns"] !== 0; { name: "data", type: "buffer", typeArgs: { count: "dataLength" }, condition: {"field":"columns","values":[0],"different":true}},
}},
{ name: "y", type: "byte", condition: function(field_values) {
return field_values["columns"] !== 0;
}},
{ name: "dataLength", type: "count", typeArgs: { countFor: "data", type: "varint" }, condition: function(field_values) {
return field_values["columns"] !== 0;
}},
{ name: "data", type: "buffer", typeArgs: { count: "dataLength" }, condition: function(field_values) {
return field_values["columns"] !== 0;
}},
]}, ]},
tile_entity_data:{id: 0x35, fields: [ tile_entity_data:{id: 0x35, fields: [
{ name: "location", type: "position" }, { name: "location", type: "position" },
@ -471,34 +453,20 @@ module.exports= {
{ name: "length", type: "count", typeArgs: { type: "varint", countFor: "data" }}, { name: "length", type: "count", typeArgs: { type: "varint", countFor: "data" }},
{ name: "data", type: "array", typeArgs: { count: "length", type: "container", typeArgs: { fields: [ { name: "data", type: "array", typeArgs: { count: "length", type: "container", typeArgs: { fields: [
{ name: "UUID", type: "UUID" }, { name: "UUID", type: "UUID" },
{ name: "name", type: "string", condition: function(field_values) { { name: "name", type: "string", condition: {"field":"action","values":[0]}},
return field_values["action"] === 0; { name: "propertiesLength", type: "count", condition: {"field":"action","values":[0]}
}}, , typeArgs: { countFor: "this.properties", type: "varint" }},
{ name: "propertiesLength", type: "count", condition: function(field_values) { { name: "properties", type: "array", condition: {"field":"action","values":[0]}
return field_values["action"] === 0; , typeArgs: { count: "this.propertiesLength", type: "container", typeArgs: { fields: [
}, typeArgs: { countFor: "this.properties", type: "varint" }},
{ name: "properties", type: "array", condition: function(field_values) {
return field_values["action"] === 0;
}, typeArgs: { count: "this.propertiesLength", type: "container", typeArgs: { fields: [
{ name: "name", type: "string" }, { name: "name", type: "string" },
{ name: "value", type: "ustring" }, { name: "value", type: "ustring" },
{ name: "isSigned", type: "bool" }, { name: "isSigned", type: "bool" },
{ name: "signature", type: "ustring", condition: function(field_values) { { name: "signature", type: "ustring", condition: {"field":"isSigned","values":[true],"this":true}}
return field_values["this"]["isSigned"];
}}
]}}}, ]}}},
{ name: "gamemode", type: "varint", condition: function(field_values) { { name: "gamemode", type: "varint", condition: {"field":"action","values":[0,1]}},
return field_values["action"] === 0 || field_values["action"] === 1; { name: "ping", type: "varint", condition: {"field":"action","values":[0,2]}},
}}, { name: "hasDisplayName", type: "bool", condition: {"field":"action","values":[0,3]}},
{ name: "ping", type: "varint", condition: function(field_values) { { name: "displayName", type: "string", condition: {"field":"hasDisplayName","values":[true]}}
return field_values["action"] === 0 || field_values["action"] === 2;
}},
{ name: "hasDisplayName", type: "bool", condition: function(field_values) {
return field_values["action"] === 0 || field_values["action"] === 3;
}},
{ name: "displayName", type: "string", condition: function(field_values) {
return field_values["hasDisplayName"]; // Returns false if there is no value "hasDisplayName"
}}
]}}} ]}}}
]}, ]},
abilities: {id: 0x39, fields: [ abilities: {id: 0x39, fields: [
@ -513,20 +481,14 @@ module.exports= {
scoreboard_objective: {id: 0x3b, fields: [ scoreboard_objective: {id: 0x3b, fields: [
{ name: "name", type: "string" }, { name: "name", type: "string" },
{ name: "action", type: "byte" }, { name: "action", type: "byte" },
{ name: "displayText", type: "string", condition: function(field_values) { { name: "displayText", type: "string", condition: {"field":"action","values":[0,2]}},
return field_values["action"] == 0 || field_values["action"] == 2; { name: "type", type: "string", condition: {"field":"action","values":[0,2]}}
}},
{ name: "type", type: "string", condition: function(field_values) {
return field_values["action"] == 0 || field_values["action"] == 2;
}}
]}, ]},
scoreboard_score: {id: 0x3c, fields: [ /* TODO: itemName and scoreName may need to be switched */ scoreboard_score: {id: 0x3c, fields: [ /* TODO: itemName and scoreName may need to be switched */
{ name: "itemName", type: "string" }, { name: "itemName", type: "string" },
{ name: "action", type: "byte" }, { name: "action", type: "byte" },
{ name: "scoreName", type: "string" }, { name: "scoreName", type: "string" },
{ name: "value", type: "varint", condition: function(field_values) { { name: "value", type: "varint", condition: {"field":"action","values":[1],"different":true}}
return field_values['action'] != 1;
} }
]}, ]},
scoreboard_display_objective: {id: 0x3d, fields: [ scoreboard_display_objective: {id: 0x3d, fields: [
{ name: "position", type: "byte" }, { name: "position", type: "byte" },
@ -535,30 +497,14 @@ module.exports= {
scoreboard_team: {id: 0x3e, fields: [ scoreboard_team: {id: 0x3e, fields: [
{ name: "team", type: "string" }, { name: "team", type: "string" },
{ name: "mode", type: "byte" }, { name: "mode", type: "byte" },
{ name: "name", type: "string", condition: function(field_values) { { name: "name", type: "string", condition: {"field":"mode","values":[0,2]}},
return field_values['mode'] == 0 || field_values['mode'] == 2; { name: "prefix", type: "string", condition: {"field":"mode","values":[0,2]}},
} }, { name: "suffix", type: "string", condition: {"field":"mode","values":[0,2]}},
{ name: "prefix", type: "string", condition: function(field_values) { { name: "friendlyFire", type: "byte", condition: {"field":"mode","values":[0,2]}},
return field_values['mode'] == 0 || field_values['mode'] == 2; { name: "nameTagVisibility", type: "string", condition: {"field":"mode","values":[0,2]}},
} }, { name: "color", type: "byte", condition: {"field":"mode","values":[0,2]}},
{ name: "suffix", type: "string", condition: function(field_values) { { name: "playerCount", type: "count", condition: {"field":"mode","values":[0,3,4]}, typeArgs: { type: "short", countFor: "players" } },
return field_values['mode'] == 0 || field_values['mode'] == 2; { name: "players", type: "array", condition: {"field":"mode","values":[0,3,4]}, typeArgs: { type: "string", count: "playerCount" } }
} },
{ name: "friendlyFire", type: "byte", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 2;
} },
{ name: "nameTagVisibility", type: "string", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 2;
} },
{ name: "color", type: "byte", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 2;
} },
{ name: "playerCount", type: "count", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 3 || field_values['mode'] == 4;
}, typeArgs: { type: "short", countFor: "players" } },
{ name: "players", type: "array", condition: function(field_values) {
return field_values['mode'] == 0 || field_values['mode'] == 3 || field_values['mode'] == 4;
}, typeArgs: { type: "string", count: "playerCount" } }
]}, ]},
custom_payload: {id: 0x3f, fields: [ custom_payload: {id: 0x3f, fields: [
{ name: "channel", type: "string" }, { name: "channel", type: "string" },
@ -572,66 +518,32 @@ module.exports= {
]}, ]},
combat_event: { id: 0x42, fields: [ combat_event: { id: 0x42, fields: [
{ name: "event", type: "varint"}, { name: "event", type: "varint"},
{ name: "duration", type: "varint", condition: function(field_values) { { name: "duration", type: "varint", condition: {"field":"event","values":[1]}},
return field_values['event'] == 1; { name: "playerId", type: "varint", condition: {"field":"event","values":[2]}},
} }, { name: "entityId", type: "int", condition: {"field":"event","values":[1,2]}},
{ name: "playerId", type: "varint", condition: function(field_values) { { name: "message", type: "string", condition: {"field":"event","values":[2]}}
return field_values['event'] == 2;
} },
{ name: "entityId", type: "int", condition: function(field_values) {
return field_values['event'] == 1 || field_values['event'] == 2;
} },
{ name: "message", type: "string", condition: function(field_values) {
return field_values['event'] == 2;
} }
]}, ]},
camera: { id: 0x43, fields: [ camera: { id: 0x43, fields: [
{ name: "cameraId", type: "varint" } { name: "cameraId", type: "varint" }
]}, ]},
world_border: { id: 0x44, fields: [ world_border: { id: 0x44, fields: [
{ name: "action", type: "varint"}, { name: "action", type: "varint"},
{ name: "radius", type: "double", condition: function(field_values) { { name: "radius", type: "double", condition: {"field":"action","values":[0]}},
return field_values['action'] == 0; { name: "x", type: "double", condition: {"field":"action","values":[2,3]}},
} }, { name: "z", type: "double", condition: {"field":"action","values":[2,3]}},
{ name: "x", type: "double", condition: function(field_values) { { name: "old_radius", type: "double", condition: {"field":"action","values":[1,3]}},
return field_values['action'] == 2 || field_values['action'] == 3; { name: "new_radius", type: "double", condition: {"field":"action","values":[1,3]}},
} }, { name: "speed", type: "varint", condition: {"field":"action","values":[1,3]}},
{ name: "z", type: "double", condition: function(field_values) { { name: "portalBoundary", type: "varint", condition: {"field":"action","values":[3]}},
return field_values['action'] == 2 || field_values['action'] == 3; { name: "warning_time", type: "varint", condition: {"field":"action","values":[4,3]}},
} }, { name: "warning_blocks", type: "varint", condition: {"field":"action","values":[5,3]}}
{ name: "old_radius", type: "double", condition: function(field_values) {
return field_values['action'] == 1 || field_values['action'] == 3;
} },
{ name: "new_radius", type: "double", condition: function(field_values) {
return field_values['action'] == 1 || field_values['action'] == 3;
} },
{ name: "speed", type: "varint", condition: function(field_values) {
return field_values['action'] == 1 || field_values['action'] == 3;
} },
{ name: "portalBoundary", type: "varint", condition: function(field_values) {
return field_values['action'] == 3;
} },
{ name: "warning_time", type: "varint", condition: function(field_values) {
return field_values['action'] == 4 || field_values['action'] == 3;
} },
{ name: "warning_blocks", type: "varint", condition: function(field_values) {
return field_values['action'] == 5 || field_values['action'] == 3;
} }
]}, ]},
title: { id: 0x45, fields: [ title: { id: 0x45, fields: [
{ name: "action", type: "varint"}, { name: "action", type: "varint"},
{ name: "text", type: "string", condition: function(field_values) { { name: "text", type: "string", condition: {"field":"action","values":[0,1]}},
return field_values['action'] == 0 || field_values['action'] == 1; { name: "fadeIn", type: "int", condition: {"field":"action","values":[2]}},
} }, { name: "stay", type: "int", condition: {"field":"action","values":[2]}},
{ name: "fadeIn", type: "int", condition: function(field_values) { { name: "fadeOut", type: "int", condition: {"field":"action","values":[2]}}
return field_values['action'] == 2;
} },
{ name: "stay", type: "int", condition: function(field_values) {
return field_values['action'] == 2;
} },
{ name: "fadeOut", type: "int", condition: function(field_values) {
return field_values['action'] == 2;
} }
]}, ]},
set_compression: { id: 0x46, fields: [ set_compression: { id: 0x46, fields: [
{ name: "threshold", type: "varint"} { name: "threshold", type: "varint"}
@ -659,15 +571,9 @@ module.exports= {
use_entity: {id: 0x02, fields: [ use_entity: {id: 0x02, fields: [
{ name: "target", type: "varint" }, { name: "target", type: "varint" },
{ name: "mouse", type: "varint" }, { name: "mouse", type: "varint" },
{ name: "x", type: "float", condition: function(field_values) { { name: "x", type: "float", condition: {"field":"mouse","values":[2]}},
return field_values["mouse"] == 2; { name: "y", type: "float", condition: {"field":"mouse","values":[2]}},
}}, { name: "z", type: "float", condition: {"field":"mouse","values":[2]}},
{ name: "y", type: "float", condition: function(field_values) {
return field_values["mouse"] == 2;
}},
{ name: "z", type: "float", condition: function(field_values) {
return field_values["mouse"] == 2;
}},
]}, ]},
flying: {id: 0x03, fields: [ flying: {id: 0x03, fields: [
{ name: "onGround", type: "bool" } { name: "onGround", type: "bool" }
@ -757,9 +663,7 @@ module.exports= {
tab_complete: {id: 0x14, fields: [ tab_complete: {id: 0x14, fields: [
{ name: "text", type: "string" }, { name: "text", type: "string" },
{ name: "hasPosition", type: "bool" }, { name: "hasPosition", type: "bool" },
{ name: "block", type: "position", condition: function(field_values) { { name: "block", type: "position", condition: {"field":"hasPosition","values":[true]}}
return field_values['hasPosition'];
} }
]}, ]},
settings: {id: 0x15, fields: [ settings: {id: 0x15, fields: [
{ name: "locale", type: "string" }, { name: "locale", type: "string" },

View file

@ -173,7 +173,7 @@ describe("packets", function() {
// empty object uses default values // empty object uses default values
var packet = {}; var packet = {};
packetInfo.forEach(function(field) { packetInfo.forEach(function(field) {
if (!field.hasOwnProperty("condition") || field.condition(packet)) { if (!field.hasOwnProperty("condition") || protocol.evalCondition(field.condition,packet)) {
var fieldVal = values[field.type]; var fieldVal = values[field.type];
if (typeof fieldVal === "undefined") { if (typeof fieldVal === "undefined") {
throw new Error("No value for type " + field.type); throw new Error("No value for type " + field.type);