mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-06-28 18:31:44 +02:00
Compare commits
34 Commits
Author | SHA1 | Date | |
---|---|---|---|
e502e49d64 | |||
604cf7094a | |||
3bfa7e5f21 | |||
e3789b4fb7 | |||
0551d909e5 | |||
da6ab51ba0 | |||
4a65221ad0 | |||
528c6774fe | |||
3c8a35d441 | |||
544ededb64 | |||
f4f88f688b | |||
1fb1a64767 | |||
769649a376 | |||
057adb62df | |||
98e8ff4783 | |||
f5e1b0a9fa | |||
8ea3503dd3 | |||
b733d55e9e | |||
317ac9017b | |||
b8c62a1f4d | |||
7332528f72 | |||
d063500aae | |||
29ff1bc09c | |||
8998daf14c | |||
8bdad8b319 | |||
5dd3ebdea1 | |||
55d7796f96 | |||
0b02a758db | |||
3b2abbf6bb | |||
43a66db697 | |||
a3130101f4 | |||
3483672554 | |||
75d7443e0f | |||
b5d2d0fdec |
46
bun.lock
46
bun.lock
@ -3,11 +3,11 @@
|
||||
"workspaces": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.0",
|
||||
"@types/node": "^22.10.10",
|
||||
"@types/bun": "^1.2.9",
|
||||
"@types/node": "^22.14.1",
|
||||
"@types/stylus": "^0.48.43",
|
||||
"@webgpu/types": "^0.1.53",
|
||||
"eslint": "^9.19.0",
|
||||
"@webgpu/types": "^0.1.60",
|
||||
"eslint": "^9.24.0",
|
||||
"eslint-plugin-compat": "^6.0.2",
|
||||
"stylus": "^0.64.0",
|
||||
},
|
||||
@ -23,17 +23,19 @@
|
||||
|
||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
||||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.19.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.4", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ=="],
|
||||
"@eslint/config-array": ["@eslint/config-array@0.20.0", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@0.11.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA=="],
|
||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.2.1", "", {}, "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.2.0", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w=="],
|
||||
"@eslint/core": ["@eslint/core@0.13.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.20.0", "", {}, "sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ=="],
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.1", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.4", "", {}, "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ=="],
|
||||
"@eslint/js": ["@eslint/js@9.25.0", "", {}, "sha512-iWhsUS8Wgxz9AXNfvfOPFSW4VfMXdVhp1hjkZVhXCrpgh/aLcc45rX6MPu+tIVUWDw0HfNwth7O28M1xDxNf9w=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.5", "", { "dependencies": { "@eslint/core": "^0.10.0", "levn": "^0.4.1" } }, "sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A=="],
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.2.8", "", { "dependencies": { "@eslint/core": "^0.13.0", "levn": "^0.4.1" } }, "sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
||||
@ -41,7 +43,7 @@
|
||||
|
||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.1", "", {}, "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA=="],
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.2", "", {}, "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ=="],
|
||||
|
||||
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
|
||||
|
||||
@ -49,19 +51,17 @@
|
||||
|
||||
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.2.2", "", { "dependencies": { "bun-types": "1.2.2" } }, "sha512-tr74gdku+AEDN5ergNiBnplr7hpDp3V1h7fqI2GcR/rsUaM39jpSeKH0TFibRvU0KwniRx5POgaYnaXbk0hU+w=="],
|
||||
"@types/bun": ["@types/bun@1.2.10", "", { "dependencies": { "bun-types": "1.2.10" } }, "sha512-eilv6WFM3M0c9ztJt7/g80BDusK98z/FrFwseZgT4bXCq2vPhXD4z8R3oddmAn+R/Nmz9vBn4kweJKmGTZj+lg=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/node": ["@types/node@22.13.1", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew=="],
|
||||
"@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="],
|
||||
|
||||
"@types/stylus": ["@types/stylus@0.48.43", "", { "dependencies": { "@types/node": "*" } }, "sha512-72dv/zdhuyXWVHUXG2VTPEQdOG+oen95/DNFx2aMFFaY6LoITI6PwEqf5x31JF49kp2w9hvUzkNfTGBIeg61LQ=="],
|
||||
|
||||
"@types/ws": ["@types/ws@8.5.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A=="],
|
||||
|
||||
"@webgpu/types": ["@webgpu/types@0.1.54", "", {}, "sha512-81oaalC8LFrXjhsczomEQ0u3jG+TqE6V9QHLA8GNZq/Rnot0KDugu3LhSYSlie8tSdooAN1Hov05asrUUp9qgg=="],
|
||||
"@webgpu/types": ["@webgpu/types@0.1.60", "", {}, "sha512-8B/tdfRFKdrnejqmvq95ogp8tf52oZ51p3f4QD5m5Paey/qlX4Rhhy5Y8tgFMi7Ms70HzcMMw3EQjH/jdhTwlA=="],
|
||||
|
||||
"acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
|
||||
|
||||
@ -83,7 +83,7 @@
|
||||
|
||||
"browserslist": ["browserslist@4.24.3", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="],
|
||||
"bun-types": ["bun-types@1.2.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-b5ITZMnVdf3m1gMvJHG+gIfeJHiQPJak0f7925Hxu6ZN5VKA8AGy4GZ4lM+Xkn6jtWxg5S3ldWvfmXdvnkp3GQ=="],
|
||||
|
||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||
|
||||
@ -113,11 +113,11 @@
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.20.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.0", "@eslint/core": "^0.11.0", "@eslint/eslintrc": "^3.2.0", "@eslint/js": "9.20.0", "@eslint/plugin-kit": "^0.2.5", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.1", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-aL4F8167Hg4IvsW89ejnpTwx+B/UQRzJPGgbIOl+4XqffWsahVVsLEWoZvnrVuwpWmnRd7XeXmQI1zlKcFDteA=="],
|
||||
"eslint": ["eslint@9.25.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.0", "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.13.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.25.0", "@eslint/plugin-kit": "^0.2.8", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.3.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-MsBdObhM4cEwkzCiraDv7A6txFXEqtNXOb877TsSp2FCkBNl8JfVQrmiuDqC1IkejT6JLPzYBXx/xAiYhyzgGA=="],
|
||||
|
||||
"eslint-plugin-compat": ["eslint-plugin-compat@6.0.2", "", { "dependencies": { "@mdn/browser-compat-data": "^5.5.35", "ast-metadata-inferer": "^0.8.1", "browserslist": "^4.24.2", "caniuse-lite": "^1.0.30001687", "find-up": "^5.0.0", "globals": "^15.7.0", "lodash.memoize": "^4.1.2", "semver": "^7.6.2" }, "peerDependencies": { "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" } }, "sha512-1ME+YfJjmOz1blH0nPZpHgjMGK4kjgEeoYqGCqoBPQ/mGu/dJzdoP0f1C8H2jcWZjzhZjAMccbM/VdXhPORIfA=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.2.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A=="],
|
||||
"eslint-scope": ["eslint-scope@8.3.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ=="],
|
||||
|
||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
|
||||
|
||||
@ -255,7 +255,7 @@
|
||||
|
||||
"typescript": ["typescript@5.7.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg=="],
|
||||
|
||||
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"update-browserslist-db": ["update-browserslist-db@1.1.1", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.0" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A=="],
|
||||
|
||||
@ -275,14 +275,10 @@
|
||||
|
||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.10.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw=="],
|
||||
|
||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||
|
||||
"@types/stylus/@types/node": ["@types/node@22.5.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-Xjs4y5UPO/CLdzpgR6GirZJx36yScjh73+2NlLlkFRSoQN8B0DpfXPdZGnvVmLRLOsqDpOfTNv7D9trgGhmOIA=="],
|
||||
|
||||
"@types/ws/@types/node": ["@types/node@20.14.2", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q=="],
|
||||
|
||||
"ast-metadata-inferer/@mdn/browser-compat-data": ["@mdn/browser-compat-data@5.6.26", "", {}, "sha512-7NdgdOR7lkzrN70zGSULmrcvKyi/aJjpTJRCbuy8IZuHiLkPTvsr10jW0MJgWzK2l2wTmhdQvegTw6yNU5AVNQ=="],
|
||||
|
||||
"foreground-child/cross-spawn": ["cross-spawn@7.0.3", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="],
|
||||
@ -303,8 +299,6 @@
|
||||
|
||||
"@types/stylus/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
|
||||
|
||||
"@types/ws/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||
|
||||
"glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
||||
|
||||
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
||||
|
2
dist/better-xcloud.meta.js
vendored
2
dist/better-xcloud.meta.js
vendored
@ -1,5 +1,5 @@
|
||||
// ==UserScript==
|
||||
// @name Better xCloud
|
||||
// @namespace https://github.com/redphx
|
||||
// @version 6.4.2
|
||||
// @version 6.5.0
|
||||
// ==/UserScript==
|
||||
|
278
dist/better-xcloud.pretty.user.js
vendored
278
dist/better-xcloud.pretty.user.js
vendored
File diff suppressed because one or more lines are too long
67
dist/better-xcloud.user.js
vendored
67
dist/better-xcloud.user.js
vendored
File diff suppressed because one or more lines are too long
@ -10,11 +10,11 @@
|
||||
"build": "build.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.2",
|
||||
"@types/node": "^22.13.1",
|
||||
"@types/bun": "^1.2.10",
|
||||
"@types/node": "^22.14.1",
|
||||
"@types/stylus": "^0.48.43",
|
||||
"@webgpu/types": "^0.1.54",
|
||||
"eslint": "^9.20.0",
|
||||
"@webgpu/types": "^0.1.60",
|
||||
"eslint": "^9.25.0",
|
||||
"eslint-plugin-compat": "^6.0.2",
|
||||
"stylus": "^0.64.0"
|
||||
},
|
||||
|
@ -60,9 +60,35 @@ button_color(name, normal, hover, active, disabled)
|
||||
}
|
||||
|
||||
/* Remove the "Cloud Gaming" text in header when the screen is too small */
|
||||
@media screen and (min-width: 641px) and (max-width: 767px) {
|
||||
header {
|
||||
button[class^="ExperienceDropdown-module__toggleButton"],
|
||||
button[class^="XboxButton-module__headerXboxButton"] {
|
||||
margin-right: 10px !important;
|
||||
}
|
||||
|
||||
a[href="/play"],
|
||||
button[class^="ExperienceDropdown-module__toggleButton"] {
|
||||
> div {
|
||||
> div {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
> svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 640px) {
|
||||
header a[href="/play"] {
|
||||
display: none;
|
||||
header {
|
||||
a[href="/play"],
|
||||
button[class^="ExperienceDropdown-module__toggleButton"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
// @license MIT
|
||||
// @match https://www.xbox.com/*/play*
|
||||
// @match https://www.xbox.com/*/auth/msa?*loggedIn*
|
||||
// @exclude https://www.xbox.com/*/xbox-game-pass/play-day-one
|
||||
// @run-at document-start
|
||||
// @grant none
|
||||
// @updateURL https://raw.githubusercontent.com/redphx/better-xcloud/typescript/dist/better-xcloud.meta.js
|
||||
|
@ -79,7 +79,6 @@ export const enum GlobalPref {
|
||||
AUDIO_MIC_ON_PLAYING = 'audio.mic.onPlaying',
|
||||
AUDIO_VOLUME_CONTROL_ENABLED = 'audio.volume.booster.enabled',
|
||||
|
||||
REMOTE_PLAY_ENABLED = 'xhome.enabled',
|
||||
REMOTE_PLAY_STREAM_RESOLUTION = 'xhome.video.resolution',
|
||||
|
||||
GAME_FORTNITE_FORCE_CONSOLE = 'game.fortnite.forceConsole',
|
||||
@ -99,7 +98,6 @@ export type GlobalPrefTypeMap = {
|
||||
[GlobalPref.MKB_HIDE_IDLE_CURSOR]: boolean;
|
||||
[GlobalPref.NATIVE_MKB_FORCED_GAMES]: string[];
|
||||
[GlobalPref.NATIVE_MKB_MODE]: NativeMkbMode;
|
||||
[GlobalPref.REMOTE_PLAY_ENABLED]: boolean;
|
||||
[GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION]: StreamResolution;
|
||||
[GlobalPref.SCREENSHOT_APPLY_FILTERS]: boolean;
|
||||
[GlobalPref.SERVER_BYPASS_RESTRICTION]: string;
|
||||
@ -232,7 +230,6 @@ export const ALL_PREFS: {
|
||||
GlobalPref.MKB_HIDE_IDLE_CURSOR,
|
||||
GlobalPref.NATIVE_MKB_FORCED_GAMES,
|
||||
GlobalPref.NATIVE_MKB_MODE,
|
||||
GlobalPref.REMOTE_PLAY_ENABLED,
|
||||
GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION,
|
||||
GlobalPref.SCREENSHOT_APPLY_FILTERS,
|
||||
GlobalPref.SERVER_BYPASS_RESTRICTION,
|
||||
|
@ -95,10 +95,13 @@ export const enum StreamStatPosition {
|
||||
|
||||
export const enum VideoRatio {
|
||||
'16:9' = '16:9',
|
||||
'18:9' = '18:9',
|
||||
'21:9' = '21:9',
|
||||
'16:10' = '16:10',
|
||||
'18:9' = '18:9',
|
||||
'20:9' = '20:9',
|
||||
'21:9' = '21:9',
|
||||
'3:2' = '3:2',
|
||||
'4:3' = '4:3',
|
||||
'5:4' = '5:4',
|
||||
FILL = 'fill',
|
||||
}
|
||||
|
||||
@ -133,6 +136,7 @@ export const enum BlockFeature {
|
||||
BYOG = 'byog',
|
||||
NOTIFICATIONS_INVITES = 'notifications-invites',
|
||||
NOTIFICATIONS_ACHIEVEMENTS = 'notifications-achievements',
|
||||
REMOTE_PLAY = 'remote-play',
|
||||
}
|
||||
|
||||
export const enum UiTheme {
|
||||
|
13
src/index.ts
13
src/index.ts
@ -147,6 +147,12 @@ if (isFullVersion() && BX_FLAGS.SafariWorkaround && document.readyState !== 'loa
|
||||
throw new Error('[Better xCloud] Executing workaround for Safari');
|
||||
}
|
||||
|
||||
// Make sure it only run on /play
|
||||
if (!window.location.pathname.match(/^\/[a-zA-Z]{2}-[a-zA-Z]{2}\/play/)) {
|
||||
throw new Error('[Better xCloud] Not xCloud page');
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener('load', e => {
|
||||
// Automatically reload the page when running into the "We are sorry..." error message
|
||||
window.setTimeout(() => {
|
||||
@ -323,7 +329,7 @@ BxEventBus.Stream.on('dataChannelCreated', payload => {
|
||||
let newId: number = parseInt(json.titleid, 16);
|
||||
|
||||
// Get titleSlug for Remote Play
|
||||
if (STATES.remotePlay.isPlaying) {
|
||||
if (window.location.pathname.includes('/play/consoles/launch/')) {
|
||||
currentStream.titleSlug = 'remote-play';
|
||||
if (json.focused) {
|
||||
const productTitle = await XboxApi.getProductTitle(newId);
|
||||
@ -442,11 +448,6 @@ function main() {
|
||||
Patcher.init();
|
||||
disablePwa();
|
||||
|
||||
// Preload Remote Play
|
||||
if (getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED)) {
|
||||
RemotePlayManager.detect();
|
||||
}
|
||||
|
||||
if (getGlobalPref(GlobalPref.TOUCH_CONTROLLER_MODE) === TouchControllerMode.ALL) {
|
||||
TouchController.setup();
|
||||
}
|
||||
|
@ -36,18 +36,24 @@ export class PatcherUtils {
|
||||
return txt.substring(0, index) + toString + txt.substring(index + fromString.length);
|
||||
}
|
||||
|
||||
static replaceAfterIndex(txt: string, search: string, replaceWith: string, index: number) {
|
||||
const before = txt.slice(0, index);
|
||||
const after = txt.slice(index).replace(search, replaceWith);
|
||||
return before + after;
|
||||
}
|
||||
|
||||
static filterPatches(patches: Array<PatchName | false>): PatchArray {
|
||||
return patches.filter((item): item is PatchName => !!item);
|
||||
}
|
||||
|
||||
static patchBeforePageLoad(str: string, page: PatchPage): string | false {
|
||||
let text = `chunkName:()=>"${page}-page",`;
|
||||
if (!str.includes(text)) {
|
||||
const index = str.indexOf(`chunkName:()=>"${page}-page",`);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
str = str.replace('requireAsync(e){', `requireAsync(e){window.BX_EXPOSED.beforePageLoad("${page}");`);
|
||||
str = str.replace('requireSync(e){', `requireSync(e){window.BX_EXPOSED.beforePageLoad("${page}");`);
|
||||
str = PatcherUtils.replaceAfterIndex(str, 'requireAsync(e){', `requireAsync(e){window.BX_EXPOSED.beforePageLoad("${page}");`, index);
|
||||
str = PatcherUtils.replaceAfterIndex(str, 'requireSync(e){', `requireSync(e){window.BX_EXPOSED.beforePageLoad("${page}");`, index);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
@ -16,13 +16,12 @@ import codeCreatePortal from "./patches/create-portal.js" with { type: "text" };
|
||||
import { GlobalPref, StorageKey } from "@/enums/pref-keys.js";
|
||||
import { getGlobalPref } from "@/utils/pref-utils.js";
|
||||
import { GamePassCloudGallery } from "@/enums/game-pass-gallery";
|
||||
import { t } from "@/utils/translation";
|
||||
import { BlockFeature, NativeMkbMode, TouchControllerMode, UiLayout, UiSection } from "@/enums/pref-values";
|
||||
import { PatcherUtils } from "./patcher-utils.js";
|
||||
|
||||
export type PatchName = keyof typeof PATCHES;
|
||||
export type PatchArray = PatchName[];
|
||||
export type PatchPage = 'home' | 'stream' | 'product-detail';
|
||||
export type PatchPage = 'home' | 'stream' | 'remote-play-stream' | 'product-detail';
|
||||
type PatchFunction = (str: string) => string | false;
|
||||
|
||||
const LOG_TAG = 'Patcher';
|
||||
@ -40,6 +39,7 @@ const PATCHES = {
|
||||
},
|
||||
|
||||
// Set disableTelemetry() to true
|
||||
/*
|
||||
disableTelemetry(str: string) {
|
||||
let text = '.disableTelemetry=function(){return!1}';
|
||||
if (!str.includes(text)) {
|
||||
@ -48,6 +48,7 @@ const PATCHES = {
|
||||
|
||||
return str.replace(text, '.disableTelemetry=function(){return!0}');
|
||||
},
|
||||
*/
|
||||
|
||||
disableTelemetryProvider(str: string) {
|
||||
let text = 'this.enableLightweightTelemetry=!';
|
||||
@ -92,14 +93,14 @@ const PATCHES = {
|
||||
return str.replace(text, `?"${layout}":"${layout}"`);
|
||||
},
|
||||
|
||||
// Replace "/direct-connect" with "/play"
|
||||
remotePlayDirectConnectUrl(str: string) {
|
||||
const index = str.indexOf('/direct-connect');
|
||||
if (index < 0) {
|
||||
remotePlayPostStreamRedirectUrl(str: string) {
|
||||
let text = '.RemotePlayRoot.getLink()):';
|
||||
if (!str.includes(text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return str.replace(str.substring(index - 9, index + 15), 'https://www.xbox.com/play');
|
||||
str = str.replace(text, '.Home.getLink()):');
|
||||
return str;
|
||||
},
|
||||
|
||||
remotePlayKeepAlive(str: string) {
|
||||
@ -113,18 +114,6 @@ const PATCHES = {
|
||||
return str;
|
||||
},
|
||||
|
||||
// Enable Remote Play feature
|
||||
remotePlayConnectMode(str: string) {
|
||||
let text = 'connectMode:"cloud-connect",';
|
||||
if (!str.includes(text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const newCode = `connectMode: window.BX_REMOTE_PLAY_CONFIG ? "xhome-connect" : "cloud-connect",
|
||||
remotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFIG.serverId) || '',`;
|
||||
return str.replace(text, newCode);
|
||||
},
|
||||
|
||||
// Remote Play: Disable achievement toast
|
||||
remotePlayDisableAchievementToast(str: string) {
|
||||
let text = '.AchievementUnlock:{';
|
||||
@ -132,33 +121,10 @@ remotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFI
|
||||
return false;
|
||||
}
|
||||
|
||||
const newCode = `if (!!window.BX_REMOTE_PLAY_CONFIG) return;`;
|
||||
const newCode = `if (window.location.pathname.includes('/play/consoles/launch/')) return;`;
|
||||
return str.replace(text, text + newCode);
|
||||
},
|
||||
|
||||
// Remote Play: Prevent adding "Fortnite" to the "Jump back in" list
|
||||
remotePlayRecentlyUsedTitleIds(str: string) {
|
||||
let text = '(e.data.recentlyUsedTitleIds)){';
|
||||
if (!str.includes(text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const newCode = `if (window.BX_REMOTE_PLAY_CONFIG) return;`;
|
||||
return str.replace(text, text + newCode);
|
||||
},
|
||||
|
||||
// Remote Play: change web page's title
|
||||
remotePlayWebTitle(str: string) {
|
||||
let text = 'titleTemplate:void 0,title:';
|
||||
const index = str.indexOf(text);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
str = PatcherUtils.insertAt(str, index + text.length, `!!window.BX_REMOTE_PLAY_CONFIG ? "${t('remote-play')} - Better xCloud" :`);
|
||||
return str;
|
||||
},
|
||||
|
||||
// Block WebRTC stats collector
|
||||
blockWebRtcStatsCollector(str: string) {
|
||||
let text = 'this.shouldCollectStats=!0';
|
||||
@ -226,8 +192,11 @@ remotePlayServerId: (window.BX_REMOTE_PLAY_CONFIG && window.BX_REMOTE_PLAY_CONFI
|
||||
},
|
||||
|
||||
enableXcloudLogger(str: string) {
|
||||
let text = 'this.telemetryProvider=e}log(e,t,r){';
|
||||
if (!str.includes(text)) {
|
||||
let index = str.indexOf('this.telemetryProvider.trackErrorLike');
|
||||
index > -1 && (index = PatcherUtils.lastIndexOf(str, '}log(', index, 1500));
|
||||
index > -1 && (index = PatcherUtils.indexOf(str, '{', index, 30, true));
|
||||
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -237,7 +206,7 @@ const logFunc = [console.debug, console.log, console.warn, console.error][logLev
|
||||
logFunc(logTag, '//', logMessage);
|
||||
`;
|
||||
|
||||
str = str.replaceAll(text, text + newCode);
|
||||
str = PatcherUtils.insertAt(str, index, newCode);
|
||||
return str;
|
||||
},
|
||||
|
||||
@ -922,7 +891,7 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
||||
|
||||
// Disable long touch activating context menu
|
||||
disableTouchContextMenu(str: string) {
|
||||
let index = str.indexOf('"ContextualCardActions-module__container');
|
||||
let index = str.indexOf('arguments.length>2&&void 0!==arguments[2]?arguments[2]:500;');
|
||||
index >= 0 && (index = str.indexOf('addEventListener("touchstart"', index));
|
||||
index >= 0 && (index = PatcherUtils.lastIndexOf(str, 'return ', index, 50));
|
||||
if (index < 0) {
|
||||
@ -933,20 +902,6 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
||||
return str;
|
||||
},
|
||||
|
||||
// Optimize Game slug generator by using cached RegEx
|
||||
optimizeGameSlugGenerator(str: string) {
|
||||
let text = '/[;,/?:@&=+_`~$%#^*()!^\\u2122\\xae\\xa9]/g';
|
||||
if (!str.includes(text)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
str = str.replace(text, 'window.BX_EXPOSED.GameSlugRegexes[0]');
|
||||
str = str.replace('/ {2,}/g', 'window.BX_EXPOSED.GameSlugRegexes[1]');
|
||||
str = str.replace('/ /g', 'window.BX_EXPOSED.GameSlugRegexes[2]');
|
||||
|
||||
return str;
|
||||
},
|
||||
|
||||
modifyPreloadedState(str: string) {
|
||||
let text = '=window.__PRELOADED_STATE__;';
|
||||
if (!str.includes(text)) {
|
||||
@ -969,6 +924,10 @@ if (this.baseStorageKey in window.BX_EXPOSED.overrideSettings) {
|
||||
return PatcherUtils.patchBeforePageLoad(str, 'stream');
|
||||
},
|
||||
|
||||
remotePlayStreamPageBeforeLoad(str: string) {
|
||||
return PatcherUtils.patchBeforePageLoad(str, 'remote-play-stream');
|
||||
},
|
||||
|
||||
disableAbsoluteMouse(str: string) {
|
||||
let text = 'sendAbsoluteMouseCapableMessage(e){';
|
||||
if (!str.includes(text)) {
|
||||
@ -1132,7 +1091,7 @@ ${subsVar} = subs;
|
||||
},
|
||||
|
||||
injectHeaderUseEffect(str: string) {
|
||||
let index = str.indexOf('"EdgewaterHeader-module__spaceBetween');
|
||||
let index = str.indexOf('className:"Header-module__header');
|
||||
index > -1 && (index = PatcherUtils.lastIndexOf(str, 'return', index, 300));
|
||||
if (index < 0) {
|
||||
return false;
|
||||
@ -1202,6 +1161,36 @@ ${subsVar} = subs;
|
||||
return PatcherUtils.injectUseEffect(str, index, 'Script', 'ui.guideAchievementDetail.rendered');
|
||||
},
|
||||
|
||||
patchCustomInputIcon(str: string) {
|
||||
let index = str.indexOf('.MouseAndKeyboard="MouseAndKeyboard"');
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get productId
|
||||
const productIdMatch = /const (\w+)=(\w+)=>{/.exec(str.substring(index, index + 200));
|
||||
if (!productIdMatch) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Define productId variable
|
||||
str = str.replace(productIdMatch[0], productIdMatch[0] + `const productId = ${productIdMatch[2]};`);
|
||||
|
||||
let match = /(\w+)&&(\w+\.push\(\w+\.Touch\))/.exec(str);
|
||||
if (!match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
str = str.replace(match[0], `(${match[1]} || window.BX_EXPOSED.hasCustomTouchControl(productId)) && ${match[2]}`);
|
||||
|
||||
match = /(\w+)&&(\w+\.push\(\w+\.MouseAndKeyboard\))/.exec(str);
|
||||
if (match) {
|
||||
str = str.replace(match[0], `(${match[1]} || window.BX_EXPOSED.hasCustomNativeMkb(productId)) && ${match[2]}`);
|
||||
}
|
||||
|
||||
return str;
|
||||
},
|
||||
|
||||
/*
|
||||
patchBasicGameInfo(str: string) {
|
||||
let index = str.indexOf('.ChildXboxTitleIds,offerings');
|
||||
@ -1243,8 +1232,6 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||
|
||||
'patchGamepadPolling',
|
||||
|
||||
'optimizeGameSlugGenerator',
|
||||
|
||||
'modifyPreloadedState',
|
||||
|
||||
'detectBrowserRouterReady',
|
||||
@ -1265,6 +1252,7 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||
'injectErrorPageUseEffect',
|
||||
|
||||
'streamPageBeforeLoad',
|
||||
'remotePlayStreamPageBeforeLoad',
|
||||
|
||||
'injectGuideHomeUseEffect',
|
||||
'injectAchievementsProgressUseEffect',
|
||||
@ -1275,6 +1263,8 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||
|
||||
'homePageBeforeLoad',
|
||||
|
||||
'patchCustomInputIcon',
|
||||
|
||||
'gameCardCustomIcons',
|
||||
// 'gameCardPassTitle',
|
||||
|
||||
@ -1293,7 +1283,7 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||
|
||||
...(getGlobalPref(GlobalPref.BLOCK_TRACKING) ? [
|
||||
'disableAiTrack',
|
||||
'disableTelemetry',
|
||||
// 'disableTelemetry',
|
||||
|
||||
'blockWebRtcStatsCollector',
|
||||
'disableIndexDbLogging',
|
||||
@ -1301,12 +1291,9 @@ let PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||
'disableTelemetryProvider',
|
||||
] : []) as PatchArray,
|
||||
|
||||
...(getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED) ? [
|
||||
'remotePlayDirectConnectUrl',
|
||||
...(!getGlobalPref(GlobalPref.BLOCK_FEATURES).includes(BlockFeature.REMOTE_PLAY) ? [
|
||||
'remotePlayKeepAlive',
|
||||
'remotePlayWebTitle',
|
||||
'remotePlayDisableAchievementToast',
|
||||
'remotePlayRecentlyUsedTitleIds',
|
||||
STATES.userAgent.capabilities.touch && 'patchUpdateInputConfigurationAsync',
|
||||
] : []) as PatchArray,
|
||||
|
||||
@ -1367,15 +1354,13 @@ let STREAM_PAGE_PATCH_ORDERS = PatcherUtils.filterPatches([
|
||||
(getGlobalPref(GlobalPref.TOUCH_CONTROLLER_MODE) !== TouchControllerMode.OFF && (getGlobalPref(GlobalPref.MKB_ENABLED) || getGlobalPref(GlobalPref.NATIVE_MKB_MODE) === NativeMkbMode.ON)) && 'patchBabylonRendererClass',
|
||||
] : []) as PatchArray,
|
||||
|
||||
BX_FLAGS.EnableXcloudLogging && 'enableConsoleLogging',
|
||||
|
||||
'patchPollGamepads',
|
||||
|
||||
getGlobalPref(GlobalPref.STREAM_COMBINE_SOURCES) && 'streamCombineSources',
|
||||
|
||||
...(getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED) ? [
|
||||
...(!getGlobalPref(GlobalPref.BLOCK_FEATURES).includes(BlockFeature.REMOTE_PLAY) ? [
|
||||
'remotePlayPostStreamRedirectUrl',
|
||||
'patchRemotePlayMkb',
|
||||
'remotePlayConnectMode',
|
||||
] : []) as PatchArray,
|
||||
|
||||
// Native MKB
|
||||
@ -1395,6 +1380,7 @@ export class Patcher {
|
||||
private static remainingPatches: { [key in PatchPage]: PatchArray } = {
|
||||
home: HOME_PAGE_PATCH_ORDERS,
|
||||
stream: STREAM_PAGE_PATCH_ORDERS,
|
||||
'remote-play-stream': STREAM_PAGE_PATCH_ORDERS,
|
||||
'product-detail': PRODUCT_DETAIL_PAGE_PATCH_ORDERS,
|
||||
};
|
||||
|
||||
@ -1558,7 +1544,9 @@ export class PatcherCache {
|
||||
BxLogger.info(LOG_TAG, 'Cache', this.CACHE);
|
||||
|
||||
const pathName = window.location.pathname;
|
||||
if (pathName.includes('/play/launch/')) {
|
||||
if (pathName.includes('/play/consoles/launch/')) {
|
||||
Patcher.patchPage('remote-play-stream');
|
||||
} else if (pathName.includes('/play/launch/')) {
|
||||
Patcher.patchPage('stream');
|
||||
} else if (pathName.includes('/play/games/')) {
|
||||
Patcher.patchPage('product-detail');
|
||||
@ -1583,11 +1571,13 @@ export class PatcherCache {
|
||||
|
||||
// Get client.js's hash
|
||||
let webVersion = '';
|
||||
const $link = document.querySelector<HTMLLinkElement>('link[data-chunk="client"][href*="/client."]');
|
||||
const $link = document.querySelector<HTMLLinkElement>('link[data-chunk="client"][as="script"][href*="/client."]');
|
||||
if ($link) {
|
||||
const match = /\/client\.([^\.]+)\.js/.exec($link.href);
|
||||
match && (webVersion = match[1]);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (!webVersion) {
|
||||
// Get version from <meta>
|
||||
// Sometimes this value is missing
|
||||
webVersion = (document.querySelector<HTMLMetaElement>('meta[name=gamepass-app-version]'))?.content ?? '';
|
||||
|
@ -3,7 +3,7 @@ declare const e: string;
|
||||
|
||||
try {
|
||||
const msg = JSON.parse(e);
|
||||
if (msg.reason === 'WarningForBeingIdle' && !window.location.pathname.includes('/launch/')) {
|
||||
if (msg.reason === 'WarningForBeingIdle' && window.location.pathname.includes('/play/consoles/launch/')) {
|
||||
$this$.sendKeepAlive();
|
||||
// @ts-ignore
|
||||
return;
|
||||
|
@ -8,6 +8,7 @@ import { HeaderSection } from "./ui/header";
|
||||
import { GlobalPref } from "@/enums/pref-keys";
|
||||
import { getGlobalPref, setGlobalPref } from "@/utils/pref-utils";
|
||||
import { RemotePlayDialog } from "./ui/dialog/remote-play-dialog";
|
||||
import { BlockFeature } from "@/enums/pref-values";
|
||||
|
||||
export const enum RemotePlayConsoleState {
|
||||
ON = 'On',
|
||||
@ -37,7 +38,7 @@ export class RemotePlayManager {
|
||||
private static instance: RemotePlayManager | null | undefined;
|
||||
public static getInstance(): typeof RemotePlayManager['instance'] {
|
||||
if (typeof RemotePlayManager.instance === 'undefined') {
|
||||
if (getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED)) {
|
||||
if (!getGlobalPref(GlobalPref.BLOCK_FEATURES).includes(BlockFeature.REMOTE_PLAY)) {
|
||||
RemotePlayManager.instance = new RemotePlayManager();
|
||||
} else {
|
||||
RemotePlayManager.instance = null;
|
||||
@ -156,6 +157,11 @@ export class RemotePlayManager {
|
||||
},
|
||||
};
|
||||
|
||||
// Start with "isDefault" = true first
|
||||
this.regions.sort((a: RemotePlayRegion, b: RemotePlayRegion) => {
|
||||
return a.isDefault ? -1 : 0;
|
||||
})
|
||||
|
||||
// Test servers one by one
|
||||
for (const region of this.regions) {
|
||||
try {
|
||||
@ -189,12 +195,7 @@ export class RemotePlayManager {
|
||||
setGlobalPref(GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION, resolution, 'ui');
|
||||
}
|
||||
|
||||
STATES.remotePlay.config = {
|
||||
serverId: serverId,
|
||||
};
|
||||
window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config;
|
||||
|
||||
localRedirect('/launch/fortnite/BT5P2X999VH2#remote-play');
|
||||
localRedirect('/consoles/launch/' + serverId);
|
||||
}
|
||||
|
||||
togglePopup(force = null) {
|
||||
@ -220,21 +221,6 @@ export class RemotePlayManager {
|
||||
RemotePlayDialog.getInstance().show();
|
||||
}
|
||||
|
||||
static detect() {
|
||||
if (!getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED)) {
|
||||
return;
|
||||
}
|
||||
|
||||
STATES.remotePlay.isPlaying = window.location.pathname.includes('/launch/') && window.location.hash.startsWith('#remote-play');
|
||||
if (STATES.remotePlay?.isPlaying) {
|
||||
window.BX_REMOTE_PLAY_CONFIG = STATES.remotePlay.config;
|
||||
// Remove /launch/... from URL
|
||||
window.history.replaceState({origin: 'better-xcloud'}, '', 'https://www.xbox.com/' + location.pathname.substring(1, 6) + '/play');
|
||||
} else {
|
||||
window.BX_REMOTE_PLAY_CONFIG = null;
|
||||
}
|
||||
}
|
||||
|
||||
isReady() {
|
||||
return this.consoles !== null;
|
||||
}
|
||||
|
@ -209,7 +209,7 @@ export class TouchController {
|
||||
}
|
||||
|
||||
if (!layoutId) {
|
||||
BxLogger.error(LOG_TAG, 'Invalid layoutId, show default controller');
|
||||
BxLogger.warning(LOG_TAG, 'Invalid layoutId, show default controller');
|
||||
TouchController.#enabled && TouchController.#showDefault();
|
||||
return;
|
||||
}
|
||||
@ -267,6 +267,10 @@ export class TouchController {
|
||||
return TouchController.#customList;
|
||||
}
|
||||
|
||||
static hasCustomControl(productId: string): boolean {
|
||||
return TouchController.#customList?.includes(productId);
|
||||
}
|
||||
|
||||
static setup() {
|
||||
// Function for testing touch control
|
||||
window.testTouchLayout = (layout: any) => {
|
||||
|
@ -44,14 +44,14 @@ export class RemotePlayDialog extends NavigationDialog {
|
||||
let $resolutions : HTMLSelectElement | NavigationElement = CE('select', false,
|
||||
CE('option', { value: StreamResolution.DIM_720P }, '720p'),
|
||||
CE('option', { value: StreamResolution.DIM_1080P }, '1080p'),
|
||||
// CE('option', { value: StreamResolution.DIM_1080P_HQ }, `1080p (HQ)`),
|
||||
CE('option', { value: StreamResolution.DIM_1080P_HQ }, `1080p (HQ)`),
|
||||
);
|
||||
|
||||
$resolutions = BxSelectElement.create($resolutions as HTMLSelectElement);
|
||||
$resolutions.addEventListener('input', (e: Event) => {
|
||||
const value = (e.target as HTMLSelectElement).value;
|
||||
|
||||
$settingNote.textContent = value === '1080p' ? '✅ ' + t('can-stream-xbox-360-games') : '❌ ' + t('cant-stream-xbox-360-games');
|
||||
$settingNote.textContent = `✅ ${t('xbox-360-games')} ${value === StreamResolution.DIM_1080P_HQ ? '❌' : '✅'} ${t('xbox-apps')}`;
|
||||
setGlobalPref(GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION, value, 'ui');
|
||||
});
|
||||
|
||||
|
@ -191,7 +191,6 @@ export class SettingsDialog extends NavigationDialog {
|
||||
},
|
||||
GlobalPref.SERVER_BYPASS_RESTRICTION,
|
||||
GlobalPref.UI_CONTROLLER_FRIENDLY,
|
||||
GlobalPref.REMOTE_PLAY_ENABLED,
|
||||
],
|
||||
}, {
|
||||
group: 'server',
|
||||
|
@ -11,6 +11,7 @@ import { GlobalPref } from "@/enums/pref-keys";
|
||||
import { getGlobalPref } from "@/utils/pref-utils";
|
||||
import { BxLogger } from "@/utils/bx-logger";
|
||||
import { BxEventBus } from "@/utils/bx-event-bus";
|
||||
import { BlockFeature } from "@/enums/pref-values";
|
||||
|
||||
export class HeaderSection {
|
||||
private static instance: HeaderSection;
|
||||
@ -44,7 +45,7 @@ export class HeaderSection {
|
||||
});
|
||||
|
||||
this.$buttonsWrapper = CE('div', false,
|
||||
getGlobalPref(GlobalPref.REMOTE_PLAY_ENABLED) ? this.$btnRemotePlay : null,
|
||||
!getGlobalPref(GlobalPref.BLOCK_FEATURES).includes(BlockFeature.REMOTE_PLAY) ? this.$btnRemotePlay : null,
|
||||
this.$btnSettings,
|
||||
);
|
||||
|
||||
@ -74,7 +75,12 @@ export class HeaderSection {
|
||||
}
|
||||
|
||||
checkHeader = () => {
|
||||
let $target = document.querySelector('#PageContent div[class*=EdgewaterHeader-module__rightSectionSpacing]');
|
||||
const $header = document.querySelector('#gamepass-root header[class^=Header-module__header]');
|
||||
if (!$header) {
|
||||
return;
|
||||
}
|
||||
|
||||
let $target = $header.querySelector('div[class*=EdgewaterHeader-module__rightSectionSpacing], div[class*=RemotePlayHeader-module__rightSectionSpacing]');
|
||||
if (!$target) {
|
||||
$target = document.querySelector('div[class^=UnsupportedMarketPage-module__buttons]');
|
||||
}
|
||||
|
1
src/types/global.d.ts
vendored
1
src/types/global.d.ts
vendored
@ -26,7 +26,6 @@ declare global {
|
||||
touchLayoutManager: any;
|
||||
}>;
|
||||
|
||||
BX_REMOTE_PLAY_CONFIG: BxStates.remotePlay.config;
|
||||
BX_STREAM_SETTINGS: StreamSettingsData;
|
||||
|
||||
BX_FETCH: typeof window['fetch'];
|
||||
|
2
src/types/index.d.ts
vendored
2
src/types/index.d.ts
vendored
@ -135,7 +135,7 @@ type XboxAchievement = {
|
||||
}
|
||||
};
|
||||
|
||||
type OsName = 'windows' | 'tizen' | 'android';
|
||||
type OsName = 'windows' | 'tizen' | 'webOS' | 'xboxOS' | 'android';
|
||||
|
||||
type XcloudGamepad = {
|
||||
GamepadIndex: number;
|
||||
|
4
src/types/states.d.ts
vendored
4
src/types/states.d.ts
vendored
@ -41,11 +41,7 @@ type BxStates = {
|
||||
}>;
|
||||
|
||||
remotePlay: Partial<{
|
||||
isPlaying: boolean;
|
||||
server: string;
|
||||
config: {
|
||||
serverId: string;
|
||||
};
|
||||
titleId?: string;
|
||||
}>;
|
||||
|
||||
|
@ -261,4 +261,9 @@ export const BxExposed = {
|
||||
),
|
||||
);
|
||||
} : () => {},
|
||||
|
||||
hasCustomTouchControl: TouchController.hasCustomControl,
|
||||
hasCustomNativeMkb: (productId: string) => {
|
||||
return BX_FLAGS.ForceNativeMkbTitles?.includes(productId);
|
||||
}
|
||||
};
|
||||
|
@ -10,6 +10,8 @@ export let FeatureGates: { [key: string]: boolean } = {
|
||||
ShowForcedUpdateScreen: false,
|
||||
EnableTakControlResizing: true, // Experimenting
|
||||
EnableLazyLoadedHome: false,
|
||||
EnableRemotePlay: !getGlobalPref(GlobalPref.BLOCK_FEATURES).includes(BlockFeature.REMOTE_PLAY),
|
||||
EnableConsoles: !getGlobalPref(GlobalPref.BLOCK_FEATURES).includes(BlockFeature.REMOTE_PLAY),
|
||||
};
|
||||
|
||||
// Enable Native Mouse & Keyboard
|
||||
|
@ -1,8 +1,5 @@
|
||||
import { isFullVersion } from "@macros/build" with { type: "macro" };
|
||||
|
||||
import { BxEvent } from "@utils/bx-event";
|
||||
import { LoadingScreen } from "@modules/loading-screen";
|
||||
import { RemotePlayManager } from "@/modules/remote-play-manager";
|
||||
import { BxEventBus } from "./bx-event-bus";
|
||||
import { NavigationDialogManager } from "@/modules/ui/dialog/navigation-dialog";
|
||||
|
||||
@ -26,10 +23,6 @@ export function onHistoryChanged(e: PopStateEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isFullVersion()) {
|
||||
window.setTimeout(RemotePlayManager.detect, 10);
|
||||
}
|
||||
|
||||
// Hide Navigation dialog
|
||||
NavigationDialogManager.getInstance().hide();
|
||||
|
||||
|
@ -55,9 +55,9 @@ export function patchVideoApi() {
|
||||
return nativePlay.apply(this);
|
||||
}
|
||||
|
||||
const $parent = this.parentElement!!;
|
||||
const $parent = this.parentElement;
|
||||
// Video tag is stream player
|
||||
if (!this.src && $parent.dataset.testid === 'media-container') {
|
||||
if (!this.src && $parent?.dataset.testid === 'media-container') {
|
||||
this.addEventListener('loadedmetadata', showFunc, { once: true });
|
||||
}
|
||||
|
||||
|
@ -49,8 +49,11 @@ function updateIceCandidates(candidates: any, options: { preferIpv6Server: boole
|
||||
continue;
|
||||
}
|
||||
|
||||
const groups: { [index: string]: string | number } = pattern.exec(item.candidate)!.groups!;
|
||||
lst.push(groups);
|
||||
const match = pattern.exec(item.candidate);
|
||||
if (match && match.groups) {
|
||||
const groups: { [index: string]: string | number } = match.groups;
|
||||
lst.push(groups);
|
||||
}
|
||||
}
|
||||
|
||||
if (options.preferIpv6Server) {
|
||||
@ -294,7 +297,7 @@ export function interceptHttpRequests() {
|
||||
}
|
||||
|
||||
let requestType: RequestType;
|
||||
if (url.includes('/sessions/home') || url.includes('xhome.') || (STATES.remotePlay.isPlaying && url.endsWith('/inputconfigs'))) {
|
||||
if (url.includes('/sessions/home') || url.includes('xhome.') || (window.location.pathname.includes('/play/consoles/launch/') && url.endsWith('/inputconfigs'))) {
|
||||
requestType = 'xhome';
|
||||
} else {
|
||||
requestType = 'xcloud';
|
||||
|
@ -11,7 +11,6 @@ import { BaseSettingsStorage } from "./base-settings-storage";
|
||||
import { CodecProfile, StreamResolution, TouchControllerMode, TouchControllerStyleStandard, TouchControllerStyleCustom, GameBarPosition, NativeMkbMode, UiLayout, UiSection, BlockFeature, UiTheme } from "@/enums/pref-values";
|
||||
import { GhPagesUtils } from "../gh-pages";
|
||||
import { BxEventBus } from "../bx-event-bus";
|
||||
import { BxIcon } from "../bx-icon";
|
||||
|
||||
|
||||
function getSupportedCodecProfiles() {
|
||||
@ -497,6 +496,7 @@ export class GlobalSettingsStorage extends BaseSettingsStorage<GlobalPref> {
|
||||
[BlockFeature.BYOG]: t('stream-your-own-game'),
|
||||
[BlockFeature.NOTIFICATIONS_INVITES]: t('notifications') + ': ' + t('invites'),
|
||||
[BlockFeature.NOTIFICATIONS_ACHIEVEMENTS]: t('notifications') + ': ' + t('achievements'),
|
||||
[BlockFeature.REMOTE_PLAY]: t('remote-play'),
|
||||
},
|
||||
},
|
||||
|
||||
@ -525,13 +525,6 @@ export class GlobalSettingsStorage extends BaseSettingsStorage<GlobalPref> {
|
||||
default: false,
|
||||
},
|
||||
|
||||
[GlobalPref.REMOTE_PLAY_ENABLED]: {
|
||||
requiredVariants: 'full',
|
||||
label: t('enable-remote-play-feature'),
|
||||
labelIcon: BxIcon.REMOTE_PLAY,
|
||||
default: false,
|
||||
},
|
||||
|
||||
[GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION]: {
|
||||
requiredVariants: 'full',
|
||||
default: StreamResolution.DIM_1080P,
|
||||
|
@ -228,10 +228,13 @@ export class StreamSettingsStorage extends BaseSettingsStorage<StreamPref> {
|
||||
default: VideoRatio['16:9'],
|
||||
options: {
|
||||
[VideoRatio['16:9']]: `16:9 (${t('default')})`,
|
||||
[VideoRatio['18:9']]: '18:9',
|
||||
[VideoRatio['21:9']]: '21:9',
|
||||
[VideoRatio['16:10']]: '16:10',
|
||||
[VideoRatio['18:9']]: '18:9',
|
||||
[VideoRatio['20:9']]: '20:9',
|
||||
[VideoRatio['21:9']]: '21:9',
|
||||
[VideoRatio['3:2']]: '3:2',
|
||||
[VideoRatio['4:3']]: '4:3',
|
||||
[VideoRatio['5:4']]: '5:4',
|
||||
|
||||
[VideoRatio.FILL]: t('stretch'),
|
||||
//'cover': 'Cover',
|
||||
|
@ -7,6 +7,7 @@ export const SUPPORTED_LANGUAGES = {
|
||||
'en-US': 'English (US)',
|
||||
|
||||
'ca-CA': 'Català',
|
||||
'cs-CZ': 'čeština',
|
||||
'da-DK': 'dansk',
|
||||
'de-DE': 'Deutsch',
|
||||
'en-ID': 'Bahasa Indonesia',
|
||||
@ -60,9 +61,7 @@ const Texts = {
|
||||
"browser-unsupported-feature": "Your browser doesn't support this feature",
|
||||
"button-xbox": "Xbox button",
|
||||
"bypass-region-restriction": "Bypass region restriction",
|
||||
"can-stream-xbox-360-games": "Can stream Xbox 360 games",
|
||||
"cancel": "Cancel",
|
||||
"cant-stream-xbox-360-games": "Can't stream Xbox 360 games",
|
||||
"center": "Center",
|
||||
"chat": "Chat",
|
||||
"clarity-boost": "Clarity boost",
|
||||
@ -198,6 +197,7 @@ const Texts = {
|
||||
"new-version-available": [
|
||||
(e: any) => `Version ${e.version} available`,
|
||||
(e: any) => `Versió ${e.version} disponible`,
|
||||
(e: any) => `Verze ${e.version} dostupná`,
|
||||
,
|
||||
(e: any) => `Version ${e.version} verfügbar`,
|
||||
(e: any) => `Versi ${e.version} tersedia`,
|
||||
@ -243,6 +243,7 @@ const Texts = {
|
||||
"press-key-to-toggle-mkb": [
|
||||
(e: any) => `Press ${e.key} to toggle this feature`,
|
||||
(e: any) => `Premeu ${e.key} per alternar aquesta funció`,
|
||||
(e: any) => `Zmáčknete ${e.key} pro přepnutí této funkce`,
|
||||
(e: any) => `Tryk på ${e.key} for at slå denne funktion til`,
|
||||
(e: any) => `${e.key}: Funktion an-/ausschalten`,
|
||||
(e: any) => `Tekan ${e.key} untuk mengaktifkan fitur ini`,
|
||||
@ -268,6 +269,7 @@ const Texts = {
|
||||
(e: any) => `Recommended settings for ${e.device}`,
|
||||
(e: any) => `Configuració recomanada per a ${e.device}`,
|
||||
,
|
||||
,
|
||||
(e: any) => `Empfohlene Einstellungen für ${e.device}`,
|
||||
(e: any) => `Rekomendasi pengaturan untuk ${e.device}`,
|
||||
(e: any) => `Ajustes recomendados para ${e.device}`,
|
||||
@ -378,6 +380,7 @@ const Texts = {
|
||||
"touch-control-layout-by": [
|
||||
(e: any) => `Touch control layout by ${e.name}`,
|
||||
(e: any) => `Format del control tàctil per ${e.name}`,
|
||||
(e: any) => `Rozložení dotykového ovládání ${e.name}`,
|
||||
(e: any) => `Touch-kontrol layout af ${e.name}`,
|
||||
(e: any) => `Touch-Steuerungslayout von ${e.name}`,
|
||||
(e: any) => `Tata letak Sentuhan layar oleh ${e.name}`,
|
||||
@ -430,6 +433,8 @@ const Texts = {
|
||||
"wallpaper": "Wallpaper",
|
||||
"webgl2": "WebGL2",
|
||||
"webgpu": "WebGPU",
|
||||
"xbox-360-games": "Xbox 360 games",
|
||||
"xbox-apps": "Xbox apps",
|
||||
};
|
||||
|
||||
export class Translations {
|
||||
|
@ -16,6 +16,15 @@ export function checkForUpdate() {
|
||||
return;
|
||||
}
|
||||
|
||||
// Always check for new version
|
||||
fetch('https://api.github.com/repos/redphx/better-xcloud/releases/latest')
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
// Store the latest version
|
||||
setGlobalPref(GlobalPref.VERSION_LATEST, json.tag_name.substring(1), 'direct');
|
||||
setGlobalPref(GlobalPref.VERSION_CURRENT, SCRIPT_VERSION, 'direct');
|
||||
});
|
||||
|
||||
const CHECK_INTERVAL_SECONDS = 2 * 3600; // check every 2 hours
|
||||
|
||||
const currentVersion = getGlobalPref(GlobalPref.VERSION_CURRENT);
|
||||
@ -28,13 +37,6 @@ export function checkForUpdate() {
|
||||
|
||||
// Start checking
|
||||
setGlobalPref(GlobalPref.VERSION_LAST_CHECK, now, 'direct');
|
||||
fetch('https://api.github.com/repos/redphx/better-xcloud/releases/latest')
|
||||
.then(response => response.json())
|
||||
.then(json => {
|
||||
// Store the latest version
|
||||
setGlobalPref(GlobalPref.VERSION_LATEST, json.tag_name.substring(1), 'direct');
|
||||
setGlobalPref(GlobalPref.VERSION_CURRENT, SCRIPT_VERSION, 'direct');
|
||||
});
|
||||
|
||||
// Update translations
|
||||
Translations.updateTranslations(currentVersion === SCRIPT_VERSION);
|
||||
|
@ -95,7 +95,7 @@ export class XhomeInterceptor {
|
||||
});
|
||||
} else {
|
||||
TouchController.enable();
|
||||
TouchController.requestCustomLayouts(xboxTitleId);
|
||||
TouchController.requestCustomLayouts();
|
||||
}
|
||||
|
||||
response.json = () => Promise.resolve(obj);
|
||||
|
Reference in New Issue
Block a user