298 lines
8.4 KiB
Python
298 lines
8.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
EU-Utility Premium - Main Entry Point
|
|
======================================
|
|
|
|
Launch the EU-Utility premium overlay system.
|
|
|
|
Usage:
|
|
python main.py # Start with default config
|
|
python main.py --config path/to/config.json
|
|
python main.py --no-overlay # Run without overlay (headless)
|
|
python main.py --test # Run in test mode
|
|
|
|
For more information, see TESTING.md
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
import logging
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
# Add the EU-Utility directory to path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
|
|
def setup_logging(verbose: bool = False) -> logging.Logger:
|
|
"""Setup logging configuration."""
|
|
level = logging.DEBUG if verbose else logging.INFO
|
|
|
|
logging.basicConfig(
|
|
level=level,
|
|
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
handlers=[
|
|
logging.StreamHandler(sys.stdout),
|
|
]
|
|
)
|
|
|
|
return logging.getLogger("EU-Utility")
|
|
|
|
|
|
def load_config(config_path: Path) -> dict:
|
|
"""Load configuration from file."""
|
|
if not config_path.exists():
|
|
# Create default config
|
|
default_config = {
|
|
"game_path": None,
|
|
"overlay_enabled": True,
|
|
"overlay_mode": "overlay_toggle",
|
|
"hotkey": "ctrl+shift+b",
|
|
"plugins": {
|
|
"enabled": [],
|
|
"disabled": []
|
|
},
|
|
"ui": {
|
|
"theme": "dark",
|
|
"opacity": 0.95,
|
|
"scale": 1.0
|
|
},
|
|
"features": {
|
|
"loot_tracker": True,
|
|
"skill_tracker": True,
|
|
"global_alerts": True,
|
|
"analytics": True
|
|
}
|
|
}
|
|
|
|
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(config_path, 'w') as f:
|
|
json.dump(default_config, f, indent=2)
|
|
|
|
return default_config
|
|
|
|
with open(config_path, 'r') as f:
|
|
return json.load(f)
|
|
|
|
|
|
def main():
|
|
"""Main entry point."""
|
|
parser = argparse.ArgumentParser(
|
|
description="EU-Utility Premium - Entropia Universe Overlay"
|
|
)
|
|
parser.add_argument(
|
|
'--config',
|
|
type=Path,
|
|
default=Path.home() / '.eu-utility' / 'config.json',
|
|
help='Path to configuration file'
|
|
)
|
|
parser.add_argument(
|
|
'--no-overlay',
|
|
action='store_true',
|
|
help='Run without overlay (headless mode)'
|
|
)
|
|
parser.add_argument(
|
|
'--test',
|
|
action='store_true',
|
|
help='Run in test mode (no game required)'
|
|
)
|
|
parser.add_argument(
|
|
'--verbose', '-v',
|
|
action='store_true',
|
|
help='Enable verbose logging'
|
|
)
|
|
parser.add_argument(
|
|
'--setup',
|
|
action='store_true',
|
|
help='Run first-time setup'
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Setup logging
|
|
logger = setup_logging(args.verbose)
|
|
logger.info("=" * 50)
|
|
logger.info("EU-Utility Premium Starting")
|
|
logger.info("=" * 50)
|
|
|
|
# Load config
|
|
config = load_config(args.config)
|
|
logger.info(f"Loaded config from: {args.config}")
|
|
|
|
# Run setup if requested
|
|
if args.setup:
|
|
run_setup(config, args.config)
|
|
return 0
|
|
|
|
# Check for game path
|
|
if not config.get('game_path') and not args.test:
|
|
logger.error("No game path configured. Run with --setup or edit config.json")
|
|
print("\n" + "=" * 50)
|
|
print("First-time setup required!")
|
|
print("=" * 50)
|
|
print("\nPlease run: python main.py --setup")
|
|
print("\nOr manually edit the config file:")
|
|
print(f" {args.config}")
|
|
print("\nAnd set the game_path to your Entropia Universe installation.")
|
|
print("=" * 50)
|
|
return 1
|
|
|
|
# Import and start the application
|
|
try:
|
|
from premium import EUUtilityApp
|
|
|
|
logger.info("Initializing application...")
|
|
app = EUUtilityApp(config_path=args.config)
|
|
|
|
# Override config with CLI args
|
|
if args.no_overlay:
|
|
config['overlay_enabled'] = False
|
|
|
|
if args.test:
|
|
logger.info("Running in TEST mode")
|
|
return run_test_mode(app, config)
|
|
|
|
# Normal operation
|
|
logger.info("Starting application...")
|
|
app.initialize()
|
|
app.run()
|
|
|
|
except KeyboardInterrupt:
|
|
logger.info("Interrupted by user")
|
|
return 0
|
|
|
|
except Exception as e:
|
|
logger.exception("Fatal error")
|
|
print(f"\nError: {e}")
|
|
return 1
|
|
|
|
|
|
def run_setup(config: dict, config_path: Path) -> None:
|
|
"""Run first-time setup wizard."""
|
|
print("\n" + "=" * 50)
|
|
print("EU-Utility Setup Wizard")
|
|
print("=" * 50 + "\n")
|
|
|
|
# Detect game path
|
|
print("Looking for Entropia Universe installation...")
|
|
|
|
possible_paths = [
|
|
Path("C:/Program Files (x86)/Entropia Universe"),
|
|
Path("C:/Program Files/Entropia Universe"),
|
|
Path.home() / "AppData" / "Local" / "Entropia Universe",
|
|
]
|
|
|
|
detected = None
|
|
for path in possible_paths:
|
|
if path.exists():
|
|
detected = path
|
|
print(f" Found: {path}")
|
|
break
|
|
|
|
if detected:
|
|
use = input(f"\nUse this path? [Y/n]: ").strip().lower()
|
|
if use in ('', 'y', 'yes'):
|
|
config['game_path'] = str(detected)
|
|
else:
|
|
detected = None
|
|
|
|
if not detected:
|
|
custom = input("Enter your Entropia Universe installation path: ").strip()
|
|
if custom:
|
|
config['game_path'] = custom
|
|
|
|
# Save config
|
|
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(config_path, 'w') as f:
|
|
json.dump(config, f, indent=2)
|
|
|
|
print(f"\nConfiguration saved to: {config_path}")
|
|
print("\nYou can now run: python main.py")
|
|
print("=" * 50)
|
|
|
|
|
|
def run_test_mode(app, config: dict) -> int:
|
|
"""Run in test mode without requiring game."""
|
|
print("\n" + "=" * 50)
|
|
print("EU-Utility TEST MODE")
|
|
print("=" * 50 + "\n")
|
|
|
|
try:
|
|
# Test imports
|
|
print("✓ Checking imports...")
|
|
from premium.plugins.api import PluginAPI, PluginManifest
|
|
from premium.plugins.manager import PluginManager
|
|
from premium.core.event_bus import EventBus
|
|
from premium.core.state.store import StateStore
|
|
print(" All imports successful")
|
|
|
|
# Test plugin system
|
|
print("\n✓ Testing plugin system...")
|
|
event_bus = EventBus()
|
|
store = StateStore(reducer=lambda s, a: s or {}, initial_state={})
|
|
|
|
plugin_manager = PluginManager(
|
|
plugin_dirs=[],
|
|
data_dir=Path.home() / '.eu-utility' / 'data',
|
|
event_bus=event_bus,
|
|
state_store=store
|
|
)
|
|
print(" Plugin manager initialized")
|
|
|
|
# Test event bus
|
|
print("\n✓ Testing event bus...")
|
|
test_events = []
|
|
|
|
@event_bus.on('test')
|
|
def on_test(event):
|
|
test_events.append(event)
|
|
|
|
event_bus.emit('test', {'message': 'hello'})
|
|
import time
|
|
time.sleep(0.1)
|
|
|
|
if len(test_events) == 1:
|
|
print(" Event bus working")
|
|
else:
|
|
print(" ⚠ Event bus may have issues")
|
|
|
|
# Test game client (simulated)
|
|
print("\n✓ Testing game client integration...")
|
|
from premium.eu_integration import GameClient
|
|
|
|
# Test with dummy path
|
|
client = GameClient(
|
|
game_path=Path.home(), # Dummy path for testing
|
|
event_bus=event_bus
|
|
)
|
|
print(" Game client initialized (simulated mode)")
|
|
|
|
# Test widget system
|
|
print("\n✓ Testing widget system...")
|
|
from premium.widgets import Widget, WidgetConfig
|
|
|
|
class TestWidget(Widget):
|
|
def create_ui(self, parent):
|
|
return None # No UI in test mode
|
|
|
|
widget = TestWidget(WidgetConfig(name="Test"))
|
|
print(" Widget system functional")
|
|
|
|
print("\n" + "=" * 50)
|
|
print("All tests passed!")
|
|
print("=" * 50)
|
|
print("\nThe application is ready to use.")
|
|
print("Run 'python main.py' to start with the actual game.")
|
|
|
|
return 0
|
|
|
|
except Exception as e:
|
|
print(f"\n✗ Test failed: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return 1
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|