283 lines
11 KiB
Python
283 lines
11 KiB
Python
"""
|
|
Configuration Integration Helper
|
|
Updates the actual module files with GUI configuration settings
|
|
"""
|
|
|
|
import re
|
|
import os
|
|
from pathlib import Path
|
|
from typing import Dict, Any
|
|
|
|
|
|
class ConfigIntegration:
|
|
"""Helper class to integrate GUI configuration with module files."""
|
|
|
|
def __init__(self):
|
|
self.modules_dir = Path("modules")
|
|
|
|
def update_rpgmaker_config(self, config: Dict[str, Any]) -> bool:
|
|
"""Update rpgmakermvmz.py with configuration from GUI."""
|
|
module_path = self.modules_dir / "rpgmakermvmz.py"
|
|
|
|
if not module_path.exists():
|
|
raise FileNotFoundError(f"Module file not found: {module_path}")
|
|
|
|
try:
|
|
# Read the current module file
|
|
with open(module_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Update configuration values
|
|
updated_content = self._update_config_values(content, config)
|
|
|
|
# Write back to file
|
|
with open(module_path, 'w', encoding='utf-8') as f:
|
|
f.write(updated_content)
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
raise e
|
|
|
|
def _update_config_values(self, content: str, config: Dict[str, Any]) -> str:
|
|
"""Update configuration values in the module content."""
|
|
lines = content.split('\n')
|
|
updated_lines = []
|
|
|
|
# Track which configurations we found and updated
|
|
found_configs = set()
|
|
|
|
for line in lines:
|
|
updated_line = line
|
|
|
|
# Look for configuration assignments
|
|
for config_key, config_value in config.items():
|
|
# Match lines like: CONFIG_NAME = value # comment
|
|
pattern = rf'^({re.escape(config_key)})\s*=\s*.*?(#.*)?$'
|
|
match = re.match(pattern, line.strip())
|
|
|
|
if match:
|
|
# Preserve the comment if it exists
|
|
comment = match.group(2) if match.group(2) else ""
|
|
if comment:
|
|
comment = " " + comment
|
|
|
|
# Create the new line with proper formatting
|
|
updated_line = f"{config_key} = {config_value}{comment}"
|
|
found_configs.add(config_key)
|
|
break
|
|
|
|
updated_lines.append(updated_line)
|
|
|
|
# Check if all configurations were found
|
|
missing_configs = set(config.keys()) - found_configs
|
|
if missing_configs:
|
|
print(f"Warning: Could not find these configurations in module: {missing_configs}")
|
|
|
|
return '\n'.join(updated_lines)
|
|
|
|
def update_env_file(self, config: Dict[str, Any], env_path: Path = None) -> bool:
|
|
"""Update .env file with configuration."""
|
|
if env_path is None:
|
|
env_path = Path(".env")
|
|
|
|
try:
|
|
from dotenv import set_key
|
|
|
|
for key, value in config.items():
|
|
set_key(env_path, key, str(value))
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"Error updating .env file: {e}")
|
|
return False
|
|
|
|
def read_current_config(self, module_path: Path = None) -> Dict[str, Any]:
|
|
"""Read current configuration from module file."""
|
|
if module_path is None:
|
|
module_path = self.modules_dir / "rpgmakermvmz.py"
|
|
|
|
if not module_path.exists():
|
|
return {}
|
|
|
|
config = {}
|
|
|
|
try:
|
|
with open(module_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Find configuration lines used by the RPG Maker config UI.
|
|
bool_pattern = (
|
|
r'^(FIRSTLINESPEAKERS|INLINE401SPEAKERS|FACENAME101|NAMES|'
|
|
r'BRFLAG|FIXTEXTWRAP|IGNORETLTEXT|TLSYSTEMVARIABLES|'
|
|
r'TLSYSTEMSWITCHES|JOIN408|SPEAKERS408|CODE\d+)\s*=\s*(True|False)'
|
|
)
|
|
int_pattern = r'^(CODE122_VAR_MIN|CODE122_VAR_MAX)\s*=\s*(\d+)'
|
|
|
|
for line in content.split('\n'):
|
|
line = line.strip()
|
|
match = re.match(bool_pattern, line)
|
|
if match:
|
|
key = match.group(1)
|
|
value = match.group(2) == 'True'
|
|
config[key] = value
|
|
continue
|
|
|
|
match = re.match(int_pattern, line)
|
|
if match:
|
|
key = match.group(1)
|
|
config[key] = int(match.group(2))
|
|
|
|
except Exception as e:
|
|
print(f"Error reading configuration from {module_path}: {e}")
|
|
|
|
return config
|
|
|
|
def read_plugin_config(self, module_path: Path = None) -> Dict[str, Any]:
|
|
"""Read ENABLED_PLUGINS_357 and ENABLED_PATTERNS_355655 set literals from module file."""
|
|
if module_path is None:
|
|
module_path = self.modules_dir / "rpgmakermvmz.py"
|
|
result: Dict[str, Any] = {
|
|
"ENABLED_PLUGINS_357": set(),
|
|
"ENABLED_PATTERNS_355655": set(),
|
|
}
|
|
if not module_path.exists():
|
|
return result
|
|
try:
|
|
with open(module_path, "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
for var_name in ("ENABLED_PLUGINS_357", "ENABLED_PATTERNS_355655"):
|
|
# Match: VAR_NAME: set = set() or VAR_NAME: set = {"a", "b"}
|
|
m = re.search(
|
|
rf'^{re.escape(var_name)}\s*(?::\s*set)?\s*=\s*(\{{[^}}]*\}}|set\(\))',
|
|
content,
|
|
re.MULTILINE,
|
|
)
|
|
if m:
|
|
bracket = m.group(1)
|
|
items = re.findall(r'"([^"]+)"|\'([^\']+)\'', bracket)
|
|
result[var_name] = {a or b for a, b in items}
|
|
except Exception as e:
|
|
print(f"Error reading plugin config: {e}")
|
|
return result
|
|
|
|
def update_plugin_config(
|
|
self,
|
|
enabled_357: set,
|
|
enabled_355655: set,
|
|
module_path: Path = None,
|
|
) -> bool:
|
|
"""Write ENABLED_PLUGINS_357 and ENABLED_PATTERNS_355655 set literals to module file."""
|
|
if module_path is None:
|
|
module_path = self.modules_dir / "rpgmakermvmz.py"
|
|
if not module_path.exists():
|
|
raise FileNotFoundError(f"Module file not found: {module_path}")
|
|
|
|
def _fmt(s: set) -> str:
|
|
if not s:
|
|
return "set()"
|
|
items = ", ".join(f'"{k}"' for k in sorted(s))
|
|
return "{" + items + "}"
|
|
|
|
try:
|
|
with open(module_path, "r", encoding="utf-8") as f:
|
|
content = f.read()
|
|
for var_name, val_set in (
|
|
("ENABLED_PLUGINS_357", enabled_357),
|
|
("ENABLED_PATTERNS_355655", enabled_355655),
|
|
):
|
|
content = re.sub(
|
|
rf'^{re.escape(var_name)}\s*(?::\s*set)?\s*=\s*(?:\{{[^}}]*\}}|set\(\))',
|
|
f'{var_name}: set = {_fmt(val_set)}',
|
|
content,
|
|
flags=re.MULTILINE | re.DOTALL,
|
|
)
|
|
with open(module_path, "w", encoding="utf-8") as f:
|
|
f.write(content)
|
|
return True
|
|
except Exception as e:
|
|
raise e
|
|
|
|
def validate_module_syntax(self, module_path: Path = None) -> bool:
|
|
"""Validate that the module file has correct Python syntax."""
|
|
if module_path is None:
|
|
module_path = self.modules_dir / "rpgmakermvmz.py"
|
|
|
|
try:
|
|
with open(module_path, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
# Try to compile the code
|
|
compile(content, str(module_path), 'exec')
|
|
return True
|
|
|
|
except SyntaxError as e:
|
|
print(f"Syntax error in {module_path}: {e}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"Error validating {module_path}: {e}")
|
|
return False
|
|
|
|
def create_config_template(self) -> Dict[str, Any]:
|
|
"""Create a template configuration with default values."""
|
|
return {
|
|
# General config
|
|
"FIRSTLINESPEAKERS": False,
|
|
"INLINE401SPEAKERS": False,
|
|
"FACENAME101": False,
|
|
"NAMES": False,
|
|
"BRFLAG": False,
|
|
"FIXTEXTWRAP": True,
|
|
"IGNORETLTEXT": False,
|
|
|
|
# Main Codes
|
|
"CODE401": True,
|
|
"CODE405": True,
|
|
"CODE102": True,
|
|
|
|
# Optional codes
|
|
"CODE101": False,
|
|
"CODE408": False,
|
|
|
|
# Variable codes
|
|
"CODE122": False,
|
|
|
|
# Other codes
|
|
"CODE355655": False,
|
|
"CODE357": False,
|
|
"CODE657": False,
|
|
"CODE356": False,
|
|
"CODE320": False,
|
|
"CODE324": False,
|
|
"CODE111": False,
|
|
"CODE108": False
|
|
}
|
|
|
|
def get_config_descriptions(self) -> Dict[str, str]:
|
|
"""Get descriptions for all configuration options."""
|
|
return {
|
|
"FIRSTLINESPEAKERS": "If 1st line of 401 is a speaker, set to True",
|
|
"INLINE401SPEAKERS": "Detect speaker from Name\u300cdialogue\u300d inline format in 401 lines",
|
|
"FACENAME101": "Find Speakers in 101 Codes based on Face Name",
|
|
"NAMES": "Output a list of all the character names found",
|
|
"BRFLAG": "If the game uses <br> instead of newlines",
|
|
"FIXTEXTWRAP": "Overwrites textwrap for better formatting",
|
|
"IGNORETLTEXT": "Ignores all translated text",
|
|
|
|
"CODE401": "Show Text - Main dialogue content",
|
|
"CODE405": "Show Text (Scrolling) - Longer dialogue",
|
|
"CODE102": "Show Choices - Player choice options",
|
|
"CODE101": "Character Names - Turn on when names exist in 101",
|
|
"CODE408": "Comments - WARNING: Can inflate costs significantly",
|
|
"CODE122": "Control Variables - Text stored in variables",
|
|
|
|
"CODE355655": "Scripts - Text within script commands",
|
|
"CODE357": "Picture Text - Text displayed on pictures",
|
|
"CODE657": "Picture Text Extended - Extended picture text",
|
|
"CODE356": "Plugin Commands - Plugin command parameters",
|
|
"CODE320": "Change Name Input - Name input prompts",
|
|
"CODE324": "Change Nickname - Nickname changes",
|
|
"CODE111": "Conditional Branch - Conditional text",
|
|
"CODE108": "Comments - Comment blocks"
|
|
}
|