mirror of
https://github.com/redphx/better-xcloud.git
synced 2025-07-06 14:21:43 +02:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
153b9e0cfe | |||
88151c9426 | |||
f7048a38b3 | |||
c76a3cc7a4 | |||
80f47a93d4 | |||
67fdf5ea12 | |||
4da2cfaf49 | |||
e1d053a634 |
50
bun.lock
50
bun.lock
@ -3,16 +3,16 @@
|
|||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.2.10",
|
"@types/bun": "latest",
|
||||||
"@types/node": "^22.14.1",
|
"@types/node": "latest",
|
||||||
"@types/stylus": "^0.48.43",
|
"@types/stylus": "latest",
|
||||||
"@webgpu/types": "^0.1.60",
|
"@webgpu/types": "latest",
|
||||||
"eslint": "^9.25.0",
|
"eslint": "latest",
|
||||||
"eslint-plugin-compat": "^6.0.2",
|
"eslint-plugin-compat": "latest",
|
||||||
"stylus": "^0.64.0",
|
"stylus": "latest",
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5.7.2",
|
"typescript": "latest",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.1", "", {}, "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ=="],
|
||||||
|
|
||||||
"@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/config-array": ["@eslint/config-array@0.20.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw=="],
|
||||||
|
|
||||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.2.1", "", {}, "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw=="],
|
"@eslint/config-helpers": ["@eslint/config-helpers@0.2.1", "", {}, "sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw=="],
|
||||||
|
|
||||||
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
"@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/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/js": ["@eslint/js@9.27.0", "", {}, "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA=="],
|
"@eslint/js": ["@eslint/js@9.29.0", "", {}, "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ=="],
|
||||||
|
|
||||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
"@eslint/object-schema": ["@eslint/object-schema@2.1.6", "", {}, "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA=="],
|
||||||
|
|
||||||
@ -51,19 +51,19 @@
|
|||||||
|
|
||||||
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.2.15", "", { "dependencies": { "bun-types": "1.2.15" } }, "sha512-U1ljPdBEphF0nw1MIk0hI7kPg7dFdPyM7EenHsp6W5loNHl7zqy6JQf/RKCgnUn2KDzUpkBwHPnEJEjII594bA=="],
|
"@types/bun": ["@types/bun@1.2.17", "", { "dependencies": { "bun-types": "1.2.17" } }, "sha512-l/BYs/JYt+cXA/0+wUhulYJB6a6p//GTPiJ7nV+QHa8iiId4HZmnu/3J/SowP5g0rTiERY2kfGKXEK5Ehltx4Q=="],
|
||||||
|
|
||||||
"@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="],
|
"@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/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@22.15.24", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-w9CZGm9RDjzTh/D+hFwlBJ3ziUaVw7oufKA3vOFSOZlzmW9AkZnfjPb+DLnrV6qtgL/LNmP0/2zBNCFHL3F0ng=="],
|
"@types/node": ["@types/node@24.0.3", "", { "dependencies": { "undici-types": "~7.8.0" } }, "sha512-R4I/kzCYAdRLzfiCabn9hxWfbuHS573x+r0dJMkkzThEa7pbrcDWK+9zu3e7aBOouf+rQAciqPFMnxwr0aWgKg=="],
|
||||||
|
|
||||||
"@types/stylus": ["@types/stylus@0.48.43", "", { "dependencies": { "@types/node": "*" } }, "sha512-72dv/zdhuyXWVHUXG2VTPEQdOG+oen95/DNFx2aMFFaY6LoITI6PwEqf5x31JF49kp2w9hvUzkNfTGBIeg61LQ=="],
|
"@types/stylus": ["@types/stylus@0.48.43", "", { "dependencies": { "@types/node": "*" } }, "sha512-72dv/zdhuyXWVHUXG2VTPEQdOG+oen95/DNFx2aMFFaY6LoITI6PwEqf5x31JF49kp2w9hvUzkNfTGBIeg61LQ=="],
|
||||||
|
|
||||||
"@webgpu/types": ["@webgpu/types@0.1.61", "", {}, "sha512-w2HbBvH+qO19SB5pJOJFKs533CdZqxl3fcGonqL321VHkW7W/iBo6H8bjDy6pr/+pbMwIu5dnuaAxH7NxBqUrQ=="],
|
"@webgpu/types": ["@webgpu/types@0.1.61", "", {}, "sha512-w2HbBvH+qO19SB5pJOJFKs533CdZqxl3fcGonqL321VHkW7W/iBo6H8bjDy6pr/+pbMwIu5dnuaAxH7NxBqUrQ=="],
|
||||||
|
|
||||||
"acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
|
"acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||||
|
|
||||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||||
|
|
||||||
@ -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=="],
|
"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.15", "", { "dependencies": { "@types/node": "*" } }, "sha512-NarRIaS+iOaQU1JPfyKhZm4AsUOrwUOqRNHY0XxI8GI8jYxiLXLcdjYMG9UKS+fwWasc1uw1htV9AX24dD+p4w=="],
|
"bun-types": ["bun-types@1.2.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-ElC7ItwT3SCQwYZDYoAH+q6KT4Fxjl8DtZ6qDulUFBmXA8YB4xo+l54J9ZJN+k2pphfn9vk7kfubeSd5QfTVJQ=="],
|
||||||
|
|
||||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||||
|
|
||||||
@ -113,15 +113,15 @@
|
|||||||
|
|
||||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||||
|
|
||||||
"eslint": ["eslint@9.27.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.14.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.27.0", "@eslint/plugin-kit": "^0.3.1", "@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-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q=="],
|
"eslint": ["eslint@9.29.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.20.1", "@eslint/config-helpers": "^0.2.1", "@eslint/core": "^0.14.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.29.0", "@eslint/plugin-kit": "^0.3.1", "@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.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.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-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ=="],
|
||||||
|
|
||||||
"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-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.3.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ=="],
|
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
||||||
|
|
||||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
|
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
|
||||||
|
|
||||||
"espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
|
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
||||||
|
|
||||||
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
||||||
|
|
||||||
@ -253,9 +253,9 @@
|
|||||||
|
|
||||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||||
|
|
||||||
"typescript": ["typescript@5.7.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg=="],
|
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||||
|
|
||||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
"undici-types": ["undici-types@7.8.0", "", {}, "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw=="],
|
||||||
|
|
||||||
"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=="],
|
"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=="],
|
||||||
|
|
||||||
@ -273,6 +273,8 @@
|
|||||||
|
|
||||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||||
|
|
||||||
|
"@eslint/eslintrc/espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
|
||||||
|
|
||||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||||
|
|
||||||
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
|
||||||
@ -281,6 +283,8 @@
|
|||||||
|
|
||||||
"ast-metadata-inferer/@mdn/browser-compat-data": ["@mdn/browser-compat-data@5.6.26", "", {}, "sha512-7NdgdOR7lkzrN70zGSULmrcvKyi/aJjpTJRCbuy8IZuHiLkPTvsr10jW0MJgWzK2l2wTmhdQvegTw6yNU5AVNQ=="],
|
"ast-metadata-inferer/@mdn/browser-compat-data": ["@mdn/browser-compat-data@5.6.26", "", {}, "sha512-7NdgdOR7lkzrN70zGSULmrcvKyi/aJjpTJRCbuy8IZuHiLkPTvsr10jW0MJgWzK2l2wTmhdQvegTw6yNU5AVNQ=="],
|
||||||
|
|
||||||
|
"bun-types/@types/node": ["@types/node@22.15.32", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-3jigKqgSjsH6gYZv2nEsqdXfZqIFGAV36XYYjf9KGZ3PSG+IhLecqPnI310RvjutyMwifE2hhhNEklOUrvx/wA=="],
|
||||||
|
|
||||||
"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=="],
|
"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=="],
|
||||||
|
|
||||||
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
"glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||||
@ -297,8 +301,14 @@
|
|||||||
|
|
||||||
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
||||||
|
|
||||||
|
"@eslint/eslintrc/espree/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
|
||||||
|
|
||||||
|
"@eslint/eslintrc/espree/eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
|
||||||
|
|
||||||
"@types/stylus/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
|
"@types/stylus/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
|
||||||
|
|
||||||
|
"bun-types/@types/node/undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||||
|
|
||||||
"glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
|
"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=="],
|
"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==
|
// ==UserScript==
|
||||||
// @name Better xCloud
|
// @name Better xCloud
|
||||||
// @namespace https://github.com/redphx
|
// @namespace https://github.com/redphx
|
||||||
// @version 6.6.2
|
// @version 6.7.0
|
||||||
// ==/UserScript==
|
// ==/UserScript==
|
||||||
|
428
dist/better-xcloud.pretty.user.js
vendored
428
dist/better-xcloud.pretty.user.js
vendored
File diff suppressed because one or more lines are too long
34
dist/better-xcloud.user.js
vendored
34
dist/better-xcloud.user.js
vendored
File diff suppressed because one or more lines are too long
@ -10,15 +10,15 @@
|
|||||||
"build": "build.ts"
|
"build": "build.ts"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.2.15",
|
"@types/bun": "^1.2.17",
|
||||||
"@types/node": "^22.15.24",
|
"@types/node": "^24.0.3",
|
||||||
"@types/stylus": "^0.48.43",
|
"@types/stylus": "^0.48.43",
|
||||||
"@webgpu/types": "^0.1.61",
|
"@webgpu/types": "^0.1.61",
|
||||||
"eslint": "^9.27.0",
|
"eslint": "^9.29.0",
|
||||||
"eslint-plugin-compat": "^6.0.2",
|
"eslint-plugin-compat": "^6.0.2",
|
||||||
"stylus": "^0.64.0"
|
"stylus": "^0.64.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,22 +2,29 @@
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
border-bottom: 1px solid #2d2d2d;
|
border-bottom: 1px solid #2d2d2d;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
min-height: 30px;
|
||||||
|
|
||||||
label {
|
> label {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
align-self: center;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 4px 0 0;
|
margin: 4px 0 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
color: #888;
|
color: #888;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-remote-play-resolution {
|
.bx-remote-play-resolution {
|
||||||
@ -36,16 +43,16 @@
|
|||||||
.bx-remote-play-device-wrapper {
|
.bx-remote-play-device-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
gap: 10px;
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-remote-play-device-info {
|
.bx-remote-play-device-info {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
padding: 4px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-remote-play-device-name {
|
.bx-remote-play-device-name {
|
||||||
@ -73,7 +80,6 @@
|
|||||||
|
|
||||||
.bx-remote-play-connect-button {
|
.bx-remote-play-connect-button {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
margin: 4px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bx-remote-play-buttons {
|
.bx-remote-play-buttons {
|
||||||
|
@ -80,6 +80,7 @@ export const enum GlobalPref {
|
|||||||
AUDIO_VOLUME_CONTROL_ENABLED = 'audio.volume.booster.enabled',
|
AUDIO_VOLUME_CONTROL_ENABLED = 'audio.volume.booster.enabled',
|
||||||
|
|
||||||
REMOTE_PLAY_STREAM_RESOLUTION = 'xhome.video.resolution',
|
REMOTE_PLAY_STREAM_RESOLUTION = 'xhome.video.resolution',
|
||||||
|
REMOTE_PLAY_PREFER_IPV6 = 'xhome.ipv6.prefer',
|
||||||
|
|
||||||
GAME_FORTNITE_FORCE_CONSOLE = 'game.fortnite.forceConsole',
|
GAME_FORTNITE_FORCE_CONSOLE = 'game.fortnite.forceConsole',
|
||||||
}
|
}
|
||||||
@ -99,6 +100,7 @@ export type GlobalPrefTypeMap = {
|
|||||||
[GlobalPref.NATIVE_MKB_FORCED_GAMES]: string[];
|
[GlobalPref.NATIVE_MKB_FORCED_GAMES]: string[];
|
||||||
[GlobalPref.NATIVE_MKB_MODE]: NativeMkbMode;
|
[GlobalPref.NATIVE_MKB_MODE]: NativeMkbMode;
|
||||||
[GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION]: StreamResolution;
|
[GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION]: StreamResolution;
|
||||||
|
[GlobalPref.REMOTE_PLAY_PREFER_IPV6]: boolean;
|
||||||
[GlobalPref.SCREENSHOT_APPLY_FILTERS]: boolean;
|
[GlobalPref.SCREENSHOT_APPLY_FILTERS]: boolean;
|
||||||
[GlobalPref.SERVER_BYPASS_RESTRICTION]: string;
|
[GlobalPref.SERVER_BYPASS_RESTRICTION]: string;
|
||||||
[GlobalPref.SERVER_PREFER_IPV6]: boolean;
|
[GlobalPref.SERVER_PREFER_IPV6]: boolean;
|
||||||
@ -233,6 +235,7 @@ export const ALL_PREFS: {
|
|||||||
GlobalPref.NATIVE_MKB_FORCED_GAMES,
|
GlobalPref.NATIVE_MKB_FORCED_GAMES,
|
||||||
GlobalPref.NATIVE_MKB_MODE,
|
GlobalPref.NATIVE_MKB_MODE,
|
||||||
GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION,
|
GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION,
|
||||||
|
GlobalPref.REMOTE_PLAY_PREFER_IPV6,
|
||||||
GlobalPref.SCREENSHOT_APPLY_FILTERS,
|
GlobalPref.SCREENSHOT_APPLY_FILTERS,
|
||||||
GlobalPref.SERVER_BYPASS_RESTRICTION,
|
GlobalPref.SERVER_BYPASS_RESTRICTION,
|
||||||
GlobalPref.SERVER_PREFER_IPV6,
|
GlobalPref.SERVER_PREFER_IPV6,
|
||||||
|
15
src/index.ts
15
src/index.ts
@ -47,6 +47,8 @@ import { Toast } from "./utils/toast";
|
|||||||
import { WebGPUPlayer } from "./modules/player/webgpu/webgpu-player";
|
import { WebGPUPlayer } from "./modules/player/webgpu/webgpu-player";
|
||||||
import { StreamUiHandler } from "./modules/stream/stream-ui";
|
import { StreamUiHandler } from "./modules/stream/stream-ui";
|
||||||
import { TrueAchievements } from "./utils/true-achievements";
|
import { TrueAchievements } from "./utils/true-achievements";
|
||||||
|
import { localRedirect } from "./modules/ui/ui";
|
||||||
|
import { handleDeepLink } from "./utils/deep-link";
|
||||||
|
|
||||||
SettingsManager.getInstance();
|
SettingsManager.getInstance();
|
||||||
|
|
||||||
@ -190,7 +192,18 @@ document.addEventListener('readystatechange', e => {
|
|||||||
|
|
||||||
// Preload fonts
|
// Preload fonts
|
||||||
preloadFonts();
|
preloadFonts();
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// Deep link
|
||||||
|
if (AppInterface) {
|
||||||
|
window.addEventListener(BxEvent.XCLOUD_ROUTER_HISTORY_READY, e => {
|
||||||
|
if (window.location.pathname.includes('/fireos-browser-update')) {
|
||||||
|
localRedirect('/play');
|
||||||
|
} else {
|
||||||
|
handleDeepLink();
|
||||||
|
}
|
||||||
|
}, { once: true });
|
||||||
|
}
|
||||||
|
|
||||||
window.BX_EXPOSED = BxExposed;
|
window.BX_EXPOSED = BxExposed;
|
||||||
|
|
||||||
|
@ -209,15 +209,6 @@ export class RemotePlayManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Show native dialog in Android app
|
|
||||||
if (AppInterface && AppInterface.showRemotePlayDialog) {
|
|
||||||
AppInterface.showRemotePlayDialog(JSON.stringify(this.consoles));
|
|
||||||
(document.activeElement as HTMLElement).blur();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
RemotePlayDialog.getInstance().show();
|
RemotePlayDialog.getInstance().show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ButtonStyle, CE, createButton } from "@/utils/html";
|
import { ButtonStyle, CE, createButton, escapeCssSelector } from "@/utils/html";
|
||||||
import { NavigationDialog, type NavigationElement } from "./navigation-dialog";
|
import { NavigationDialog, type NavigationElement } from "./navigation-dialog";
|
||||||
import { GlobalPref } from "@/enums/pref-keys";
|
import { GlobalPref } from "@/enums/pref-keys";
|
||||||
import { BxIcon } from "@/utils/bx-icon";
|
import { BxIcon } from "@/utils/bx-icon";
|
||||||
@ -9,6 +9,9 @@ import { BxSelectElement } from "@/web-components/bx-select";
|
|||||||
import { BxEvent } from "@/utils/bx-event";
|
import { BxEvent } from "@/utils/bx-event";
|
||||||
import { BxLogger } from "@/utils/bx-logger";
|
import { BxLogger } from "@/utils/bx-logger";
|
||||||
import { StreamResolution } from "@/enums/pref-values";
|
import { StreamResolution } from "@/enums/pref-values";
|
||||||
|
import { setNearby } from "@/utils/navigation-utils";
|
||||||
|
import { AppInterface } from "@/utils/global";
|
||||||
|
import { SettingElement } from "@/utils/setting-element";
|
||||||
|
|
||||||
|
|
||||||
export class RemotePlayDialog extends NavigationDialog {
|
export class RemotePlayDialog extends NavigationDialog {
|
||||||
@ -65,6 +68,9 @@ export class RemotePlayDialog extends NavigationDialog {
|
|||||||
}, CE('div', false,
|
}, CE('div', false,
|
||||||
CE('label', false, t('target-resolution'), $settingNote),
|
CE('label', false, t('target-resolution'), $settingNote),
|
||||||
$resolutions,
|
$resolutions,
|
||||||
|
), CE('div', false,
|
||||||
|
CE('label', { 'for': `bx_setting_${escapeCssSelector(GlobalPref.REMOTE_PLAY_PREFER_IPV6)}` }, t('prefer-ipv6-server')),
|
||||||
|
SettingElement.fromPref(GlobalPref.REMOTE_PLAY_PREFER_IPV6),
|
||||||
));
|
));
|
||||||
|
|
||||||
$fragment.appendChild($qualitySettings);
|
$fragment.appendChild($qualitySettings);
|
||||||
@ -73,8 +79,20 @@ export class RemotePlayDialog extends NavigationDialog {
|
|||||||
const manager = RemotePlayManager.getInstance()!;
|
const manager = RemotePlayManager.getInstance()!;
|
||||||
const consoles = manager.getConsoles();
|
const consoles = manager.getConsoles();
|
||||||
|
|
||||||
|
const createConsoleShortcut = (e: Event) => {
|
||||||
|
const { serverId, deviceName } = (e.target as HTMLElement).dataset;
|
||||||
|
const optionsJson = JSON.stringify({
|
||||||
|
'resolution': getGlobalPref(GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION),
|
||||||
|
});
|
||||||
|
|
||||||
|
AppInterface?.createConsoleShortcut(serverId!, deviceName!, optionsJson);
|
||||||
|
};
|
||||||
|
|
||||||
for (let con of consoles) {
|
for (let con of consoles) {
|
||||||
const $child = CE('div', { class: 'bx-remote-play-device-wrapper' },
|
let $connect;
|
||||||
|
const $child = CE('div', {
|
||||||
|
class: 'bx-remote-play-device-wrapper',
|
||||||
|
},
|
||||||
CE('div', { class: 'bx-remote-play-device-info' },
|
CE('div', { class: 'bx-remote-play-device-info' },
|
||||||
CE('div', false,
|
CE('div', false,
|
||||||
CE('span', { class: 'bx-remote-play-device-name' }, con.deviceName),
|
CE('span', { class: 'bx-remote-play-device-name' }, con.deviceName),
|
||||||
@ -83,8 +101,20 @@ export class RemotePlayDialog extends NavigationDialog {
|
|||||||
CE('div', { class: 'bx-remote-play-power-state' }, this.STATE_LABELS[con.powerState]),
|
CE('div', { class: 'bx-remote-play-power-state' }, this.STATE_LABELS[con.powerState]),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Shortcut button
|
||||||
|
AppInterface ? createButton({
|
||||||
|
attributes: {
|
||||||
|
'data-server-id': con.serverId,
|
||||||
|
'data-device-name': con.deviceName,
|
||||||
|
},
|
||||||
|
icon: BxIcon.CREATE_SHORTCUT,
|
||||||
|
style: ButtonStyle.GHOST | ButtonStyle.FOCUSABLE,
|
||||||
|
title: t('create-shortcut'),
|
||||||
|
onClick: createConsoleShortcut,
|
||||||
|
}) : null,
|
||||||
|
|
||||||
// Connect button
|
// Connect button
|
||||||
createButton({
|
$connect = createButton({
|
||||||
classes: ['bx-remote-play-connect-button'],
|
classes: ['bx-remote-play-connect-button'],
|
||||||
label: t('console-connect'),
|
label: t('console-connect'),
|
||||||
style: ButtonStyle.PRIMARY | ButtonStyle.FOCUSABLE,
|
style: ButtonStyle.PRIMARY | ButtonStyle.FOCUSABLE,
|
||||||
@ -92,6 +122,10 @@ export class RemotePlayDialog extends NavigationDialog {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
setNearby($child, {
|
||||||
|
orientation: 'horizontal',
|
||||||
|
focus: $connect,
|
||||||
|
})
|
||||||
$fragment.appendChild($child);
|
$fragment.appendChild($child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +164,7 @@ export class RemotePlayDialog extends NavigationDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
focusIfNeeded(): void {
|
focusIfNeeded(): void {
|
||||||
const $btnConnect = this.$container.querySelector<HTMLElement>('.bx-remote-play-device-wrapper button');
|
const $btnConnect = this.$container.querySelector<HTMLElement>('.bx-remote-play-device-wrapper button:last-of-type');
|
||||||
$btnConnect && $btnConnect.focus();
|
$btnConnect && $btnConnect.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ export class SettingsDialog extends NavigationDialog {
|
|||||||
$parent => {
|
$parent => {
|
||||||
$parent.appendChild(createButton({
|
$parent.appendChild(createButton({
|
||||||
label: t('clear-data'),
|
label: t('clear-data'),
|
||||||
style: ButtonStyle.GHOST | ButtonStyle.FULL_WIDTH | ButtonStyle.FOCUSABLE,
|
style: ButtonStyle.DANGER | ButtonStyle.FROSTED | ButtonStyle.FULL_WIDTH | ButtonStyle.FOCUSABLE,
|
||||||
onClick: e => {
|
onClick: e => {
|
||||||
if (confirm(t('clear-data-confirm'))) {
|
if (confirm(t('clear-data-confirm'))) {
|
||||||
clearAllData();
|
clearAllData();
|
||||||
|
@ -12,6 +12,7 @@ import { getGlobalPref } from "@/utils/pref-utils";
|
|||||||
import { BxLogger } from "@/utils/bx-logger";
|
import { BxLogger } from "@/utils/bx-logger";
|
||||||
import { BxEventBus } from "@/utils/bx-event-bus";
|
import { BxEventBus } from "@/utils/bx-event-bus";
|
||||||
import { BlockFeature } from "@/enums/pref-values";
|
import { BlockFeature } from "@/enums/pref-values";
|
||||||
|
import { Toast } from "@/utils/toast";
|
||||||
|
|
||||||
export class HeaderSection {
|
export class HeaderSection {
|
||||||
private static instance: HeaderSection;
|
private static instance: HeaderSection;
|
||||||
@ -60,6 +61,8 @@ export class HeaderSection {
|
|||||||
if (!SCRIPT_VERSION.includes('beta') && PREF_LATEST_VERSION && PREF_LATEST_VERSION !== SCRIPT_VERSION) {
|
if (!SCRIPT_VERSION.includes('beta') && PREF_LATEST_VERSION && PREF_LATEST_VERSION !== SCRIPT_VERSION) {
|
||||||
$btnSettings.setAttribute('data-update-available', 'true');
|
$btnSettings.setAttribute('data-update-available', 'true');
|
||||||
}
|
}
|
||||||
|
} else if (status === 'error') {
|
||||||
|
Toast.show(t('server-list-error'), '❌', { instant: true });
|
||||||
} else if (status === 'unavailable') {
|
} else if (status === 'unavailable') {
|
||||||
STATES.supportedRegion = false;
|
STATES.supportedRegion = false;
|
||||||
|
|
||||||
|
23
src/types/global.d.ts
vendored
23
src/types/global.d.ts
vendored
@ -11,7 +11,28 @@ export {};
|
|||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
AppInterface: any;
|
AppInterface: {
|
||||||
|
startPointerServer(),
|
||||||
|
requestPointerCapture(),
|
||||||
|
releasePointerCapture(),
|
||||||
|
|
||||||
|
runShortcut?(action: string),
|
||||||
|
saveScreenshot(name: string | undefined, data: string),
|
||||||
|
vibrate(dataJson: string, intensity: number),
|
||||||
|
openTrueAchievementsLink(override: boolean, xboxTitleId?: string | undefined, id?: string | undefined),
|
||||||
|
|
||||||
|
openAppSettings?(),
|
||||||
|
updateLatestScript(),
|
||||||
|
closeApp(),
|
||||||
|
getDeepLinkData(): string,
|
||||||
|
|
||||||
|
createShortcut(path: string),
|
||||||
|
createConsoleShortcut(serverId: string, deviceName: string, optionsJson: string),
|
||||||
|
downloadWallpapers(titleSlug: string | undefined, productId: string | undefined),
|
||||||
|
|
||||||
|
onEvent(event: String),
|
||||||
|
onEventBus(event: String),
|
||||||
|
};
|
||||||
BX_FLAGS?: BxFlags;
|
BX_FLAGS?: BxFlags;
|
||||||
BX_CE: (elmName: string, props: { [index: string]: any }={}) => HTMLElement;
|
BX_CE: (elmName: string, props: { [index: string]: any }={}) => HTMLElement;
|
||||||
BX_EXPOSED: typeof BxExposed & Partial<{
|
BX_EXPOSED: typeof BxExposed & Partial<{
|
||||||
|
@ -9,7 +9,7 @@ type EventCallback<T = any> = (payload: T) => void;
|
|||||||
|
|
||||||
export type ScriptEvents = {
|
export type ScriptEvents = {
|
||||||
'xcloud.server': {
|
'xcloud.server': {
|
||||||
status: 'ready' | 'unavailable' | 'signed-out',
|
status: 'ready' | 'unavailable' | 'signed-out' | 'error',
|
||||||
};
|
};
|
||||||
|
|
||||||
'dialog.shown': {};
|
'dialog.shown': {};
|
||||||
@ -152,7 +152,10 @@ export class BxEventBus<TEvents extends Record<string, any>> {
|
|||||||
try {
|
try {
|
||||||
if (event in this.appJsInterfaces) {
|
if (event in this.appJsInterfaces) {
|
||||||
const method = this.appJsInterfaces[event];
|
const method = this.appJsInterfaces[event];
|
||||||
AppInterface[method] && AppInterface[method]();
|
if (method && method in AppInterface) {
|
||||||
|
// @ts-ignore
|
||||||
|
AppInterface[method]();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
AppInterface.onEventBus(this.group + '.' + (event as string));
|
AppInterface.onEventBus(this.group + '.' + (event as string));
|
||||||
}
|
}
|
||||||
|
56
src/utils/deep-link.ts
Normal file
56
src/utils/deep-link.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { localRedirect } from "@/modules/ui/ui";
|
||||||
|
import { AppInterface } from "./global";
|
||||||
|
import { RemotePlayManager } from "@/modules/remote-play-manager";
|
||||||
|
import { BxEvent } from "./bx-event";
|
||||||
|
|
||||||
|
|
||||||
|
export function handleDeepLink() {
|
||||||
|
const deepLinkData = JSON.parse(AppInterface.getDeepLinkData());
|
||||||
|
console.log('deepLinkData', deepLinkData);
|
||||||
|
if (!deepLinkData.host) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const onReady = () => {
|
||||||
|
if (deepLinkData.host === 'PLAY') {
|
||||||
|
localRedirect('/launch/' + deepLinkData.data.join('/'));
|
||||||
|
} else if (deepLinkData.host === 'DEVICE_CODE') {
|
||||||
|
localRedirect('/login/deviceCode');
|
||||||
|
} else if (deepLinkData.host === 'REMOTE_PLAY') {
|
||||||
|
const serverId = deepLinkData.data[0];
|
||||||
|
const resolution = deepLinkData.data[1] || '1080p';
|
||||||
|
|
||||||
|
const manager = RemotePlayManager.getInstance();
|
||||||
|
if (!manager) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manager.isReady()) {
|
||||||
|
manager.play(serverId, resolution);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener(BxEvent.REMOTE_PLAY_READY, () => {
|
||||||
|
manager.play(serverId, resolution);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let handled = false
|
||||||
|
const observer = new MutationObserver(mutationList => {
|
||||||
|
mutationList.forEach(mutation => {
|
||||||
|
if (handled || mutation.type !== 'childList') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const $target = mutation.target as HTMLElement;
|
||||||
|
if (!handled && $target.className && $target.className['startsWith'] && $target.className.includes('HomePage-module__homePage')) {
|
||||||
|
handled = true;
|
||||||
|
observer.disconnect();
|
||||||
|
setTimeout(onReady, 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
observer.observe(document.documentElement, {subtree: true, childList: true});
|
||||||
|
}
|
@ -109,7 +109,7 @@ export async function patchIceCandidates(request: Request, consoleAddrs?: Remote
|
|||||||
}
|
}
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
preferIpv6Server: getGlobalPref(GlobalPref.SERVER_PREFER_IPV6),
|
preferIpv6Server: getGlobalPref(consoleAddrs ? GlobalPref.REMOTE_PLAY_PREFER_IPV6 : GlobalPref.SERVER_PREFER_IPV6),
|
||||||
consoleAddrs: consoleAddrs,
|
consoleAddrs: consoleAddrs,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -535,6 +535,11 @@ export class GlobalSettingsStorage extends BaseSettingsStorage<GlobalPref> {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[GlobalPref.REMOTE_PLAY_PREFER_IPV6]: {
|
||||||
|
requiredVariants: 'full',
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
|
||||||
[GlobalPref.GAME_FORTNITE_FORCE_CONSOLE]: {
|
[GlobalPref.GAME_FORTNITE_FORCE_CONSOLE]: {
|
||||||
requiredVariants: 'full',
|
requiredVariants: 'full',
|
||||||
label: '🎮 ' + t('fortnite-force-console-version'),
|
label: '🎮 ' + t('fortnite-force-console-version'),
|
||||||
|
@ -153,7 +153,7 @@ export class TrueAchievements {
|
|||||||
xboxTitleId = this.getStreamXboxTitleId();
|
xboxTitleId = this.getStreamXboxTitleId();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AppInterface && AppInterface.openTrueAchievementsLink) {
|
if (AppInterface?.openTrueAchievementsLink) {
|
||||||
AppInterface.openTrueAchievementsLink(override, xboxTitleId?.toString(), id?.toString());
|
AppInterface.openTrueAchievementsLink(override, xboxTitleId?.toString(), id?.toString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -136,7 +136,8 @@ export function parseDetailsPath(path: string) {
|
|||||||
|
|
||||||
export function clearAllData() {
|
export function clearAllData() {
|
||||||
// Delete localStorage items
|
// Delete localStorage items
|
||||||
for (let i = 0; i < localStorage.length; i++) {
|
|
||||||
|
for (let i = localStorage.length - 1; i >= 0; i--) {
|
||||||
const key = localStorage.key(i);
|
const key = localStorage.key(i);
|
||||||
if (!key) {
|
if (!key) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -49,7 +49,13 @@ export class XcloudInterceptor {
|
|||||||
ip && (request as Request).headers.set('X-Forwarded-For', ip);
|
ip && (request as Request).headers.set('X-Forwarded-For', ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await NATIVE_FETCH(request, init);
|
let response;
|
||||||
|
try {
|
||||||
|
response = await NATIVE_FETCH(request, init);
|
||||||
|
} catch (e) {
|
||||||
|
BxEventBus.Script.emit('xcloud.server', { status: 'error' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
// Unsupported region
|
// Unsupported region
|
||||||
BxEventBus.Script.emit('xcloud.server', { status: 'unavailable' });
|
BxEventBus.Script.emit('xcloud.server', { status: 'unavailable' });
|
||||||
|
@ -2,10 +2,8 @@ import { TouchController } from "@/modules/touch-controller";
|
|||||||
import { BxEvent } from "./bx-event";
|
import { BxEvent } from "./bx-event";
|
||||||
import { SupportedInputType } from "./bx-exposed";
|
import { SupportedInputType } from "./bx-exposed";
|
||||||
import { NATIVE_FETCH } from "./bx-flags";
|
import { NATIVE_FETCH } from "./bx-flags";
|
||||||
import { STATES } from "./global";
|
|
||||||
import { generateMsDeviceInfo, getOsNameFromResolution, patchIceCandidates } from "./network";
|
import { generateMsDeviceInfo, getOsNameFromResolution, patchIceCandidates } from "./network";
|
||||||
import { GlobalPref } from "@/enums/pref-keys";
|
import { GlobalPref } from "@/enums/pref-keys";
|
||||||
import { RemotePlayManager } from "@/modules/remote-play-manager";
|
|
||||||
import { TouchControllerMode } from "@/enums/pref-values";
|
import { TouchControllerMode } from "@/enums/pref-values";
|
||||||
import { BxEventBus } from "./bx-event-bus";
|
import { BxEventBus } from "./bx-event-bus";
|
||||||
import { getGlobalPref } from "./pref-utils";
|
import { getGlobalPref } from "./pref-utils";
|
||||||
@ -111,7 +109,6 @@ export class XhomeInterceptor {
|
|||||||
for (const pair of (clone.headers as any).entries()) {
|
for (const pair of (clone.headers as any).entries()) {
|
||||||
headers[pair[0]] = pair[1];
|
headers[pair[0]] = pair[1];
|
||||||
}
|
}
|
||||||
headers.authorization = `Bearer ${RemotePlayManager.getInstance()!.getXcloudToken()}`;
|
|
||||||
|
|
||||||
const index = request.url.indexOf('.xboxlive.com');
|
const index = request.url.indexOf('.xboxlive.com');
|
||||||
request = new Request('https://wus.core.gssv-play-prod' + request.url.substring(index), {
|
request = new Request('https://wus.core.gssv-play-prod' + request.url.substring(index), {
|
||||||
@ -147,8 +144,6 @@ export class XhomeInterceptor {
|
|||||||
for (const pair of (clone.headers as any).entries()) {
|
for (const pair of (clone.headers as any).entries()) {
|
||||||
headers[pair[0]] = pair[1];
|
headers[pair[0]] = pair[1];
|
||||||
}
|
}
|
||||||
// Add xHome token to headers
|
|
||||||
headers.authorization = `Bearer ${RemotePlayManager.getInstance()!.getXhomeToken()}`;
|
|
||||||
|
|
||||||
// Patch resolution
|
// Patch resolution
|
||||||
const osName = getOsNameFromResolution(getGlobalPref(GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION));
|
const osName = getOsNameFromResolution(getGlobalPref(GlobalPref.REMOTE_PLAY_STREAM_RESOLUTION));
|
||||||
@ -164,12 +159,7 @@ export class XhomeInterceptor {
|
|||||||
opts.body = await clone.text();
|
opts.body = await clone.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace xCloud domain with xHome domain
|
const url = request.url;
|
||||||
let url = request.url;
|
|
||||||
if (!url.includes('/servers/home')) {
|
|
||||||
const parsed = new URL(url);
|
|
||||||
url = STATES.remotePlay.server + parsed.pathname;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new Request instance
|
// Create new Request instance
|
||||||
request = new Request(url, opts);
|
request = new Request(url, opts);
|
||||||
|
Reference in New Issue
Block a user