Build package before commit.
This commit is contained in:
parent
06c77c3668
commit
c75a661a48
8 changed files with 1699 additions and 20 deletions
70
dist/createClient.js
vendored
Normal file
70
dist/createClient.js
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
'use strict';
|
||||
|
||||
var assert = require('assert');
|
||||
|
||||
var raknet = require('raknet');
|
||||
|
||||
var fs = require('fs');
|
||||
|
||||
var path = require('path');
|
||||
|
||||
var zlib = require('zlib');
|
||||
|
||||
var ProtoDef = require('protodef').ProtoDef;
|
||||
|
||||
var batchProto = new ProtoDef();
|
||||
batchProto.addTypes(require("./datatypes/minecraft"));
|
||||
batchProto.addType("insideBatch", ["endOfArray", {
|
||||
"type": ["buffer", {
|
||||
"countType": "i32"
|
||||
}]
|
||||
}]);
|
||||
|
||||
function createClient(options) {
|
||||
return null; //FIXME
|
||||
|
||||
assert.ok(options, 'options is required');
|
||||
var port = options.port || 19132;
|
||||
var host = options.host || 'localhost';
|
||||
assert.ok(options.username, 'username is required');
|
||||
options.customPackets = require('../data/protocol');
|
||||
options.customTypes = require('./datatypes/minecraft');
|
||||
var client = raknet.createClient(options);
|
||||
client.username = options.username;
|
||||
client.on('mcpe', function (packet) {
|
||||
return client.emit(packet.name, packet.params);
|
||||
});
|
||||
|
||||
client.writeMCPE = function (name, packet) {
|
||||
client.writeEncapsulated('mcpe', {
|
||||
name: name,
|
||||
params: packet
|
||||
});
|
||||
};
|
||||
|
||||
client.on('login', function () {
|
||||
client.writeMCPE('game_login', {
|
||||
username: client.username,
|
||||
protocol: 70,
|
||||
protocol2: 70,
|
||||
clientId: [-1, -697896776],
|
||||
clientUuid: '86372ed8-d055-b23a-9171-5e3ac594d766',
|
||||
serverAddress: client.host + ":" + client.port,
|
||||
clientSecret: new Buffer('e8 88 db 7b 9f f2 f0 44 a3 51 08 18 4e 8c 7f 9a'.replace(/ /g, ''), 'hex'),
|
||||
skin: {
|
||||
skinType: 'Standard_Steve',
|
||||
texture: fs.readFileSync(path.join(__dirname, 'texture'))
|
||||
}
|
||||
});
|
||||
});
|
||||
client.on('batch', function (packet) {
|
||||
var buf = zlib.inflateSync(packet.payload);
|
||||
var packets = batchProto.parsePacketBuffer("insideBatch", buf).data;
|
||||
packets.forEach(function (packet) {
|
||||
return client.readEncapsulatedPacket(Buffer.concat([new Buffer([0xfe]), packet]));
|
||||
});
|
||||
});
|
||||
return client;
|
||||
}
|
||||
|
||||
module.exports = createClient;
|
||||
147
dist/createServer.js
vendored
Normal file
147
dist/createServer.js
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
"use strict";
|
||||
|
||||
var _raknet = _interopRequireDefault(require("raknet"));
|
||||
|
||||
var _zlib = _interopRequireDefault(require("zlib"));
|
||||
|
||||
var _jwtSimple = _interopRequireDefault(require("jwt-simple"));
|
||||
|
||||
var _protodef = require("protodef");
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
var batchProto = new _protodef.ProtoDef();
|
||||
var PUBLIC_KEY = 'MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8ELkixyLcwlZryUQcu1TvPOmI2B7vX83ndnWRUaXm74wFfa5f/lwQNTfrLVHa2PmenpGI6JhIMUJaWZrjmMj90NoKNFSNBuKdm8rYiXsfaz3K36x/1U26HpG0ZxK/V1V'; // createServer (object, boolean)
|
||||
//
|
||||
// Create & launch a MCPE raknet-based server.
|
||||
// object: raknet options
|
||||
// encryption: enable/disable encryption
|
||||
|
||||
function createServer(options, encryption) {
|
||||
options = options || {};
|
||||
var port = options.port || options['server-port'] || 19132;
|
||||
var host = options.host || '0.0.0.0';
|
||||
options.customPackets = (options.protocol ? options.protocol.packets : null) || require('../data/protocol');
|
||||
options.customTypes = (options.protocol ? options.protocol.types : null) || require('./datatypes/minecraft');
|
||||
batchProto.addTypes(options.customTypes);
|
||||
batchProto.addType('insideBatch', ['endOfArray', {
|
||||
'type': ['buffer', {
|
||||
'countType': 'varint'
|
||||
}]
|
||||
}]);
|
||||
|
||||
var server = _raknet["default"].createServer(options);
|
||||
|
||||
server.name = options.name || 'Minecraft Server';
|
||||
server.motd = options.motd || 'A Minecraft server'; //FIXME
|
||||
|
||||
server.maxPlayers = options['max-players'] || 20; //FIXME
|
||||
|
||||
server.playerCount = 0; //FIXME
|
||||
|
||||
server.on('connection', function (client) {
|
||||
client.receiveCounter = 0;
|
||||
client.sendCounter = 0;
|
||||
client.encryptionEnabled = encryption ? true : false;
|
||||
var proto = new _protodef.ProtoDef();
|
||||
proto.addTypes(options.customTypes);
|
||||
proto.addTypes(options.customPackets.types);
|
||||
client.mcpePacketSerializer = new _protodef.Serializer(proto, 'mcpe_packet');
|
||||
client.on('mcpe', function (packet) {
|
||||
client.emit(packet.name, packet.params);
|
||||
client.emit('debug', packet.name);
|
||||
});
|
||||
client.on('batch', function (packets) {
|
||||
var buf = _zlib["default"].inflateSync(packets.payload);
|
||||
|
||||
var packets = batchProto.parsePacketBuffer('insideBatch', buf).data;
|
||||
packets.forEach(function (packet) {
|
||||
return client.readEncapsulatedPacket(Buffer.concat([new Buffer([0xfe]), packet]));
|
||||
});
|
||||
}); // client.writePacket (string, object)
|
||||
// Send data to the client
|
||||
//
|
||||
// string: packet name
|
||||
// object: packet data
|
||||
|
||||
client.writeMCPE = function (name, params) {
|
||||
if (client.encryptionEnabled) {
|
||||
client.mcpePacketSerializer.write({
|
||||
name: name,
|
||||
params: params
|
||||
});
|
||||
} else {
|
||||
client.writeEncapsulated('mcpe', {
|
||||
name: name,
|
||||
params: params
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
client.writePacket = client.writeMCPE; // client.writeData (array)
|
||||
// Send data to the client
|
||||
//
|
||||
// array: packets to send
|
||||
|
||||
client.writeBatch = function (packets) {
|
||||
var payload = _zlib["default"].deflateSync(batchProto.createPacketBuffer('insideBatch', packets.map(function (packet) {
|
||||
return client.mcpePacketSerializer.createPacketBuffer(packet);
|
||||
})));
|
||||
|
||||
client.writePacket('batch', {
|
||||
payload: payload
|
||||
});
|
||||
};
|
||||
|
||||
client.writeData = client.writeBatch; // client.writeAll (string, object)
|
||||
// Send data to the client
|
||||
//
|
||||
// string: packet name
|
||||
// object: packet data
|
||||
|
||||
client.writeAll = function (name, data) {
|
||||
server._writeAll(name, data);
|
||||
};
|
||||
|
||||
client.on('game_login', function (packet) {
|
||||
try {
|
||||
var dataProto = new _protodef.ProtoDef();
|
||||
dataProto.addType('data_chain', ['container', [{
|
||||
'name': 'chain',
|
||||
'type': ['pstring', {
|
||||
'countType': 'li32'
|
||||
}]
|
||||
}, {
|
||||
'name': 'clientData',
|
||||
'type': ['pstring', {
|
||||
'countType': 'li32'
|
||||
}]
|
||||
}]]); //FIXME: Xbox & Non-Xbox support
|
||||
|
||||
console.log(packet);
|
||||
var body = dataProto.parsePacketBuffer('data_chain', _zlib["default"].inflateSync(packet.body)),
|
||||
chain = null,
|
||||
decode = null,
|
||||
data = null;
|
||||
body.data.chain = JSON.parse(body.data.chain);
|
||||
chain = body.data.chain.chain[0];
|
||||
decode = _jwtSimple["default"].decode(chain, PUBLIC_KEY, 'ES384');
|
||||
data = _jwtSimple["default"].decode(body.data.clientData, decode.identityPublicKey, 'ES384');
|
||||
client.emit('mcpe_login', {
|
||||
protocol: packet.protocol,
|
||||
uuid: decode.extraData != null ? decode.extraData.identity : null,
|
||||
id: decode.extraData != null ? decode.extraData.identityPublicKey : null,
|
||||
username: decode.extraData != null ? decode.extraData.displayName : null,
|
||||
skinData: data.SkinData,
|
||||
skinId: data.SkinId
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
});
|
||||
return server;
|
||||
}
|
||||
|
||||
module.exports = createServer;
|
||||
139
dist/datatypes/minecraft.js
vendored
Normal file
139
dist/datatypes/minecraft.js
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
'use strict';
|
||||
|
||||
var nbt = require('prismarine-nbt');
|
||||
|
||||
var UUID = require('uuid-1345');
|
||||
|
||||
function readUUID(buffer, offset) {
|
||||
if (offset + 16 > buffer.length) throw new PartialReadError();
|
||||
return {
|
||||
value: UUID.stringify(buffer.slice(offset, 16 + offset)),
|
||||
size: 16
|
||||
};
|
||||
}
|
||||
|
||||
function writeUUID(value, buffer, offset) {
|
||||
var buf = UUID.parse(value);
|
||||
buf.copy(buffer, offset);
|
||||
return offset + 16;
|
||||
}
|
||||
|
||||
function readNbt(buffer, offset) {
|
||||
return nbt.protoLE.read(buffer, offset, "nbt");
|
||||
}
|
||||
|
||||
function writeNbt(value, buffer, offset) {
|
||||
return nbt.protoLE.write(value, buffer, offset, "nbt");
|
||||
}
|
||||
|
||||
function sizeOfNbt(value) {
|
||||
return nbt.protoLE.sizeOf(value, "nbt");
|
||||
}
|
||||
|
||||
function readEntityMetadata(buffer, offset, _ref) {
|
||||
var type = _ref.type;
|
||||
var endVal = _ref.endVal;
|
||||
var cursor = offset;
|
||||
var metadata = [];
|
||||
var item = undefined;
|
||||
|
||||
while (true) {
|
||||
if (offset + 1 > buffer.length) throw new PartialReadError();
|
||||
item = buffer.readUInt8(cursor);
|
||||
|
||||
if (item === endVal) {
|
||||
return {
|
||||
value: metadata,
|
||||
size: cursor + 1 - offset
|
||||
};
|
||||
}
|
||||
|
||||
var results = this.read(buffer, cursor, type, {});
|
||||
metadata.push(results.value);
|
||||
cursor += results.size;
|
||||
}
|
||||
}
|
||||
|
||||
function writeEntityMetadata(value, buffer, offset, _ref2) {
|
||||
var type = _ref2.type;
|
||||
var endVal = _ref2.endVal;
|
||||
var self = this;
|
||||
value.forEach(function (item) {
|
||||
offset = self.write(item, buffer, offset, type, {});
|
||||
});
|
||||
buffer.writeUInt8(endVal, offset);
|
||||
return offset + 1;
|
||||
}
|
||||
|
||||
function sizeOfEntityMetadata(value, _ref3) {
|
||||
var type = _ref3.type;
|
||||
var size = 1;
|
||||
|
||||
for (var i = 0; i < value.length; ++i) {
|
||||
size += this.sizeOf(value[i], type, {});
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
function readIpAddress(buffer, offset) {
|
||||
var address = buffer[offset] + '.' + buffer[offset + 1] + '.' + buffer[offset + 2] + '.' + buffer[offset + 3];
|
||||
return {
|
||||
size: 4,
|
||||
value: address
|
||||
};
|
||||
}
|
||||
|
||||
function writeIpAddress(value, buffer, offset) {
|
||||
var address = value.split('.');
|
||||
address.forEach(function (b) {
|
||||
buffer[offset] = parseInt(b);
|
||||
offset++;
|
||||
});
|
||||
return offset;
|
||||
}
|
||||
|
||||
function readEndOfArray(buffer, offset, typeArgs) {
|
||||
var type = typeArgs.type;
|
||||
var cursor = offset;
|
||||
var elements = [];
|
||||
|
||||
while (cursor < buffer.length) {
|
||||
var results = this.read(buffer, cursor, type, {});
|
||||
elements.push(results.value);
|
||||
cursor += results.size;
|
||||
}
|
||||
|
||||
return {
|
||||
value: elements,
|
||||
size: cursor - offset
|
||||
};
|
||||
}
|
||||
|
||||
function writeEndOfArray(value, buffer, offset, typeArgs) {
|
||||
var type = typeArgs.type;
|
||||
var self = this;
|
||||
value.forEach(function (item) {
|
||||
offset = self.write(item, buffer, offset, type, {});
|
||||
});
|
||||
return offset;
|
||||
}
|
||||
|
||||
function sizeOfEndOfArray(value, typeArgs) {
|
||||
var type = typeArgs.type;
|
||||
var size = 0;
|
||||
|
||||
for (var i = 0; i < value.length; ++i) {
|
||||
size += this.sizeOf(value[i], type, {});
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
'uuid': [readUUID, writeUUID, 16],
|
||||
'nbt': [readNbt, writeNbt, sizeOfNbt],
|
||||
'entityMetadataLoop': [readEntityMetadata, writeEntityMetadata, sizeOfEntityMetadata],
|
||||
'ipAddress': [readIpAddress, writeIpAddress, 4],
|
||||
'endOfArray': [readEndOfArray, writeEndOfArray, sizeOfEndOfArray]
|
||||
};
|
||||
9
dist/index.js
vendored
Normal file
9
dist/index.js
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
createSerializer: require("./transforms/serializer").createSerializer,
|
||||
createDeserializer: require("./transforms/serializer").createDeserializer,
|
||||
createProtocol: require('./transforms/serializer').createProtocol,
|
||||
createServer: require("./createServer"),
|
||||
createClient: require("./createClient")
|
||||
};
|
||||
32
dist/transforms/serializer.js
vendored
Normal file
32
dist/transforms/serializer.js
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
'use strict';
|
||||
|
||||
var ProtoDef = require('protodef').ProtoDef;
|
||||
|
||||
var Serializer = require('protodef').Serializer;
|
||||
|
||||
var Parser = require('protodef').Parser;
|
||||
|
||||
var protocol = require('../../data/protocol.json').types;
|
||||
|
||||
function createProtocol() {
|
||||
var proto = new ProtoDef();
|
||||
proto.addTypes(require('../datatypes/minecraft'));
|
||||
proto.addTypes(protocol);
|
||||
return proto;
|
||||
}
|
||||
|
||||
function createSerializer() {
|
||||
var proto = createProtocol();
|
||||
return new Serializer(proto, 'packet');
|
||||
}
|
||||
|
||||
function createDeserializer() {
|
||||
var proto = createProtocol();
|
||||
return new Parser(proto, 'packet');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createDeserializer: createDeserializer,
|
||||
createSerializer: createSerializer,
|
||||
createProtocol: createProtocol
|
||||
};
|
||||
13
index.js
13
index.js
|
|
@ -1,14 +1,3 @@
|
|||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const register = require('@babel/register').default;
|
||||
register({
|
||||
extends: path.resolve(__dirname, '.babelrc'),
|
||||
ignore: [/node_modules/],
|
||||
extensions: [
|
||||
".js",
|
||||
".ts"
|
||||
]
|
||||
});
|
||||
|
||||
module.exports = require('./src/index.js');
|
||||
module.exports = require('./dist/index.js');
|
||||
|
|
|
|||
10
package.json
10
package.json
|
|
@ -4,6 +4,7 @@
|
|||
"description": "Parse and serialize Minecraft Pocket Edition packets",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "babel src --out-dir dist",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
|
|
@ -27,8 +28,10 @@
|
|||
"uuid-1345": "^0.99.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.5.0",
|
||||
"buffer-equal": "^1.0.0",
|
||||
"mocha": "^2.5.3"
|
||||
"mocha": "^2.5.3",
|
||||
"pre-commit": "^1.2.2"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
@ -37,5 +40,8 @@
|
|||
"bugs": {
|
||||
"url": "https://github.com/mhsjlw/pocket-minecraft-protocol/issues"
|
||||
},
|
||||
"homepage": "https://github.com/mhsjlw/pocket-minecraft-protocol#readme"
|
||||
"homepage": "https://github.com/mhsjlw/pocket-minecraft-protocol#readme",
|
||||
"pre-commit": [
|
||||
"build"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue