From ce1fab700c90f54cd42182ed5608c40b95b95efe Mon Sep 17 00:00:00 2001 From: Mike Ratcliffe Date: Tue, 17 Sep 2024 11:22:35 +0100 Subject: [PATCH] build: Add eslint fix: Battery not displayed properly build: Add eslint --- eslint.config.mjs | 167 ++++++++ main.js | 77 ++-- package.json | 13 + removeLocales.js | 12 +- tools.js | 693 ++++++++++++++++++------------- versioncheck.js | 18 +- views/browse_include.twig | 4 +- views/device_info.twig | 15 +- views/index.twig | 16 +- views/js/browse.js | 33 +- views/js/installed.js | 10 +- views/js/main.js | 7 + views/js/search.js | 34 +- views/layout.twig | 63 ++- views/modals/app_start.twig | 4 +- views/modals/app_tools.twig | 15 +- views/modals/appinfo.twig | 20 +- views/modals/appinfo_events.twig | 16 +- views/modals/confirm.twig | 10 +- views/modals/installed.twig | 7 + views/modals/prompt.twig | 16 +- views/modals/scrcpy.twig | 2 +- views/modals/sideload-queue.twig | 56 ++- views/modals/sideload.twig | 42 +- views/modals/tweaks.twig | 33 +- views/settings_include.twig | 30 +- 26 files changed, 948 insertions(+), 465 deletions(-) create mode 100644 eslint.config.mjs diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..50afe90 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,167 @@ +import eslintConfigPrettier from "eslint-config-prettier"; +import globals from "globals"; +import html from "eslint-plugin-html"; +import json from "eslint-plugin-json"; +import pluginJs from "@eslint/js"; +import stylisticJs from "@stylistic/eslint-plugin-js"; + +export default [ + pluginJs.configs.recommended, + eslintConfigPrettier, + { + files: ["**/*.js", "**/*.html", "**/*.twig"], + languageOptions: { + ecmaVersion: "latest", + sourceType: "commonjs", + globals: { + ...globals.browser, + ...globals.commonjs, + ...globals.node, + $: "readonly", + $id: "readonly", + arch: "readonly", + checkMount: "readonly", + dialog: "readonly", + formatBytes: "readonly", + formatEta: "readonly", + hash_alg: "readonly", + id: "readonly", + ipcRenderer: "readonly", + loadInclude: "readonly", + path: "readonly", + platform: "readonly", + remote: "readonly", + shell: "readonly", + sidenoderHome: "readonly", + version: "readonly", + win: "readonly", + }, + }, + plugins: { + html, + "@stylistic/js": stylisticJs, + }, + rules: { + "@stylistic/js/brace-style": [ + "error", + "1tbs", + { allowSingleLine: false }, + ], + "@stylistic/js/indent": [ + "error", + 2, + { + ignoredNodes: ["TemplateLiteral"], + SwitchCase: 1, + }, + ], + "@stylistic/js/no-mixed-spaces-and-tabs": ["error"], + "@stylistic/js/semi": ["error", "always"], + "constructor-super": ["error"], + curly: ["error", "all"], + eqeqeq: ["error", "always"], + "for-direction": ["error"], + "getter-return": ["error"], + "no-async-promise-executor": ["error"], + "no-case-declarations": ["error"], + "no-class-assign": ["error"], + "no-compare-neg-zero": ["error"], + "no-cond-assign": ["error"], + "no-const-assign": ["error"], + "no-constant-condition": ["error"], + "no-control-regex": ["error"], + "no-debugger": ["error"], + "no-delete-var": ["error"], + "no-dupe-args": ["error"], + "no-dupe-class-members": ["error"], + "no-dupe-else-if": ["error"], + "no-dupe-keys": ["error"], + "no-duplicate-case": ["error"], + "no-else-return": ["error"], + "no-empty": ["error"], + "no-empty-character-class": ["error"], + "no-empty-pattern": ["error"], + "no-ex-assign": ["error"], + "no-extra-boolean-cast": ["off"], + "no-fallthrough": ["error"], + "no-func-assign": ["error"], + "no-global-assign": ["error"], + "no-import-assign": ["error"], + "no-inner-declarations": ["off"], + "no-invalid-regexp": ["error"], + "no-irregular-whitespace": ["error"], + "no-loss-of-precision": ["error"], + "no-misleading-character-class": ["error"], + "no-nonoctal-decimal-escape": ["error"], + "no-obj-calls": ["error"], + "no-octal": ["error"], + "no-prototype-builtins": ["error"], + "no-redeclare": ["error"], + "no-regex-spaces": ["error"], + "no-self-assign": ["error"], + "no-setter-return": ["error"], + "no-shadow-restricted-names": ["error"], + "no-sparse-arrays": ["error"], + "no-this-before-super": ["error"], + "no-undef": ["error"], + "no-unexpected-multiline": ["error"], + "no-unreachable": ["error"], + "no-unsafe-finally": ["error"], + "no-unsafe-negation": ["error"], + "no-unsafe-optional-chaining": ["error"], + "no-unused-labels": ["error"], + "no-unused-vars": [ + "error", + { + argsIgnorePattern: "^_", + caughtErrors: "all", + caughtErrorsIgnorePattern: "^_", + }, + ], + "no-use-before-define": [ + "error", + { + functions: false, + classes: true, + variables: true, + allowNamedExports: true, + }, + ], + "no-useless-backreference": ["error"], + "no-useless-catch": ["error"], + "no-useless-escape": ["error"], + "no-var": ["error"], + "no-with": ["error"], + "prefer-const": [ + "error", + { + destructuring: "all", + }, + ], + "prefer-regex-literals": ["error"], + "prefer-template": ["error"], + "require-yield": ["error"], + "use-isnan": ["error"], + "valid-typeof": ["error"], + }, + }, + { + files: ["**/*.mjs"], + languageOptions: { + sourceType: "module", + }, + }, + { + files: ["**/*.json"], + plugins: { + json, + }, + processor: json.processors[".json"], + rules: { + ...json.configs.recommended.rules, + }, + }, + { + ignores: ["**/node_modules/**", "**/*.min.js", "**/modernizr.custom.js"], + }, +]; diff --git a/main.js b/main.js index e75412d..5643e0b 100644 --- a/main.js +++ b/main.js @@ -1,13 +1,18 @@ +/* eslint + no-unused-vars: [ + "error", { + "varsIgnorePattern": "dialog", + "argsIgnorePattern": "^_" + } + ] +*/ const { app, BrowserWindow, Notification, - powerSaveBlocker, ipcMain, dialog, } = require("electron"); -// const { BrowserWindow } = require('@electron/remote') -const fs = require("fs"); const path = require("path"); global.twig = require("electron-twig"); @@ -35,20 +40,18 @@ global.hash_alg = "sha256"; global.locale = "en-US"; global.platform = global.platform.replace("32", "").replace("64", ""); -if (global.platform == "darwin") global.platform = "mac"; +if (global.platform === "darwin") { + global.platform = "mac"; +} app.on("ready", () => { global.locale = app.getLocale(); }); -eval(fs.readFileSync(path.join(__dirname, "versioncheck.js"), "utf8")); - +const checkVersion = require("./versioncheck"); const tools = require("./tools"); -// const id = powerSaveBlocker.start('prevent-display-sleep'); -// console.log(powerSaveBlocker.isStarted(id)); - -ipcMain.on("get_installed", async (event, arg) => { +ipcMain.on("get_installed", async (event, _arg) => { console.log("get_installed received"); const apps = await tools.getInstalledApps(); @@ -58,7 +61,7 @@ ipcMain.on("get_installed", async (event, arg) => { return; }); -ipcMain.on("get_installed_with_updates", async (event, arg) => { +ipcMain.on("get_installed_with_updates", async (event, _arg) => { console.log("get_installed_with_updates received"); const apps = await tools.getInstalledAppsWithUpdates(); @@ -67,7 +70,7 @@ ipcMain.on("get_installed_with_updates", async (event, arg) => { event.reply("get_installed_with_updates", { success: true, apps }); }); -ipcMain.on("get_device_info", async (event, arg) => { +ipcMain.on("get_device_info", async (event, _arg) => { getDeviceInfo(event); }); @@ -78,7 +81,7 @@ async function getDeviceInfo(event) { event.reply("get_device_info", res); } -ipcMain.on("connect_wireless", async (event, arg) => { +ipcMain.on("connect_wireless", async (event, _arg) => { console.log("connect_wireless received"); if (!global.adbDevice && !global.currentConfiguration.lastIp) { console.log("Missing device, sending ask_device"); @@ -92,7 +95,7 @@ ipcMain.on("connect_wireless", async (event, arg) => { return; }); -ipcMain.on("disconnect_wireless", async (event, arg) => { +ipcMain.on("disconnect_wireless", async (event, _arg) => { console.log("disconnect_wireless received"); const res = await tools.disconnectWireless(); event.reply("connect_wireless", { success: !res }); @@ -106,14 +109,14 @@ ipcMain.on("check_deps", async (event, arg) => { event.reply("check_deps", res); }); -ipcMain.on("mount", async (event, arg) => { +ipcMain.on("mount", async (event, _arg) => { await tools.mount(); setTimeout(() => checkMount(event), 1000); return; }); -ipcMain.on("check_mount", async (event, arg) => { +ipcMain.on("check_mount", async (event, _arg) => { checkMount(event); }); @@ -179,6 +182,7 @@ ipcMain.on("reset_cache", async (event, arg) => { ipcMain.on("get_dir", async (event, arg) => { console.log("get_dir received", arg); + if (typeof arg === "string" && arg.endsWith(".apk")) { const install = { path: arg, @@ -199,11 +203,12 @@ ipcMain.on("get_dir", async (event, arg) => { const list = await tools.getDir(folder); - dirList = []; - incList = []; - notSupported = []; - if (!list) incList = [{ name: "ERROR: Browse failed" }]; - else + const notSupported = []; + const dirList = []; + let incList = []; + if (!list) { + incList = [{ name: "ERROR: Browse failed" }]; + } else { for (const item of list) { if (!item.isFile) { dirList.push(item); @@ -217,8 +222,9 @@ ipcMain.on("get_dir", async (event, arg) => { notSupported.push(item); } + } - response = {}; + const response = {}; response.success = true; response.list = dirList.concat(incList, notSupported); response.path = folder; @@ -227,7 +233,7 @@ ipcMain.on("get_dir", async (event, arg) => { //event.reply('get_dir', response) }); -ipcMain.on("enable_mtp", async (event, arg) => { +ipcMain.on("enable_mtp", async (event, _arg) => { console.log("enable_mtp received"); if (!global.adbDevice) { console.log("Missing device, sending ask_device"); @@ -245,7 +251,7 @@ ipcMain.on("enable_mtp", async (event, arg) => { return; }); -ipcMain.on("scrcpy_start", async (event, arg) => { +ipcMain.on("scrcpy_start", async (event, _arg) => { console.log("scrcpy_start received"); if (!global.adbDevice) { console.log("Missing device, sending ask_device"); @@ -259,7 +265,7 @@ ipcMain.on("scrcpy_start", async (event, arg) => { return; }); -ipcMain.on("reboot_device", async (event, arg) => { +ipcMain.on("reboot_device", async (event, _arg) => { console.log("reboot_device received"); if (!global.adbDevice) { console.log("Missing device, sending ask_device"); @@ -277,7 +283,7 @@ ipcMain.on("reboot_device", async (event, arg) => { return; }); -ipcMain.on("reboot_recovery", async (event, arg) => { +ipcMain.on("reboot_recovery", async (event, _arg) => { console.log("reboot_recovery received"); if (!global.adbDevice) { console.log("Missing device, sending ask_device"); @@ -295,7 +301,7 @@ ipcMain.on("reboot_recovery", async (event, arg) => { return; }); -ipcMain.on("reboot_bootloader", async (event, arg) => { +ipcMain.on("reboot_bootloader", async (event, _arg) => { console.log("reboot_bootloader received"); if (!global.adbDevice) { console.log("Missing device, sending ask_device"); @@ -339,12 +345,12 @@ ipcMain.on("sideload_update", async (event, arg) => { ipcMain.on("device_tweaks", async (event, arg) => { console.log("device_tweaks received", arg); - if (arg.cmd == "get") { + if (arg.cmd === "get") { const res = await tools.deviceTweaksGet(arg); event.reply("device_tweaks", res); } - if (arg.cmd == "set") { + if (arg.cmd === "set") { if (!global.adbDevice) { console.log("Missing device, sending ask_device"); event.reply("ask_device", ""); @@ -352,7 +358,7 @@ ipcMain.on("device_tweaks", async (event, arg) => { } const res = await tools.deviceTweaksSet(arg); - event.reply("device_tweaks", arg); + event.reply("device_tweaks", res); } return; @@ -360,7 +366,7 @@ ipcMain.on("device_tweaks", async (event, arg) => { ipcMain.on("uninstall", async (event, arg) => { console.log("uninstall received"); - resp = await tools.uninstall(arg); + await tools.uninstall(arg); event.reply("uninstall", { success: true }); getDeviceInfo(event); return; @@ -480,7 +486,7 @@ function createWindow() { }; win.loadURL(`file://${__dirname}/views/index.twig`); - if (process.argv[2] == "--dev") { + if (process.argv[2] === "--dev") { win.webContents.openDevTools(); } @@ -528,11 +534,12 @@ async function startApp() { createWindow(); app.on("activate", () => { - if (BrowserWindow.getAllWindows().length != 0) return; + if (BrowserWindow.getAllWindows().length !== 0) { + return; + } createWindow(); }); - app.on("window-all-closed", (e) => { - // powerSaveBlocker.stop(id) + app.on("window-all-closed", () => { console.log("quit"); if (global.platform !== "mac") { app.quit(); diff --git a/package.json b/package.json index 81cefe7..05e48fc 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "dependencies": { "@devicefarmer/adbkit": "3.2.6", "@electron/remote": "2.1.2", + "@eslint/js": "^9.10.0", "@fortawesome/fontawesome-free": "^6.6.0", + "@stylistic/eslint-plugin-js": "^2.7.2", "adbkit-apkreader": "3.2.0", "bootstrap": "^5.3.3", "bootswatch": "^5.3.3", @@ -14,7 +16,12 @@ "compare-versions": "6.1.1", "electron-find": "1.0.7", "electron-twig": "1.1.1", + "eslint": "^9.10.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-html": "^8.1.1", + "eslint-plugin-json": "^4.0.1", "fix-path": "4.0.0", + "globals": "^15.9.0", "jquery": "3.7.1", "jquery-ui": "^1.14.0", "node-fetch": "3.3.2", @@ -36,6 +43,8 @@ "dist-win": "electron-builder -w", "dist-mac": "electron-builder -m", "dist-linux": "electron-builder -l", + "eslint:check": "eslint .", + "eslint:fix": "eslint . --fix", "pre-commit": "lint-staged --concurrent false", "prettier:check": "prettier --check \"**/*.{css,js,json,md,twig,yml}\"", "prettier:format": "prettier --write \"**/*.{css,js,json,md,twig,yml}\"", @@ -46,6 +55,10 @@ "prepare": "husky" }, "lint-staged": { + "*.{js,html,twig}": [ + "eslint --fix", + "eslint" + ], "*.{css,html,js,json,md,twig,yml}": [ "prettier --write", "prettier --check" diff --git a/removeLocales.js b/removeLocales.js index 14301b4..9f61a07 100644 --- a/removeLocales.js +++ b/removeLocales.js @@ -3,14 +3,18 @@ const LOCALES = ["en-US.pak", "ru.pak"]; exports.default = async function (context) { // console.log(context); - var fs = require("fs"); - var localeDir = context.appOutDir + "/locales/"; + const fs = require("fs"); + const localeDir = `${context.appOutDir}/locales/`; fs.readdir(localeDir, function (err, files) { //files is array of filenames (basename form) - if (!(files && files.length)) return; + if (!(files && files.length)) { + return; + } for (const file of files) { - if (LOCALES.includes(file)) continue; + if (LOCALES.includes(file)) { + continue; + } fs.unlinkSync(localeDir + file); } }); diff --git a/tools.js b/tools.js index c83b74e..9103058 100644 --- a/tools.js +++ b/tools.js @@ -1,12 +1,18 @@ +/* eslint + no-unused-vars: [ + "error", { + "caughtErrorsIgnorePattern": "^_", + "argsIgnorePattern": "^_" + } + ] +*/ const exec = require("child_process").exec; -// const fs = require('fs'); const fs = require("fs"); const fsp = fs.promises; const util = require("util"); const path = require("path"); const crypto = require("crypto"); const commandExists = require("command-exists"); -const { dialog } = require("electron"); const ApkReader = require("adbkit-apkreader"); const adbkit = require("@devicefarmer/adbkit").default; const adb = adbkit.createClient(); @@ -15,17 +21,12 @@ const fetch = (...args) => const WAE = require("web-auto-extractor").default; // const HttpProxyAgent = require('https-proxy-agent'); // TODO add https proxy support const { SocksProxyAgent } = require("socks-proxy-agent"); -const url = require("url"); -// const ApkReader = require('node-apk-parser'); -const fixPath = (...args) => - import("fix-path").then(({ default: fixPath }) => fixPath(...args)); -// adb.kill(); const pkg = require("./package.json"); const _sec = 1000; const _min = 60 * _sec; -let CHECK_META_PERIOD = 2 * _min; +const CHECK_META_PERIOD = 2 * _min; const l = 32; const configLocationOld = path.join(global.homedir, "sidenoder-config.json"); const configLocation = path.join(global.sidenoderHome, "config.json"); @@ -45,11 +46,11 @@ let META_VERSION = []; let QUEST_ICONS = []; let cacheOculusGames = false; let KMETAS = {}; -let KMETAS2 = {}; +const KMETAS2 = {}; let adbCmd = "adb"; let grep_cmd = "| grep "; -if (platform == "win") { +if (platform === "win") { grep_cmd = "| findstr "; } @@ -145,7 +146,9 @@ async function getDeviceInfo() { async function getFwInfo() { console.log("getFwInfo()"); const res = await adbShell("getprop ro.build.branch"); - if (!res) return false; + if (!res) { + return false; + } return { version: res.replace("releases-oculus-", ""), @@ -155,20 +158,44 @@ async function getFwInfo() { async function getBatteryInfo() { console.log("getBatteryInfo()"); const res = await adbShell("dumpsys battery"); - if (!res) return false; + if (!res) { + return false; + } - return parceOutOptions(res); + const opts = {}; + for (const line of res.replace(/ /g, "").split("\n")) { + const splitLine = line.split(":"); + const key = splitLine[0]; + let value = splitLine[1]; + + if (value === "true") { + value = true; + } + if (value === "false") { + value = false; + } + if (isFinite(+value)) { + value = +value; + } + + opts[key] = value; + } + + return opts; } async function getUserInfo() { - if (global.currentConfiguration.userHide) + if (global.currentConfiguration.userHide) { return { name: "hidden", }; + } console.log("getUserInfo()"); const res = await adbShell("dumpsys user | grep UserInfo"); - if (!res) return false; + if (!res) { + return false; + } return { name: res.split(":")[1], @@ -177,7 +204,7 @@ async function getUserInfo() { async function deviceTweaksGet(arg) { console.log("deviceTweaksGet()", arg); - let res = { + const res = { cmd: "get", // mp_name: '', // guardian_pause: '0', @@ -192,29 +219,37 @@ async function deviceTweaksGet(arg) { // gSSO: '1440x1584', }; - if (arg.key === "mp_name") + if (arg.key === "mp_name") { res.mp_name = await adbShell("settings get global username"); - if (arg.key === "guardian_pause") + } + if (arg.key === "guardian_pause") { res.guardian_pause = await adbShell("getprop debug.oculus.guardian_pause"); - if (arg.key === "frc") + } + if (arg.key === "frc") { res.frc = await adbShell("getprop debug.oculus.fullRateCapture"); - if (arg.key === "gRR") + } + if (arg.key === "gRR") { res.gRR = await adbShell("getprop debug.oculus.refreshRate"); - if (arg.key === "gCA") + } + if (arg.key === "gCA") { res.gCA = await adbShell("getprop debug.oculus.forceChroma"); - if (arg.key === "gFFR") + } + if (arg.key === "gFFR") { res.gFFR = await adbShell("getprop debug.oculus.foveation.level"); - if (arg.key === "CPU") + } + if (arg.key === "CPU") { res.CPU = await adbShell("getprop debug.oculus.cpuLevel"); - if (arg.key === "GPU") + } + if (arg.key === "GPU") { res.GPU = await adbShell("getprop debug.oculus.gpuLevel"); - if (arg.key === "vres") + } + if (arg.key === "vres") { res.vres = await adbShell("getprop debug.oculus.videoResolution"); + } if (arg.key === "cres") { - let captureDims = - (await adbShell("getprop debug.oculus.capture.width")) + - "x" + - (await adbShell("getprop debug.oculus.capture.height")); + let captureDims = `${await adbShell( + "getprop debug.oculus.capture.width", + )}x${await adbShell("getprop debug.oculus.capture.height")}`; // Default when not set if (captureDims === "x") { @@ -222,11 +257,11 @@ async function deviceTweaksGet(arg) { } res.cres = captureDims; } - if (arg.key === "gSSO") - res.gSSO = - (await adbShell("getprop debug.oculus.textureWidth")) + - "x" + - (await adbShell("getprop debug.oculus.textureHeight")); + if (arg.key === "gSSO") { + res.gSSO = `${await adbShell( + "getprop debug.oculus.textureWidth", + )}x${await adbShell("getprop debug.oculus.textureHeight")}`; + } //oculus.capture.bitrate return res; @@ -234,60 +269,60 @@ async function deviceTweaksGet(arg) { async function deviceTweaksSet(arg) { console.log("deviceTweaksSet()", arg); - let res = { cmd: "set" }; - if (typeof arg.mp_name != "undefined") { - res.mp_name = await adbShell("settings put global username " + arg.mp_name); + const res = { cmd: "set" }; + if (typeof arg.mp_name !== "undefined") { + res.mp_name = await adbShell(`settings put global username ${arg.mp_name}`); } - if (typeof arg.guardian_pause != "undefined") { + if (typeof arg.guardian_pause !== "undefined") { res.guardian_pause = await adbShell( - "setprop debug.oculus.guardian_pause " + (arg.guardian_pause ? "1" : "0"), + `setprop debug.oculus.guardian_pause ${arg.guardian_pause ? "1" : "0"}`, ); } - if (typeof arg.frc != "undefined") { + if (typeof arg.frc !== "undefined") { res.frc = await adbShell( - "setprop debug.oculus.fullRateCapture " + (arg.frc ? "1" : "0"), + `setprop debug.oculus.fullRateCapture ${arg.frc ? "1" : "0"}`, ); } - if (typeof arg.gRR != "undefined") { - res.gRR = await adbShell("setprop debug.oculus.refreshRate " + arg.gRR); + if (typeof arg.gRR !== "undefined") { + res.gRR = await adbShell(`setprop debug.oculus.refreshRate ${arg.gRR}`); } - if (typeof arg.gCA != "undefined") { - res.gCA = await adbShell("setprop debug.oculus.forceChroma " + arg.gCA); + if (typeof arg.gCA !== "undefined") { + res.gCA = await adbShell(`setprop debug.oculus.forceChroma ${arg.gCA}`); } - if (typeof arg.gFFR != "undefined") { + if (typeof arg.gFFR !== "undefined") { res.gFFR = await adbShell( - "setprop debug.oculus.foveation.level " + arg.gFFR, + `setprop debug.oculus.foveation.level ${arg.gFFR}`, ); } - if (typeof arg.CPU != "undefined") { - res.CPU = await adbShell("setprop debug.oculus.cpuLevel " + arg.CPU); + if (typeof arg.CPU !== "undefined") { + res.CPU = await adbShell(`setprop debug.oculus.cpuLevel ${arg.CPU}`); } - if (typeof arg.GPU != "undefined") { - res.GPU = await adbShell("setprop debug.oculus.gpuLevel " + arg.GPU); + if (typeof arg.GPU !== "undefined") { + res.GPU = await adbShell(`setprop debug.oculus.gpuLevel ${arg.GPU}`); } - if (typeof arg.vres != "undefined") { + if (typeof arg.vres !== "undefined") { res.vres = await adbShell( - "setprop debug.oculus.videoResolution " + arg.vres, + `setprop debug.oculus.videoResolution ${arg.vres}`, ); } - if (typeof arg.cres != "undefined") { + if (typeof arg.cres !== "undefined") { const [width, height] = arg.cres.split("x"); - await adbShell("setprop debug.oculus.capture.width " + width); - res.cres = await adbShell("setprop debug.oculus.capture.height " + height); + await adbShell(`setprop debug.oculus.capture.width ${width}`); + res.cres = await adbShell(`setprop debug.oculus.capture.height ${height}`); } - if (typeof arg.gSSO != "undefined") { + if (typeof arg.gSSO !== "undefined") { const [width, height] = arg.gSSO.split("x"); - await adbShell("setprop debug.oculus.textureWidth " + width); - await adbShell("setprop debug.oculus.textureHeight " + height); + await adbShell(`setprop debug.oculus.textureWidth ${width}`); + await adbShell(`setprop debug.oculus.textureHeight ${height}`); res.gSSO = await adbShell( "settings put system font_scale 0.85 && settings put system font_scale 1.0", ); @@ -300,13 +335,15 @@ async function getStorageInfo() { console.log("getStorageInfo()"); const linematch = await adbShell('df -h | grep "/storage/emulated"'); - if (!linematch) return false; + if (!linematch) { + return false; + } - const refree = new RegExp("([0-9(.{1})]+[a-zA-Z%])", "g"); + const refree = /([0-9(.{1})]+[a-zA-Z%])/g; const storage = linematch.match(refree); console.log(storage); - if (storage.length == 3) { + if (storage.length === 3) { return { size: storage[0], used: storage[1], @@ -331,13 +368,15 @@ async function getLaunchActivity(pkg) { return startActivity(activity); } -async function getActivities(pkg, activity = false) { +async function getActivities(pkg) { console.log("getActivities()", pkg); let activities = await adbShell( `dumpsys package | grep -Eo '^[[:space:]]+[0-9a-f]+[[:space:]]+${pkg}/[^[:space:]]+' | grep -oE '[^[:space:]]+$'`, ); - if (!activities) return false; + if (!activities) { + return false; + } activities = activities.split("\n"); // activities.pop(); @@ -389,7 +428,7 @@ async function checkAppTools(pkg) { if (await fsp.exists(backupPath)) { try { availableRestore = await fsp.readFile(`${backupPath}/time.txt`, "utf8"); - } catch (err) { + } catch (_err) { availableRestore = 1; } } @@ -444,13 +483,17 @@ async function getDeviceIp() { `ip -o route get to 8.8.8.8 | sed -n 's/.*src \\([0-9.]\\+\\).*/\\1/p'`, ); console.log({ ip }); - if (ip) return ip; + if (ip) { + return ip; + } ip = await adbShell( `ip addr show wlan0 | grep 'inet ' | cut -d ' ' -f 6 | cut -d / -f 1`, ); console.log({ ip }); - if (ip) return ip; + if (ip) { + return ip; + } return false; } @@ -464,7 +507,6 @@ async function wifiEnable(enable) { } async function connectWireless() { - const on = await adbShell("settings get global wifi_on"); if (!(await wifiGetStat())) { console.error("connectWireless", "wifi disabled"); await wifiEnable(true); @@ -475,7 +517,9 @@ async function connectWireless() { // TODO: save ip & try use it const ip = await getDeviceIp(); console.log({ ip }); - if (!ip) return false; + if (!ip) { + return false; + } try { if (global.adbDevice) { @@ -500,7 +544,9 @@ async function connectWireless() { async function disconnectWireless() { const ip = await getDeviceIp(); - if (!ip) return false; + if (!ip) { + return false; + } try { const res = await adb.disconnect(ip, 5555); @@ -519,8 +565,12 @@ async function isWireless() { try { const devices = await adb.listDevices(); for (const device of devices) { - if (!device.id.includes(":5555")) continue; - if (["offline", "authorizing"].includes(device.type)) continue; + if (!device.id.includes(":5555")) { + continue; + } + if (["offline", "authorizing"].includes(device.type)) { + continue; + } if (["unauthorized"].includes(device.type)) { win.webContents.send( "alert", @@ -553,7 +603,9 @@ async function isIdle() { } async function wakeUp() { - if (!(await isIdle())) return; + if (!(await isIdle())) { + return; + } return adbShell(`input keyevent KEYCODE_POWER`); } @@ -568,22 +620,23 @@ async function startSCRCPY() { } const scrcpyCmd = - `"${global.currentConfiguration.scrcpyPath || "scrcpy"}" ` + - (global.currentConfiguration.scrcpyCrop - ? `--crop ${global.currentConfiguration.scrcpyCrop} ` - : "") + - `-b ${global.currentConfiguration.scrcpyBitrate || 1}M ` + - (global.currentConfiguration.scrcpyFps - ? `--max-fps ${global.currentConfiguration.scrcpyFps} ` - : "") + - (global.currentConfiguration.scrcpySize - ? `--max-size ${global.currentConfiguration.scrcpySize} ` - : "") + - (!global.currentConfiguration.scrcpyWindow ? "-f " : "") + - (global.currentConfiguration.scrcpyOnTop ? "--always-on-top " : "") + - (!global.currentConfiguration.scrcpyControl ? "-n " : "") + - '--window-title "SideNoder Stream" ' + - `-s ${global.adbDevice} `; + `"${global.currentConfiguration.scrcpyPath || "scrcpy"}" ${ + global.currentConfiguration.scrcpyCrop + ? `--crop ${global.currentConfiguration.scrcpyCrop} ` + : "" + }-b ${global.currentConfiguration.scrcpyBitrate || 1}M ${ + global.currentConfiguration.scrcpyFps + ? `--max-fps ${global.currentConfiguration.scrcpyFps} ` + : "" + }${ + global.currentConfiguration.scrcpySize + ? `--max-size ${global.currentConfiguration.scrcpySize} ` + : "" + }${!global.currentConfiguration.scrcpyWindow ? "-f " : ""}${ + global.currentConfiguration.scrcpyOnTop ? "--always-on-top " : "" + }${ + !global.currentConfiguration.scrcpyControl ? "-n " : "" + }--window-title "SideNoder Stream" ` + `-s ${global.adbDevice} `; console.log({ scrcpyCmd }); wakeUp(); exec(scrcpyCmd, (error, stdout, stderr) => { @@ -626,14 +679,16 @@ async function sideloadFile(path) { return res; } -async function getDeviceSync(attempt = 0) { +async function getDeviceSync() { try { // const lastDevice = global.adbDevice; const devices = await adb.listDevices(); console.log({ devices }); global.adbDevice = false; for (const device of devices) { - if (["offline", "authorizing"].includes(device.type)) continue; + if (["offline", "authorizing"].includes(device.type)) { + continue; + } if (["unauthorized"].includes(device.type)) { win.webContents.send( "alert", @@ -644,18 +699,14 @@ async function getDeviceSync(attempt = 0) { if ( !global.currentConfiguration.allowOtherDevices && - (await adbShell("getprop ro.product.brand", device.id)) != "oculus" - ) + (await adbShell("getprop ro.product.brand", device.id)) !== "oculus" + ) { continue; + } global.adbDevice = device.id; } - /*if (!global.adbDevice && devices.length > 0 && attempt < 1) { - return setTimeout(()=> getDeviceSync(attempt + 1), 1000); - }*/ - // if (lastDevice == global.adbDevice) return; - win.webContents.send("check_device", { success: global.adbDevice }); return global.adbDevice; @@ -687,14 +738,16 @@ async function adbShell(cmd, deviceId = global.adbDevice, skipRead = false) { output = await output.toString(); // output = output.split('\n'); // const end = output.pop(); - // if (end != '') output.push(); + // if (end !== '') output.push(); console.log(`adbShell[${deviceId}]`, { cmd, output }); - if (output.substr(-1) == "\n") return output.slice(0, -1); + if (output.substr(-1) === "\n") { + return output.slice(0, -1); + } return output; } catch (err) { console.error(`adbShell[${deviceId}]: err`, { cmd }, err); global.adbError = err; - if (err.toString() == `FailError: Failure: 'device offline'`) { + if (err.toString() === `FailError: Failure: 'device offline'`) { getDeviceSync(); } @@ -702,22 +755,6 @@ async function adbShell(cmd, deviceId = global.adbDevice, skipRead = false) { } } -function parceOutOptions(line) { - let opts = {}; - for (let l of line.split("\n")) { - l = l.split(" ").join(""); - let [k, v] = l.split(":"); - - if (v == "true") v = true; - if (v == "false") v = false; - if (!isNaN(+v)) v = +v; - - opts[k] = v; - } - - return opts; -} - // on empty dirrectory return false async function adbFileExists(path) { const r = await adbShell(`ls "${path}" 1>&1 2> /dev/null`); @@ -733,7 +770,9 @@ async function adbPull(orig, dest, sync = false) { let c = 0; transfer.on("progress", (stats) => { c++; - if (c % 40 != 1) return; // skip 20 events + if (c % 40 !== 1) { + return; + } // skip 20 events // console.log(orig + ' pulled', stats); const res = { @@ -769,7 +808,7 @@ async function adbPullFolder(orig, dest, sync = false) { sync = await adb.getDevice(global.adbDevice).syncService(); }*/ - let actions = []; + const actions = []; await fsp.mkdir(dest, { recursive: true }); const files = sync ? await sync.readdir(orig) @@ -805,7 +844,9 @@ async function adbPush(orig, dest, sync = false) { let c = 0; transfer.on("progress", (stats) => { c++; - if (c % 40 != 1) return; // skip 20 events + if (c % 40 !== 1) { + return; + } // skip 20 events // console.log(orig + ' pushed', stats); const res = { @@ -837,7 +878,9 @@ async function adbPushFolder(orig, dest, sync = false) { const stat = await fsp.lstat(orig); console.log({ orig, stat }, stat.isFile()); - if (stat.isFile()) return adbPush(orig, dest); + if (stat.isFile()) { + return adbPush(orig, dest); + } /*let need_close = false; if (!sync) { @@ -845,7 +888,7 @@ async function adbPushFolder(orig, dest, sync = false) { sync = await adb.getDevice(global.adbDevice).syncService(); }*/ - let actions = []; + const actions = []; await adbShell(`mkdir -p ${dest}`, global.adbDevice, true); const files = await fsp.readdir(orig, { withFileTypes: true }); for (const file of files) { @@ -886,7 +929,9 @@ function execShellCommand(cmd, ignoreError = false, buffer = 100) { return new Promise((resolve, reject) => { exec(cmd, { maxBuffer: 1024 * buffer }, (error, stdout, stderr) => { if (error) { - if (ignoreError) return resolve(false); + if (ignoreError) { + return resolve(false); + } console.error("exec_error", cmd, error); return reject(error); } @@ -894,11 +939,12 @@ function execShellCommand(cmd, ignoreError = false, buffer = 100) { if (stdout || !stderr) { console.log("exec_stdout", cmd, stdout); return resolve(stdout); - } else { - if (ignoreError) return resolve(false); - console.error("exec_stderr", cmd, stderr); - return reject(stderr); } + if (ignoreError) { + return resolve(false); + } + console.error("exec_stderr", cmd, stderr); + return reject(stderr); }); }); } @@ -939,7 +985,7 @@ async function appInfo(args) { const { res, pkg } = args; const app = KMETAS[pkg]; - let data = { + const data = { res, pkg, id: 0, @@ -955,9 +1001,11 @@ async function appInfo(args) { }; try { - if (res == "steam") { + if (res === "steam") { const steam = app && app.steam; - if (!steam || !steam.id) throw "incorrect args"; + if (!steam || !steam.id) { + throw "incorrect args"; + } data.id = steam.id; data.url = `https://store.steampowered.com/app/${data.id}/`; @@ -966,7 +1014,7 @@ async function appInfo(args) { `https://store.steampowered.com/api/appdetails?appids=${data.id}`, { headers: { - "Accept-Language": global.locale + ",en-US;q=0.5,en;q=0.3", + "Accept-Language": `${global.locale},en-US;q=0.5,en;q=0.3`, }, agent: agentSteam, }, @@ -977,9 +1025,11 @@ async function appInfo(args) { Object.assign(data, json[data.id].data); } - if (res == "oculus") { + if (res === "oculus") { const oculus = app && app.oculus; - if (!oculus || !oculus.id) throw "incorrect args"; + if (!oculus || !oculus.id) { + throw "incorrect args"; + } // console.log({ oculus }); data.id = oculus.id; @@ -993,7 +1043,7 @@ async function appInfo(args) { method: "POST", body: `access_token=OC|1317831034909742|&variables={"itemId":"${oculus.id}","first":1}&doc_id=5373392672732392`, headers: { - "Accept-Language": global.locale + ",en-US;q=0.5,en;q=0.3", + "Accept-Language": `${global.locale},en-US;q=0.5,en;q=0.3`, "Content-Type": "application/x-www-form-urlencoded", Origin: "https://www.oculus.com", }, @@ -1001,12 +1051,16 @@ async function appInfo(args) { }, ); try { - let json = await resp.json(); + const json = await resp.json(); // console.log('json', json); - if (json.error) throw json.error; + if (json.error) { + throw json.error; + } const meta = json.data.node; - if (!meta) throw "empty json.data.node"; + if (!meta) { + throw "empty json.data.node"; + } data.name = meta.appName; data.detailed_description = @@ -1066,13 +1120,17 @@ async function appInfo(args) { // console.log(jsonld); if (jsonld) { - if (jsonld.name) data.name = jsonld.name; + if (jsonld.name) { + data.name = jsonld.name; + } data.detailed_description = jsonld.description && jsonld.description.split("\n").join("
"); if (jsonld.image) { for (const id in jsonld.image) { - if (["0", "1", "2"].includes(id)) continue; // skip resizes of header + if (["0", "1", "2"].includes(id)) { + continue; + } // skip resizes of header data.screenshots.push({ id, @@ -1084,9 +1142,11 @@ async function appInfo(args) { } } - if (res == "sq") { + if (res === "sq") { const sq = app && app.sq; - if (!sq || !sq.id) throw "incorrect args"; + if (!sq || !sq.id) { + throw "incorrect args"; + } // console.log({ sq }); data.id = sq.id; @@ -1096,7 +1156,7 @@ async function appInfo(args) { method: "POST", body: JSON.stringify({ apps_id: data.id }), headers: { - "Accept-Language": global.locale + ",en-US;q=0.5,en;q=0.3", + "Accept-Language": `${global.locale},en-US;q=0.5,en;q=0.3`, "Content-Type": "application/json", Origin: "https://sidequestvr.com", Cookie: @@ -1112,7 +1172,7 @@ async function appInfo(args) { data.header_image = meta.image_url; data.short_description = meta.summary; data.detailed_description = meta.description.split("\n").join("
"); - if (meta.video_url) + if (meta.video_url) { data.youtube = [ meta.video_url .replace("youtube.com", "youtube.com/embed") @@ -1120,6 +1180,7 @@ async function appInfo(args) { .replace("/embed/embed", "/embed") .replace("/watch?v=", "/"), ]; + } const resp_img = await fetchTimeout( `https://api.sidequestvr.com/get-app-screenshots`, @@ -1155,16 +1216,18 @@ async function appInfo(args) { async function appInfoEvents(args) { const { res, pkg } = args; const app = KMETAS[pkg]; - let data = { + const data = { res, pkg, events: [], }; try { - if (res == "steam") { + if (res === "steam") { const steam = app && app.steam; - if (!steam || !steam.id) throw "incorrect args"; + if (!steam || !steam.id) { + throw "incorrect args"; + } data.url = `https://store.steampowered.com/news/app/${steam.id}/`; @@ -1172,7 +1235,7 @@ async function appInfoEvents(args) { `http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002?appid=${steam.id}`, { headers: { - "Accept-Language": global.locale + ",en-US;q=0.5,en;q=0.3", + "Accept-Language": `${global.locale},en-US;q=0.5,en;q=0.3`, }, agent: agentSteam, }, @@ -1218,9 +1281,11 @@ async function appInfoEvents(args) { } } - if (res == "oculus") { + if (res === "oculus") { const oculus = app && app.oculus; - if (!oculus || !oculus.id) throw "incorrect args"; + if (!oculus || !oculus.id) { + throw "incorrect args"; + } // data.url = `https://store.steampowered.com/news/app/${steam.id}/`; @@ -1230,7 +1295,7 @@ async function appInfoEvents(args) { method: "POST", body: `access_token=OC|1317831034909742|&variables={"id":"${oculus.id}"}&doc_id=1586217024733717`, headers: { - "Accept-Language": global.locale + ",en-US;q=0.5,en;q=0.3", + "Accept-Language": `${global.locale},en-US;q=0.5,en;q=0.3`, "Content-Type": "application/x-www-form-urlencoded", Origin: "https://www.oculus.com", }, @@ -1238,8 +1303,10 @@ async function appInfoEvents(args) { }, ); try { - let json = await resp.json(); - if (json.error) throw json.error; + const json = await resp.json(); + if (json.error) { + throw json.error; + } // console.log({ json }); const events = json.data.node.supportedBinaries.edges; @@ -1255,7 +1322,9 @@ async function appInfoEvents(args) { // author: '', }; - if (e.richChangeLog) console.log("RICHCHANGELOG", e.richChangeLog); + if (e.richChangeLog) { + console.log("RICHCHANGELOG", e.richChangeLog); + } data.events.push(event); } @@ -1266,14 +1335,16 @@ async function appInfoEvents(args) { resp = await fetch( `https://computerelite.github.io/tools/Oculus/OlderAppVersions/${oculus.id}.json`, ); - json = await resp.json(); + const json = await resp.json(); // console.log({ json }); const events = json.data.node.binaries.edges; for (const { node } of events) { const e = node; let found = false; for (const i in data.events) { - if (data.events[i].id != e.id) continue; + if (data.events[i].id !== e.id) { + continue; + } data.events[i].date = new Date( e.created_date * _sec, @@ -1281,7 +1352,9 @@ async function appInfoEvents(args) { found = true; break; } - if (found) continue; + if (found) { + continue; + } const event = { id: e.id, @@ -1296,9 +1369,11 @@ async function appInfoEvents(args) { } } - if (res == "sq") { + if (res === "sq") { const sq = app && app.sq; - if (!sq || !sq.id) throw "incorrect args"; + if (!sq || !sq.id) { + throw "incorrect args"; + } // console.log({ sq }); for (const is_news of [true, false]) { @@ -1308,7 +1383,7 @@ async function appInfoEvents(args) { method: "POST", body: JSON.stringify({ apps_id: sq.id, is_news }), headers: { - "Accept-Language": global.locale + ",en-US;q=0.5,en;q=0.3", + "Accept-Language": `${global.locale},en-US;q=0.5,en;q=0.3`, "Content-Type": "application/json", Origin: "https://sidequestvr.com", Cookie: @@ -1332,7 +1407,7 @@ async function appInfoEvents(args) { }; if (e.event_image) { - event.contents += `
`; + event.contents += `
`; } if (e.event_description) { @@ -1380,7 +1455,7 @@ async function checkMount(attempt = 0) { async function checkDeps(arg) { console.log("checkDeps()", arg); - let res = { + const res = { [arg]: { version: false, cmd: false, @@ -1389,36 +1464,39 @@ async function checkDeps(arg) { }; try { - if (arg == "adb") { + if (arg === "adb") { let globalAdb = false; try { globalAdb = await commandExists("adb"); - } catch (e) {} + } catch (_e) { + // Do nothing + } res[arg].cmd = adbCmd = globalAdb ? "adb" : await fetchBinary("adb"); try { await execShellCommand(`"${res[arg].cmd}" start-server`); } catch (err) { - if (!err.toString().includes("daemon started successfully")) throw err; + if (!err.toString().includes("daemon started successfully")) { + throw err; + } } res[arg].version = - "adbkit v." + - (await adb.version()) + - "\n" + - (await execShellCommand(`"${res[arg].cmd}" version`)); + `adbkit v.${await adb.version()}\n${await execShellCommand( + `"${res[arg].cmd}" version`, + )}`; await trackDevices(); } - if (arg == "rclone") { + if (arg === "rclone") { // module with autodownload https://github.com/sntran/rclone.js/blob/main/index.js // res.rclone.cmd = global.currentConfiguration.rclonePath || await commandExists('rclone'); res[arg].cmd = await fetchBinary("rclone"); res[arg].version = await execShellCommand(`"${res[arg].cmd}" --version`); } - if (arg == "zip") { + if (arg === "zip") { res[arg].cmd = await fetchBinary("7za"); res[arg].version = await execShellCommand( `"${res[arg].cmd}" --help ${grep_cmd} "7-Zip"`, @@ -1426,7 +1504,7 @@ async function checkDeps(arg) { console.log(res[arg].version); } - if (arg == "scrcpy") { + if (arg === "scrcpy") { res[arg].cmd = global.currentConfiguration.scrcpyPath || (await commandExists("scrcpy")); @@ -1450,16 +1528,18 @@ async function checkDeps(arg) { async function fetchBinary(bin) { const cfgKey = `${bin}Path`; const cmd = global.currentConfiguration[cfgKey]; - if (cmd) return cmd; + if (cmd) { + return cmd; + } - const file = global.platform == "win" ? `${bin}.exe` : bin; + const file = global.platform === "win" ? `${bin}.exe` : bin; const binPath = path.join(sidenoderHome, file); - const branch = /*bin == 'rclone' ? 'new' :*/ "master"; + const branch = /*bin === 'rclone' ? 'new' :*/ "master"; const binUrl = `https://raw.githubusercontent.com/vKolerts/${bin}-bin/${branch}/${global.platform}/${global.arch}/${file}`; await fetchFile(binUrl, binPath); - if (bin == "adb" && global.platform == "win") { + if (bin === "adb" && global.platform === "win") { const libFile = "AdbWinApi.dll"; const libUrl = `https://raw.githubusercontent.com/vKolerts/${bin}-bin/master/${global.platform}/${global.arch}/${libFile}`; await fetchFile(libUrl, path.join(sidenoderHome, libFile)); @@ -1475,9 +1555,13 @@ async function fetchBinary(bin) { async function fetchFile(url, dest) { console.log("fetchFile", { url, dest }); const resp = await fetch(url); - if (!resp.ok) throw new Error(`Can't download '${url}': ${resp.statusText}`); + if (!resp.ok) { + throw new Error(`Can't download '${url}': ${resp.statusText}`); + } - if (await fsp.exists(dest)) await fsp.unlink(dest); + if (await fsp.exists(dest)) { + await fsp.unlink(dest); + } return fsp.writeFile(dest, await resp.buffer(), { mode: 0o755 }); } @@ -1492,7 +1576,7 @@ function returnError(message) { async function killRClone() { RCLONE_ID++; const killCmd = - platform == "win" + platform === "win" ? `taskkill.exe /F /T /IM rclone.exe` : `killall -9 rclone`; console.log("try kill rclone"); @@ -1540,7 +1624,9 @@ async function parseRcloneSections(newCfg = false) { const sections = out .split("\n") .map((section) => section.replace(/:$/, "")); - if (sections.length) sections.pop(); + if (sections.length) { + sections.pop(); + } if (!sections.length) { return console.error( "rclone config sections not found", @@ -1550,22 +1636,25 @@ async function parseRcloneSections(newCfg = false) { } global.rcloneSections = sections; - } catch (err) { + } catch (_err) { const cfg = await fsp.readFile( global.currentConfiguration.rcloneConf, "utf8", ); - if (!cfg) + if (!cfg) { return console.error( "rclone config is empty", global.currentConfiguration.rcloneConf, ); + } const lines = cfg.split("\n"); - let sections = []; + const sections = []; for (const line of lines) { - if (line[0] != "[") continue; + if (line[0] !== "[") { + continue; + } const section = line.match(/\[(.*?)\]/)[1]; sections.push(section); } @@ -1582,8 +1671,10 @@ async function parseRcloneSections(newCfg = false) { } async function umount() { - if (platform == "win") { - if (!(await fsp.exists(global.mountFolder))) return; + if (platform === "win") { + if (!(await fsp.exists(global.mountFolder))) { + return; + } await fsp.rmdir(global.mountFolder, { recursive: true }); return; @@ -1606,7 +1697,7 @@ async function mount() { // return; try { await killRClone(); - } catch (err) { + } catch (_err) { console.log("rclone not started"); } // } @@ -1626,7 +1717,9 @@ async function mount() { (error, stdout, stderr) => { if (error) { console.error("rclone error:", error); - if (RCLONE_ID != myId) error = false; + if (RCLONE_ID !== myId) { + error = false; + } console.log({ RCLONE_ID, myId }); win.webContents.send("check_mount", { success: false, error }); // checkMount(); @@ -1653,7 +1746,7 @@ function resetCache(folder) { .join(global.mountFolder, global.currentConfiguration.mntGamePath) .replace(/\\/g, "/"); - if (folder == oculusGamesDir) { + if (folder === oculusGamesDir) { cacheOculusGames = false; return true; } @@ -1667,7 +1760,7 @@ async function getDir(folder) { .replace(/\\/g, "/"); //console.log(folder, oculusGamesDir); if ( - folder == oculusGamesDir && + folder === oculusGamesDir && global.currentConfiguration.cacheOculusGames && cacheOculusGames ) { @@ -1677,14 +1770,15 @@ async function getDir(folder) { try { const files = await fsp.readdir(folder /*, { withFileTypes: true }*/); - let gameList = {}; - let gameListName2Package = {}; + const gameList = {}; let installedApps = {}; let gameListName = false; try { // throw 'test'; for (const name of GAME_LIST_NAMES) { - if (!fs.existsSync(path.join(folder, name))) continue; + if (!fs.existsSync(path.join(folder, name))) { + continue; + } // if (!files.includes(name)) continue; gameListName = name; break; @@ -1695,17 +1789,19 @@ async function getDir(folder) { await fsp.readFile(path.join(folder, gameListName), "utf8") ).split("\n"); let listVer; - if (!list.length) throw gameListName + " is empty"; + if (!list.length) { + throw `${gameListName} is empty`; + } for (const line of list) { const meta = line.split(";"); if (!listVer) { - listVer = meta[2] == "Release APK Path" ? 1 : 2; + listVer = meta[2] === "Release APK Path" ? 1 : 2; console.log({ gameListName, listVer }); continue; } - if (listVer == 1) { + if (listVer === 1) { gameList[meta[1]] = { simpleName: meta[0], releaseName: meta[1], @@ -1714,7 +1810,7 @@ async function getDir(folder) { versionName: meta[5], imagePath: `file://${global.tmpdir}/mnt/${global.currentConfiguration.mntGamePath}/.meta/thumbnails/${meta[3]}.jpg`, }; - } else if (listVer == 2) { + } else if (listVer === 2) { gameList[meta[1]] = { simpleName: meta[0], releaseName: meta[1], @@ -1745,7 +1841,7 @@ async function getDir(folder) { console.error("Can`t get installed apps", err); } - let fileNames = await Promise.all( + const fileNames = await Promise.all( files.map(async (fileName) => { // console.log(fileName); @@ -1785,7 +1881,7 @@ async function getDir(folder) { // If gameMeta is still not defined then there is no game with a // matching version number. We now query gameList using the game name // without the version number. - let regex = /^([\w -.,!?&+™®'"]+) v\d+\+/; + const regex = /^([\w -.,!?&+™®'"]+) v\d+\+/; if (regex.test(fileName)) { // Only do this if this is a folder containing an apk file. if (info.isDirectory()) { @@ -1813,7 +1909,7 @@ async function getDir(folder) { size = gameMeta.size; imagePath = gameMeta.imagePath; - let regex = /\((.*?)\)/; + const regex = /\((.*?)\)/; if (regex.test(gameMeta.releaseName)) { const match = gameMeta.releaseName.match(regex)[0]; note += match.replace(", only autoinstalls with Rookie", ""); @@ -1849,11 +1945,11 @@ async function getDir(folder) { versionName = fileName.match(regex)[1]; } - if (!versionCode && new RegExp(".* -versionCode-").test(fileName)) { + if (!versionCode && /.* -versionCode-/.test(fileName)) { versionCode = fileName.match(/-versionCode-([0-9]*)/)[1]; } - if (!packageName && new RegExp(".* -packageName-").test(fileName)) { + if (!packageName && /.* -packageName-/.test(fileName)) { packageName = fileName.match(/-packageName-([a-zA-Z0-9.]*)/)[1]; } @@ -1864,7 +1960,7 @@ async function getDir(folder) { if (packageName) { if (!imagePath) { - if (QUEST_ICONS.includes(packageName + ".jpg")) { + if (QUEST_ICONS.includes(`${packageName}.jpg`)) { imagePath = `https://raw.githubusercontent.com/vKolerts/quest_icons/master/250/${packageName}.jpg`; } else if (!imagePath) { imagePath = "unknown.png"; @@ -1872,7 +1968,7 @@ async function getDir(folder) { } kmeta = KMETAS[packageName]; - installedApp = installedApps[packageName]; + const installedApp = installedApps[packageName]; if (installedApp) { installed = 1; if (versionCode && versionCode > installedApp.versionCode) { @@ -1953,7 +2049,7 @@ async function getDir(folder) { // console.log(fileNames) if ( - folder == oculusGamesDir && + folder === oculusGamesDir && global.currentConfiguration.cacheOculusGames ) { console.log("getDir cached", folder); @@ -1966,7 +2062,7 @@ async function getDir(folder) { return fileNames; } catch (error) { - console.error("Can`t open folder " + folder, error); + console.error(`Can\`t open folder ${folder}`, error); //returnError(e.message) return false; } @@ -1981,7 +2077,7 @@ async function cleanUpFoldername(simpleName) { async function getDirListing(folder) { const files = await fsp.readdir(folder); - let fileNames = await Promise.all( + const fileNames = await Promise.all( files.map(async (file) => { return path.join(folder, file).replace(/\\/g, "/"); }), @@ -1998,7 +2094,9 @@ async function backupApp({ location, pkg }) { let folderName = pkg; for (const app of global.installedApps) { - if (app["packageName"] != pkg) continue; + if (app["packageName"] !== pkg) { + continue; + } folderName = `${app["simpleName"]} -versionCode-${app["versionCode"]} -packageName-${pkg}`; break; } @@ -2009,7 +2107,9 @@ async function backupApp({ location, pkg }) { await fsp.mkdir(location, { recursive: true }); await adbPull(apk, path.join(location, "base.apk")); const obbsPath = `/sdcard/Android/obb/${pkg}`; - if (!(await adbFileExists(obbsPath))) return true; + if (!(await adbFileExists(obbsPath))) { + return true; + } await adbPullFolder(obbsPath, path.join(location, pkg)); @@ -2049,7 +2149,9 @@ async function restoreAppData( ) { console.log("restoreAppData()", packageName); backupPath = path.join(backupPath, packageName); - if (!(await fsp.exists(backupPath))) throw `Backup not found ${backupPath}`; + if (!(await fsp.exists(backupPath))) { + throw `Backup not found ${backupPath}`; + } await adbPushFolder( path.join(backupPath, "Android", packageName), @@ -2074,7 +2176,9 @@ async function copyAppPrefs(packageName, removeAfter = false) { async function restoreAppPrefs(packageName, removeAfter = true) { const cmd = removeAfter ? "mv -f" : "cp -rf"; const backup_path = `${backupPrefsPath}/${packageName}`; - if (!(await adbFileExists(backup_path))) return; + if (!(await adbFileExists(backup_path))) { + return; + } return adbShell( `run-as ${packageName} ${cmd} "${backup_path}" "/data/data/"`, @@ -2084,7 +2188,7 @@ async function restoreAppPrefs(packageName, removeAfter = true) { async function sideloadFolder(arg) { location = arg.path; console.log("sideloadFolder()", arg); - let res = { + const res = { device: "done", aapt: false, check: false, @@ -2103,6 +2207,7 @@ async function sideloadFolder(arg) { win.webContents.send("sideload_process", res); + let apkfile = ""; if (location.endsWith(".apk")) { apkfile = location; location = path.dirname(location); @@ -2111,16 +2216,16 @@ async function sideloadFolder(arg) { return; } - console.log("start sideload: " + apkfile); + console.log(`start sideload: ${apkfile}`); - fromremote = false; + let fromremote = false; if (location.includes(global.mountFolder)) { fromremote = true; } console.log("fromremote:", fromremote); - packageName = ""; + let packageName = ""; let apktmp = ""; try { if (!fromremote) { @@ -2130,14 +2235,16 @@ async function sideloadFolder(arg) { win.webContents.send("sideload_process", res); apktmp = path.join(global.tmpdir, path.basename(apkfile)); - console.log("is remote, copying to " + apktmp); + console.log(`is remote, copying to ${apktmp}`); if (await fsp.exists(apktmp)) { - console.log("is remote, " + apktmp + "already exists, using"); + console.log(`is remote, ${apktmp}already exists, using`); res.download = "skip"; } else { const tmpname = `${apktmp}.part`; - if (await fsp.exists(tmpname)) await fsp.unlink(tmpname); + if (await fsp.exists(tmpname)) { + await fsp.unlink(tmpname); + } await fsp.copyFile(apkfile, tmpname); await fsp.rename(tmpname, apktmp); res.download = "done"; @@ -2158,7 +2265,7 @@ async function sideloadFolder(arg) { win.webContents.send("sideload_process", res); try { - packageinfo = await getPackageInfo(apkfile); + const packageinfo = await getPackageInfo(apkfile); packageName = packageinfo.packageName; console.log({ apkfile, packageinfo, packageName }); @@ -2190,7 +2297,7 @@ async function sideloadFolder(arg) { try { installed = await adb.getDevice(global.adbDevice).isInstalled(packageName); res.check = "done"; - } catch (err) { + } catch (e) { console.error("check", e); res.check = "fail"; res.error = e; @@ -2286,13 +2393,16 @@ async function sideloadFolder(arg) { const obbFolderOrig = path.join(location, packageName); console.log({ obbFolderOrig }); + + let obbFolderDest = ""; try { - if (!(await fsp.exists(obbFolderOrig))) throw "Can`t find obbs folder"; + if (!(await fsp.exists(obbFolderOrig))) { + throw "Can`t find obbs folder"; + } obbFolderDest = `/sdcard/Android/obb/${packageName}`; - console.log("DATAFOLDER to copy:" + obbFolderDest); + console.log(`DATAFOLDER to copy:${obbFolderDest}`); } catch (error) { console.log(error); - obbFolderDest = false; res.remove_obb = "skip"; res.download_obb = "skip"; res.push_obb = "skip"; @@ -2322,9 +2432,8 @@ async function sideloadFolder(arg) { obbFiles = await fsp.readdir(obbFolderOrig); console.log("obbFiles: ", obbFiles.length); - res.download_obb = - (fromremote ? "0" : obbFiles.length) + "/" + obbFiles.length; - res.push_obb = "0/" + obbFiles.length; + res.download_obb = `${fromremote ? "0" : obbFiles.length}/${obbFiles.length}`; + res.push_obb = `0/${obbFiles.length}`; win.webContents.send("sideload_process", res); const tmpFolder = path.join(global.tmpdir, packageName); @@ -2334,25 +2443,26 @@ async function sideloadFolder(arg) { for (const obbName of obbFiles) { const obb = path.join(obbFolderOrig, obbName); - console.log("obb File: " + obbName); + console.log(`obb File: ${obbName}`); console.log("doing obb push"); const destFile = `${obbFolderDest}/${obbName}`; if (fromremote) { const obbtmp = path.join(tmpFolder, obbName); - console.log("obb is remote, copying to " + obbtmp); + console.log(`obb is remote, copying to ${obbtmp}`); if (await fsp.exists(obbtmp)) { console.log(`obb is remote, ${obbtmp} already exists, using`); } else { const tmpname = `${obbtmp}.part`; - if (await fsp.exists(tmpname)) await fsp.unlink(tmpname); + if (await fsp.exists(tmpname)) { + await fsp.unlink(tmpname); + } await fsp.copyFile(obb, tmpname); await fsp.rename(tmpname, obbtmp); } - res.download_obb = - +res.download_obb.split("/")[0] + 1 + "/" + obbFiles.length; + res.download_obb = `${+res.download_obb.split("/")[0] + 1}/${obbFiles.length}`; win.webContents.send("sideload_process", res); await adbPush(obbtmp, `${destFile}`, false); } else { @@ -2360,7 +2470,7 @@ async function sideloadFolder(arg) { await adbPush(obb, `${destFile}`, false); } - res.push_obb = +res.push_obb.split("/")[0] + 1 + "/" + obbFiles.length; + res.push_obb = `${+res.push_obb.split("/")[0] + 1}/${obbFiles.length}`; win.webContents.send("sideload_process", res); } @@ -2397,7 +2507,7 @@ async function getPackageInfo(apkPath) { const reader = await ApkReader.open(apkPath); const manifest = await reader.readManifest(); - info = { + const info = { packageName: manifest.package, versionCode: manifest.versionCode, versionName: manifest.versionName, @@ -2410,7 +2520,7 @@ async function getInstalledApps(obj = false) { let apps = await adbShell(`pm list packages -3 --show-versioncode`); apps = apps.split("\n"); // apps.pop(); - appinfo = {}; + const appinfo = {}; for (const appLine of apps) { const [packageName, versionCode] = appLine.slice(8).split(" versionCode:"); @@ -2420,7 +2530,7 @@ async function getInstalledApps(obj = false) { (KMETAS[packageName] && KMETAS[packageName].simpleName) || packageName; info["packageName"] = packageName; info["versionCode"] = versionCode; - info["imagePath"] = QUEST_ICONS.includes(packageName + ".jpg") + info["imagePath"] = QUEST_ICONS.includes(`${packageName}.jpg`) ? `https://raw.githubusercontent.com/vKolerts/quest_icons/master/250/${packageName}.jpg` : `http://cdn.apk-cloud.com/detail/image/${packageName}-w130.png`; //'unknown.png'; @@ -2451,16 +2561,20 @@ async function getInstalledAppsWithUpdates() { global.currentConfiguration.mntGamePath, ); // TODO: folder path to config const list = await getDir(remotePath); - let remotePackages = {}; - let remoteList = {}; + const remotePackages = {}; + const remoteList = {}; - if (list) + if (list) { for (const app of list) { const { name, packageName, versionCode, simpleName, filePath, size } = app; - if (!packageName) continue; + if (!packageName) { + continue; + } - if (!remotePackages[packageName]) remotePackages[packageName] = []; + if (!remotePackages[packageName]) { + remotePackages[packageName] = []; + } remotePackages[packageName].push(name); remoteList[name] = { @@ -2470,26 +2584,31 @@ async function getInstalledAppsWithUpdates() { size, }; } + } const remoteKeys = Object.keys(remotePackages); const apps = global.installedApps || (await getInstalledApps()); - let updates = []; + const updates = []; for (const app of apps) { const packageName = app["packageName"]; // console.log(packageName, 'checking'); - if (!remoteKeys.includes(packageName)) continue; + if (!remoteKeys.includes(packageName)) { + continue; + } - for (name of remotePackages[packageName]) { - const pkg = remoteList[name]; + for (const pkgName of remotePackages[packageName]) { + const pkg = remoteList[pkgName]; const installedVersion = app["versionCode"]; const remoteversion = pkg.versionCode; // console.log({ packageName, installedVersion, remoteversion }); // console.log({ pkg }); - if (remoteversion <= installedVersion) continue; + if (remoteversion <= installedVersion) { + continue; + } app["simpleName"] = pkg.simpleName; app["update"] = []; @@ -2509,7 +2628,7 @@ async function getInstalledAppsWithUpdates() { async function detectNoteTxt(files, folder) { // TODO: check .meta/notes - if (typeof files == "string") { + if (typeof files === "string") { folder = files; files = false; } @@ -2526,7 +2645,7 @@ async function detectNoteTxt(files, folder) { } async function detectInstallTxt(files, folder) { - if (typeof files == "string") { + if (typeof files === "string") { folder = files; files = false; } @@ -2547,7 +2666,7 @@ async function detectInstallTxt(files, folder) { } async function getApkFromFolder(folder) { - let res = { + const res = { path: false, install_desc: false, }; @@ -2557,19 +2676,19 @@ async function getApkFromFolder(folder) { res.notes = await detectNoteTxt(files, folder); console.log({ files }); - for (file of files) { + for (const file of files) { if (file.endsWith(".apk")) { res.path = path.join(folder, file).replace(/\\/g, "/"); return res; } } - returnError("No apk found in " + folder); + returnError(`No apk found in ${folder}`); return res; } async function uninstall(packageName) { - resp = await adb.getDevice(global.adbDevice).uninstall(packageName); + await adb.getDevice(global.adbDevice).uninstall(packageName); } let rcloneProgress = false; @@ -2579,7 +2698,9 @@ async function updateRcloneProgress() { method: "POST", }); const data = await response.json(); - if (!data.transferring || !data.transferring[0]) throw "no data"; + if (!data.transferring || !data.transferring[0]) { + throw "no data"; + } const transferring = data.transferring[0]; rcloneProgress = { cmd: "download", @@ -2592,8 +2713,8 @@ async function updateRcloneProgress() { }; //console.log('sending rclone data'); win.webContents.send("process_data", rcloneProgress); - } catch (error) { - //console.error('Fetch-Error:', error); + } catch (_e) { + //console.error('Fetch-Error:', _e); if (rcloneProgress) { rcloneProgress = false; win.webContents.send("process_data", rcloneProgress); @@ -2608,7 +2729,7 @@ async function init() { fsp .access(p) .then(() => true) - .catch((e) => false); + .catch((_e) => false); await initLogs(); @@ -2625,22 +2746,22 @@ async function init() { async function loadMeta() { try { const res = await fetch( - "https://raw.githubusercontent.com/vKolerts/quest_icons/master/version?" + - Date.now(), + `https://raw.githubusercontent.com/vKolerts/quest_icons/master/version?${Date.now()}`, ); - version = await res.text(); - if (version == META_VERSION) return setTimeout(loadMeta, CHECK_META_PERIOD); + const metaVersion = await res.text(); + if (metaVersion === META_VERSION) { + return setTimeout(loadMeta, CHECK_META_PERIOD); + } - META_VERSION = version; + META_VERSION = metaVersion; console.log("Meta version", META_VERSION); } catch (err) { - console.error("can`t get meta version", err); + console.error("Can`t get meta version", err); } try { const res = await fetch( - "https://raw.githubusercontent.com/vKolerts/quest_icons/master/list.json?" + - Date.now(), + `https://raw.githubusercontent.com/vKolerts/quest_icons/master/list.json?${Date.now()}`, ); QUEST_ICONS = await res.json(); console.log("icons list loaded"); @@ -2650,8 +2771,7 @@ async function loadMeta() { try { const res = await fetch( - "https://raw.githubusercontent.com/vKolerts/quest_icons/master/.e?" + - Date.now(), + `https://raw.githubusercontent.com/vKolerts/quest_icons/master/.e?${Date.now()}`, ); const text = await res.text(); const iv = Buffer.from(text.substring(0, l), "hex"); @@ -2679,7 +2799,7 @@ async function loadMeta() { function escString(val) { let res = val.toLowerCase(); - res = res.replace(/[-\_:.,!?\"'&™®| ]/g, ""); + res = res.replace(/[-_:.,!?"'&™®| ]/g, ""); return res; } @@ -2703,39 +2823,39 @@ async function initLogs() { let line = ""; let line_color = ""; for (const l of d) { - if (typeof l == "string") { - line += l + " "; - line_color += l + " "; + if (typeof l === "string") { + line += `${l} `; + line_color += `${l} `; continue; } const formated = util.format(l); - line += formated + " "; - line_color += "\x1b[32m" + formated + "\x1b[0m "; + line += `${formated} `; + line_color += `\x1b[32m${formated}\x1b[0m `; } - log_stdout.write(dateF() + line_color + "\n"); - log_file.write(dateF() + line + "\n"); + log_stdout.write(`${dateF() + line_color}\n`); + log_file.write(`${dateF() + line}\n`); }; console.error = function (...d) { let line = ""; for (const l of d) { - line += util.format(l) + " "; + line += `${util.format(l)} `; } - log_stdout.write(`\x1b[31m${dateF()}ERROR: ` + line + "\x1b[0m\n"); - log_file.write(dateF() + "ERROR: " + line + "\n"); + log_stdout.write(`\x1b[31m${dateF()}ERROR: ${line}\x1b[0m\n`); + log_file.write(`${dateF()}ERROR: ${line}\n`); }; console.warning = function (...d) { let line = ""; for (const l of d) { - line += util.format(l) + " "; + line += `${util.format(l)} `; } - log_stdout.write(`\x1b[33m${dateF()}WARN: ` + line + "\x1b[0m\n"); - log_file.write(dateF() + "WARN: " + line + "\n"); + log_stdout.write(`\x1b[33m${dateF()}WARN: ${line}\x1b[0m\n`); + log_file.write(`${dateF()}WARN: ${line}\n`); }; } @@ -2782,7 +2902,7 @@ async function reloadConfig() { } if (await fsp.exists(configLocation)) { - console.log("Config exist, using " + configLocation); + console.log(`Config exist, using ${configLocation}`); global.currentConfiguration = Object.assign( defaultConfig, require(configLocation), @@ -2818,15 +2938,22 @@ function proxySettings(proxyUrl = global.currentConfiguration.proxyUrl) { async function changeConfig(key, value) { console.log("cfg.update", key, value); - if (key == "proxyUrl") proxySettings(value); - if (["proxyOculus", "proxySteam", "proxySQ"].includes(key)) proxySettings(); + if (key === "proxyUrl") { + proxySettings(value); + } + if (["proxyOculus", "proxySteam", "proxySQ"].includes(key)) { + proxySettings(); + } global.currentConfiguration[key] = value; await saveConfig(); - if (key == "rcloneConf") await parseRcloneSections(true); - if (key == "tmpdir") + if (key === "rcloneConf") { + await parseRcloneSections(true); + } + if (key === "tmpdir") { global.tmpdir = value || require("os").tmpdir().replace(/\\/g, "/"); + } return value; } diff --git a/versioncheck.js b/versioncheck.js index 147faab..1715ea6 100644 --- a/versioncheck.js +++ b/versioncheck.js @@ -1,3 +1,11 @@ +/* eslint + no-unused-vars: [ + "error", { + "varsIgnorePattern": "checkVersion", + "argsIgnorePattern": "^_" + } + ] +*/ const pkg = require("./package.json"); const fetch = (...args) => import("node-fetch").then(({ default: fetch }) => fetch(...args)); @@ -12,9 +20,11 @@ async function checkVersion() { const content = JSON.parse(await res.text()); const remoteversion = content.name; - console.log("Current version: " + pkg.version); - console.log("Github version: " + remoteversion); - if (!remoteversion) return; + console.log(`Current version: ${pkg.version}`); + console.log(`Github version: ${remoteversion}`); + if (!remoteversion) { + return; + } if (compareVersions.compare(remoteversion, pkg.version, "<=")) { console.log("Using latest version"); @@ -32,3 +42,5 @@ async function checkVersion() { console.error("checkVersion.Fail", err); } } + +module.exports = checkVersion; diff --git a/views/browse_include.twig b/views/browse_include.twig index d2b1595..be03060 100644 --- a/views/browse_include.twig +++ b/views/browse_include.twig @@ -111,10 +111,10 @@