mirror of
https://github.com/unmojang/node-minecraft-protocol.git
synced 2025-09-29 22:23:21 -04:00
Proper generic read/write/sizeOf functions
This commit is contained in:
parent
7b9f170fb2
commit
c0ba7f8127
117
lib/protocol.js
117
lib/protocol.js
@ -633,20 +633,21 @@ var packetStates = {toClient: {}, toServer: {}};
|
||||
|
||||
|
||||
var types = {
|
||||
'int': [readInt, writeInt, 4],
|
||||
'short': [readShort, writeShort, 2],
|
||||
'ushort': [readUShort, writeUShort, 2],
|
||||
'byte': [readByte, writeByte, 1],
|
||||
'ubyte': [readUByte, writeUByte, 1],
|
||||
'string': [readString, writeString, sizeOfString],
|
||||
'ustring': [readString, writeString, sizeOfUString],
|
||||
'byteArray16': [readByteArray16, writeByteArray16, sizeOfByteArray16],
|
||||
'bool': [readBool, writeBool, 1],
|
||||
'double': [readDouble, writeDouble, 8],
|
||||
'float': [readFloat, writeFloat, 4],
|
||||
'slot': [readSlot, writeSlot, sizeOfSlot],
|
||||
'short': [readShort, writeShort, 2],
|
||||
'ushort': [readUShort, writeUShort, 2],
|
||||
'int': [readInt, writeInt, 4],
|
||||
'long': [readLong, writeLong, 8],
|
||||
'varint': [readVarInt, writeVarInt, sizeOfVarInt],
|
||||
'float': [readFloat, writeFloat, 4],
|
||||
'double': [readDouble, writeDouble, 8],
|
||||
'bool': [readBool, writeBool, 1],
|
||||
'string': [readString, writeString, sizeOfString],
|
||||
'ustring': [readString, writeString, sizeOfUString], // TODO : remove ustring
|
||||
// TODO : remove type-specific, replace with generic containers and arrays.
|
||||
'slot': [readSlot, writeSlot, sizeOfSlot],
|
||||
'byteArray16': [readByteArray16, writeByteArray16, sizeOfByteArray16],
|
||||
'ascii': [readAscii, writeAscii, sizeOfAscii],
|
||||
'entityMetadata': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata],
|
||||
'byteArray32': [readByteArray32, writeByteArray32, sizeOfByteArray32],
|
||||
@ -728,7 +729,7 @@ function sizeOfEntityMetadata(value) {
|
||||
var item;
|
||||
for (var i = 0; i < value.length; ++i) {
|
||||
item = value[i];
|
||||
size += sizeOf(item.type, item.value);
|
||||
size += sizeOf(item.value, { type: item.type }, {});
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@ -1599,6 +1600,50 @@ function writeMatchArray(value, buffer, offset) {
|
||||
return offset;
|
||||
}
|
||||
|
||||
function read(buffer, cursor, fieldInfo, rootNodes) {
|
||||
if (fieldInfo.condition && !fieldInfo.condition(rootNodes)) {
|
||||
return null;
|
||||
}
|
||||
var type = types[fieldInfo.type];
|
||||
if (!type) {
|
||||
return {
|
||||
error: new Error("missing data type: " + fieldInfo.type)
|
||||
};
|
||||
}
|
||||
var readResults = type[0](buffer, cursor, fieldInfo.typeArgs, rootNodes);
|
||||
if (readResults.error) return { error: readResults.error };
|
||||
|
||||
return readResults;
|
||||
}
|
||||
|
||||
function write(value, buffer, offset, fieldInfo, rootNodes) {
|
||||
if (fieldInfo.condition && !fieldInfo.condition(rootNodes)) {
|
||||
return null;
|
||||
}
|
||||
var type = types[fieldInfo.type];
|
||||
if (!type) {
|
||||
return {
|
||||
error: new Error("missing data type: " + fieldInfo.type)
|
||||
};
|
||||
}
|
||||
return type[1](value, buffer, offset, fieldInfo.typeArgs);
|
||||
}
|
||||
|
||||
function sizeOf(value, fieldInfo, rootNodes) {
|
||||
if (fieldInfo.condition && !fieldInfo.condition(rootNodes)) {
|
||||
return 0;
|
||||
}
|
||||
var type = types[fieldInfo.type];
|
||||
if (!type) {
|
||||
throw new Error("missing data type: " + fieldInfo.type);
|
||||
}
|
||||
if (typeof type[2] === 'function') {
|
||||
return type[2](value, fieldInfo.typeArgs);
|
||||
} else {
|
||||
return type[2];
|
||||
}
|
||||
}
|
||||
|
||||
function get(packetId, state, toServer) {
|
||||
var direction = toServer ? "toServer" : "toClient";
|
||||
var packetInfo = packetFields[state][direction][packetId];
|
||||
@ -1608,17 +1653,6 @@ function get(packetId, state, toServer) {
|
||||
return packetInfo;
|
||||
}
|
||||
|
||||
function sizeOf(type, value) {
|
||||
var dataType = types[type];
|
||||
assert.ok(dataType, "unknown data type " + type);
|
||||
var size = dataType[2];
|
||||
if (typeof size === "function") {
|
||||
return size(value);
|
||||
} else {
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
||||
function createPacketBuffer(packetId, state, params, isServer) {
|
||||
var length = 0;
|
||||
if (typeof packetId === 'string' && typeof state !== 'string' && !params) {
|
||||
@ -1632,10 +1666,7 @@ function createPacketBuffer(packetId, state, params, isServer) {
|
||||
var packet = get(packetId, state, !isServer);
|
||||
assert.notEqual(packet, null);
|
||||
packet.forEach(function(fieldInfo) {
|
||||
var condition = fieldInfo.condition;
|
||||
if (typeof condition != "undefined" && !condition(params))
|
||||
return;
|
||||
length += sizeOf(fieldInfo.type, params[fieldInfo.name]);
|
||||
length += sizeOf(params[fieldInfo.name], fieldInfo, params);
|
||||
});
|
||||
length += sizeOfVarInt(packetId);
|
||||
var size = length + sizeOfVarInt(length);
|
||||
@ -1643,32 +1674,14 @@ function createPacketBuffer(packetId, state, params, isServer) {
|
||||
var offset = writeVarInt(length, buffer, 0);
|
||||
offset = writeVarInt(packetId, buffer, offset);
|
||||
packet.forEach(function(fieldInfo) {
|
||||
var condition = fieldInfo.condition;
|
||||
if (typeof condition != "undefined" && !condition(params))
|
||||
return;
|
||||
var write = types[fieldInfo.type][1];
|
||||
var value = params[fieldInfo.name];
|
||||
if(typeof value === "undefined") value = 0;
|
||||
offset = write(value, buffer, offset);
|
||||
if(typeof value === "undefined") value = 0; // TODO : Why ?
|
||||
offset = write(value, buffer, offset, fieldInfo, params);
|
||||
});
|
||||
return buffer;
|
||||
}
|
||||
|
||||
function parsePacket(buffer, state, isServer) {
|
||||
|
||||
function readPacketField(fieldInfo) {
|
||||
var read = types[fieldInfo.type][0];
|
||||
if (!read) {
|
||||
return {
|
||||
error: new Error("missing reader for data type: " + fieldInfo.type)
|
||||
}
|
||||
}
|
||||
var readResults = read(buffer, cursor);
|
||||
if (! readResults) return null; // buffer needs to be more full
|
||||
if (readResults.error) return { error: readResults.error };
|
||||
|
||||
return readResults;
|
||||
}
|
||||
if (state == null) state == states.PLAY;
|
||||
var cursor = 0;
|
||||
var lengthField = readVarInt(buffer, 0);
|
||||
@ -1697,12 +1710,9 @@ function parsePacket(buffer, state, isServer) {
|
||||
var i, fieldInfo, readResults;
|
||||
for (i = 0; i < packetInfo.length; ++i) {
|
||||
fieldInfo = packetInfo[i];
|
||||
var condition = fieldInfo.condition;
|
||||
if (typeof condition != "undefined" && !condition(results)) {
|
||||
results[fieldInfo.name] = null;
|
||||
continue;
|
||||
}
|
||||
readResults = readPacketField(fieldInfo);
|
||||
readResults = read(buffer, cursor, fieldInfo, results);
|
||||
/* A deserializer cannot return null anymore. Besides, read() returns
|
||||
* null when the condition is not fulfilled.
|
||||
if (!!!readResults) {
|
||||
var error = new Error("A deserializer returned null");
|
||||
error.packetId = packetId;
|
||||
@ -1712,7 +1722,8 @@ function parsePacket(buffer, state, isServer) {
|
||||
error: error,
|
||||
results: results
|
||||
};
|
||||
}
|
||||
}*/
|
||||
if (readResults === null) continue;
|
||||
if (readResults.error) {
|
||||
return readResults;
|
||||
}
|
||||
|
@ -164,7 +164,9 @@ describe("packets", function() {
|
||||
// empty object uses default values
|
||||
var packet = {};
|
||||
packetInfo.forEach(function(field) {
|
||||
if (!field.hasOwnProperty("condition") || field.condition(packet)) {
|
||||
packet[field.name] = values[field.type];
|
||||
}
|
||||
});
|
||||
if (toServer) {
|
||||
serverClient.once([state, packetId], function(receivedPacket) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user