Compare commits

..

10 Commits

Author SHA1 Message Date
AAGaming 1781c19c11 Fix broken checkboxes on Beta Steam client (#710) 2024-10-04 13:26:00 -04:00
Lukas Senionis 1ef3cb8307 fix(http_request): remove conflicting CORS headers (#708) 2024-10-04 13:15:58 -04:00
WerWolvTranslationBot 5bc4dc684d Translations update from Weblate (#707)
Co-authored-by: ayssia <nynaevealmearah@gmail.com>
2024-10-03 17:28:00 -04:00
AAGaming 4cff530b52 Fix missing components on Oct 2 2024 Steam Beta (#709) 2024-10-03 17:08:35 -04:00
Marco Rodolfi 2f90a4fcf7 Rebase semver parsing on main (#677)
Co-authored-by: Marco Rodolfi <marco.rodolfi.1992@gmail.com>
2024-09-17 06:21:31 -07:00
AAGaming 24fce1e093 bump @decky/ui to include findSP fix 2024-09-16 19:31:04 -04:00
AAGaming 97b12972ee shut ts up 2024-09-16 16:21:00 -04:00
AAGaming f69eb72df9 wait for SteamApp init stage 1 to finish before loading decky's frontend bundle
should fix the startup race condition
2024-09-16 16:17:20 -04:00
WerWolvTranslationBot 24215c0732 Translations update from Weblate (#704)
* Translated using Weblate (German)

Currently translated at 100.0% (158 of 158 strings)

Translation: Decky/Decky
Translate-URL: https://weblate.werwolv.net/projects/decky/decky/de/

* Translated using Weblate (Dutch)

Currently translated at 100.0% (158 of 158 strings)

Translation: Decky/Decky
Translate-URL: https://weblate.werwolv.net/projects/decky/decky/nl/

* Translated using Weblate (Bulgarian)

Currently translated at 100.0% (158 of 158 strings)

Translation: Decky/Decky
Translate-URL: https://weblate.werwolv.net/projects/decky/decky/bg/

---------

Co-authored-by: SecularSteve <fairfull.playing@gmail.com>
2024-09-14 23:01:47 -07:00
Sims e87ce625fb Test (#701) 2024-09-13 16:59:35 -07:00
12 changed files with 142 additions and 45 deletions
+33 -2
View File
@@ -99,12 +99,14 @@
}
},
"PluginListIndex": {
"freeze": "Замразяване на актуализациите",
"hide": "Бърз достъп: Скриване",
"no_plugin": "Няма инсталирани добавки!",
"plugin_actions": "Действия с добавката",
"reinstall": "Преинсталиране",
"reload": "Презареждане",
"show": "Бърз достъп: Показване",
"unfreeze": "Разрешаване на актуализациите",
"uninstall": "Деинсталиране",
"update_all_one": "Обновяване на 1 добавка",
"update_all_other": "Обновяване на {{count}} добавки",
@@ -192,9 +194,19 @@
"SettingsIndex": {
"developer_title": "Разработчик",
"general_title": "Общи",
"plugins_title": "Добавки"
"plugins_title": "Добавки",
"testing_title": "Тестване"
},
"Store": {
"download_progress_info": {
"download_zip": "Изтегляне на плъгина",
"increment_count": "Увеличаване на броя изтегляния",
"installing_plugin": "Инсталиране на плъгина",
"open_zip": "Отваряне на zip файла",
"parse_zip": "Разглеждане на zip файла",
"start": "Иницииране",
"uninstalling_previous": "Деинсталиране на предишното копие"
},
"store_contrib": {
"desc": "Ако искате да допринесете към магазина за добавки на Decky, разгледайте хранилището SteamDeckHomebrew/decky-plugin-template в GitHub. Може да намерите информация относно разработката и разпространението във файла README.",
"label": "Допринасяне"
@@ -218,9 +230,17 @@
"about": "Относно",
"alph_asce": "По азбучен ред (Я -> А)",
"alph_desc": "По азбучен ред (А -> Я)",
"date_asce": "Най-старият първи",
"date_desc": "Най-новият първи",
"downloads_asce": "Най-малко изтеглени първи",
"downloads_desc": "Най-изтеглени първи",
"title": "Разглеждане"
},
"store_testing_cta": "Помислете дали искате да тествате новите добавки, за да помогнете на екипа на Decky Loader!"
"store_testing_cta": "Помислете дали искате да тествате новите добавки, за да помогнете на екипа на Decky Loader!",
"store_testing_warning": {
"desc": "Можете да използвате този канал на магазина, за да тествате най-новите версии на плъгините. Не забравяйте да оставите обратна връзка в GitHub, за да може плъгинът да бъде актуализиран за всички потребители.",
"label": "Добре дошли в канала на магазина за тестване"
}
},
"StoreSelect": {
"custom_store": {
@@ -234,6 +254,17 @@
"testing": "Тестване"
}
},
"Testing": {
"download": "Изтегляне",
"error": "Грешка при инсталирането на PR",
"header": "Следните версии на Decky Loader са създадени от отворени заявки за изтегляне от трети страни. Екипът на Decky Loader не е проверявал тяхната функционалност или сигурност и е възможно те да са остарели.",
"loading": "Зареждане на отворени заявки за изтегляне...",
"start_download_toast": "Изтегляне на PR #{{id}}"
},
"TitleView": {
"decky_store_desc": "Отворете Decky Store",
"settings_desc": "Отворете настройките на Decky"
},
"Updater": {
"decky_updates": "Обновления на Decky",
"no_patch_notes_desc": "няма бележки за промените в тази версия",
+14 -1
View File
@@ -198,6 +198,15 @@
"testing_title": "Testen"
},
"Store": {
"download_progress_info": {
"download_zip": "Plugin herunterladen",
"increment_count": "Erhöhen der Downloadanzahl",
"installing_plugin": "Plugin installieren",
"open_zip": "Öffnen der Zip-Datei",
"parse_zip": "Parsen der Zip-Datei",
"start": "Initialisieren",
"uninstalling_previous": "Vorherige Kopie deinstallieren"
},
"store_contrib": {
"desc": "Wenn du Erweiterungen im Decky Store veröffentlichen willst, besuche die SteamDeckHomebrew/decky-plugin-template Repository auf GitHub. Informationen rund um Entwicklung und Veröffentlichung findest du in der README.",
"label": "Mitwirken"
@@ -246,7 +255,11 @@
}
},
"Testing": {
"download": "Download"
"download": "Download",
"error": "Fehler beim Installieren von PR",
"header": "Die folgenden Versionen von Decky Loader wurden aus offenen Pull Requests von Dritten erstellt. Das Decky Loader-Team hat ihre Funktionalität oder Sicherheit nicht überprüft, und sie können veraltet sein.",
"loading": "Offene Pull Requests laden...",
"start_download_toast": "Herunterladen von PR #{{id}}"
},
"TitleView": {
"decky_store_desc": "Decky Store Öffnen",
+19 -6
View File
@@ -2,9 +2,9 @@
"BranchSelect": {
"update_channel": {
"label": "Updatekanaal",
"prerelease": "Prerelease",
"prerelease": "Vooruitgave",
"stable": "Stabiel",
"testing": "Testing"
"testing": "Testen"
}
},
"Developer": {
@@ -188,7 +188,7 @@
"header": "Overige"
},
"updates": {
"header": "Updates"
"header": "Bijwerkingen"
}
},
"SettingsIndex": {
@@ -198,6 +198,15 @@
"testing_title": "Testen"
},
"Store": {
"download_progress_info": {
"download_zip": "Plugin downloaden",
"increment_count": "Aantal downloads verhogen",
"installing_plugin": "Plugin installeren",
"open_zip": "Zip-bestand openen",
"parse_zip": "Zip-bestand parseren",
"start": "Initialiseren",
"uninstalling_previous": "Vorige kopie verwijderen"
},
"store_contrib": {
"desc": "Als je wilt bijdragen aan de Decky Plugin Store, kijk dan in de SteamDeckHomebrew/decky-plugin-template repository op GitHub. Informatie over ontwikkeling en distributie is beschikbaar in de README.",
"label": "Bijdragen"
@@ -242,11 +251,15 @@
"custom": "Aangepast",
"default": "Standaard",
"label": "Winkelkanaal",
"testing": "Testing"
"testing": "Testen"
}
},
"Testing": {
"download": "Downloaden"
"download": "Downloaden",
"error": "Fout bij installatie van PR",
"header": "De volgende versies van Decky Loader zijn gebouwd op basis van open Pull Requests van derden. Het Decky Loader-team heeft hun functionaliteit of veiligheid niet gecontroleerd en ze kunnen verouderd zijn.",
"loading": "Openstaande Pull Requests laden...",
"start_download_toast": "PR #{{id}} downloaden"
},
"TitleView": {
"decky_store_desc": "Decky Store openen",
@@ -261,7 +274,7 @@
"checking": "Bezig met controleren op updates",
"cur_version": "Huidige versie: {{ver}}",
"install_button": "Bijwerken",
"label": "Updates",
"label": "Bijwerkingen",
"lat_version": "Bijwerkt: versie {{ver}}",
"reloading": "Bezig met herstarten",
"updating": "Bezig met bijwerken"
+14 -1
View File
@@ -191,6 +191,15 @@
"testing_title": "测试"
},
"Store": {
"download_progress_info": {
"download_zip": "正在下载插件",
"increment_count": "正在计入下载次数",
"installing_plugin": "正在安装插件",
"open_zip": "正在打开 ZIP 文件",
"parse_zip": "正在解析 ZIP 文件",
"start": "正在初始化",
"uninstalling_previous": "正在卸载之前的版本"
},
"store_contrib": {
"desc": "如果你想要提交你的插件到 Decky 插件商店,请访问 GitHub 上的 SteamDeckHomebrew/decky-plugin-template 存储库。有关开发和分发插件的信息,请查看 README 文件。",
"label": "贡献"
@@ -239,7 +248,11 @@
}
},
"Testing": {
"download": "下载"
"download": "下载",
"error": "安装 PR 时出错",
"header": "以下版本的 Decky Loader 是根据开放的第三方 Pull Request 构建的。Decky Loader 团队尚未验证这些版本的功能或安全性,且它们可能已经过期。",
"loading": "正在加载尚未合并的 Pull Request ...",
"start_download_toast": "正在下载 PR #{{id}}"
},
"TitleView": {
"decky_store_desc": "打开 Decky 商店",
@@ -11,7 +11,7 @@ from setproctitle import setproctitle, setthreadtitle
from .messages import SocketResponseDict, SocketMessageType
from ..localplatform.localsocket import LocalSocket
from ..localplatform.localplatform import setgid, setuid, get_username, get_home_path
from ..localplatform.localplatform import setgid, setuid, get_username, get_home_path, ON_LINUX
from ..enums import UserType
from .. import helpers, settings, injector # pyright: ignore [reportUnusedImport]
@@ -54,10 +54,13 @@ class SandboxedPlugin:
loop = new_event_loop()
set_event_loop(loop)
# When running Decky manually in a terminal, ctrl-c will trigger this, so we have to handle it properly
loop.add_signal_handler(SIGINT, lambda: ensure_future(self.shutdown()))
loop.add_signal_handler(SIGTERM, lambda: ensure_future(self.shutdown()))
if ON_LINUX:
loop.add_signal_handler(SIGINT, lambda: ensure_future(self.shutdown()))
loop.add_signal_handler(SIGTERM, lambda: ensure_future(self.shutdown()))
if self.passive:
return
setgid(UserType.ROOT if "root" in self.flags else UserType.HOST_USER)
setuid(UserType.ROOT if "root" in self.flags else UserType.HOST_USER)
# export a bunch of environment variables to help plugin developers
+18 -4
View File
@@ -9,7 +9,7 @@ from traceback import format_exc
from stat import FILE_ATTRIBUTE_HIDDEN # pyright: ignore [reportAttributeAccessIssue, reportUnknownVariableType]
from asyncio import StreamReader, StreamWriter, start_server, gather, open_connection
from aiohttp import ClientSession
from aiohttp import ClientSession, hdrs
from aiohttp.web import Request, StreamResponse, Response, json_response, post
from typing import TYPE_CHECKING, Callable, Coroutine, Dict, Any, List, TypedDict
@@ -153,14 +153,14 @@ class Utilities:
headers["User-Agent"] = helpers.user_agent
for excluded_header in excluded_default_headers:
self.logger.debug(f"Excluding default header {excluded_header}")
if excluded_header in headers:
self.logger.debug(f"Excluding default header {excluded_header}: {headers[excluded_header]}")
del headers[excluded_header]
if "X-Decky-Fetch-Excluded-Headers" in req.headers:
for excluded_header in req.headers["X-Decky-Fetch-Excluded-Headers"].split(", "):
self.logger.debug(f"Excluding header {excluded_header}")
if excluded_header in headers:
self.logger.debug(f"Excluding header {excluded_header}: {headers[excluded_header]}")
del headers[excluded_header]
for header in req.headers:
@@ -187,7 +187,21 @@ class Utilities:
# defeat the point of this proxy.
async with ClientSession(auto_decompress=False) as web:
async with web.request(req.method, url, headers=headers, data=body, ssl=helpers.get_ssl_context()) as web_res:
res = StreamResponse(headers=web_res.headers, status=web_res.status)
# Whenever the aiohttp_cors is used, it expects a near complete control over whatever headers are needed
# for `aiohttp_cors.ResourceOptions`. As a server, if you delegate CORS handling to aiohttp_cors,
# the headers below must NOT be set. Otherwise they would be overwritten by aiohttp_cors and there would be
# logic bugs, so it was probably a smart choice to assert if the headers are present.
#
# However, this request handler method does not act like our own local server, it always acts like a proxy
# where we do not have control over the response headers. For responses that do not allow CORS, we add the support
# via aiohttp_cors. For responses that allow CORS, we have to remove the conflicting headers to allow
# aiohttp_cors handle it for us as if there was no CORS support.
aiohttp_cors_compatible_headers = web_res.headers.copy()
aiohttp_cors_compatible_headers.popall(hdrs.ACCESS_CONTROL_ALLOW_ORIGIN, default=None)
aiohttp_cors_compatible_headers.popall(hdrs.ACCESS_CONTROL_ALLOW_CREDENTIALS, default=None)
aiohttp_cors_compatible_headers.popall(hdrs.ACCESS_CONTROL_EXPOSE_HEADERS, default=None)
res = StreamResponse(headers=aiohttp_cors_compatible_headers, status=web_res.status)
if web_res.headers.get('Transfer-Encoding', '').lower() == 'chunked':
res.enable_chunked_encoding()
+2 -1
View File
@@ -47,7 +47,8 @@
}
},
"dependencies": {
"@decky/ui": "^4.7.1",
"@decky/ui": "^4.7.4",
"compare-versions": "^6.1.1",
"filesize": "^10.1.2",
"i18next": "^23.11.5",
"i18next-http-backend": "^2.5.2",
+13 -5
View File
@@ -9,8 +9,11 @@ importers:
.:
dependencies:
'@decky/ui':
specifier: ^4.7.1
version: 4.7.1
specifier: ^4.7.4
version: 4.7.4
compare-versions:
specifier: ^6.1.1
version: 6.1.1
filesize:
specifier: ^10.1.2
version: 10.1.2
@@ -215,8 +218,8 @@ packages:
'@decky/api@1.1.1':
resolution: {integrity: sha512-R5fkBRHBt5QIQY7Q0AlbVIhlIZ/nTzwBOoi8Rt4Go2fjFnoMKPInCJl6cPjXzimGwl2pyqKJgY6VnH6ar0XrHQ==}
'@decky/ui@4.7.1':
resolution: {integrity: sha512-yJwBgW+J2cMDfMkmcDFtzsubhUjekFZAtCnP55QEJ/1UKGR7sLNOvDLFYi1h5PI0K4L1XYcAMKHwbYFFTzcDTA==}
'@decky/ui@4.7.4':
resolution: {integrity: sha512-ziCP3akLJVYG5FFoS0ao9MYEYJ09g44FP4xMmOUFe8SFRjC9BqBvbJBF0+OUOKgp2C7SJ0rNPSIFm4RwCUvoug==}
'@esbuild/aix-ppc64@0.20.2':
resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==}
@@ -848,6 +851,9 @@ packages:
commondir@1.0.1:
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
compare-versions@6.1.1:
resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==}
concat-map@0.0.1:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
@@ -2289,7 +2295,7 @@ snapshots:
'@decky/api@1.1.1': {}
'@decky/ui@4.7.1': {}
'@decky/ui@4.7.4': {}
'@esbuild/aix-ppc64@0.20.2':
optional: true
@@ -2816,6 +2822,8 @@ snapshots:
commondir@1.0.1: {}
compare-versions@6.1.1: {}
concat-map@0.0.1: {}
convert-source-map@2.0.0: {}
+8 -18
View File
@@ -5,29 +5,19 @@ interface Window {
}
(async () => {
// Wait for main webpack chunks to definitely be loaded
console.time('[Decky:Boot] Waiting for main Webpack chunks...');
while (!window.webpackChunksteamui || window.webpackChunksteamui.length < 5) {
await new Promise((r) => setTimeout(r, 10)); // Can't use DFL sleep here.
}
console.timeEnd('[Decky:Boot] Waiting for main Webpack chunks...');
console.debug('[Decky:Boot] Frontend init');
// Wait for the React root to be mounted
console.time('[Decky:Boot] Waiting for React root mount...');
let root;
while (
// Does React root node exist?
!(root = document.getElementById('root')) ||
// Does it have a child element?
!(root as any)[Object.keys(root).find((k) => k.startsWith('__reactContainer$')) as string].child
) {
await new Promise((r) => setTimeout(r, 10)); // Can't use DFL sleep here.
console.time('[Decky:Boot] Waiting for SteamApp init stage 1 to finish...');
// @ts-expect-error TODO type BFinishedInitStageOne in @decky/ui
while (!window.App?.BFinishedInitStageOne()) {
await new Promise((r) => setTimeout(r, 0)); // Can't use DFL sleep here.
}
console.timeEnd('[Decky:Boot] Waiting for React root mount...');
console.timeEnd('[Decky:Boot] Waiting for SteamApp init stage 1 to finish...');
if (!window.SP_REACT) {
console.debug('[Decky:Boot] Setting up Webpack & React globals...');
await new Promise((r) => setTimeout(r, 500)); // Can't use DFL sleep here.
// deliberate partial import
const DFLWebpack = await import('@decky/ui/dist/webpack');
window.SP_REACT = DFLWebpack.findModule((m) => m.Component && m.PureComponent && m.useLayoutEffect);
+3 -2
View File
@@ -168,8 +168,9 @@ class PluginLoader extends Logger {
Promise.all([this.getUserInfo(), this.updateVersion()])
.then(() => this.loadPlugins())
.then(() => this.checkPluginUpdates())
.then(() => this.log('Initialized'));
.then(() => this.log('Initialized'))
.then(() => sleep(30000)) // Internet might not immediately be up
.then(() => this.checkPluginUpdates());
}
private checkForSP(): boolean {
+11 -1
View File
@@ -1,3 +1,5 @@
import { compare } from 'compare-versions';
import { InstallType, Plugin, installPlugin, installPlugins } from './plugin';
import { getSetting, setSetting } from './utils/settings';
@@ -137,7 +139,15 @@ export async function checkForPluginUpdates(plugins: Plugin[]): Promise<PluginUp
const updateMap = new Map<string, StorePluginVersion>();
for (let plugin of plugins) {
const remotePlugin = serverData?.find((x) => x.name == plugin.name);
if (remotePlugin && remotePlugin.versions?.length > 0 && plugin.version != remotePlugin?.versions?.[0]?.name) {
//FIXME: Ugly hack since plugin.version might be null during evaluation,
//so this will set the older version possible
const curVer = plugin.version ? plugin.version : '0.0';
if (
remotePlugin &&
remotePlugin.versions?.length > 0 &&
plugin.version != remotePlugin?.versions?.[0]?.name &&
compare(remotePlugin?.versions?.[0]?.name, curVer, '>')
) {
updateMap.set(plugin.name, remotePlugin.versions[0]);
}
}
+1 -1
View File
@@ -30,7 +30,7 @@ while :; do
if [[ $NEWTARGET != "" ]] && [[ $NEWTARGET != $TARGET ]]; then
echo found new tab at $NEWTARGET
TARGET=$NEWTARGET
TARGETURL="devtools://devtools/bundled/inspector.html?remoteFrontend=true&ws=$ADDR/devtools/page/$TARGET"
TARGETURL="http://$ADDR/devtools/inspector.html?ws=$ADDR/devtools/page/$TARGET"
LOCALTARGET=$(echo '{"id": 1, "method": "Target.createTarget", "params": {"background": true, "url": "'$TARGETURL'"}}
{"id": 2, "method": "Target.closeTarget", "params": {"targetId": "'$LOCALTARGET'"}}' \