diff --git a/package.json b/package.json index 8090cfa..51cdac9 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "@azure/msal-node": "^1.0.0-beta.6", "@jsprismarine/jsbinaryutils": "^2.1.8", "@xboxreplay/xboxlive-auth": "^3.3.3", - "aes-js": "^3.1.2", "asn1": "^0.2.4", "browserify-cipher": "^1.0.1", "debug": "^4.3.1", @@ -35,7 +34,7 @@ "node-fetch": "^2.6.1", "prismarine-nbt": "^1.5.0", "protodef": "^1.11.0", - "raknet-native": "^0.2.0", + "raknet-native": "^1.0.0", "uuid-1345": "^1.0.2" }, "devDependencies": { diff --git a/src/rak.js b/src/rak.js index 88682d6..912df2d 100644 --- a/src/rak.js +++ b/src/rak.js @@ -5,8 +5,9 @@ const Reliability = require('jsp-raknet/protocol/reliability') const RakClient = require('jsp-raknet/client') const ConnWorker = require('./rakWorker') const { waitFor } = require('./datatypes/util') +const ServerName = require('./server/advertisement') try { - var { Client, Server, PacketPriority, PacketReliability, McPingMessage } = require('raknet-native') // eslint-disable-line + var { Client, Server, PacketPriority, PacketReliability } = require('raknet-native') // eslint-disable-line } catch (e) { console.debug('[raknet] native not found, using js', e) } @@ -19,7 +20,7 @@ class RakNativeClient extends EventEmitter { this.onCloseConnection = () => { } this.onEncapsulated = () => { } - this.raknet = new Client(options.hostname, options.port, 'minecraft') + this.raknet = new Client(options.hostname, options.port, { protocolVersion: 10 }) this.raknet.on('encapsulated', ({ buffer, address }) => { this.onEncapsulated(buffer, address) }) @@ -65,16 +66,17 @@ class RakNativeClient extends EventEmitter { } class RakNativeServer extends EventEmitter { - constructor (options = {}) { + constructor (options = {}, server) { super() this.onOpenConnection = () => { } this.onCloseConnection = () => { } this.onEncapsulated = () => { } this.raknet = new Server(options.hostname, options.port, { maxConnections: options.maxConnections || 3, - minecraft: {}, - message: new McPingMessage().toBuffer() + protocolVersion: 10, + message: ServerName.getServerName(server) }) + // TODO: periodically update the server name until we're closed this.raknet.on('openConnection', (client) => { client.sendReliable = function (buffer, immediate) { @@ -91,7 +93,6 @@ class RakNativeServer extends EventEmitter { }) this.raknet.on('encapsulated', ({ buffer, address }) => { - // console.log('ENCAP',thingy) this.onEncapsulated(buffer, address) }) } diff --git a/src/server/advertisement.js b/src/server/advertisement.js new file mode 100644 index 0000000..0b9a401 --- /dev/null +++ b/src/server/advertisement.js @@ -0,0 +1,39 @@ +class ServerName { + motd = 'Bedrock Protocol Server' + name = 'bedrock-protocol' + protocol = 408 + version = '1.16.20' + players = { + online: 0, + max: 5 + } + + gamemode = 'Creative' + serverId = '0' + + toString (version) { + return [ + 'MCPE', + this.motd, + this.protocol, + this.version, + this.players.online, + this.players.max, + this.serverId, + this.name, + this.gamemode + ].join(';') + ';' + } + + toBuffer (version) { + const str = this.toString(version) + return Buffer.concat([Buffer.from([0, str.length]), Buffer.from(str)]) + } +} + +module.exports = { + ServerName, + getServerName (client) { + return new ServerName().toBuffer() + } +} diff --git a/src/transforms/encryption.js b/src/transforms/encryption.js index 81a70af..f06a279 100644 --- a/src/transforms/encryption.js +++ b/src/transforms/encryption.js @@ -1,8 +1,7 @@ const { Transform } = require('readable-stream') -const crypto = globalThis.isElectron ? require('browserify-cipher/browser') : require('crypto') -const { createHash } = require('crypto') -const aesjs = require('aes-js') +const crypto = require('crypto') const Zlib = require('zlib') +if (globalThis.isElectron) var { CipherCFB8 } = require('raknet-native') // eslint-ignore-line const CIPHER_ALG = 'aes-256-cfb8' @@ -23,37 +22,28 @@ function createDecipher (secret, initialValue) { class Cipher extends Transform { constructor (secret, iv) { super() - this.aes = new aesjs.ModeOfOperation.cfb(secret, iv, 1) // eslint-disable-line new-cap + this.aes = new CipherCFB8(secret, iv) } _transform (chunk, enc, cb) { - try { - const res = this.aes.encrypt(chunk) - cb(null, res) - } catch (e) { - cb(e) - } + const ciphered = this.aes.cipher(chunk) + cb(null, ciphered) } } class Decipher extends Transform { constructor (secret, iv) { super() - this.aes = new aesjs.ModeOfOperation.cfb(secret, iv, 1) // eslint-disable-line new-cap + this.aes = new CipherCFB8(secret, iv) } _transform (chunk, enc, cb) { - try { - const res = this.aes.decrypt(chunk) - cb(null, res) - } catch (e) { - cb(e) - } + cb(null, this.aes.decipher(chunk)) } } function computeCheckSum (packetPlaintext, sendCounter, secretKeyBytes) { - const digest = createHash('sha256') + const digest = crypto.createHash('sha256') const counter = Buffer.alloc(8) counter.writeBigInt64LE(sendCounter, 0) digest.update(counter)