mirror of
https://github.com/SteamDeckHomebrew/decky-loader.git
synced 2026-07-11 19:02:03 +00:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
+13
-4
@@ -62,19 +62,19 @@ class Loader:
|
|||||||
self.logger = getLogger("Loader")
|
self.logger = getLogger("Loader")
|
||||||
self.plugin_path = plugin_path
|
self.plugin_path = plugin_path
|
||||||
self.logger.info(f"plugin_path: {self.plugin_path}")
|
self.logger.info(f"plugin_path: {self.plugin_path}")
|
||||||
self.plugins = {}
|
self.plugins : dict[str, PluginWrapper] = {}
|
||||||
self.watcher = None
|
self.watcher = None
|
||||||
self.live_reload = live_reload
|
self.live_reload = live_reload
|
||||||
|
self.reload_queue = Queue()
|
||||||
|
self.loop.create_task(self.handle_reloads())
|
||||||
|
|
||||||
if live_reload:
|
if live_reload:
|
||||||
self.reload_queue = Queue()
|
|
||||||
self.observer = Observer()
|
self.observer = Observer()
|
||||||
self.watcher = FileChangeHandler(self.reload_queue, plugin_path)
|
self.watcher = FileChangeHandler(self.reload_queue, plugin_path)
|
||||||
self.observer.schedule(self.watcher, self.plugin_path, recursive=True)
|
self.observer.schedule(self.watcher, self.plugin_path, recursive=True)
|
||||||
self.observer.start()
|
self.observer.start()
|
||||||
self.loop.create_task(self.handle_reloads())
|
|
||||||
self.loop.create_task(self.enable_reload_wait())
|
self.loop.create_task(self.enable_reload_wait())
|
||||||
|
|
||||||
server_instance.add_routes([
|
server_instance.add_routes([
|
||||||
web.get("/frontend/{path:.*}", self.handle_frontend_assets),
|
web.get("/frontend/{path:.*}", self.handle_frontend_assets),
|
||||||
web.get("/locales/{path:.*}", self.handle_frontend_locales),
|
web.get("/locales/{path:.*}", self.handle_frontend_locales),
|
||||||
@@ -82,6 +82,7 @@ class Loader:
|
|||||||
web.get("/plugins/{plugin_name}/frontend_bundle", self.handle_frontend_bundle),
|
web.get("/plugins/{plugin_name}/frontend_bundle", self.handle_frontend_bundle),
|
||||||
web.post("/plugins/{plugin_name}/methods/{method_name}", self.handle_plugin_method_call),
|
web.post("/plugins/{plugin_name}/methods/{method_name}", self.handle_plugin_method_call),
|
||||||
web.get("/plugins/{plugin_name}/assets/{path:.*}", self.handle_plugin_frontend_assets),
|
web.get("/plugins/{plugin_name}/assets/{path:.*}", self.handle_plugin_frontend_assets),
|
||||||
|
web.post("/plugins/{plugin_name}/reload", self.handle_backend_reload_request),
|
||||||
|
|
||||||
# The following is legacy plugin code.
|
# The following is legacy plugin code.
|
||||||
web.get("/plugins/load_main/{name}", self.load_plugin_main_view),
|
web.get("/plugins/load_main/{name}", self.load_plugin_main_view),
|
||||||
@@ -217,3 +218,11 @@ class Loader:
|
|||||||
return web.Response(text=await tab.get_steam_resource(f"https://steamloopback.host/{request.match_info['path']}"), content_type="text/html")
|
return web.Response(text=await tab.get_steam_resource(f"https://steamloopback.host/{request.match_info['path']}"), content_type="text/html")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return web.Response(text=str(e), status=400)
|
return web.Response(text=str(e), status=400)
|
||||||
|
|
||||||
|
async def handle_backend_reload_request(self, request):
|
||||||
|
plugin_name : str = request.match_info["plugin_name"]
|
||||||
|
plugin = self.plugins[plugin_name]
|
||||||
|
|
||||||
|
await self.reload_queue.put((plugin.file, plugin.plugin_directory))
|
||||||
|
|
||||||
|
return web.Response(status=200)
|
||||||
@@ -100,6 +100,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"SettingsDeveloperIndex": {
|
"SettingsDeveloperIndex": {
|
||||||
|
"cef_console": {
|
||||||
|
"button": "Open Console",
|
||||||
|
"desc": "Opens the CEF Console. Only useful for debugging purposes. Stuff here is potentially dangerous and should only be used if you are a plugin dev, or are directed here by one.",
|
||||||
|
"label": "CEF Console"
|
||||||
|
},
|
||||||
"header": "Other",
|
"header": "Other",
|
||||||
"react_devtools": {
|
"react_devtools": {
|
||||||
"desc": "Enables connection to a computer running React DevTools. Changing this setting will reload Steam. Set the IP address before enabling.",
|
"desc": "Enables connection to a computer running React DevTools. Changing this setting will reload Steam. Set the IP address before enabling.",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from asyncio import sleep, start_server, gather, open_connection
|
|||||||
from aiohttp import ClientSession, web
|
from aiohttp import ClientSession, web
|
||||||
|
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from injector import inject_to_tab, get_gamepadui_tab, close_old_tabs
|
from injector import inject_to_tab, get_gamepadui_tab, close_old_tabs, get_tab
|
||||||
import helpers
|
import helpers
|
||||||
import subprocess
|
import subprocess
|
||||||
from localplatform import service_stop, service_start
|
from localplatform import service_stop, service_start
|
||||||
@@ -32,7 +32,8 @@ class Utilities:
|
|||||||
"get_setting": self.get_setting,
|
"get_setting": self.get_setting,
|
||||||
"filepicker_ls": self.filepicker_ls,
|
"filepicker_ls": self.filepicker_ls,
|
||||||
"disable_rdt": self.disable_rdt,
|
"disable_rdt": self.disable_rdt,
|
||||||
"enable_rdt": self.enable_rdt
|
"enable_rdt": self.enable_rdt,
|
||||||
|
"get_tab_id": self.get_tab_id
|
||||||
}
|
}
|
||||||
|
|
||||||
self.logger = getLogger("Utilities")
|
self.logger = getLogger("Utilities")
|
||||||
@@ -287,3 +288,6 @@ class Utilities:
|
|||||||
await close_old_tabs()
|
await close_old_tabs()
|
||||||
await tab.evaluate_js("location.reload();", False, True, False)
|
await tab.evaluate_js("location.reload();", False, True, False)
|
||||||
self.logger.info("React DevTools disabled")
|
self.logger.info("React DevTools disabled")
|
||||||
|
|
||||||
|
async def get_tab_id(self, name):
|
||||||
|
return (await get_tab(name)).id
|
||||||
|
|||||||
@@ -4,12 +4,13 @@ import {
|
|||||||
DialogControlsSection,
|
DialogControlsSection,
|
||||||
DialogControlsSectionHeader,
|
DialogControlsSectionHeader,
|
||||||
Field,
|
Field,
|
||||||
|
Navigation,
|
||||||
TextField,
|
TextField,
|
||||||
Toggle,
|
Toggle,
|
||||||
} from 'decky-frontend-lib';
|
} from 'decky-frontend-lib';
|
||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { FaFileArchive, FaLink, FaReact, FaSteamSymbol } from 'react-icons/fa';
|
import { FaFileArchive, FaLink, FaReact, FaSteamSymbol, FaTerminal } from 'react-icons/fa';
|
||||||
|
|
||||||
import { setShouldConnectToReactDevTools, setShowValveInternal } from '../../../../developer';
|
import { setShouldConnectToReactDevTools, setShowValveInternal } from '../../../../developer';
|
||||||
import { installFromURL } from '../../../../store';
|
import { installFromURL } from '../../../../store';
|
||||||
@@ -75,6 +76,27 @@ export default function DeveloperSettings() {
|
|||||||
</DialogControlsSection>
|
</DialogControlsSection>
|
||||||
<DialogControlsSection>
|
<DialogControlsSection>
|
||||||
<DialogControlsSectionHeader>{t('SettingsDeveloperIndex.header')}</DialogControlsSectionHeader>
|
<DialogControlsSectionHeader>{t('SettingsDeveloperIndex.header')}</DialogControlsSectionHeader>
|
||||||
|
<Field
|
||||||
|
label={t('SettingsDeveloperIndex.cef_console.label')}
|
||||||
|
description={<span style={{ whiteSpace: 'pre-line' }}>{t('SettingsDeveloperIndex.cef_console.desc')}</span>}
|
||||||
|
icon={<FaTerminal style={{ display: 'block' }} />}
|
||||||
|
>
|
||||||
|
<DialogButton
|
||||||
|
onClick={async () => {
|
||||||
|
let res = await window.DeckyPluginLoader.callServerMethod('get_tab_id', { name: 'SharedJSContext' });
|
||||||
|
if (res.success) {
|
||||||
|
Navigation.NavigateToExternalWeb(
|
||||||
|
'localhost:8080/devtools/inspector.html?ws=localhost:8080/devtools/page/' + res.result,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.error('Unable to find ID for SharedJSContext tab ', res.result);
|
||||||
|
Navigation.NavigateToExternalWeb('localhost:8080');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('SettingsDeveloperIndex.cef_console.button')}
|
||||||
|
</DialogButton>
|
||||||
|
</Field>
|
||||||
<RemoteDebuggingSettings />
|
<RemoteDebuggingSettings />
|
||||||
<Field
|
<Field
|
||||||
label={t('SettingsDeveloperIndex.valve_internal.label')}
|
label={t('SettingsDeveloperIndex.valve_internal.label')}
|
||||||
|
|||||||
@@ -44,7 +44,23 @@ function PluginInteractables(props: { entry: ReorderableEntry<PluginData> }) {
|
|||||||
const showCtxMenu = (e: MouseEvent | GamepadEvent) => {
|
const showCtxMenu = (e: MouseEvent | GamepadEvent) => {
|
||||||
showContextMenu(
|
showContextMenu(
|
||||||
<Menu label={t('PluginListIndex.plugin_actions')}>
|
<Menu label={t('PluginListIndex.plugin_actions')}>
|
||||||
<MenuItem onSelected={() => window.DeckyPluginLoader.importPlugin(pluginName, data?.version)}>
|
<MenuItem
|
||||||
|
onSelected={() => {
|
||||||
|
try {
|
||||||
|
fetch(`http://127.0.0.1:1337/plugins/${pluginName}/reload`, {
|
||||||
|
method: 'POST',
|
||||||
|
credentials: 'include',
|
||||||
|
headers: {
|
||||||
|
Authentication: window.deckyAuthToken,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error Reloading Plugin Backend', err);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.DeckyPluginLoader.importPlugin(pluginName, data?.version);
|
||||||
|
}}
|
||||||
|
>
|
||||||
{t('PluginListIndex.reload')}
|
{t('PluginListIndex.reload')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|||||||
Reference in New Issue
Block a user