mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2024-11-14 19:04:59 -05:00
Add extend type support
This commit is contained in:
parent
ee3b865daa
commit
79ded321bf
8 changed files with 81 additions and 79 deletions
|
@ -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"
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
14
test/test.js
14
test/test.js
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue