import { //ButtonItem, definePlugin, DialogButton, //Menu, //MenuItem, PanelSection, PanelSectionRow, //Router, ServerAPI, //showContextMenu, staticClasses, SliderField, ToggleField, //NotchLabel gamepadDialogClasses, joinClassNames, } from "decky-frontend-lib"; import { VFC, useState } from "react"; import { GiDrill } from "react-icons/gi"; import * as python from "./python"; //import logo from "../assets/logo.png"; // interface AddMethodArgs { // left: number; // right: number; // } var firstTime: boolean = true; var versionGlobal: string = "0.0.0-jank"; var periodicHook: NodeJS.Timer | null = null; var lastGame: string = ""; var lifetimeHook: any = null; var startHook: any = null; var reload = function(){}; const Content: VFC<{ serverAPI: ServerAPI }> = ({serverAPI}) => { // const [result, setResult] = useState(); // const onClick = async () => { // const result = await serverAPI.callPluginMethod( // "add", // { // left: 2, // right: 2, // } // ); // if (result.success) { // setResult(result.result); // } // }; python.setServer(serverAPI); const [smtGlobal, setSMT] = useState(true); const [cpusGlobal, setCPUs] = useState(8); const [boostGlobal, setBoost] = useState(true); const [freqGlobal, setFreq] = useState(8); const [slowPPTGlobal, setSlowPPT] = useState(1); const [fastPPTGlobal, setFastPPT] = useState(1); const [chargeNowGlobal, setChargeNow] = useState(40); const [chargeFullGlobal, setChargeFull] = useState(40); const [chargeDesignGlobal, setChargeDesign] = useState(40); const [persistGlobal, setPersist] = useState(false); const [perGameProfileGlobal, setPerGameProfile] = useState(false); const [gameGlobal, setGame] = useState(lastGame); reload = function () { python.execute(python.onViewReady()); python.resolve(python.getSMT(), setSMT); python.resolve(python.getCPUs(), setCPUs); python.resolve(python.getCPUBoost(), setBoost); python.resolve(python.getMaxBoost(), setFreq); python.resolve(python.getGPUPowerI(1), setSlowPPT); python.resolve(python.getGPUPowerI(2), setFastPPT); python.resolve(python.getPersistent(), setPersist); python.resolve(python.getPerGameProfile(), setPerGameProfile); }; if (periodicHook == null) { periodicHook = setInterval(function() { python.resolve(python.getCurrentGame(), (game: string) => { python.resolve(python.getChargeNow(), setChargeNow); if (lastGame != game) { setGame(game); lastGame = game; reload(); } python.resolve(python.getChargeFull(), setChargeFull); }); }, 1000); } if (firstTime) { firstTime = false; reload(); // technically it's just load, not reload ;) python.resolve(python.getChargeNow(), setChargeNow); python.resolve(python.getChargeFull(), setChargeFull); python.resolve(python.getChargeDesign(), setChargeDesign); python.resolve(python.getCurrentGame(), setGame); python.resolve(python.getVersion(), (v: string) => {versionGlobal = v;}); } const FieldWithSeparator = joinClassNames(gamepadDialogClasses.Field, gamepadDialogClasses.WithBottomSeparatorStandard); return ( {/* CPU */}
CPU
{ console.log("SMT is now " + smt.toString()); python.execute(python.setCPUs(cpusGlobal, smt)); python.resolve(python.getCPUs(), setCPUs); python.resolve(python.getSMT(), setSMT); }} /> { console.log("CPU slider is now " + cpus.toString()); if (cpus != cpusGlobal) { python.execute(python.setCPUs(cpus, smtGlobal)); python.resolve(python.getCPUs(), setCPUs); } }} /> { console.log("Boost is now " + boost.toString()); python.execute(python.setCPUBoost(boost)); python.resolve(python.getCPUBoost(), setBoost); }} /> { console.log("CPU slider is now " + freq.toString()); if (freq != freqGlobal) { python.execute(python.setMaxBoost(freq)); python.resolve(python.getMaxBoost(), setFreq); } }} /> {/* GPU */}
GPU
{/* index: 1 */} { console.log("SlowPPT is now " + ppt.toString()); if (ppt != slowPPTGlobal) { python.execute(python.setGPUPowerI(ppt, 1)); python.resolve(python.getGPUPowerI(1), setSlowPPT); } }} /> {/* index: 2 */} { console.log("FastPPT is now " + ppt.toString()); if (ppt != fastPPTGlobal) { python.execute(python.setGPUPowerI(ppt, 2)); python.resolve(python.getGPUPowerI(2), setFastPPT); } }} /> {/* Battery */}
Battery
Now (Charge)
{(7.7 * chargeNowGlobal / 1000000).toFixed(1).toString() + " Wh (" + (100 * chargeNowGlobal / chargeFullGlobal).toFixed(1).toString() + "%)"}
Max (Design)
{(7.7 * chargeFullGlobal / 1000000).toFixed(1).toString() + " Wh (" + (100 * chargeFullGlobal / chargeDesignGlobal).toFixed(1).toString() + "%)"}
{/* Persistence */} { console.log("Persist is now " + persist.toString()); python.execute(python.setPersistent(persist)); python.resolve(python.getPersistent(), setPersist); }} /> { console.log("Per game profile is now " + p.toString()); python.execute(python.setPerGameProfile(p)); python.resolve(python.getPerGameProfile(), setPerGameProfile); reload(); }} />
Now Playing
{gameGlobal}
{/* Version */}
Debug
PowerTools
v{versionGlobal}
); }; const DeckyPluginRouterTest: VFC = () => { return (
Hello World! {}}> Go to Store
); }; export default definePlugin((serverApi: ServerAPI) => { serverApi.routerHook.addRoute("/decky-plugin-test", DeckyPluginRouterTest, { exact: true, }); //@ts-ignore lifetimeHook = SteamClient.GameSessions.RegisterForAppLifetimeNotifications((update) => { if (update.bRunning) { console.log("AppID " + update.unAppID.toString() + " is now running"); } else { console.log("AppID " + update.unAppID.toString() + " is no longer running"); python.execute(python.onGameStop(null)); } }); //@ts-ignore startHook = SteamClient.Apps.RegisterForGameActionStart((actionType, id) => { //@ts-ignore let gameInfo: any = appStore.GetAppOverviewByGameID(id); python.execute(python.onGameStart(id, gameInfo)); }); console.log("Registered PowerTools callbacks, hello!"); return { title:
PowerTools
, content: , icon: , onDismount() { console.log("PowerTools shutting down"); clearInterval(periodicHook!); lifetimeHook!.unregister(); startHook!.unregister(); serverApi.routerHook.removeRoute("/decky-plugin-test"); firstTime = true; lastGame = ""; console.log("Unregistered PowerTools callbacks, goodbye."); }, }; });