EU-Utility/ARCHITECTURE.md

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