add minecraft datatype file for minecraft specific packets

This commit is contained in:
Romain Beaumont 2015-05-13 02:58:07 +02:00
parent 6f460e1626
commit 3b7ae54b88
2 changed files with 195 additions and 175 deletions

138
src/datatypes/minecraft.js Normal file
View File

@ -0,0 +1,138 @@
var nbt = require('prismarine-nbt');
var utils = require("./utils");
var numeric = require("./numeric");
module.exports = {
'UUID': [readUUID, writeUUID, 16],
'position': [readPosition, writePosition, 8],
'slot': [readSlot, writeSlot, sizeOfSlot],
'nbt': [readNbt, utils.buffer[1], utils.buffer[2]]
};
function readUUID(buffer, offset) {
return {
value: [
buffer.readUInt32BE(offset),
buffer.readUInt32BE(offset + 4),
buffer.readUInt32BE(offset + 8),
buffer.readUInt32BE(offset + 12),
],
size: 16,
};
}
function writeUUID(value, buffer, offset) {
buffer.writeUInt32BE(value[0], offset);
buffer.writeUInt32BE(value[1], offset + 4);
buffer.writeUInt32BE(value[2], offset + 8);
buffer.writeUInt32BE(value[3], offset + 12);
return offset + 16;
}
function readPosition(buffer, offset) {
var longVal = numeric.long[0](buffer, offset).value;
var x = signExtend26(longVal[0] >> 6);
var y = signExtend12(((longVal[0] & 0x3f) << 6) | ((longVal[1] >> 26) & 0x3f));
var z = signExtend26(longVal[1] & 0x3FFFFFF);
return {
value: { x: x, y: y, z: z },
size: 8
};
}
function signExtend26(value) {
if (value > 0x2000000) value -= 0x4000000;
return value;
}
function signExtend12(value) {
if (value > 0x800) value -= 0x1000;
return value;
}
function writePosition(value, buffer, offset) {
var longVal = [];
longVal[0] = ((value.x & 0x3FFFFFF) << 6) | ((value.y & 0xFFF) >> 6);
longVal[1] = ((value.y & 0x3F) << 26) | (value.z & 0x3FFFFFF);
return numeric.long[1](longVal, buffer, offset);
}
function readSlot(buffer, offset) {
var value = {};
var results = numeric.short[0](buffer, offset);
if (! results) return null;
value.blockId = results.value;
if (value.blockId === -1) {
return {
value: value,
size: 2,
};
}
var cursorEnd = offset + 6;
if (cursorEnd > buffer.length) return null;
value.itemCount = buffer.readInt8(offset + 2);
value.itemDamage = buffer.readInt16BE(offset + 3);
var nbtData = buffer.readInt8(offset + 5);
if (nbtData == 0) {
return {
value: value,
size: 6
}
}
var nbtData = readNbt(buffer, offset + 5);
value.nbtData = nbtData.value;
return {
value: value,
size: nbtData.size + 5
};
}
function writeSlot(value, buffer, offset) {
buffer.writeInt16BE(value.blockId, offset);
if (value.blockId === -1) return offset + 2;
buffer.writeInt8(value.itemCount, offset + 2);
buffer.writeInt16BE(value.itemDamage, offset + 3);
var nbtDataLen;
if (value.nbtData)
{
var newbuf = nbt.writeUncompressed(value.nbtData);
newbuf.copy(buffer, offset + 5);
nbtDataLen = newbuf.length;
}
else
{
buffer.writeInt8(0, offset + 5);
nbtDataLen = 1;
}
return offset + 5 + nbtDataLen;
}
function sizeOfSlot(value) {
if (value.blockId === -1)
return (2);
else if (!value.nbtData) {
return (6);
} else {
return (5 + sizeOfNbt(value.nbtData));
}
}
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;
}

View File

@ -1,7 +1,6 @@
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('prismarine-nbt');
var getField= require("./utils").getField; var getField= require("./utils").getField;
@ -53,6 +52,7 @@ var packetStates = {toClient: {}, toServer: {}};
var numeric=require("./datatypes/numeric"); var numeric=require("./datatypes/numeric");
var utils=require("./datatypes/utils"); var utils=require("./datatypes/utils");
var minecraft=require("./datatypes/minecraft");
var types = { var types = {
'byte': numeric.byte, 'byte': numeric.byte,
@ -66,17 +66,17 @@ var types = {
'double': numeric.double, 'double': numeric.double,
'bool': utils.bool, 'bool': utils.bool,
'string': utils.string, 'string': utils.string,
'ustring': utils.ustring, // TODO : remove ustring 'ustring': utils.ustring,
'UUID': [readUUID, writeUUID, 16], 'UUID': minecraft.UUID,
'container': [readContainer, writeContainer, sizeOfContainer], 'container': [readContainer, writeContainer, sizeOfContainer],
'array': [readArray, writeArray, sizeOfArray], 'array': [readArray, writeArray, sizeOfArray],
'buffer': utils.buffer, 'buffer': utils.buffer,
'restBuffer': [readRestBuffer, utils.buffer[1], utils.buffer[2]], 'restBuffer': [readRestBuffer, utils.buffer[1], utils.buffer[2]],
'count': [readCount, writeCount, sizeOfCount], 'count': [readCount, writeCount, sizeOfCount],
// 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': minecraft.position,
'slot': [readSlot, writeSlot, sizeOfSlot], 'slot': minecraft.slot,
'nbt': [readNbt, utils.buffer[1], utils.buffer[2]], 'nbt': minecraft.nbt,
'entityMetadata': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata], 'entityMetadata': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata],
'condition': [readCondition, writeCondition, sizeOfCondition] 'condition': [readCondition, writeCondition, sizeOfCondition]
}; };
@ -154,184 +154,66 @@ function evalCondition(condition,field_values)
return b; return b;
} }
function sizeOfEntityMetadata(value) {
var size = 1 + value.length;
var item;
for (var i = 0; i < value.length; ++i) {
item = value[i];
size += sizeOf(item.value, entityMetadataTypes[entityMetadataTypeBytes[item.type]], {});
}
return size;
}
function writeEntityMetadata(value, buffer, offset) {
value.forEach(function(item) {
var type = entityMetadataTypeBytes[item.type];
var headerByte = (type << 5) | item.key;
buffer.writeUInt8(headerByte, offset);
offset += 1;
offset = write(item.value, buffer, offset, entityMetadataTypes[type], {});
});
buffer.writeUInt8(0x7f, offset);
return offset + 1;
}
function writeUUID(value, buffer, offset) {
buffer.writeUInt32BE(value[0], offset);
buffer.writeUInt32BE(value[1], offset + 4);
buffer.writeUInt32BE(value[2], offset + 8);
buffer.writeUInt32BE(value[3], offset + 12);
return offset + 16;
}
function readEntityMetadata(buffer, offset) { 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; 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) {
return { return {
value: metadata, value: metadata,
size: cursor - offset, size: cursor - offset,
}; };
}
key = item & 0x1f;
type = item >> 5;
dataType = entityMetadataTypes[type];
typeName = dataType.type;
//debug("Reading entity metadata type " + dataType + " (" + ( typeName || "unknown" ) + ")");
if (!dataType) {
return {
error: new Error("unrecognized entity metadata type " + type)
}
}
results = read(buffer, cursor, dataType, {});
if (! results) return null;
metadata.push({
key: key,
value: results.value,
type: typeName,
});
cursor += results.size;
} }
key = item & 0x1f; }
type = item >> 5;
dataType = entityMetadataTypes[type];
typeName = dataType.type;
//debug("Reading entity metadata type " + dataType + " (" + ( typeName || "unknown" ) + ")"); function writeEntityMetadata(value, buffer, offset) {
if (!dataType) { value.forEach(function(item) {
return { var type = entityMetadataTypeBytes[item.type];
error: new Error("unrecognized entity metadata type " + type) var headerByte = (type << 5) | item.key;
} buffer.writeUInt8(headerByte, offset);
} offset += 1;
results = read(buffer, cursor, dataType, {}); offset = write(item.value, buffer, offset, entityMetadataTypes[type], {});
if (! results) return null;
metadata.push({
key: key,
value: results.value,
type: typeName,
}); });
cursor += results.size; buffer.writeUInt8(0x7f, offset);
} return offset + 1;
} }
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) { function sizeOfEntityMetadata(value) {
return nbt.writeUncompressed(value).length; var size = 1 + value.length;
} var item;
for (var i = 0; i < value.length; ++i) {
function readUUID(buffer, offset) { item = value[i];
return { size += sizeOf(item.value, entityMetadataTypes[entityMetadataTypeBytes[item.type]], {});
value: [
buffer.readUInt32BE(offset),
buffer.readUInt32BE(offset + 4),
buffer.readUInt32BE(offset + 8),
buffer.readUInt32BE(offset + 12),
],
size: 16,
};
}
function readPosition(buffer, offset) {
var longVal = numeric.long[0](buffer, offset).value;
var x = signExtend26(longVal[0] >> 6);
var y = signExtend12(((longVal[0] & 0x3f) << 6) | ((longVal[1] >> 26) & 0x3f));
var z = signExtend26(longVal[1] & 0x3FFFFFF);
return {
value: { x: x, y: y, z: z },
size: 8
};
}
function signExtend26(value) {
if (value > 0x2000000) value -= 0x4000000;
return value;
}
function signExtend12(value) {
if (value > 0x800) value -= 0x1000;
return value;
}
function readSlot(buffer, offset) {
var value = {};
var results = numeric.short[0](buffer, offset);
if (! results) return null;
value.blockId = results.value;
if (value.blockId === -1) {
return {
value: value,
size: 2,
};
}
var cursorEnd = offset + 6;
if (cursorEnd > buffer.length) return null;
value.itemCount = buffer.readInt8(offset + 2);
value.itemDamage = buffer.readInt16BE(offset + 3);
var nbtData = buffer.readInt8(offset + 5);
if (nbtData == 0) {
return {
value: value,
size: 6
} }
} return size;
var nbtData = readNbt(buffer, offset + 5);
value.nbtData = nbtData.value;
return {
value: value,
size: nbtData.size + 5
};
}
function sizeOfSlot(value) {
if (value.blockId === -1)
return (2);
else if (!value.nbtData) {
return (6);
} else {
return (5 + sizeOfNbt(value.nbtData));
}
}
function writePosition(value, buffer, offset) {
var longVal = [];
longVal[0] = ((value.x & 0x3FFFFFF) << 6) | ((value.y & 0xFFF) >> 6);
longVal[1] = ((value.y & 0x3F) << 26) | (value.z & 0x3FFFFFF);
return numeric.long[1](longVal, buffer, offset);
}
function writeSlot(value, buffer, offset) {
buffer.writeInt16BE(value.blockId, offset);
if (value.blockId === -1) return offset + 2;
buffer.writeInt8(value.itemCount, offset + 2);
buffer.writeInt16BE(value.itemDamage, offset + 3);
var nbtDataLen;
if (value.nbtData)
{
var newbuf = nbt.writeUncompressed(value.nbtData);
newbuf.copy(buffer, offset + 5);
nbtDataLen = newbuf.length;
}
else
{
buffer.writeInt8(0, offset + 5);
nbtDataLen = 1;
}
return offset + 5 + nbtDataLen;
} }