diff --git a/html/mainPage/index.html b/html/mainPage/index.html index b9b30f3..2cb52e8 100644 --- a/html/mainPage/index.html +++ b/html/mainPage/index.html @@ -18,7 +18,7 @@ - +
diff --git a/html/mainPage/js/main.js b/html/mainPage/js/main.js index 891a5d8..27085ba 100644 --- a/html/mainPage/js/main.js +++ b/html/mainPage/js/main.js @@ -47,6 +47,7 @@ function toggleCheckbox (box, packetName, direction) { box.readOnly = true box.indeterminate = true } */ + box.checked = !box.checked // console.log('Toggled visibility of', packetName, 'to', box.checked) const index = sharedVars.hiddenPackets[direction].indexOf(packetName) @@ -221,7 +222,7 @@ function addPacketsToFiltering (packetsObject, direction, appendTo) { if (packetsObject.hasOwnProperty(key)) { console.log(!sharedVars.hiddenPackets[direction].includes(packetsObject[key])) filteringPackets.innerHTML += - `
  • + `
  • ${escapeHtml(key)} @@ -300,7 +301,7 @@ function editAndResend (id) { function errorDialog(header, info, fatal) { // dialogOpen = true document.getElementById('dialog-overlay').className = 'dialog-overlay active' - document.getElementById('dialog').className='dialog dialog-small' + document.getElementById('dialog').className='dialog dialog-small error-dialog' document.getElementById('dialog').innerHTML = `

    ${header}

    @@ -321,7 +322,8 @@ function deselectPacket () { currentPacket = undefined currentPacketType = undefined sharedVars.packetDom.getTreeElement().firstElementChild.innerHTML = 'No packet selected!' - document.body.className = 'noPacketSelected' + document.body.classList.remove('packetSelected') + document.body.classList.add('noPacketSelected') hexViewer.style.display = 'none' } @@ -364,10 +366,11 @@ window.packetClick = function (id) { // window. stops standardjs from complainin } currentPacket = id - const element = document.getElementById('packet' + id) - currentPacketType = element.children[1].innerText + // const element = document.getElementById('packet' + id) + currentPacketType = sharedVars.allPackets[id].name removeOrAddSelection(currentPacket, true) - document.body.className = 'packetSelected' + document.body.classList.remove('noPacketSelected') + document.body.classList.add('packetSelected') if (sharedVars.proxyCapabilities.jsonData) { // sidebar.innerHTML = '
    Loading packet data...
    '; sharedVars.packetDom.getTree().loadData(sharedVars.allPackets[id].data) @@ -444,7 +447,7 @@ document.body.addEventListener('contextmenu', (event) => { sharedVars.ipcRenderer.send('contextMenu', JSON.stringify({ direction: target.className.split(' ')[1], - text: target.children[0].innerText + ' ' + target.children[1].innerText, + text: target.children[0].children[0].innerText + ' ' + target.children[0].children[1].innerText, id: target.id.replace('packet', '') })) }) diff --git a/html/mainPage/js/packetDom.js b/html/mainPage/js/packetDom.js index 42eddda..793d6f0 100644 --- a/html/mainPage/js/packetDom.js +++ b/html/mainPage/js/packetDom.js @@ -31,13 +31,21 @@ function trimData (data) { // Function to trim the size of stringified data for return newData } +function formatTime (ms) { + // Based on https://stackoverflow.com/a/50409993/4012708 + return new Date(new Date(ms).getTime() - new Date().getTimezoneOffset() * 60000).toISOString().split("T")[1].replace(/[0-9]Z$/, ''); +} + function addPacketToDOM (packet) { const isHidden = filteringLogic.packetFilteredByFilterBox(packet, sharedVars.lastFilter, sharedVars.hiddenPackets) sharedVars.allPacketsHTML.push([ `
  • - ${escapeHtml(packet.hexIdString)} - ${escapeHtml(packet.meta.name)} - ${escapeHtml(trimData(packet.data))} +
    + ${escapeHtml(packet.hexIdString)} + ${escapeHtml(packet.meta.name)} + ${escapeHtml(trimData(packet.data))} +
    + ${escapeHtml(formatTime(packet.time))}
  • `]) /* if (!noUpdate) { clusterize.append(sharedVars.allPacketsHTML.slice(-1)[0]); diff --git a/html/mainPage/style.css b/html/mainPage/style.css index c29d7c8..d52d771 100644 --- a/html/mainPage/style.css +++ b/html/mainPage/style.css @@ -21,23 +21,35 @@ body { -moz-box-sizing: border-box; box-sizing: border-box; height: 100%; + /* Default before everything loads */ + width: calc(50% - 5px); } + +/* Targets the right panel to add spacing, but only before the gutter loads */ +#packets + #sidebar { + margin-left: 10px; +} + .gutter.gutter-horizontal { cursor: ew-resize; } + .box { overflow-y: auto; border: 1px solid #1A1A1A; border-radius: 10px; height: calc(100% - 24px); /* Take off toolbar height */ } + div.toolbar { height: 24px; overflow: hidden; } + #packets { position: relative; /* Is this needed? TODO: Check */ } + .packetlist { list-style: none; padding: 0; @@ -251,6 +263,7 @@ div.error { text-align: right; font-size: 90%; color: red; + user-select: text; } .packet.selected { @@ -261,7 +274,25 @@ div.error { display: contents; } +.error-dialog { + user-select: text; +} + .bottom-button { position: absolute; bottom: 16px; -} \ No newline at end of file + user-select: none; +} + +body.timeShown div.main-data { + display: inline-block; + width: calc(100% - 120px); + overflow-x: hidden; + text-overflow: ellipsis; + /* Makes up for inline-block causing extra space on the bottom */ + margin-bottom: -4px; +} + +body.timeNotShown div.main-data { + display: inline; +} diff --git a/html/scrollbar.css b/html/scrollbar.css index 0dfb87b..57ae1aa 100644 --- a/html/scrollbar.css +++ b/html/scrollbar.css @@ -1,4 +1,5 @@ ::-webkit-scrollbar { + background: #242424; width: 17px; } @@ -14,3 +15,7 @@ ::-webkit-scrollbar-thumb:hover { background: rgba(0, 0, 0, 0.5); } + +::-webkit-scrollbar-corner { + background: #242424; +} diff --git a/html/shared.css b/html/shared.css index c6b90bd..bbf9132 100644 --- a/html/shared.css +++ b/html/shared.css @@ -24,3 +24,65 @@ a { a:active { color: rgba(255, 255, 255, 0.6); } + +/* Based on https://www.w3schools.com/howto/howto_css_switch.asp */ + +.switch { + position: relative; + display: inline-block; + width: 42px; + height: 24px; +} + +.switch input { + opacity: 0; + width: 0; + height: 0; +} + +.slider { + position: absolute; + cursor: pointer; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: #ccc; + -webkit-transition: .07s; + transition: .07s; +} + +.slider:before { + position: absolute; + content: ""; + height: 18px; + width: 18px; + left: 3px; + bottom: 3px; + background-color: white; + -webkit-transition: .07s; + transition: .07s; +} + +input:checked + .slider { + background-color: #2196F3; +} + +input:focus + .slider { + box-shadow: 0 0 1px #2196F3; +} + +input:checked + .slider:before { + -webkit-transform: translateX(18px); + -ms-transform: translateX(18px); + transform: translateX(18px); +} + +/* Rounded sliders */ +.slider.round { + border-radius: 24px; +} + +.slider.round:before { + border-radius: 50%; +} \ No newline at end of file diff --git a/html/startPage/index.html b/html/startPage/index.html index 3d7df42..1e634aa 100644 --- a/html/startPage/index.html +++ b/html/startPage/index.html @@ -86,10 +86,19 @@

    pakkit


    diff --git a/html/startPage/script.js b/html/startPage/script.js index 20343e2..fde71f7 100644 --- a/html/startPage/script.js +++ b/html/startPage/script.js @@ -1,7 +1,7 @@ const { ipcRenderer } = require('electron') -const Store = require('electron-store'); +const Store = require('electron-store') -const store = new Store(); +const store = new Store() /* const customTitlebar = require('custom-electron-titlebar'); diff --git a/html/startPage/style.css b/html/startPage/style.css index 6a5c066..be03639 100644 --- a/html/startPage/style.css +++ b/html/startPage/style.css @@ -1,10 +1,19 @@ +body { + max-width: 500px; +} + h1.title { font-family: "Lucida Console", Monaco, monospace; } + form { display: table; } + form p { display: table-row; } + form p label { display: table-cell; padding-left: 16px; padding-right: 16px; text-align: center; } + form p input { display: table-cell; } + input#start { padding: 10px 78.5px; } diff --git a/package-lock.json b/package-lock.json index 4ba1e69..5057f60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -878,6 +878,51 @@ "@types/node": "*" } }, + "@xboxreplay/errors": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@xboxreplay/errors/-/errors-0.1.0.tgz", + "integrity": "sha512-Tgz1d/OIPDWPeyOvuL5+aai5VCcqObhPnlI3skQuf80GVF3k1I0lPCnGC+8Cm5PV9aLBT5m8qPcJoIUQ2U4y9g==" + }, + "@xboxreplay/xboxlive-auth": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@xboxreplay/xboxlive-auth/-/xboxlive-auth-3.3.0.tgz", + "integrity": "sha512-4bKgw35kq8NGxt2lGmBVXTdieTs1E+JGWrf/shMWpdLIhZ0okRTJ/bpBo/Foa9YZXka+8wWb0pQu92MWKacCFA==", + "requires": { + "@xboxreplay/errors": "^0.1.0", + "axios": "^0.19.2" + }, + "dependencies": { + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "requires": { + "follow-redirects": "1.5.10" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", @@ -3906,9 +3951,10 @@ } }, "minecraft-protocol": { - "version": "github:Heath123/node-minecraft-protocol#876f723fc2060d9fb253ef8542186d2d5ee89501", - "from": "github:Heath123/node-minecraft-protocol#ph0t0shop", + "version": "github:PrismarineJS/node-minecraft-protocol#c7a021d689bfd19b5ce1329928e1db6822e50108", + "from": "github:PrismarineJS/node-minecraft-protocol#master", "requires": { + "@xboxreplay/xboxlive-auth": "^3.3.0", "aes-js": "^3.1.2", "buffer-equal": "^1.0.0", "debug": "^4.1.0", @@ -3917,12 +3963,13 @@ "lodash.merge": "^4.3.0", "minecraft-data": "^2.70.0", "minecraft-folder-path": "^1.1.0", + "node-fetch": "^2.6.1", "node-rsa": "^0.4.2", "prismarine-nbt": "^1.3.0", "protodef": "^1.8.0", "readable-stream": "^3.0.6", "uuid-1345": "^1.0.1", - "yggdrasil": "github:ph0t0shop/node-yggdrasil#patch-1" + "yggdrasil": "^1.4.0" }, "dependencies": { "readable-stream": { @@ -4055,8 +4102,7 @@ "node-fetch": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" }, "node-gyp": { "version": "7.1.2", @@ -5851,8 +5897,9 @@ } }, "yggdrasil": { - "version": "github:ph0t0shop/node-yggdrasil#e8da5eed15f6942b434ad10ed8983bb167b48db0", - "from": "github:ph0t0shop/node-yggdrasil#patch-1", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/yggdrasil/-/yggdrasil-1.4.0.tgz", + "integrity": "sha512-pN4OFtvJ4WnbvGe6dSsOUx8C6I19Tzv2hVCcoIjekFOuL9zWc7C993z3STmCI6NuWVAgtQsLv+ciNVOWHIL/pA==", "requires": { "phin": "^3.4.1", "uuid": "^8.2.0" diff --git a/package.json b/package.json index b130de7..934d751 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "md5-file": "^5.0.0", "minecraft-data": "^2.70.2", "minecraft-folder-path": "^1.1.0", - "minecraft-protocol": "github:Heath123/node-minecraft-protocol#ph0t0shop", + "minecraft-protocol": "github:PrismarineJS/node-minecraft-protocol#master", "node-eval": "^2.0.0", "source-map-support": "^0.5.19" } diff --git a/src/index.js b/src/index.js index 890bd1f..8695b06 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,9 @@ const {app, BrowserWindow, ipcMain, clipboard, Menu} = require('electron') app.allowRendererProcessReuse = true const fs = require('fs') +const Store = require('electron-store') + +const store = new Store() let proxy // Defined later when an option is chosen const resourcesPath = fs.existsSync('resources/app') @@ -138,22 +141,15 @@ if (continueProgram) { } function createWindow() { - // Load the previous state with fallback to defaults - const mainWindowState = windowStateKeeper({ - defaultWidth: 1000, - defaultHeight: 800 - }); - // Let us register listeners on the window, so we can update the state // automatically (the listeners will be removed when the window is closed) // and restore the maximized or full screen state // Create the browser window. const win = new BrowserWindow({ - x: mainWindowState.x, - y: mainWindowState.y, - width: mainWindowState.width, - height: mainWindowState.height, + height: store.get('authConsentGiven') ? 535 : 691, + width: 500, + resizable: false, // frame: false, webPreferences: { nodeIntegration: true @@ -178,8 +174,6 @@ if (continueProgram) { }, showDialog: false }); - - mainWindowState.manage(win) } // This method will be called when Electron has finished @@ -216,7 +210,22 @@ if (continueProgram) { } packetHandler.init(BrowserWindow.getAllWindows()[0], ipcMain, proxy) proxy.startProxy(ipcMessage.connectAddress, ipcMessage.connectPort, ipcMessage.listenPort, ipcMessage.version, ipcMessage.consent, packetHandler.packetHandler, packetHandler.messageHandler , dataFolder) - BrowserWindow.getAllWindows()[0].loadFile('html/mainPage/index.html') + + const win = BrowserWindow.getAllWindows()[0] + + win.loadFile('html/mainPage/index.html') + + // Load the previous state with fallback to defaults + const mainWindowState = windowStateKeeper({ + defaultWidth: 1000, + defaultHeight: 800 + }); + + win.setResizable(true) + win.setPosition(mainWindowState.x, mainWindowState.y) + win.setSize(mainWindowState.width, mainWindowState.height) + + mainWindowState.manage(win) }) ipcMain.on('proxyCapabilities', (event, arg) => { diff --git a/src/packetHandler.js b/src/packetHandler.js index 9a04fbf..10024f9 100644 --- a/src/packetHandler.js +++ b/src/packetHandler.js @@ -44,7 +44,7 @@ exports.init = function (window, passedIpcMain, passedProxy) { exports.packetHandler = function (direction, meta, data, id, raw, canUseScripting) { try { - mainWindow.send('packet', JSON.stringify({ meta: meta, data: data, direction: direction, hexIdString: id, raw: raw })) + mainWindow.send('packet', JSON.stringify({ meta: meta, data: data, direction: direction, hexIdString: id, raw: raw, time: Date.now() })) // TODO: Maybe write raw data? if (proxy.capabilities.scriptingSupport && canUseScripting) { if (direction === 'clientbound') { diff --git a/src/proxy/java/proxy.js b/src/proxy/java/proxy.js index 240c188..c505efb 100644 --- a/src/proxy/java/proxy.js +++ b/src/proxy/java/proxy.js @@ -194,12 +194,12 @@ exports.startProxy = function (host, port, listenPort, version, authConsent, cal }) targetClient.on('end', function () { endedTargetClient = true - console.log('Connection closed by server', '(' + addr + ')') - if (!endedClient) { client.end('Connection closed by server ' + '(' + addr + ')') } + console.log('Connection closed by server', '(' + host + ':' + port + ')') + if (!endedClient) { client.end('Connection closed by server ' + '(' + host + ':' + port + ')') } }) targetClient.on('error', function (err) { endedTargetClient = true - console.log('Connection error by server', '(' + addr + ') ', err) + console.log('Connection error by server', '(' + host + ':' + port + ') ', err) console.log(err.stack) let header = 'Unable to connect to server' let message = err.message