From e699cec870545ba95532b34e56dbf66f604fcd9d Mon Sep 17 00:00:00 2001 From: Heath123 Date: Fri, 25 Dec 2020 13:58:19 +0000 Subject: [PATCH] Add message when port is in use --- html/mainPage/js/ipcHandler.js | 2 +- html/mainPage/js/main.js | 4 +- package-lock.json | 2 +- src/packetHandler.js | 4 +- src/proxy/bedrock/proxy.js | 2 +- src/proxy/java/proxy.js | 257 +++++++++++++++++++-------------- 6 files changed, 159 insertions(+), 112 deletions(-) diff --git a/html/mainPage/js/ipcHandler.js b/html/mainPage/js/ipcHandler.js index 526a77e..4c8366a 100644 --- a/html/mainPage/js/ipcHandler.js +++ b/html/mainPage/js/ipcHandler.js @@ -50,6 +50,6 @@ exports.setup = function (passedSharedVars) { sharedVars.ipcRenderer.on('message', (event, arg) => { const ipcMessage = JSON.parse(arg) - errorDialog(ipcMessage.header, ipcMessage.info) + errorDialog(ipcMessage.header, ipcMessage.info, ipcMessage.fatal) }) } diff --git a/html/mainPage/js/main.js b/html/mainPage/js/main.js index 4c01b75..891a5d8 100644 --- a/html/mainPage/js/main.js +++ b/html/mainPage/js/main.js @@ -297,7 +297,7 @@ function editAndResend (id) { }) } -function errorDialog(header, info) { +function errorDialog(header, info, fatal) { // dialogOpen = true document.getElementById('dialog-overlay').className = 'dialog-overlay active' document.getElementById('dialog').className='dialog dialog-small' @@ -306,7 +306,7 @@ function errorDialog(header, info) { `

${header}

${info}
- ` + ` } sharedVars.ipcRenderer.on('editAndResend', (event, arg) => { // Context menu diff --git a/package-lock.json b/package-lock.json index a12d1b2..4ba1e69 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5851,7 +5851,7 @@ } }, "yggdrasil": { - "version": "github:ph0t0shop/node-yggdrasil#7ba383a52fc564b0c48495b59ca0b97532963218", + "version": "github:ph0t0shop/node-yggdrasil#e8da5eed15f6942b434ad10ed8983bb167b48db0", "from": "github:ph0t0shop/node-yggdrasil#patch-1", "requires": { "phin": "^3.4.1", diff --git a/src/packetHandler.js b/src/packetHandler.js index 681e366..2acbf5b 100644 --- a/src/packetHandler.js +++ b/src/packetHandler.js @@ -65,6 +65,6 @@ exports.packetHandler = function (direction, meta, data, id, raw) { } } -exports.messageHandler = function (header, info) { - mainWindow.send('message', JSON.stringify({ header: header, info: info })) +exports.messageHandler = function (header, info, fatal) { + mainWindow.send('message', JSON.stringify({ header: header, info: info, fatal: fatal })) } \ No newline at end of file diff --git a/src/proxy/bedrock/proxy.js b/src/proxy/bedrock/proxy.js index 0a25d68..52de5df 100644 --- a/src/proxy/bedrock/proxy.js +++ b/src/proxy/bedrock/proxy.js @@ -64,7 +64,7 @@ exports.startProxy = function (passedHost, passedPort, passedListenPort, version if (item.isEvent) { switch(item.eventType) { case 'unableToConnect': - messageCallback('Ubale to connect to server', 'Unable to connect to the Bedrock server at ' + + messageCallback('Unable to connect to server', 'Unable to connect to the Bedrock server at ' + item.eventData.replace(/^\//, '') + // Remove slash at start '. Make sure the server is online.') relaunch() diff --git a/src/proxy/java/proxy.js b/src/proxy/java/proxy.js index ff3f59a..6750f4a 100644 --- a/src/proxy/java/proxy.js +++ b/src/proxy/java/proxy.js @@ -11,6 +11,21 @@ let toClientMappings let toServerMappings let storedCallback +// https://gist.github.com/timoxley/1689041 +function isPortTaken (port, fn) { + const net = require('net') + const tester = net.createServer() + .once('error', function (err) { + if (err.code != 'EADDRINUSE') return fn(err) + fn(null, true) + }) + .once('listening', function() { + tester.once('close', function() { fn(null, false) }) + .close() + }) + .listen(port) +} + exports.capabilities = { modifyPackets: true, jsonData: true, @@ -40,116 +55,148 @@ exports.startProxy = function (host, port, listenPort, version, authConsent, cal port = host.substring(host.indexOf(':') + 1) host = host.substring(0, host.indexOf(':')) } - - const srv = mc.createServer({ - 'online-mode': false, - port: listenPort, - keepAlive: false, - version: version - }) - console.log('Proxy started (Java)!') - srv.on('login', function (client) { - realClient = client - const addr = client.socket.remoteAddress - console.log('Incoming connection', '(' + addr + ')') - let endedClient = false - let endedTargetClient = false - client.on('end', function () { - endedClient = true - console.log('Connection closed by client', '(' + addr + ')') - if (!endedTargetClient) { targetClient.end('End') } - }) - client.on('error', function (err) { - endedClient = true - console.log('Connection error by client', '(' + addr + ')') - console.log(err.stack) - if (!endedTargetClient) { targetClient.end('Error') } - }) - if (authConsent) { - console.log('Will attempt to use launcher_profiles.json for online mode login data') + isPortTaken(listenPort, (err, taken) => { + // TODO: Handle errors + console.log(err, taken) + if (taken) { + console.log('call') + // Wait for the renderer to be ready + setTimeout(() => { + messageCallback('Unable to start pakkit', 'The port ' + listenPort + ' is in use. ' + + 'Make sure to close any other instances of pakkit running on the same port or try a different port.', true) + }, 1000) } else { - console.warn('Consent not given to use launcher_profiles.json - online mode will not work') - } - const targetClient = mc.createClient({ - host: host, - port: port, - username: client.username, - keepAlive: false, - version: version, - profilesFolder: authConsent ? minecraftFolder : undefined - }) - realServer = targetClient - function handleServerboundPacket (data, meta, raw) { - // console.log('serverbound packet', meta, data) - if (targetClient.state === states.PLAY && meta.state === states.PLAY) { - const id = Object.keys(toServerMappings).find(key => toServerMappings[key] === meta.name) - const direction = 'serverbound' // Stops standardjs complaining (no-callback-literal) - // callback(direction, meta, data, id) - if (!endedTargetClient) { - // targetClient.write(meta.name, data) - callback(direction, meta, data, id, raw) + let srv + try { + srv = mc.createServer({ + 'online-mode': false, + port: listenPort, + keepAlive: false, + version: version + }) + console.log('Proxy started (Java)!') + } catch (err) { + let header = 'Unable to start pakkit' + let message = err.message + if (err.message.includes('EADDRINUSE')) { + message = 'The port ' + listenPort + ' is in use. ' + + 'Make sure to close any other instances of pakkit running on the same port or try a different port.' } + messageCallback(header, message) + return } - } - function handleClientboundPacket (data, meta, raw) { - if (meta.state === states.PLAY && client.state === states.PLAY) { - const id = Object.keys(toClientMappings).find(key => toClientMappings[key] === meta.name) - const direction = 'clientbound' // Stops standardjs complaining (no-callback-literal) - // callback(direction, meta, data, id) - if (!endedClient) { - // client.write(meta.name, data) - callback(direction, meta, data, id, raw) - if (meta.name === 'set_compression') { - client.compressionThreshold = data.threshold - } // Set compression + srv.on('login', function (client) { + realClient = client + const addr = client.socket.remoteAddress + console.log('Incoming connection', '(' + addr + ')') + let endedClient = false + let endedTargetClient = false + client.on('end', function () { + endedClient = true + console.log('Connection closed by client', '(' + addr + ')') + if (!endedTargetClient) { targetClient.end('End') } + }) + client.on('error', function (err) { + endedClient = true + console.log('Connection error by client', '(' + addr + ')') + console.log(err.stack) + if (!endedTargetClient) { targetClient.end('Error') } + }) + if (authConsent) { + console.log('Will attempt to use launcher_profiles.json for online mode login data') + } else { + console.warn('Consent not given to use launcher_profiles.json - online mode will not work') } - } + const targetClient = mc.createClient({ + host: host, + port: port, + username: client.username, + keepAlive: false, + version: version, + profilesFolder: authConsent ? minecraftFolder : undefined + }) + realServer = targetClient + function handleServerboundPacket (data, meta, raw) { + // console.log('serverbound packet', meta, data) + if (targetClient.state === states.PLAY && meta.state === states.PLAY) { + const id = Object.keys(toServerMappings).find(key => toServerMappings[key] === meta.name) + const direction = 'serverbound' // Stops standardjs complaining (no-callback-literal) + // callback(direction, meta, data, id) + if (!endedTargetClient) { + // targetClient.write(meta.name, data) + callback(direction, meta, data, id, raw) + } + } + } + function handleClientboundPacket (data, meta, raw) { + if (meta.state === states.PLAY && client.state === states.PLAY) { + const id = Object.keys(toClientMappings).find(key => toClientMappings[key] === meta.name) + const direction = 'clientbound' // Stops standardjs complaining (no-callback-literal) + // callback(direction, meta, data, id) + if (!endedClient) { + // client.write(meta.name, data) + callback(direction, meta, data, id, raw) + if (meta.name === 'set_compression') { + client.compressionThreshold = data.threshold + } // Set compression + } + } + } + const bufferEqual = require('buffer-equal') + targetClient.on('raw', function (buffer, meta) { + if (client.state !== states.PLAY || meta.state !== states.PLAY) { return } + const packetData = targetClient.deserializer.parsePacketBuffer(buffer).data.params + handleClientboundPacket(packetData, meta, [...buffer]) + const packetBuff = client.serializer.createPacketBuffer({ name: meta.name, params: packetData }) + if (!bufferEqual(buffer, packetBuff)) { + console.log('client<-server: Error in packet ' + meta.state + '.' + meta.name) + console.log('received buffer', buffer.toString('hex')) + console.log('produced buffer', packetBuff.toString('hex')) + console.log('received length', buffer.length) + console.log('produced length', packetBuff.length) + } + /* if (client.state === states.PLAY && brokenPackets.indexOf(packetId.value) !=== -1) + { + console.log(`client<-server: raw packet); + console.log(packetData); + if (!endedClient) + client.writeRaw(buffer); + } */ + }) + client.on('raw', function (buffer, meta) { + if (meta.state !== states.PLAY || targetClient.state !== states.PLAY) { return } + const packetData = client.deserializer.parsePacketBuffer(buffer).data.params + handleServerboundPacket(packetData, meta, [...buffer]) + const packetBuff = targetClient.serializer.createPacketBuffer({ name: meta.name, params: packetData }) + if (!bufferEqual(buffer, packetBuff)) { + console.log('client->server: Error in packet ' + meta.state + '.' + meta.name) + console.log('received buffer', buffer.toString('hex')) + console.log('produced buffer', packetBuff.toString('hex')) + console.log('received length', buffer.length) + console.log('produced length', packetBuff.length) + } + }) + targetClient.on('end', function () { + endedTargetClient = true + console.log('Connection closed by server', '(' + addr + ')') + if (!endedClient) { client.end('Connection closed by server ' + '(' + addr + ')') } + }) + targetClient.on('error', function (err) { + endedTargetClient = true + console.log('Connection error by server', '(' + addr + ') ', err) + console.log(err.stack) + let header = 'Unable to connect to server' + let message = err.message + if (err.message.includes('ECONNREFUSED')) { + message = 'Unable to connect to the Java server at ' + + host + ':' + port + + '. Make sure the server is online.' + } + messageCallback(header, message) + if (!endedClient) { client.end('pakkit - ' + header + '\n' + message) } + }) + }) } - const bufferEqual = require('buffer-equal') - targetClient.on('raw', function (buffer, meta) { - if (client.state !== states.PLAY || meta.state !== states.PLAY) { return } - const packetData = targetClient.deserializer.parsePacketBuffer(buffer).data.params - handleClientboundPacket(packetData, meta, [...buffer]) - const packetBuff = client.serializer.createPacketBuffer({ name: meta.name, params: packetData }) - if (!bufferEqual(buffer, packetBuff)) { - console.log('client<-server: Error in packet ' + meta.state + '.' + meta.name) - console.log('received buffer', buffer.toString('hex')) - console.log('produced buffer', packetBuff.toString('hex')) - console.log('received length', buffer.length) - console.log('produced length', packetBuff.length) - } - /* if (client.state === states.PLAY && brokenPackets.indexOf(packetId.value) !=== -1) - { - console.log(`client<-server: raw packet); - console.log(packetData); - if (!endedClient) - client.writeRaw(buffer); - } */ - }) - client.on('raw', function (buffer, meta) { - if (meta.state !== states.PLAY || targetClient.state !== states.PLAY) { return } - const packetData = client.deserializer.parsePacketBuffer(buffer).data.params - handleServerboundPacket(packetData, meta, [...buffer]) - const packetBuff = targetClient.serializer.createPacketBuffer({ name: meta.name, params: packetData }) - if (!bufferEqual(buffer, packetBuff)) { - console.log('client->server: Error in packet ' + meta.state + '.' + meta.name) - console.log('received buffer', buffer.toString('hex')) - console.log('produced buffer', packetBuff.toString('hex')) - console.log('received length', buffer.length) - console.log('produced length', packetBuff.length) - } - }) - targetClient.on('end', function () { - endedTargetClient = true - console.log('Connection closed by server', '(' + addr + ')') - if (!endedClient) { client.end('End') } - }) - targetClient.on('error', function (err) { - endedTargetClient = true - console.log('Connection error by server', '(' + addr + ') ', err) - console.log(err.stack) - if (!endedClient) { client.end('Error') } - }) }) }