EU-Utility/ARCHITECTURE.md

29 KiB

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.

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.

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.

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

# 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

# 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