# EU-Utility Architecture > System architecture, component design, and data flow documentation --- ## System Overview EU-Utility is built on a **modular plugin architecture** with clear separation of concerns. The system is organized into three main layers: 1. **Core Layer** - Foundation services and APIs 2. **Plugin Layer** - Extensible functionality modules 3. **UI Layer** - User interface components and overlays ``` ┌─────────────────────────────────────────────────────────────────┐ │ UI Layer │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ │ │ Overlay │ │ Widgets │ │ Activity Bar │ │ │ │ Window │ │ (Draggable)│ │ (Taskbar + App Drawer) │ │ │ └──────┬──────┘ └──────┬──────┘ └───────────┬─────────────┘ │ └─────────┼────────────────┼─────────────────────┼────────────────┘ │ │ │ └────────────────┴──────────┬──────────┘ │ ┌─────────────────────────────────────┼─────────────────────────────┐ │ Plugin Layer │ │ │ ┌──────────────────────────────────┘ │ │ │ │ │ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │ │ │ Search │ │ Calculator│ │ Tracker │ │ Scanner │ │ │ │ │ Plugins │ │ Plugins │ │ Plugins │ │ Plugins │ │ │ │ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘ │ │ │ │ │ │ │ │ │ │ └─────────────┴──────┬──────┴─────────────┘ │ │ │ │ │ │ │ ┌────────┴────────┐ │ │ │ │ BasePlugin API │ │ │ │ │ (Base Class) │ │ │ │ └────────┬────────┘ │ │ └─────────────────────────────┼─────────────────────────────────┘ └────────────────────────────────┼─────────────────────────────────┘ │ ┌────────────────────────────────┼─────────────────────────────────┐ │ Core Layer│ │ │ ┌─────────────────────────────┘ │ │ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ │ Three-Tier API System │ │ │ │ ├───────────────┬───────────────┬───────────────────────┤ │ │ │ │ PluginAPI │ WidgetAPI │ ExternalAPI │ │ │ │ │ (Services) │ (Overlays) │ (REST/Webhooks) │ │ │ │ └───────┬───────┴───────┬───────┴───────────┬───────────┘ │ │ │ │ │ │ │ │ │ ┌───────┴───────┐ ┌─────┴─────┐ ┌───────────┴──────────┐ │ │ │ │ Core Services │ │ Event │ │ Data Layer │ │ │ │ │ │ │ Bus │ │ │ │ │ │ │ • Window Mgr │ │ (Pub/Sub) │ │ • SQLite Store │ │ │ │ │ • OCR Service │ │ │ │ • Settings │ │ │ │ │ • Screenshot │ │ │ │ • Plugin States │ │ │ │ │ • Log Reader │ │ │ │ • Activity Log │ │ │ │ │ • Nexus API │ │ │ │ │ │ │ │ │ • HTTP Client │ │ │ │ │ │ │ │ │ • Audio │ │ │ │ │ │ │ │ └───────────────┘ └───────────┘ └──────────────────────┘ │ │ │ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ │ Plugin Manager │ │ │ │ │ (Discovery, Loading, Lifecycle, Dependencies) │ │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ │ │ └────────────────────────────────────────────────────────────────┘ └────────────────────────────────────────────────────────────────────┘ ``` --- ## Core Layer ### Three-Tier API System The Core provides a unified API organized into three tiers: #### 1. PluginAPI Primary interface for plugin developers to access core services. ```python from core.api import get_api api = get_api() # Window Management window = api.get_eu_window() is_focused = api.is_eu_focused() # OCR if api.ocr_available(): text = api.recognize_text(region=(100, 100, 200, 50)) # Data Storage api.set_data("key", value) value = api.get_data("key", default) ``` **Available Services:** - `LogReader` - Read and monitor Entropia Universe chat logs - `WindowManager` - Detect and interact with EU window - `OCRService` - Screen text recognition (EasyOCR/Tesseract/PaddleOCR) - `Screenshot` - Screen capture with multiple backends - `NexusAPI` - Entropia Nexus item database integration - `HTTPClient` - Cached web requests with rate limiting - `Audio` - Sound playback and volume control - `Clipboard` - Cross-platform copy/paste - `Notifications` - Desktop toast notifications - `EventBus` - Pub/sub event system - `DataStore` - Persistent key-value storage - `TaskManager` - Background task execution #### 2. WidgetAPI Manages overlay widgets - floating UI components. ```python from core.api import get_widget_api widget_api = get_widget_api() # Create widget widget = widget_api.create_widget( name="loot_tracker", title="Loot Tracker", size=(400, 300) ) widget.show() ``` **Features:** - Draggable overlay widgets - Size and position persistence - Opacity control - Lock/unlock positioning - Layout helpers (grid, cascade) #### 3. ExternalAPI Provides REST endpoints and webhook support for third-party integrations. ```python from core.api import get_external_api ext = get_external_api() ext.start_server(port=8080) # Register endpoint @ext.endpoint("stats", methods=["GET"]) def get_stats(): return {"kills": 100, "loot": "50 PED"} ``` **Features:** - REST API server with CORS - Incoming/outgoing webhooks - HMAC authentication - IPC (Inter-Process Communication) - Server-Sent Events (SSE) --- ## Plugin Layer ### Plugin Architecture All plugins inherit from `BasePlugin` and implement a standard interface: ``` ┌─────────────────────────────────────────┐ │ BasePlugin (Abstract) │ ├─────────────────────────────────────────┤ │ Metadata: name, version, author, etc. │ ├─────────────────────────────────────────┤ │ initialize() → Setup plugin │ │ get_ui() → Return QWidget │ │ on_show() → Overlay visible │ │ on_hide() → Overlay hidden │ │ on_hotkey() → Hotkey pressed │ │ shutdown() → Cleanup resources │ ├─────────────────────────────────────────┤ │ Helper Methods: │ │ • OCR capture │ │ • Screenshot │ │ • Log reading │ │ • Data storage │ │ • Event publishing/subscribing │ │ • Nexus API access │ │ • Background tasks │ │ • Notifications │ └─────────────────────────────────────────┘ │ ┌───────────┼───────────┐ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ Search │ │ Tracker │ │Utility │ │ Plugins │ │ Plugins │ │ Plugins │ └─────────┘ └─────────┘ └─────────┘ ``` ### Plugin Categories | Category | Purpose | Examples | |----------|---------|----------| | **Search** | Data lookup | Universal Search, Nexus Search, TP Runner | | **Trackers** | Progress monitoring | Loot, Skills, Codex, Missions, Globals | | **Calculators** | Game math | DPP, Crafting, Enhancer, Markup | | **Scanners** | OCR-based tools | Game Reader, Skill Scanner | | **Integration** | External services | Spotify Controller, Chat Logger | | **System** | Core functionality | Dashboard, Settings, Plugin Store | ### Plugin Lifecycle ``` Discovery │ ▼ ┌──────────┐ │ Import │ └────┬─────┘ │ ▼ ┌──────────┐ No ┌──────────┐ │ Enabled? │───────────▶│ Skip │ └────┬─────┘ └──────────┘ │ Yes ▼ ┌──────────┐ │ Load │ │ Module │ └────┬─────┘ │ ▼ ┌──────────┐ Error ┌──────────┐ │Initialize│───────────▶│ Disable │ └────┬─────┘ └──────────┘ │ Success ▼ ┌──────────┐ │ Running │◀───────┐ └────┬─────┘ │ │ │ ▼ │ ┌──────────┐ │ │ Hotkey │ │ │ Pressed │────────┘ └──────────┘ │ ▼ ┌──────────┐ │ Shutdown │ └──────────┘ ``` --- ## Event System ### Event Bus Architecture The Event Bus provides typed, filterable pub/sub communication: ``` ┌─────────────────────────────────────────────────┐ │ Event Bus │ ├─────────────────────────────────────────────────┤ │ │ │ Publisher ─────┐ │ │ │ │ │ ▼ │ │ ┌─────────────────────────┐ │ │ │ Event Router │ │ │ │ (Type + Filter Match) │ │ │ └────────────┬────────────┘ │ │ │ │ │ ┌───────────┼───────────┐ │ │ ▼ ▼ ▼ │ │ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ Sub │ │ Sub │ │ Sub │ │ │ │ #1 │ │ #2 │ │ #3 │ │ │ └──────┘ └──────┘ └──────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ Plugin A Plugin B Plugin C │ │ │ │ ┌────────────────────────────────────────────┐ │ │ │ Event Types: │ │ │ │ • SkillGainEvent │ │ │ │ • LootEvent │ │ │ │ • DamageEvent │ │ │ │ • GlobalEvent │ │ │ │ • ChatEvent │ │ │ │ • EconomyEvent │ │ │ │ • SystemEvent │ │ │ └────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────┘ ``` ### Event Flow Example ```python # Plugin A publishes loot event from core.event_bus import LootEvent self.publish_typed(LootEvent( mob_name="Daikiba", items=[{"name": "Animal Oil", "value": 0.05}], total_tt_value=0.05 )) # Plugin B subscribes with filter self.subscribe_typed( LootEvent, on_loot, mob_types=["Daikiba", "Atrox"] # Filter ) ``` --- ## Data Flow ### Data Layer Architecture ``` ┌─────────────────────────────────────────────────────────┐ │ Data Layer │ ├─────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ SQLite Data Store │ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │user_prefs │ │plugin_states│ │ │ │ │ ├─────────────┤ ├─────────────┤ │ │ │ │ │• settings │ │• enabled │ │ │ │ │ │• hotkeys │ │• version │ │ │ │ │ │• theme │ │• settings │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │sessions │ │activity_log │ │ │ │ │ ├─────────────┤ ├─────────────┤ │ │ │ │ │• start_time │ │• timestamp │ │ │ │ │ │• end_time │ │• category │ │ │ │ │ │• stats │ │• action │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │dashboard │ │hotkeys │ │ │ │ │ │_widgets │ │ │ │ │ │ │ ├─────────────┤ ├─────────────┤ │ │ │ │ │• position │ │• key_combo │ │ │ │ │ │• size │ │• action │ │ │ │ │ │• config │ │• plugin_id │ │ │ │ │ └─────────────┘ └─────────────┘ │ │ │ │ │ │ │ └─────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────────┐ │ │ │ Data Access Pattern │ │ │ │ │ │ │ │ Plugin ──▶ API ──▶ SQLiteStore ──▶ SQLite DB │ │ │ │ │ │ │ │ All data is JSON-serialized for flexibility │ │ │ └─────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────┘ ``` --- ## UI Architecture ### Overlay System ``` ┌─────────────────────────────────────────────────────────────┐ │ Desktop │ │ ┌─────────────────────────────────────────────────────┐ │ │ │ Main Overlay Window │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ Plugin Tab Bar │ │ │ │ │ │ [Dash][Search][Calc][Track][...] │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ │ ┌─────────┬──────────────────────────────────┐ │ │ │ │ │ Plugin │ │ │ │ │ │ │ List │ Active Plugin Content │ │ │ │ │ │ │ │ │ │ │ │ │ • Search│ ┌──────────────────────┐ │ │ │ │ │ │ • Calc │ │ │ │ │ │ │ │ │ • Track │ │ Plugin UI Here │ │ │ │ │ │ │ • ... │ │ │ │ │ │ │ │ │ │ └──────────────────────┘ │ │ │ │ │ └─────────┴──────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────────────────┐ │ │ │ │ │ Quick Actions Bar │ │ │ │ │ └─────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────┼─────────────────┐ │ │ ▼ ▼ ▼ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Floating │ │ Widget │ │ Activity │ │ │ │ Icon │ │ (Loot) │ │ Bar │ │ │ │ (Draggable)│ │ (Draggable)│ │(Bottom/Top) │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ └─────────────────────────────────────────────────────────────┘ ``` ### Component Hierarchy ``` QApplication └── EUUtilityApp ├── MainOverlayWindow │ ├── PluginTabBar │ ├── PluginSidebar │ ├── PluginContentArea │ └── QuickActionsBar ├── FloatingIcon (always on top) ├── ActivityBar (optional, bottom/top) │ ├── StartButton (opens AppDrawer) │ ├── PinnedPlugins │ ├── SearchBox │ └── Clock/Settings ├── WidgetOverlay │ └── Individual Widgets └── TrayIcon └── ContextMenu ``` --- ## Security Architecture ### Data Protection ``` ┌─────────────────────────────────────────┐ │ Security Layer │ ├─────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────┐ │ │ │ Input Sanitization │ │ │ │ • Path traversal protection │ │ │ │ • SQL injection prevention │ │ │ │ • XSS protection │ │ │ └─────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────┐ │ │ │ Data Encryption │ │ │ │ • AES-256 for sensitive data │ │ │ │ • Secure key storage │ │ │ │ • Encrypted settings │ │ │ └─────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────┐ │ │ │ File Operations │ │ │ │ • Atomic writes (temp files) │ │ │ │ • Proper file permissions │ │ │ │ • Safe temp file handling │ │ │ └─────────────────────────────────┘ │ │ │ │ ┌─────────────────────────────────┐ │ │ │ Plugin Isolation │ │ │ │ • Try/except around plugin ops │ │ │ │ • Separate error handling │ │ │ │ • Resource cleanup on crash │ │ │ └─────────────────────────────────┘ │ │ │ └─────────────────────────────────────────┘ ``` --- ## Performance Optimizations ### Caching Strategy | Layer | Cache Type | TTL | Purpose | |-------|------------|-----|---------| | HTTP Client | Response cache | Configurable | API responses | | Nexus API | Item data | 5 minutes | Item/market data | | Icon Manager | Loaded icons | Session | UI performance | | Plugin Manager | Loaded plugins | Session | Startup time | | Settings | Config values | Session | Fast access | ### Resource Management ```python # Lazy initialization pattern class ExpensiveService: def __init__(self): self._initialized = False self._resource = None @property def resource(self): if not self._initialized: self._resource = self._create_expensive_resource() self._initialized = True return self._resource ``` --- ## Technology Stack | Component | Technology | |-----------|------------| | **Language** | Python 3.11+ | | **UI Framework** | PyQt6 | | **Database** | SQLite | | **HTTP Client** | `requests` with caching | | **OCR** | EasyOCR / Tesseract / PaddleOCR | | **Screenshot** | PIL / MSS / Win32 (Windows) | | **Audio** | pygame.mixer / simpleaudio | | **Task Queue** | ThreadPoolExecutor | --- ## See Also - [API Reference](./API.md) - Complete API documentation - [Plugin Development](./docs/PLUGIN_DEVELOPMENT.md) - Creating plugins - [Contributing](./CONTRIBUTING.md) - Contribution guidelines