534 lines
29 KiB
Markdown
534 lines
29 KiB
Markdown
# 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
|