mirror of
https://github.com/PrismarineJS/node-minecraft-protocol.git
synced 2024-11-14 19:04:59 -05:00
Merge pull request #253 from roblabla/feature-newContextSyntax
New context syntax
This commit is contained in:
commit
a7e74cdb1d
6 changed files with 88 additions and 96 deletions
|
@ -4,19 +4,18 @@ var states = mc.states;
|
||||||
function printHelpAndExit(exitCode) {
|
function printHelpAndExit(exitCode) {
|
||||||
console.log("usage: node proxy.js [<options>...] <target_srv> <user> [<password>]");
|
console.log("usage: node proxy.js [<options>...] <target_srv> <user> [<password>]");
|
||||||
console.log("options:");
|
console.log("options:");
|
||||||
console.log(" --dump ID");
|
console.log(" --dump name");
|
||||||
console.log(" print to stdout messages with the specified ID.");
|
console.log(" print to stdout messages with the specified name.");
|
||||||
console.log(" --dump-all");
|
console.log(" --dump-all");
|
||||||
console.log(" print to stdout all messages, except those specified with -x.");
|
console.log(" print to stdout all messages, except those specified with -x.");
|
||||||
console.log(" -x ID");
|
console.log(" -x name");
|
||||||
console.log(" do not print messages with this ID.");
|
console.log(" do not print messages with this name.");
|
||||||
console.log(" ID");
|
console.log(" name");
|
||||||
console.log(" an integer in decimal or hex (given to JavaScript's parseInt())");
|
console.log(" a packet name as defined in protocol.json");
|
||||||
console.log(" optionally prefixed with o for client->server or i for client<-server.");
|
|
||||||
console.log("examples:");
|
console.log("examples:");
|
||||||
console.log(" node proxy.js --dump-all -x 0x0 -x 0x3 -x 0x12 -x 0x015 -x 0x16 -x 0x17 -x 0x18 -x 0x19 localhost Player");
|
console.log(" node proxy.js --dump-all -x keep_alive -x update_time -x entity_velocity -x rel_entity_move -x entity_look -x entity_move_look -x entity_teleport -x entity_head_rotation -x position -x localhost Player");
|
||||||
console.log(" print all messages except for some of the most prolific.");
|
console.log(" print all messages except for some of the most prolific.");
|
||||||
console.log(" node examples/proxy.js --dump i0x2d --dump i0x2e --dump i0x2f dump i0x30 --dump i0x31 --dump i0x32 --dump o0x0d --dump o0x0e --dump o0x0f --dump o0x10 --dump o0x11 localhost Player");
|
console.log(" node examples/proxy.js --dump open_window --dump close_window --dump set_slot --dump window_items --dump craft_progress_bar --dump transaction --dump close_window --dump window_click --dump set_creative_slot --dump enchant_item localhost Player");
|
||||||
console.log(" print messages relating to inventory management.");
|
console.log(" print messages relating to inventory management.");
|
||||||
|
|
||||||
process.exit(exitCode);
|
process.exit(exitCode);
|
||||||
|
@ -39,27 +38,23 @@ var port = 25565;
|
||||||
var user;
|
var user;
|
||||||
var passwd;
|
var passwd;
|
||||||
|
|
||||||
var printAllIds = false;
|
var printAllNames = false;
|
||||||
var printIdWhitelist = {};
|
var printNameWhitelist = {};
|
||||||
var printIdBlacklist = {};
|
var printNameBlacklist = {};
|
||||||
(function() {
|
(function() {
|
||||||
for(var i = 0; i < args.length; i++) {
|
for(var i = 0; i < args.length; i++) {
|
||||||
var option = args[i];
|
var option = args[i];
|
||||||
if(!/^-/.test(option)) break;
|
if(!/^-/.test(option)) break;
|
||||||
if(option == "--dump-all") {
|
if(option == "--dump-all") {
|
||||||
printAllIds = true;
|
printAllNames = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
var match = /^([io]?)(.*)/.exec(args[i]);
|
var name = args[i];
|
||||||
var prefix = match[1];
|
|
||||||
if(prefix === "") prefix = "io";
|
|
||||||
var number = parseInt(match[2]);
|
|
||||||
if(isNaN(number)) printHelpAndExit(1);
|
|
||||||
if(option == "--dump") {
|
if(option == "--dump") {
|
||||||
printIdWhitelist[number] = prefix;
|
printNameWhitelist[name] = "io";
|
||||||
} else if(option == "-x") {
|
} else if(option == "-x") {
|
||||||
printIdBlacklist[number] = prefix;
|
printNameBlacklist[name] = "io";
|
||||||
} else {
|
} else {
|
||||||
printHelpAndExit(1);
|
printHelpAndExit(1);
|
||||||
}
|
}
|
||||||
|
@ -105,41 +100,38 @@ srv.on('login', function(client) {
|
||||||
'online-mode': passwd != null ? true : false,
|
'online-mode': passwd != null ? true : false,
|
||||||
keepAlive:false
|
keepAlive:false
|
||||||
});
|
});
|
||||||
var brokenPackets = [/*0x04, 0x2f, 0x30*/];
|
client.on('packet', function(data, meta) {
|
||||||
client.on('packet', function(packet) {
|
if(targetClient.state == states.PLAY && meta.state == states.PLAY) {
|
||||||
if(targetClient.state == states.PLAY && packet.state == states.PLAY) {
|
if(shouldDump(meta.name, "o")) {
|
||||||
if(shouldDump(packet.id, "o")) {
|
|
||||||
console.log("client->server:",
|
console.log("client->server:",
|
||||||
client.state + ".0x" + packet.id.toString(16) + " :",
|
client.state + ".0x" + meta.id.toString(16) + " :",
|
||||||
JSON.stringify(packet));
|
JSON.stringify(data));
|
||||||
}
|
}
|
||||||
if(!endedTargetClient)
|
if(!endedTargetClient)
|
||||||
targetClient.write(packet.id, packet);
|
targetClient.write(meta.name, data);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
targetClient.on('packet', function(packet) {
|
targetClient.on('packet', function(data, meta) {
|
||||||
if(packet.state == states.PLAY && client.state == states.PLAY &&
|
if(meta.state == states.PLAY && client.state == states.PLAY) {
|
||||||
brokenPackets.indexOf(packet.id) === -1) {
|
if(shouldDump(meta.name, "i")) {
|
||||||
if(shouldDump(packet.id, "i")) {
|
|
||||||
console.log("client<-server:",
|
console.log("client<-server:",
|
||||||
targetClient.state + ".0x" + packet.id.toString(16) + " :",
|
targetClient.state + "." + meta.name + " :" +
|
||||||
(packet.id != 38 ? JSON.stringify(packet) : "Packet too big"));
|
JSON.stringify(data));
|
||||||
}
|
}
|
||||||
if(!endedClient)
|
if(!endedClient)
|
||||||
client.write(packet.id, packet);
|
client.write(meta.name, data);
|
||||||
if (packet.id === 0x46) // Set compression
|
if (meta.name === 'set_compression' || meta.name === 'compression') // Set compression
|
||||||
client.compressionThreshold = packet.threshold;
|
client.compressionThreshold = data.threshold;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
var buffertools = require('buffertools');
|
var buffertools = require('buffertools');
|
||||||
targetClient.on('raw', function(buffer, state) {
|
targetClient.on('raw', function(buffer, meta) {
|
||||||
if(client.state != states.PLAY || state != states.PLAY)
|
if(client.state != states.PLAY || meta.state != states.PLAY)
|
||||||
return;
|
return;
|
||||||
var packetId = mc.types.varint[0](buffer, 0);
|
var packetData = mc.parsePacketData(buffer, meta.state, false, {"packet": 1}).data;
|
||||||
var packetData = mc.parsePacketData(buffer, state, false, {"packet": 1}).results;
|
var packetBuff = mc.createPacketBuffer(meta.name, meta.state, packetData, true);
|
||||||
var packetBuff = mc.createPacketBuffer(packetData.id, packetData.state, packetData, true);
|
|
||||||
if(buffertools.compare(buffer, packetBuff) != 0) {
|
if(buffertools.compare(buffer, packetBuff) != 0) {
|
||||||
console.log("client<-server: Error in packetId " + state + ".0x" + packetId.value.toString(16));
|
console.log("client<-server: Error in packet " + state + "." + meta.name);
|
||||||
console.log(buffer.toString('hex'));
|
console.log(buffer.toString('hex'));
|
||||||
console.log(packetBuff.toString('hex'));
|
console.log(packetBuff.toString('hex'));
|
||||||
console.log(buffer.length);
|
console.log(buffer.length);
|
||||||
|
@ -153,14 +145,13 @@ srv.on('login', function(client) {
|
||||||
client.writeRaw(buffer);
|
client.writeRaw(buffer);
|
||||||
}*/
|
}*/
|
||||||
});
|
});
|
||||||
client.on('raw', function(buffer, state) {
|
client.on('raw', function(buffer, meta) {
|
||||||
if(state != states.PLAY || targetClient.state != states.PLAY)
|
if(meta.state != states.PLAY || targetClient.state != states.PLAY)
|
||||||
return;
|
return;
|
||||||
var packetId = mc.types.varint[0](buffer, 0);
|
var packetData = mc.parsePacketData(buffer, meta.state, true, {"packet": 1}).data;
|
||||||
var packetData = mc.parsePacketData(buffer, state, true, {"packet": 1}).results;
|
var packetBuff = mc.createPacketBuffer(meta.name, meta.state, packetData, false);
|
||||||
var packetBuff = mc.createPacketBuffer(packetData.id, packetData.state, packetData, false);
|
|
||||||
if(buffertools.compare(buffer, packetBuff) != 0) {
|
if(buffertools.compare(buffer, packetBuff) != 0) {
|
||||||
console.log("client->server: Error in packetId " + state + ".0x" + packetId.value.toString(16));
|
console.log("client->server: Error in packet " + state + "." + meta.name);
|
||||||
console.log(buffer.toString('hex'));
|
console.log(buffer.toString('hex'));
|
||||||
console.log(packetBuff.toString('hex'));
|
console.log(packetBuff.toString('hex'));
|
||||||
console.log(buffer.length);
|
console.log(buffer.length);
|
||||||
|
@ -182,10 +173,10 @@ srv.on('login', function(client) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function shouldDump(id, direction) {
|
function shouldDump(name, direction) {
|
||||||
if(matches(printIdBlacklist[id])) return false;
|
if(matches(printNameBlacklist[name])) return false;
|
||||||
if(printAllIds) return true;
|
if(printAllNames) return true;
|
||||||
if(matches(printIdWhitelist[id])) return true;
|
if(matches(printNameWhitelist[name])) return true;
|
||||||
return false;
|
return false;
|
||||||
function matches(result) {
|
function matches(result) {
|
||||||
return result != null && result.indexOf(direction) !== -1;
|
return result != null && result.indexOf(direction) !== -1;
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
"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",
|
"lodash.reduce": "^3.1.2",
|
||||||
"minecraft-data": "0.10.0",
|
"minecraft-data": "0.11.0",
|
||||||
"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",
|
||||||
|
|
|
@ -97,17 +97,14 @@ function sizeOfArray(value, typeArgs, rootNode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function readContainer(buffer, offset, typeArgs, rootNode) {
|
function readContainer(buffer, offset, typeArgs, context) {
|
||||||
var results = {
|
var results = {
|
||||||
value: {},
|
value: { "..": context },
|
||||||
size: 0
|
size: 0
|
||||||
};
|
};
|
||||||
var backupThis = rootNode.this;
|
|
||||||
rootNode.this = results.value;
|
|
||||||
typeArgs.forEach((typeArg) => {
|
typeArgs.forEach((typeArg) => {
|
||||||
var readResults;
|
|
||||||
tryCatch(() => {
|
tryCatch(() => {
|
||||||
readResults = this.read(buffer, offset, typeArg.type, rootNode);
|
var readResults = this.read(buffer, offset, typeArg.type, results.value);
|
||||||
results.size += readResults.size;
|
results.size += readResults.size;
|
||||||
offset += readResults.size;
|
offset += readResults.size;
|
||||||
if (typeArg.anon) {
|
if (typeArg.anon) {
|
||||||
|
@ -124,19 +121,18 @@ function readContainer(buffer, offset, typeArgs, rootNode) {
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
rootNode.this = backupThis;
|
delete results.value[".."];
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
function writeContainer(value, buffer, offset, typeArgs, rootNode) {
|
function writeContainer(value, buffer, offset, typeArgs, context) {
|
||||||
var backupThis = rootNode.this;
|
value[".."] = context;
|
||||||
rootNode.this = value;
|
|
||||||
typeArgs.forEach((typeArg) => {
|
typeArgs.forEach((typeArg) => {
|
||||||
tryCatch(() => {
|
tryCatch(() => {
|
||||||
if (typeArg.anon)
|
if (typeArg.anon)
|
||||||
offset = this.write(value, buffer, offset, typeArg.type, rootNode);
|
offset = this.write(value, buffer, offset, typeArg.type, value);
|
||||||
else
|
else
|
||||||
offset = this.write(value[typeArg.name], buffer, offset, typeArg.type, rootNode);
|
offset = this.write(value[typeArg.name], buffer, offset, typeArg.type, value);
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
if (typeArgs && typeArg && typeArg.name)
|
if (typeArgs && typeArg && typeArg.name)
|
||||||
addErrorField(e, typeArg.name);
|
addErrorField(e, typeArg.name);
|
||||||
|
@ -145,20 +141,19 @@ function writeContainer(value, buffer, offset, typeArgs, rootNode) {
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
rootNode.this = backupThis;
|
delete value[".."];
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
function sizeOfContainer(value, typeArgs, rootNode) {
|
function sizeOfContainer(value, typeArgs, context) {
|
||||||
|
value[".."] = context;
|
||||||
var size = 0;
|
var size = 0;
|
||||||
var backupThis = rootNode.this;
|
|
||||||
rootNode.this = value;
|
|
||||||
typeArgs.forEach((typeArg) => {
|
typeArgs.forEach((typeArg) => {
|
||||||
tryCatch(() => {
|
tryCatch(() => {
|
||||||
if (typeArg.anon)
|
if (typeArg.anon)
|
||||||
size += this.sizeOf(value, typeArg.type, rootNode);
|
size += this.sizeOf(value, typeArg.type, value);
|
||||||
else
|
else
|
||||||
size += this.sizeOf(value[typeArg.name], typeArg.type, rootNode);
|
size += this.sizeOf(value[typeArg.name], typeArg.type, value);
|
||||||
}, (e) => {
|
}, (e) => {
|
||||||
if (typeArgs && typeArg && typeArg.name)
|
if (typeArgs && typeArg && typeArg.name)
|
||||||
addErrorField(e, typeArg.name);
|
addErrorField(e, typeArg.name);
|
||||||
|
@ -167,7 +162,7 @@ function sizeOfContainer(value, typeArgs, rootNode) {
|
||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
rootNode.this = backupThis;
|
delete value[".."];
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ var packetStates = packetIndexes.packetStates;
|
||||||
function createPacketBuffer(packetName, state, params, isServer) {
|
function createPacketBuffer(packetName, state, params, isServer) {
|
||||||
var direction = !isServer ? 'toServer' : 'toClient';
|
var direction = !isServer ? 'toServer' : 'toClient';
|
||||||
var packetId = packetIds[state][direction][packetName];
|
var packetId = packetIds[state][direction][packetName];
|
||||||
assert.notEqual(packetId, undefined);
|
assert.notEqual(packetId, undefined, `${state}.${isServer}.${packetName} : ${packetId}`);
|
||||||
var packet = get(packetName, state, !isServer);
|
var packet = get(packetName, state, !isServer);
|
||||||
assert.notEqual(packet, null);
|
assert.notEqual(packet, null);
|
||||||
|
|
||||||
|
@ -140,7 +140,8 @@ function parsePacketData(buffer, state, isServer, packetsToParse = {"packet": tr
|
||||||
results.data = res.value;
|
results.data = res.value;
|
||||||
cursor += res.size;
|
cursor += res.size;
|
||||||
if(buffer.length > cursor)
|
if(buffer.length > cursor)
|
||||||
throw new Error(`Read error for ${packetName} : Packet data not entirely read`);
|
throw new Error(`Read error for ${packetName} : Packet data not entirely read :
|
||||||
|
${JSON.stringify(results)}`);
|
||||||
debug(results);
|
debug(results);
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
17
src/utils.js
17
src/utils.js
|
@ -5,13 +5,18 @@ module.exports = {
|
||||||
tryCatch: tryCatch,
|
tryCatch: tryCatch,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getField(countField, rootNode) {
|
function getField(countField, context) {
|
||||||
var countFieldArr = countField.split(".");
|
var countFieldArr = countField.split("/");
|
||||||
var count = rootNode;
|
var i = 0;
|
||||||
for(var index = 0; index < countFieldArr.length; index++) {
|
if (countFieldArr[i] === "") {
|
||||||
count = count[countFieldArr[index]];
|
while (context.hasOwnProperty(".."))
|
||||||
|
context = context[".."];
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
return count;
|
for(; i < countFieldArr.length; i++) {
|
||||||
|
context = context[countFieldArr[i]];
|
||||||
|
}
|
||||||
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFieldInfo(fieldInfo) {
|
function getFieldInfo(fieldInfo) {
|
||||||
|
|
32
test/test.js
32
test/test.js
|
@ -32,29 +32,29 @@ var values = {
|
||||||
'ubyte': 8,
|
'ubyte': 8,
|
||||||
'string': "hi hi this is my client string",
|
'string': "hi hi this is my client string",
|
||||||
'buffer': new Buffer(8),
|
'buffer': new Buffer(8),
|
||||||
'array': function(typeArgs, packet) {
|
'array': function(typeArgs, context) {
|
||||||
var count;
|
var count;
|
||||||
if (typeof typeArgs.count === "object")
|
if (typeof typeArgs.count === "object")
|
||||||
count = evalCount(typeArgs.count, packet);
|
count = evalCount(typeArgs.count, context);
|
||||||
else if (typeof typeArgs.count !== "undefined")
|
else if (typeof typeArgs.count !== "undefined")
|
||||||
count = getField(typeArgs.count, rootNode);
|
count = getField(typeArgs.count, context);
|
||||||
else if (typeof typeArgs.countType !== "undefined")
|
else if (typeof typeArgs.countType !== "undefined")
|
||||||
count = 1;
|
count = 1;
|
||||||
var arr = [];
|
var arr = [];
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
arr.push(getValue(typeArgs.type, packet));
|
arr.push(getValue(typeArgs.type, context));
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
return arr;
|
return arr;
|
||||||
},
|
},
|
||||||
'container': function(typeArgs, packet) {
|
'container': function(typeArgs, context) {
|
||||||
var results = {};
|
var results = {
|
||||||
|
"..": context;
|
||||||
|
};
|
||||||
for(var index in typeArgs) {
|
for(var index in typeArgs) {
|
||||||
var backupThis = packet.this;
|
results[typeArgs[index].name] = getValue(typeArgs[index].type, results);
|
||||||
packet.this = results;
|
|
||||||
results[typeArgs[index].name] = getValue(typeArgs[index].type, packet);
|
|
||||||
packet.this = backupThis;
|
|
||||||
}
|
}
|
||||||
|
delete context[".."];
|
||||||
return results;
|
return results;
|
||||||
},
|
},
|
||||||
'count': 1, // TODO : might want to set this to a correct value
|
'count': 1, // TODO : might want to set this to a correct value
|
||||||
|
@ -90,15 +90,15 @@ var values = {
|
||||||
'UUID': "00112233-4455-6677-8899-aabbccddeeff",
|
'UUID': "00112233-4455-6677-8899-aabbccddeeff",
|
||||||
'position': {x: 12, y: 332, z: 4382821},
|
'position': {x: 12, y: 332, z: 4382821},
|
||||||
'restBuffer': new Buffer(0),
|
'restBuffer': new Buffer(0),
|
||||||
'switch': function(typeArgs, packet) {
|
'switch': function(typeArgs, context) {
|
||||||
var i = typeArgs.fields[getField(typeArgs.compareTo, packet)];
|
var i = typeArgs.fields[getField(typeArgs.compareTo, context)];
|
||||||
if (typeof i === "undefined")
|
if (typeof i === "undefined")
|
||||||
return getValue(typeArgs.default, packet);
|
return getValue(typeArgs.default, context);
|
||||||
else
|
else
|
||||||
return getValue(i, packet);
|
return getValue(i, context);
|
||||||
},
|
},
|
||||||
'option': function(typeArgs, packet) {
|
'option': function(typeArgs, context) {
|
||||||
return getValue(typeArgs, packet);
|
return getValue(typeArgs, context);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue