summaryrefslogtreecommitdiff
path: root/py_modules
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-18 12:00:31 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2025-07-18 12:00:31 -0400
commit48ee73dae1bdecec47ccbaf5456be8c5937cb0fd (patch)
tree487b0829755b51216df418477173dbb88e9af269 /py_modules
parentda113f878447e0830d414bb90b79b9a03d8cedec (diff)
downloaddecky-lsfg-vk-48ee73dae1bdecec47ccbaf5456be8c5937cb0fd.tar.gz
decky-lsfg-vk-48ee73dae1bdecec47ccbaf5456be8c5937cb0fd.zip
new profile method workaround for sudo global use
Diffstat (limited to 'py_modules')
-rw-r--r--py_modules/lsfg_vk/config_schema.py100
-rw-r--r--py_modules/lsfg_vk/plugin.py30
2 files changed, 95 insertions, 35 deletions
diff --git a/py_modules/lsfg_vk/config_schema.py b/py_modules/lsfg_vk/config_schema.py
index 42ac640..ed82d97 100644
--- a/py_modules/lsfg_vk/config_schema.py
+++ b/py_modules/lsfg_vk/config_schema.py
@@ -184,19 +184,44 @@ class ConfigurationManager:
@staticmethod
def generate_toml_content(config: ConfigurationData) -> str:
- """Generate TOML configuration file content"""
- lines = ["[global]"]
+ """Generate TOML configuration file content using the new game-specific format"""
+ lines = ["version = 1"]
+ lines.append("")
+ # Add global section with DLL path only (if specified)
+ if config.get("dll"):
+ lines.append("[global]")
+ lines.append(f"# specify where Lossless.dll is stored")
+ lines.append(f'dll = "{config["dll"]}"')
+ lines.append("")
+
+ # Add game section with process name for LSFG_PROCESS approach
+ lines.append("[[game]]")
+ lines.append("# Plugin-managed game entry (uses LSFG_PROCESS=decky-lsfg-vk)")
+ lines.append('exe = "decky-lsfg-vk"')
+ lines.append("")
+
+ # Add all configuration fields to the game section
for field_name, field_def in CONFIG_SCHEMA.items():
+ # Skip dll and enable fields - dll goes in global, enable is handled via multiplier
+ if field_name in ["dll", "enable"]:
+ continue
+
value = config[field_name]
- lines.append(f"# {field_def.description}")
+
+ # Handle enable field by setting multiplier to 1 when disabled
+ if field_name == "multiplier" and not config.get("enable", True):
+ value = 1
+ lines.append(f"# LSFG disabled via plugin - multiplier set to 1")
+ else:
+ lines.append(f"# {field_def.description}")
# Format value based on type
if isinstance(value, bool):
lines.append(f"{field_name} = {str(value).lower()}")
- elif isinstance(value, str):
+ elif isinstance(value, str) and value: # Only add non-empty strings
lines.append(f'{field_name} = "{value}"')
- else:
+ elif isinstance(value, (int, float)) and value != 0: # Only add non-zero numbers
lines.append(f"{field_name} = {value}")
lines.append("") # Empty line for readability
@@ -209,9 +234,11 @@ class ConfigurationManager:
config = ConfigurationManager.get_defaults()
try:
- # Look for [global] section
+ # Look for both [global] and [[game]] sections
lines = content.split('\n')
in_global_section = False
+ in_game_section = False
+ current_game_exe = None
for line in lines:
line = line.strip()
@@ -222,12 +249,16 @@ class ConfigurationManager:
# Check for section headers
if line.startswith('[') and line.endswith(']'):
- section = line[1:-1].strip()
- in_global_section = (section == 'global')
- continue
-
- # Only parse lines in the global section
- if not in_global_section:
+ if line == '[global]':
+ in_global_section = True
+ in_game_section = False
+ elif line == '[[game]]':
+ in_global_section = False
+ in_game_section = True
+ current_game_exe = None
+ else:
+ in_global_section = False
+ in_game_section = False
continue
# Parse key = value lines
@@ -242,21 +273,36 @@ class ConfigurationManager:
elif value.startswith("'") and value.endswith("'"):
value = value[1:-1]
- # Convert to appropriate type based on field definition
- if key in CONFIG_SCHEMA:
- field_def = CONFIG_SCHEMA[key]
- try:
- if field_def.field_type == ConfigFieldType.BOOLEAN:
- config[key] = value.lower() in ('true', '1', 'yes', 'on')
- elif field_def.field_type == ConfigFieldType.INTEGER:
- config[key] = int(value)
- elif field_def.field_type == ConfigFieldType.FLOAT:
- config[key] = float(value)
- elif field_def.field_type == ConfigFieldType.STRING:
- config[key] = value
- except (ValueError, TypeError):
- # If conversion fails, keep default value
- pass
+ # Handle global section (dll only)
+ if in_global_section and key == "dll":
+ config["dll"] = value
+
+ # Handle game section
+ elif in_game_section:
+ # Track the exe for this game section
+ if key == "exe":
+ current_game_exe = value
+ # Only parse config for our plugin-managed game entry
+ elif current_game_exe == "decky-lsfg-vk" and key in CONFIG_SCHEMA:
+ field_def = CONFIG_SCHEMA[key]
+ try:
+ if field_def.field_type == ConfigFieldType.BOOLEAN:
+ config[key] = value.lower() in ('true', '1', 'yes', 'on')
+ elif field_def.field_type == ConfigFieldType.INTEGER:
+ parsed_value = int(value)
+ # Handle enable field via multiplier
+ if key == "multiplier":
+ config[key] = parsed_value
+ config["enable"] = parsed_value != 1
+ else:
+ config[key] = parsed_value
+ elif field_def.field_type == ConfigFieldType.FLOAT:
+ config[key] = float(value)
+ elif field_def.field_type == ConfigFieldType.STRING:
+ config[key] = value
+ except (ValueError, TypeError):
+ # If conversion fails, keep default value
+ pass
return config
diff --git a/py_modules/lsfg_vk/plugin.py b/py_modules/lsfg_vk/plugin.py
index a7b6045..9caf2ea 100644
--- a/py_modules/lsfg_vk/plugin.py
+++ b/py_modules/lsfg_vk/plugin.py
@@ -352,29 +352,43 @@ class Plugin:
return False
# Plugin lifecycle methods
+ # Launch option methods
+ async def get_launch_option(self) -> Dict[str, Any]:
+ """Get the launch option that users need to set for their games
+
+ Returns:
+ Dict containing the launch option string and instructions
+ """
+ return {
+ "launch_option": "LSFG_PROCESS=decky-lsfg-vk %command%",
+ "instructions": "Add this to your game's launch options in Steam Properties",
+ "explanation": "This tells lsfg-vk to use the plugin-managed configuration for this game"
+ }
+
+ # Lifecycle methods
async def _main(self):
"""
- Asyncio-compatible long-running code, executed in a task when the plugin is loaded.
+ Main entry point for the plugin.
- This method is called by Decky Loader when the plugin starts up.
- Currently just logs that the plugin has loaded successfully.
+ This method is called by Decky Loader when the plugin is loaded.
+ Any initialization code should go here.
"""
import decky
- decky.logger.info("Lossless Scaling VK plugin loaded!")
+ decky.logger.info("Lossless Scaling VK plugin loaded")
async def _unload(self):
"""
- Function called first during the unload process.
+ Cleanup tasks when the plugin is unloaded.
This method is called by Decky Loader when the plugin is being unloaded.
- Use this for cleanup that should happen when the plugin stops.
+ Any cleanup code should go here.
"""
import decky
- decky.logger.info("Lossless Scaling VK plugin unloading")
+ decky.logger.info("Lossless Scaling VK plugin unloaded")
async def _uninstall(self):
"""
- Function called after `_unload` during uninstall.
+ Cleanup tasks when the plugin is uninstalled.
This method is called by Decky Loader when the plugin is being uninstalled.
It automatically cleans up any lsfg-vk files that were installed.