mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2024-11-14 19:04:59 -05:00
Add nbt support
This commit is contained in:
parent
25f2658895
commit
de0ea4f3f6
2 changed files with 68 additions and 22 deletions
|
@ -1,6 +1,7 @@
|
||||||
var assert = require('assert');
|
var assert = require('assert');
|
||||||
var util = require('util');
|
var util = require('util');
|
||||||
var zlib = require('zlib');
|
var zlib = require('zlib');
|
||||||
|
var nbt = require('nbt');
|
||||||
|
|
||||||
var STRING_MAX_LENGTH = 240;
|
var STRING_MAX_LENGTH = 240;
|
||||||
var SRV_STRING_MAX_LENGTH = 32767;
|
var SRV_STRING_MAX_LENGTH = 32767;
|
||||||
|
@ -853,6 +854,7 @@ var types = {
|
||||||
// TODO : remove type-specific, replace with generic containers and arrays.
|
// TODO : remove type-specific, replace with generic containers and arrays.
|
||||||
'position': [readPosition, writePosition, 8],
|
'position': [readPosition, writePosition, 8],
|
||||||
'slot': [readSlot, writeSlot, sizeOfSlot],
|
'slot': [readSlot, writeSlot, sizeOfSlot],
|
||||||
|
'nbt': [readNbt, writeBuffer, sizeOfBuffer],
|
||||||
'entityMetadata': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata],
|
'entityMetadata': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -957,6 +959,21 @@ function readEntityMetadata(buffer, offset) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function readNbt(buffer, offset) {
|
||||||
|
buffer = buffer.slice(offset);
|
||||||
|
return nbt.parseUncompressed(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeNbt(value, buffer, offset) {
|
||||||
|
var newbuf = nbt.writeUncompressed(value);
|
||||||
|
newbuf.copy(buffer, offset);
|
||||||
|
return offset + newbuf.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sizeOfNbt(value) {
|
||||||
|
return nbt.writeUncompressed(value).length;
|
||||||
|
}
|
||||||
|
|
||||||
function readString (buffer, offset) {
|
function readString (buffer, offset) {
|
||||||
var length = readVarInt(buffer, offset);
|
var length = readVarInt(buffer, offset);
|
||||||
if (!!!length) return null;
|
if (!!!length) return null;
|
||||||
|
@ -1078,27 +1095,31 @@ function readPosition(buffer, offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function readSlot(buffer, offset) {
|
function readSlot(buffer, offset) {
|
||||||
|
var value = {};
|
||||||
var results = readShort(buffer, offset);
|
var results = readShort(buffer, offset);
|
||||||
if (! results) return null;
|
if (! results) return null;
|
||||||
var blockId = results.value;
|
value.blockId = results.value;
|
||||||
var cursor = offset + results.size;
|
var cursor = offset + results.size;
|
||||||
|
|
||||||
if (blockId === -1) {
|
if (value.blockId === -1) {
|
||||||
return {
|
return {
|
||||||
value: { id: blockId },
|
value: value,
|
||||||
size: cursor - offset,
|
size: cursor - offset,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
var cursorEnd = cursor + 5;
|
var cursorEnd = cursor + 4;
|
||||||
if (cursorEnd > buffer.length) return null;
|
if (cursorEnd > buffer.length) return null;
|
||||||
var itemCount = buffer.readInt8(cursor);
|
value.itemCount = buffer.readInt8(cursor);
|
||||||
var itemDamage = buffer.readInt16BE(cursor + 1);
|
value.itemDamage = buffer.readInt16BE(cursor + 1);
|
||||||
var nbtDataSize = buffer.readInt16BE(cursor + 3);
|
var nbtData = buffer.readInt8(cursor + 3);
|
||||||
if (nbtDataSize === -1) nbtDataSize = 0;
|
if (nbtData == 0) {
|
||||||
var nbtDataEnd = cursorEnd + nbtDataSize;
|
return {
|
||||||
if (nbtDataEnd > buffer.length) return null;
|
value: value,
|
||||||
var nbtData = buffer.slice(cursorEnd, nbtDataEnd);
|
size: cursor + 4 - offset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var nbtData = readNbt(buffer, offset);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
value: {
|
value: {
|
||||||
|
@ -1112,7 +1133,13 @@ function readSlot(buffer, offset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function sizeOfSlot(value) {
|
function sizeOfSlot(value) {
|
||||||
return value.id === -1 ? 2 : 7 + value.nbtData.length;
|
if (value.id === -1)
|
||||||
|
return (2);
|
||||||
|
else if (!value.nbtData) {
|
||||||
|
return (6);
|
||||||
|
} else {
|
||||||
|
return (5 + sizeOfNbt(value.nbtData));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function writePosition(value, buffer, offset) {
|
function writePosition(value, buffer, offset) {
|
||||||
|
@ -1127,11 +1154,19 @@ function writeSlot(value, buffer, offset) {
|
||||||
if (value.id === -1) return offset + 2;
|
if (value.id === -1) return offset + 2;
|
||||||
buffer.writeInt8(value.itemCount, offset + 2);
|
buffer.writeInt8(value.itemCount, offset + 2);
|
||||||
buffer.writeInt16BE(value.itemDamage, offset + 3);
|
buffer.writeInt16BE(value.itemDamage, offset + 3);
|
||||||
var nbtDataSize = value.nbtData.length;
|
var nbtDataLen;
|
||||||
if (nbtDataSize === 0) nbtDataSize = -1; // I don't know wtf mojang smokes
|
if (value.nbtData)
|
||||||
buffer.writeInt16BE(nbtDataSize, offset + 5);
|
{
|
||||||
value.nbtData.copy(buffer, offset + 7);
|
var newbuf = nbt.writeUncompressed(value.nbtData);
|
||||||
return offset + 7 + value.nbtData.length;
|
buffer.write(newbuf, offset + 5);
|
||||||
|
nbtDataLen = newbuf.length;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
buffer.writeInt8(0, offset + 5);
|
||||||
|
nbtDataLen = 1;
|
||||||
|
}
|
||||||
|
return offset + 5 + nbtDataLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sizeOfString(value) {
|
function sizeOfString(value) {
|
||||||
|
@ -1247,6 +1282,7 @@ function readContainer(buffer, offset, typeArgs, rootNode) {
|
||||||
};
|
};
|
||||||
// BLEIGH. Huge hack because I have no way of knowing my current name.
|
// BLEIGH. Huge hack because I have no way of knowing my current name.
|
||||||
// TODO : either pass fieldInfo instead of typeArgs as argument (bleigh), or send name as argument (verybleigh).
|
// TODO : either pass fieldInfo instead of typeArgs as argument (bleigh), or send name as argument (verybleigh).
|
||||||
|
// TODO : what I do inside of roblabla/Protocols is have each "frame" create a new empty slate with just a "super" object pointing to the parent.
|
||||||
rootNode.this = results.value;
|
rootNode.this = results.value;
|
||||||
for (var index in typeArgs.fields) {
|
for (var index in typeArgs.fields) {
|
||||||
var readResults = read(buffer, offset, typeArgs.fields[index], rootNode);
|
var readResults = read(buffer, offset, typeArgs.fields[index], rootNode);
|
||||||
|
@ -1370,8 +1406,17 @@ function read(buffer, cursor, fieldInfo, rootNodes) {
|
||||||
error: new Error("missing data type: " + fieldInfo.type)
|
error: new Error("missing data type: " + fieldInfo.type)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
var readResults = type[0](buffer, cursor, fieldInfo.typeArgs, rootNodes);
|
var readResults = type[0](buffer, cursor, fieldInfo.typeArgs, rootNodes);
|
||||||
if (readResults.error) return { error: readResults.error };
|
} catch (e) {
|
||||||
|
console.log("fieldInfo : " + JSON.stringify(fieldInfo));
|
||||||
|
console.log("rootNodes : " + JSON.stringify(rootNodes));
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (readResults == null) {
|
||||||
|
throw new Error("Reader returned null : " + JSON.stringify(fieldInfo));
|
||||||
|
}
|
||||||
|
if (readResults && readResults.error) return { error: readResults.error };
|
||||||
return readResults;
|
return readResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,12 @@
|
||||||
"batch": "~0.3.1"
|
"batch": "~0.3.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-rsa": "^0.1.53",
|
|
||||||
"superagent": "~0.10.0",
|
|
||||||
"buffer-equal": "0.0.0",
|
|
||||||
"ansi-color": "0.2.1",
|
"ansi-color": "0.2.1",
|
||||||
"node-uuid": "~1.4.1"
|
"buffer-equal": "0.0.0",
|
||||||
|
"nbt": "git://github.com/roblabla/nbt-js",
|
||||||
|
"node-rsa": "^0.1.53",
|
||||||
|
"node-uuid": "~1.4.1",
|
||||||
|
"superagent": "~0.10.0"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"ursa": "~0.8.0"
|
"ursa": "~0.8.0"
|
||||||
|
|
Loading…
Reference in a new issue