mirror of
https://github.com/unmojang/node-minecraft-protocol.git
synced 2025-10-02 23:52:07 -04:00
getting encryption request
This commit is contained in:
parent
46c6aeb86e
commit
043cbd5882
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/node_modules
|
173
lib/parser.js
Normal file
173
lib/parser.js
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
var net = require('net')
|
||||||
|
, EventEmitter = require('events').EventEmitter
|
||||||
|
, util = require('util')
|
||||||
|
, assert = require('assert')
|
||||||
|
, Iconv = require('iconv').Iconv
|
||||||
|
, packets = require('../packets.json')
|
||||||
|
, toUcs2 = new Iconv('UTF-8', 'utf16be')
|
||||||
|
, fromUcs2 = new Iconv('utf16be', 'UTF-8')
|
||||||
|
|
||||||
|
module.exports = Parser;
|
||||||
|
|
||||||
|
function Parser(options) {
|
||||||
|
EventEmitter.call(this);
|
||||||
|
}
|
||||||
|
util.inherits(Parser, EventEmitter);
|
||||||
|
|
||||||
|
Parser.prototype.connect = function(port, host) {
|
||||||
|
var self = this;
|
||||||
|
self.client = net.connect(port, host, function() {
|
||||||
|
self.emit('connect');
|
||||||
|
});
|
||||||
|
var incomingBuffer = new Buffer(0);
|
||||||
|
self.client.on('data', function(data) {
|
||||||
|
incomingBuffer = Buffer.concat([incomingBuffer, data]);
|
||||||
|
var parsed;
|
||||||
|
while (true) {
|
||||||
|
parsed = parsePacket(incomingBuffer);
|
||||||
|
if (! parsed) break;
|
||||||
|
incomingBuffer = incomingBuffer.slice(parsed.size);
|
||||||
|
self.emit('packet', parsed.results);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.client.on('error', function(err) {
|
||||||
|
self.emit('error', err);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.client.on('end', function() {
|
||||||
|
self.emit('end');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Parser.prototype.writePacket = function(packetId, params) {
|
||||||
|
var buffer = createPacketBuffer(packetId, params);
|
||||||
|
this.client.write(buffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
var writers = {
|
||||||
|
'int': IntWriter,
|
||||||
|
'byte': ByteWriter,
|
||||||
|
'string': StringWriter,
|
||||||
|
};
|
||||||
|
|
||||||
|
var readers = {
|
||||||
|
'string': readString,
|
||||||
|
'byteArray': readByteArray,
|
||||||
|
'short': readShort,
|
||||||
|
};
|
||||||
|
|
||||||
|
function readString (buffer, offset) {
|
||||||
|
var results = readShort(buffer, offset);
|
||||||
|
if (! results) return null;
|
||||||
|
|
||||||
|
var strBegin = offset + results.size;
|
||||||
|
var strLen = results.value;
|
||||||
|
var strEnd = strBegin + strLen * 2;
|
||||||
|
if (strEnd > buffer.length) return null;
|
||||||
|
var str = fromUcs2.convert(buffer.slice(strBegin, strEnd)).toString();
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: str,
|
||||||
|
size: strEnd - offset,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function readByteArray (buffer, offset) {
|
||||||
|
var results = readShort(buffer, offset);
|
||||||
|
if (! results) return null;
|
||||||
|
|
||||||
|
var bytesBegin = offset + results.size;
|
||||||
|
var bytesSize = results.value;
|
||||||
|
var bytesEnd = bytesBegin + bytesSize;
|
||||||
|
if (bytesEnd > buffer.length) return null;
|
||||||
|
var bytes = buffer.slice(bytesBegin, bytesEnd);
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: bytes,
|
||||||
|
size: bytesEnd - offset,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function readShort(buffer, offset) {
|
||||||
|
if (offset + 2 > buffer.length) return null;
|
||||||
|
var value = buffer.readInt16BE(offset);
|
||||||
|
return {
|
||||||
|
value: value,
|
||||||
|
size: 2,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function StringWriter(value) {
|
||||||
|
this.value = value;
|
||||||
|
this.encoded = toUcs2.convert(value);
|
||||||
|
this.size = 2 + this.encoded.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringWriter.prototype.write = function(buffer, offset) {
|
||||||
|
buffer.writeInt16BE(this.value.length, offset);
|
||||||
|
this.encoded.copy(buffer, offset + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ByteWriter(value) {
|
||||||
|
this.value = value;
|
||||||
|
this.size = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteWriter.prototype.write = function(buffer, offset) {
|
||||||
|
buffer.writeInt8(this.value, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
function IntWriter(value) {
|
||||||
|
this.value = value;
|
||||||
|
this.size = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
IntWriter.prototype.write = function(buffer, offset) {
|
||||||
|
buffer.writeInt32BE(this.value, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPacketBuffer(packetId, params) {
|
||||||
|
var size = 1;
|
||||||
|
var fields = [ new ByteWriter(packetId) ];
|
||||||
|
var packet = packets[packetId];
|
||||||
|
packet.forEach(function(fieldInfo) {
|
||||||
|
var value = params[fieldInfo.name];
|
||||||
|
var field = new writers[fieldInfo.type](value);
|
||||||
|
size += field.size;
|
||||||
|
fields.push(field);
|
||||||
|
});
|
||||||
|
var buffer = new Buffer(size);
|
||||||
|
var cursor = 0;
|
||||||
|
fields.forEach(function(field) {
|
||||||
|
field.write(buffer, cursor);
|
||||||
|
cursor += field.size;
|
||||||
|
});
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
function parsePacket(buffer) {
|
||||||
|
if (buffer.length < 1) return null;
|
||||||
|
var packetId = buffer.readUInt8(0);
|
||||||
|
var size = 1;
|
||||||
|
var results = { id: packetId };
|
||||||
|
var packetInfo = packets[packetId];
|
||||||
|
assert.ok(packetInfo, "Unrecognized packetId: " + packetId);
|
||||||
|
var i, fieldInfo, read, readResults;
|
||||||
|
for (i = 0; i < packetInfo.length; ++i) {
|
||||||
|
fieldInfo = packetInfo[i];
|
||||||
|
read = readers[fieldInfo.type];
|
||||||
|
readResults = read(buffer, size);
|
||||||
|
if (readResults) {
|
||||||
|
results[fieldInfo.name] = readResults.value;
|
||||||
|
size += readResults.size;
|
||||||
|
} else {
|
||||||
|
// buffer needs to be more full
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
size: size,
|
||||||
|
results: results,
|
||||||
|
};
|
||||||
|
}
|
15
package.json
Normal file
15
package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "minecraft-protocol",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"description": "minecraft protocol",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"minecraft",
|
||||||
|
"protocol"
|
||||||
|
],
|
||||||
|
"author": "Andrew Kelley",
|
||||||
|
"license": "BSD",
|
||||||
|
}
|
34
packets.json
Normal file
34
packets.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"2": [
|
||||||
|
{
|
||||||
|
"name": "protocolVersion",
|
||||||
|
"type": "byte"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "userName",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "serverHost",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "serverPort",
|
||||||
|
"type": "int"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"253": [
|
||||||
|
{
|
||||||
|
"name": "serverId",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "publicKey",
|
||||||
|
"type": "byteArray"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "verifyToken",
|
||||||
|
"type": "byteArray"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
45
test.js
Normal file
45
test.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
var Parser = require('./lib/parser');
|
||||||
|
|
||||||
|
var parser = new Parser();
|
||||||
|
parser.on('connect', function() {
|
||||||
|
console.info("connect");
|
||||||
|
parser.writePacket(0x02, {
|
||||||
|
protocolVersion: 51,
|
||||||
|
userName: 'superjoe30',
|
||||||
|
serverHost: 'localhost',
|
||||||
|
serverPort: 25565,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
parser.on('packet', function(packet) {
|
||||||
|
var handler = packetHandlers[packet.id];
|
||||||
|
if (handler) {
|
||||||
|
handler(packet);
|
||||||
|
} else {
|
||||||
|
console.warn("No packet handler for", packet.id, "fields", packet);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
parser.on('error', function(err) {
|
||||||
|
console.error("error connecting", err.stack);
|
||||||
|
});
|
||||||
|
parser.on('end', function() {
|
||||||
|
console.info("disconnect");
|
||||||
|
});
|
||||||
|
parser.connect(25565, 'localhost');
|
||||||
|
|
||||||
|
var packetHandlers = {
|
||||||
|
0xFD: onEncryptionKeyRequest,
|
||||||
|
};
|
||||||
|
|
||||||
|
function onEncryptionKeyRequest(packet) {
|
||||||
|
var sharedSecret = randomBuffer(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
function randomBuffer(size) {
|
||||||
|
var buffer = new Buffer(size);
|
||||||
|
var i, number;
|
||||||
|
for (i = 0; i < size; ++i) {
|
||||||
|
number = Math.floor(Math.random() * 256);
|
||||||
|
buffer.writeUInt8(number, i);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user