Add extend type support

This commit is contained in:
roblabla 2015-08-27 11:36:07 +00:00
parent ee3b865daa
commit 79ded321bf
8 changed files with 81 additions and 79 deletions

View file

@ -42,12 +42,13 @@
"dependencies": { "dependencies": {
"babel-runtime": "^5.4.4", "babel-runtime": "^5.4.4",
"buffer-equal": "0.0.0", "buffer-equal": "0.0.0",
"lodash.reduce": "^3.1.2",
"minecraft-data": "0.8.1",
"node-uuid": "~1.4.1", "node-uuid": "~1.4.1",
"prismarine-nbt": "0.0.1", "prismarine-nbt": "0.0.1",
"readable-stream": "^1.1.0", "readable-stream": "^1.1.0",
"superagent": "~0.10.0", "superagent": "~0.10.0",
"ursa-purejs": "0.0.3", "ursa-purejs": "0.0.3"
"minecraft-data": "0.7.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"ursa": "~0.8.0" "ursa": "~0.8.0"

View file

@ -1,5 +1,5 @@
var version = require('./version'); var version = require('./version');
var packets = require('minecraft-data')(version.majorVersion).protocol; var packets = require('minecraft-data')(version.majorVersion).protocol.states;
var readPackets = require("./packets").readPackets; var readPackets = require("./packets").readPackets;
var packetIndexes = readPackets(packets, states); var packetIndexes = readPackets(packets, states);
var utils = require("./utils"); var utils = require("./utils");

View file

@ -8,7 +8,7 @@ var EventEmitter = require('events').EventEmitter
, states = serializer.states , states = serializer.states
; ;
var version = require('./version'); var version = require('./version');
var packets = require('minecraft-data')(version.majorVersion).protocol; var packets = require('minecraft-data')(version.majorVersion).protocol.states;
var readPackets = require("./packets").readPackets; var readPackets = require("./packets").readPackets;
var packetIndexes = readPackets(packets, states); var packetIndexes = readPackets(packets, states);

View file

@ -147,56 +147,11 @@ function sizeOfRestBuffer(value) {
return value.length; return value.length;
} }
var entityMetadataTypes = { function readEntityMetadata(buffer, offset, typeArgs, context) {
0: {type: 'byte'},
1: {type: 'short'},
2: {type: 'int'},
3: {type: 'float'},
4: {type: 'string'},
5: {type: 'slot'},
6: {
type: 'container', typeArgs: {
fields: [
{name: 'x', type: 'int'},
{name: 'y', type: 'int'},
{name: 'z', type: 'int'}
]
}
},
7: {
type: 'container', typeArgs: {
fields: [
{name: 'pitch', type: 'float'},
{name: 'yaw', type: 'float'},
{name: 'roll', type: 'float'}
]
}
}
};
// maps string type name to number
var entityMetadataTypeBytes = {};
for(var n in entityMetadataTypes) {
if(!entityMetadataTypes.hasOwnProperty(n)) continue;
entityMetadataTypeBytes[entityMetadataTypes[n].type] = n;
}
// container is ambiguous
function findByte(type,value)
{
if(type!="container")
return entityMetadataTypeBytes[type];
return value["x"]===undefined ? 7 : 6;
}
function readEntityMetadata(buffer, offset) {
var cursor = offset; var cursor = offset;
var metadata = []; var metadata = [];
var item, key, type, results, reader, typeName, dataType; var item, key, type, results, reader, typeName, dataType;
while(true) { while(true) {
if(cursor + 1 > buffer.length) return null;
item = buffer.readUInt8(cursor); item = buffer.readUInt8(cursor);
cursor += 1; cursor += 1;
if(item === 0x7f) { if(item === 0x7f) {
@ -207,46 +162,33 @@ function readEntityMetadata(buffer, offset) {
} }
key = item & 0x1f; key = item & 0x1f;
type = item >> 5; type = item >> 5;
dataType = entityMetadataTypes[type]; var results = this.read(buffer, cursor, ["entityMetadataItem", { "compareTo": "type" }], { type });
typeName = dataType.type;
//debug("Reading entity metadata type " + dataType + " (" + ( typeName || "unknown" ) + ")");
if(!dataType) {
return {
error: new Error("unrecognized entity metadata type " + type)
}
}
results = this.read(buffer, cursor, dataType, {});
if(!results) return null;
metadata.push({ metadata.push({
key: key, key,
type,
value: results.value, value: results.value,
type: typeName,
}); });
cursor += results.size; cursor += results.size;
} }
} }
function writeEntityMetadata(value, buffer, offset) { function writeEntityMetadata(value, buffer, offset) {
var self = this; var self = this;
value.forEach(function(item) { value.forEach(function(item) {
var type = findByte(item.type,item.value); buffer.writeUInt8(item.type << 5 | item.key, offset);
var headerByte = (type << 5) | item.key;
buffer.writeUInt8(headerByte, offset);
offset += 1; offset += 1;
offset = self.write(item.value, buffer, offset, entityMetadataTypes[type], {}); offset = self.write(item.value, buffer, offset, ["entityMetadataItem", { "compareTo": "type" }], item);
}); });
buffer.writeUInt8(0x7f, offset); buffer.writeUInt8(0x7f, offset);
return offset + 1; return offset + 1;
} }
function sizeOfEntityMetadata(value) { function sizeOfEntityMetadata(value) {
var size = 1 + value.length; var size = 1 + value.length;
var item; var item;
for(var i = 0; i < value.length; ++i) { for(var i = 0; i < value.length; ++i) {
item = value[i]; item = value[i];
size += this.sizeOf(item.value, entityMetadataTypes[findByte(item.type,item.value)], {}); size += this.sizeOf(item.value, ["entityMetadataItem", { "compareTo": "type" }], item);
} }
return size; return size;
} }

View file

@ -4,7 +4,7 @@ var Yggdrasil = require('./yggdrasil.js');
var serializer = require("./transforms/serializer"); var serializer = require("./transforms/serializer");
var utils = require("./utils"); var utils = require("./utils");
var version = require("./version"); var version = require("./version");
var packets = require('minecraft-data')(version.majorVersion).protocol; var packets = require('minecraft-data')(version.majorVersion).protocol.states;
var readPackets = require("./packets").readPackets; var readPackets = require("./packets").readPackets;
var packetIndexes = readPackets(packets, serializer.states); var packetIndexes = readPackets(packets, serializer.states);
var createClient = require("./createClient"); var createClient = require("./createClient");

View file

@ -1,13 +1,69 @@
var { getFieldInfo } = require('./utils'); var { getFieldInfo } = require('./utils');
var reduce = require('lodash.reduce');
function NMProtocols() { function NMProtocols() {
this.types = {}; this.types = {};
} }
function isFieldInfo(type) {
return typeof type === "string"
|| (Array.isArray(type) && typeof type[0] === "string")
|| type.type;
}
NMProtocols.prototype.addType = function(name, functions) { NMProtocols.prototype.addType = function(name, functions) {
this.types[name] = functions; if (functions === "native")
return;
else if (isFieldInfo(functions)) {
var fieldInfo = getFieldInfo(functions);
this.types[name] = extendType(this.types[fieldInfo.type], fieldInfo.typeArgs);
}
else
this.types[name] = functions;
}; };
function findArgs(acc, v, k) {
if (typeof v === "string" && v.charAt(0) === '$')
acc.push({ "path": k, "val": v.substr(1) });
else if (Array.isArray(v) || typeof v === "object")
acc = acc.concat(reduce(v, findArgs, []).map((v) => ({ "path": k + "." + v.path, "val": v.val })));
return acc;
}
function setField(path, val, into) {
var c = path.split('.').reverse();
while (c.length > 1) {
into = into[c.pop()];
}
into[c.pop()] = val;
}
function extendType(functions, defaultTypeArgs) {
var argPos = reduce(defaultTypeArgs, findArgs, []);
return [function read(buffer, offset, typeArgs, context) {
var args = JSON.parse(JSON.stringify(defaultTypeArgs));
argPos.forEach((v) => {
setField(v.path, typeArgs[v.val], args);
});
return functions[0].call(this, buffer, offset, args, context);
}, function write(value, buffer, offset, typeArgs, context) {
var args = JSON.parse(JSON.stringify(defaultTypeArgs));
argPos.forEach((v) => {
setField(v.path, typeArgs[v.val], args);
});
return functions[1].call(this, value, buffer, offset, args, context);
}, function sizeOf(value, typeArgs, context) {
var args = JSON.parse(JSON.stringify(defaultTypeArgs));
argPos.forEach((v) => {
setField(v.path, typeArgs[v.val], args);
});
if (typeof functions[2] === "function")
return functions[2].call(this, value, args, context);
else
return functions[2];
}];
}
NMProtocols.prototype.addTypes = function(types) { NMProtocols.prototype.addTypes = function(types) {
var self = this; var self = this;
Object.keys(types).forEach(function(name) { Object.keys(types).forEach(function(name) {

View file

@ -44,13 +44,14 @@ proto.addTypes(minecraft);
proto.addTypes(structures); proto.addTypes(structures);
proto.addTypes(conditional); proto.addTypes(conditional);
module.exports.types = proto.types; module.exports.types = proto.types;
var version = require('../version'); var version = require('../version');
var packets = require('minecraft-data')(version.majorVersion).protocol; var packets = require('minecraft-data')(version.majorVersion).protocol;
proto.addTypes(packets.types);
var readPackets = require("../packets").readPackets; var readPackets = require("../packets").readPackets;
var packetIndexes = readPackets(packets, states); var packetIndexes = readPackets(packets.states, states);
var packetFields = packetIndexes.packetFields; var packetFields = packetIndexes.packetFields;
var packetNames = packetIndexes.packetNames; var packetNames = packetIndexes.packetNames;

View file

@ -115,12 +115,14 @@ var values = {
}, },
'long': [0, 1], 'long': [0, 1],
'entityMetadata': [ 'entityMetadata': [
{key: 17, value: 0, type: 'int'}, {key: 17, value: 0, type: 0},
{key: 0, value: 0, type: 'byte'}, {key: 0, value: 257, type: 1},
{key: 16, value: 0, type: 'byte'}, {key: 16, value: 626, type: 2},
{key: 1, value: 300, type: 'short'}, {key: 1, value: 0.15, type: 3},
{key: 19, value: 0, type: 'int'}, {key: 19, value: "Some string", type: 4},
{key: 18, value: 1, type: 'int'}, //{key: 18, value: {}, type: 5}, Slot is a pain, I'll do it later
{key: 18, value: { x: 0, y: 0, z: 0 }, type: 6},
{key: 18, value: { pitch: 0.5, yaw: 0.7, roll: 12.4 }, type: 7},
], ],
'objectData': { 'objectData': {
intField: 9, intField: 9,