1302 lines
25 KiB
Markdown
1302 lines
25 KiB
Markdown
# EU-Utility API Reference
|
|
|
|
> Complete API reference for EU-Utility core services and plugin development
|
|
>
|
|
> **Version:** 2.0
|
|
> **Last Updated:** 2025-02-14
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Core Services Overview](#core-services-overview)
|
|
2. [PluginAPI](#pluginapi)
|
|
3. [BasePlugin](#baseplugin)
|
|
4. [Event Bus](#event-bus)
|
|
5. [Task Manager](#task-manager)
|
|
6. [Nexus API](#nexus-api)
|
|
7. [Settings](#settings)
|
|
8. [Data Store](#data-store)
|
|
9. [Audio Manager](#audio-manager)
|
|
10. [HTTP Client](#http-client)
|
|
11. [OCR Service](#ocr-service)
|
|
12. [Screenshot Service](#screenshot-service)
|
|
13. [Log Reader](#log-reader)
|
|
14. [Window Manager](#window-manager)
|
|
15. [Notification Manager](#notification-manager)
|
|
16. [Clipboard Manager](#clipboard-manager)
|
|
|
|
---
|
|
|
|
## Core Services Overview
|
|
|
|
EU-Utility provides a comprehensive set of core services accessible through the PluginAPI:
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ PluginAPI (Singleton) │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ OCR Service │ Screenshot │ Log Reader │ Nexus API │
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Task Manager │ Event Bus │ Audio │ HTTP Client│
|
|
├─────────────────────────────────────────────────────────────┤
|
|
│ Window Manager │ Data Store │ Clipboard │ Settings │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
### Accessing Services
|
|
|
|
```python
|
|
from core.plugin_api import get_api
|
|
|
|
api = get_api()
|
|
|
|
# Use services
|
|
result = api.ocr_capture()
|
|
```
|
|
|
|
---
|
|
|
|
## PluginAPI
|
|
|
|
### Class: `PluginAPI`
|
|
|
|
Central API registry and shared services.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.plugin_api import get_api
|
|
|
|
api = get_api()
|
|
```
|
|
|
|
#### API Registration
|
|
|
|
```python
|
|
from core.plugin_api import APIEndpoint, APIType
|
|
|
|
# Register an API endpoint
|
|
endpoint = APIEndpoint(
|
|
name="scan_window",
|
|
api_type=APIType.OCR,
|
|
description="Scan game window and return text",
|
|
handler=self.scan_window,
|
|
plugin_id=self._plugin_id,
|
|
version="1.0.0"
|
|
)
|
|
|
|
success = api.register_api(endpoint)
|
|
|
|
# Unregister
|
|
api.unregister_api(plugin_id, name)
|
|
```
|
|
|
|
#### Calling APIs
|
|
|
|
```python
|
|
# Call another plugin's API
|
|
result = api.call_api("plugin_id", "api_name", arg1, arg2)
|
|
|
|
# Find available APIs
|
|
ocr_apis = api.find_apis(APIType.OCR)
|
|
```
|
|
|
|
#### OCR Service
|
|
|
|
```python
|
|
# Capture and OCR
|
|
result = api.ocr_capture(region=(x, y, width, height))
|
|
# Returns: {'text': str, 'confidence': float, 'raw_results': list}
|
|
```
|
|
|
|
#### Screenshot Service
|
|
|
|
```python
|
|
# Capture screen
|
|
image = api.capture_screen(full_screen=True)
|
|
|
|
# Capture region
|
|
image = api.capture_region(x, y, width, height)
|
|
|
|
# Get last screenshot
|
|
image = api.get_last_screenshot()
|
|
|
|
# Save screenshot
|
|
path = api.save_screenshot(image, filename="screenshot.png")
|
|
```
|
|
|
|
#### Log Service
|
|
|
|
```python
|
|
# Read log lines
|
|
lines = api.read_log(lines=50, filter_text="loot")
|
|
# Returns: List[str]
|
|
```
|
|
|
|
#### Shared Data
|
|
|
|
```python
|
|
# Set data
|
|
api.set_data("key", value)
|
|
|
|
# Get data
|
|
value = api.get_data("key", default=None)
|
|
```
|
|
|
|
#### Audio Service
|
|
|
|
```python
|
|
# Play sounds
|
|
api.play_sound("hof") # Predefined
|
|
api.play_sound("/path/to/custom.wav") # Custom file
|
|
api.play_sound("alert", blocking=True) # Wait for completion
|
|
|
|
# Volume control
|
|
api.set_volume(0.8) # 0.0 to 1.0
|
|
volume = api.get_volume() # Get current volume
|
|
|
|
# Mute
|
|
api.mute_audio()
|
|
api.unmute_audio()
|
|
is_muted = api.is_audio_muted()
|
|
|
|
# Check availability
|
|
if api.is_audio_available():
|
|
api.play_sound("skill_gain")
|
|
```
|
|
|
|
#### Background Tasks
|
|
|
|
```python
|
|
# Run in background
|
|
task_id = api.run_in_background(
|
|
func=my_function,
|
|
arg1, arg2,
|
|
priority='normal', # 'high', 'normal', 'low'
|
|
on_complete=on_done, # Callback with result
|
|
on_error=on_error # Callback with exception
|
|
)
|
|
|
|
# Schedule task
|
|
task_id = api.schedule_task(
|
|
delay_ms=5000, # 5 seconds
|
|
func=my_function,
|
|
priority='normal',
|
|
on_complete=on_done
|
|
)
|
|
|
|
# Periodic task
|
|
task_id = api.schedule_task(
|
|
delay_ms=0,
|
|
func=refresh_data,
|
|
periodic=True,
|
|
interval_ms=30000, # Every 30 seconds
|
|
on_complete=update_ui
|
|
)
|
|
|
|
# Cancel task
|
|
api.cancel_task(task_id)
|
|
|
|
# Get status
|
|
status = api.get_task_status(task_id) # 'pending', 'running', 'completed', 'failed', 'cancelled'
|
|
|
|
# Wait for completion
|
|
completed = api.wait_for_task(task_id, timeout=10.0)
|
|
|
|
# Connect signals
|
|
api.connect_task_signal('completed', on_task_complete)
|
|
api.connect_task_signal('failed', on_task_error)
|
|
```
|
|
|
|
#### Nexus API
|
|
|
|
```python
|
|
# Search
|
|
results = api.nexus_search("ArMatrix", entity_type="items", limit=20)
|
|
results = api.nexus_search("Atrox", entity_type="mobs")
|
|
|
|
# Get details
|
|
details = api.nexus_get_item_details("armatrix_lp-35")
|
|
|
|
# Get market data
|
|
market = api.nexus_get_market_data("armatrix_lp-35")
|
|
|
|
# Check availability
|
|
if api.nexus_is_available():
|
|
results = api.nexus_search("query")
|
|
```
|
|
|
|
#### Event Bus (Typed)
|
|
|
|
```python
|
|
from core.event_bus import SkillGainEvent, LootEvent
|
|
|
|
# Publish event
|
|
api.publish_typed(SkillGainEvent(
|
|
skill_name="Rifle",
|
|
skill_value=25.5,
|
|
gain_amount=0.01
|
|
))
|
|
|
|
# Publish synchronously
|
|
count = api.publish_typed_sync(event)
|
|
|
|
# Subscribe
|
|
sub_id = api.subscribe_typed(
|
|
SkillGainEvent,
|
|
callback_function,
|
|
min_damage=100, # Filter options
|
|
replay_last=10 # Replay recent events
|
|
)
|
|
|
|
# Unsubscribe
|
|
api.unsubscribe_typed(sub_id)
|
|
|
|
# Get recent events
|
|
recent = api.get_recent_events(SkillGainEvent, count=50)
|
|
|
|
# Get stats
|
|
stats = api.get_event_stats()
|
|
```
|
|
|
|
#### Utility Methods
|
|
|
|
```python
|
|
# Currency formatting
|
|
api.format_ped(123.45) # "123.45 PED"
|
|
api.format_pec(50) # "50 PEC"
|
|
|
|
# Calculations
|
|
api.calculate_dpp(damage=45.0, ammo=100, decay=2.5)
|
|
api.calculate_markup(price=150.0, tt=100.0) # 150.0%
|
|
```
|
|
|
|
---
|
|
|
|
## BasePlugin
|
|
|
|
### Class: `BasePlugin`
|
|
|
|
Abstract base class for all plugins.
|
|
|
|
#### Attributes
|
|
|
|
| Attribute | Type | Required | Description |
|
|
|-----------|------|----------|-------------|
|
|
| `name` | str | Yes | Display name |
|
|
| `version` | str | Yes | Version string |
|
|
| `author` | str | Yes | Creator name |
|
|
| `description` | str | Yes | Short description |
|
|
| `hotkey` | str | No | Global hotkey |
|
|
| `enabled` | bool | No | Start enabled |
|
|
| `icon` | str | No | Icon path/emoji |
|
|
|
|
#### Constructor
|
|
|
|
```python
|
|
def __init__(self, overlay_window: OverlayWindow, config: Dict[str, Any])
|
|
```
|
|
|
|
#### Abstract Methods
|
|
|
|
```python
|
|
def initialize(self) -> None:
|
|
"""Called when plugin is loaded. Setup API connections."""
|
|
pass
|
|
|
|
def get_ui(self) -> Any:
|
|
"""Return the plugin's UI widget (QWidget)."""
|
|
return None
|
|
```
|
|
|
|
#### Lifecycle Methods
|
|
|
|
```python
|
|
def on_show(self) -> None:
|
|
"""Called when overlay becomes visible."""
|
|
pass
|
|
|
|
def on_hide(self) -> None:
|
|
"""Called when overlay is hidden."""
|
|
pass
|
|
|
|
def on_hotkey(self) -> None:
|
|
"""Called when plugin's hotkey is pressed."""
|
|
pass
|
|
|
|
def shutdown(self) -> None:
|
|
"""Called when app is closing. Cleanup resources."""
|
|
# Unregister APIs
|
|
if self.api and self._api_registered:
|
|
self.api.unregister_api(self._plugin_id)
|
|
|
|
# Unsubscribe from events
|
|
self.unsubscribe_all_typed()
|
|
```
|
|
|
|
#### Configuration Methods
|
|
|
|
```python
|
|
# Get config with default
|
|
value = self.get_config('key', default_value)
|
|
|
|
# Set config
|
|
self.set_config('key', value)
|
|
```
|
|
|
|
#### API Methods
|
|
|
|
```python
|
|
# Register API endpoint
|
|
self.register_api(
|
|
name="scan_window",
|
|
handler=self.scan_window,
|
|
api_type=APIType.OCR,
|
|
description="Scan game window"
|
|
)
|
|
|
|
# Call another plugin's API
|
|
result = self.call_api("plugin_id", "api_name", *args, **kwargs)
|
|
|
|
# Find APIs
|
|
apis = self.find_apis(APIType.OCR)
|
|
```
|
|
|
|
#### Service Methods
|
|
|
|
```python
|
|
# OCR
|
|
result = self.ocr_capture(region=(x, y, w, h))
|
|
|
|
# Screenshots
|
|
image = self.capture_screen(full_screen=True)
|
|
image = self.capture_region(x, y, w, h)
|
|
last = self.get_last_screenshot()
|
|
|
|
# Log
|
|
lines = self.read_log(lines=50, filter_text="keyword")
|
|
|
|
# Shared data
|
|
self.set_shared_data('key', value)
|
|
data = self.get_shared_data('key', default)
|
|
```
|
|
|
|
#### Event Methods
|
|
|
|
```python
|
|
# Legacy events
|
|
self.publish_event('event_type', {'key': 'value'})
|
|
self.subscribe('event_type', callback)
|
|
|
|
# Typed events
|
|
self.publish_typed(SkillGainEvent(...))
|
|
|
|
sub_id = self.subscribe_typed(
|
|
SkillGainEvent,
|
|
callback,
|
|
min_damage=100,
|
|
replay_last=10
|
|
)
|
|
|
|
self.unsubscribe_typed(sub_id)
|
|
self.unsubscribe_all_typed()
|
|
|
|
# Get recent events
|
|
recent = self.get_recent_events(SkillGainEvent, 50)
|
|
stats = self.get_event_stats()
|
|
```
|
|
|
|
#### Utility Methods
|
|
|
|
```python
|
|
# Currency
|
|
self.format_ped(123.45) # "123.45 PED"
|
|
self.format_pec(50) # "50 PEC"
|
|
|
|
# Calculations
|
|
self.calculate_dpp(damage, ammo, decay)
|
|
self.calculate_markup(price, tt)
|
|
```
|
|
|
|
#### Audio Methods
|
|
|
|
```python
|
|
self.play_sound('hof')
|
|
self.set_volume(0.8)
|
|
self.get_volume()
|
|
self.mute()
|
|
self.unmute()
|
|
self.toggle_mute()
|
|
self.is_muted()
|
|
self.is_audio_available()
|
|
```
|
|
|
|
#### Background Task Methods
|
|
|
|
```python
|
|
# Run in background
|
|
task_id = self.run_in_background(
|
|
func, *args,
|
|
priority='normal',
|
|
on_complete=callback,
|
|
on_error=error_callback,
|
|
**kwargs
|
|
)
|
|
|
|
# Schedule
|
|
task_id = self.schedule_task(
|
|
delay_ms, func, *args,
|
|
priority='normal',
|
|
on_complete=callback,
|
|
periodic=False,
|
|
interval_ms=None,
|
|
**kwargs
|
|
)
|
|
|
|
# Control
|
|
self.cancel_task(task_id)
|
|
self.connect_task_signals(
|
|
on_completed=callback,
|
|
on_failed=error_callback,
|
|
on_started=callback,
|
|
on_cancelled=callback
|
|
)
|
|
```
|
|
|
|
#### Nexus API Methods
|
|
|
|
```python
|
|
results = self.nexus_search(query, entity_type="items", limit=20)
|
|
details = self.nexus_get_item_details(item_id)
|
|
market = self.nexus_get_market_data(item_id)
|
|
available = self.nexus_is_available()
|
|
```
|
|
|
|
---
|
|
|
|
## Event Bus
|
|
|
|
### Class: `EventBus`
|
|
|
|
Typed event system with filtering and persistence.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.event_bus import get_event_bus
|
|
|
|
event_bus = get_event_bus()
|
|
```
|
|
|
|
#### Event Types
|
|
|
|
```python
|
|
from core.event_bus import (
|
|
BaseEvent,
|
|
SkillGainEvent,
|
|
LootEvent,
|
|
DamageEvent,
|
|
GlobalEvent,
|
|
ChatEvent,
|
|
EconomyEvent,
|
|
SystemEvent,
|
|
EventCategory
|
|
)
|
|
```
|
|
|
|
#### Publishing Events
|
|
|
|
```python
|
|
# Async (non-blocking)
|
|
event_bus.publish(event)
|
|
|
|
# Sync (blocking, returns count)
|
|
count = event_bus.publish_sync(event)
|
|
```
|
|
|
|
#### Subscribing
|
|
|
|
```python
|
|
# Basic subscription
|
|
sub_id = event_bus.subscribe(
|
|
callback=my_callback,
|
|
event_filter=filter_obj,
|
|
replay_history=True,
|
|
replay_count=100
|
|
)
|
|
|
|
# Typed subscription
|
|
sub_id = event_bus.subscribe_typed(
|
|
SkillGainEvent,
|
|
callback,
|
|
skill_names=["Rifle", "Pistol"],
|
|
replay_last=10
|
|
)
|
|
|
|
# Unsubscribe
|
|
event_bus.unsubscribe(sub_id)
|
|
```
|
|
|
|
#### Event Filters
|
|
|
|
```python
|
|
from core.event_bus import EventFilter
|
|
|
|
# Create filter
|
|
filter_obj = EventFilter(
|
|
event_types=[SkillGainEvent, LootEvent],
|
|
categories=[EventCategory.SKILL, EventCategory.LOOT],
|
|
min_damage=100,
|
|
max_damage=500,
|
|
mob_types=["Dragon", "Drake"],
|
|
skill_names=["Rifle"],
|
|
sources=["my_plugin"],
|
|
custom_predicate=lambda e: e.value > 100
|
|
)
|
|
|
|
# Check match
|
|
if filter_obj.matches(event):
|
|
print("Event matches filter!")
|
|
```
|
|
|
|
#### Getting Events
|
|
|
|
```python
|
|
# Recent events
|
|
recent = event_bus.get_recent_events(
|
|
event_type=SkillGainEvent,
|
|
count=100,
|
|
category=EventCategory.SKILL
|
|
)
|
|
|
|
# By time range
|
|
events = event_bus.get_events_by_time_range(
|
|
start=datetime_obj,
|
|
end=datetime_obj
|
|
)
|
|
```
|
|
|
|
#### Statistics
|
|
|
|
```python
|
|
stats = event_bus.get_stats()
|
|
# Returns: {
|
|
# 'total_published': int,
|
|
# 'total_delivered': int,
|
|
# 'active_subscriptions': int,
|
|
# 'events_per_minute': float,
|
|
# 'avg_delivery_ms': float,
|
|
# 'errors': int,
|
|
# 'uptime_seconds': float,
|
|
# 'top_event_types': dict
|
|
# }
|
|
```
|
|
|
|
#### Event Classes
|
|
|
|
```python
|
|
@dataclass(frozen=True)
|
|
class SkillGainEvent(BaseEvent):
|
|
skill_name: str = ""
|
|
skill_value: float = 0.0
|
|
gain_amount: float = 0.0
|
|
|
|
@dataclass(frozen=True)
|
|
class LootEvent(BaseEvent):
|
|
mob_name: str = ""
|
|
items: List[Dict[str, Any]] = field(default_factory=list)
|
|
total_tt_value: float = 0.0
|
|
position: Optional[tuple] = None
|
|
|
|
@dataclass(frozen=True)
|
|
class DamageEvent(BaseEvent):
|
|
damage_amount: float = 0.0
|
|
damage_type: str = ""
|
|
is_critical: bool = False
|
|
target_name: str = ""
|
|
attacker_name: str = ""
|
|
is_outgoing: bool = True
|
|
|
|
@dataclass(frozen=True)
|
|
class GlobalEvent(BaseEvent):
|
|
player_name: str = ""
|
|
achievement_type: str = "" # "hof", "ath", "discovery"
|
|
value: float = 0.0
|
|
item_name: Optional[str] = None
|
|
|
|
@dataclass(frozen=True)
|
|
class ChatEvent(BaseEvent):
|
|
channel: str = "" # "main", "team", "society"
|
|
sender: str = ""
|
|
message: str = ""
|
|
|
|
@dataclass(frozen=True)
|
|
class EconomyEvent(BaseEvent):
|
|
transaction_type: str = "" # "sale", "purchase"
|
|
amount: float = 0.0
|
|
currency: str = "PED"
|
|
description: str = ""
|
|
|
|
@dataclass(frozen=True)
|
|
class SystemEvent(BaseEvent):
|
|
message: str = ""
|
|
severity: str = "info" # "debug", "info", "warning", "error", "critical"
|
|
```
|
|
|
|
---
|
|
|
|
## Task Manager
|
|
|
|
### Class: `TaskManager`
|
|
|
|
Thread pool-based background task execution.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.tasks import get_task_manager
|
|
|
|
task_manager = get_task_manager(max_workers=4)
|
|
```
|
|
|
|
#### Task Priorities
|
|
|
|
```python
|
|
from core.tasks import TaskPriority
|
|
|
|
TaskPriority.HIGH # 3
|
|
TaskPriority.NORMAL # 2
|
|
TaskPriority.LOW # 1
|
|
```
|
|
|
|
#### Running Tasks
|
|
|
|
```python
|
|
# Run in thread
|
|
task_id = task_manager.run_in_thread(
|
|
func=my_function,
|
|
arg1, arg2,
|
|
priority=TaskPriority.NORMAL,
|
|
on_complete=callback,
|
|
on_error=error_callback
|
|
)
|
|
|
|
# Run later
|
|
task_id = task_manager.run_later(
|
|
delay_ms=5000,
|
|
func=my_function,
|
|
*args,
|
|
priority=TaskPriority.NORMAL,
|
|
on_complete=callback
|
|
)
|
|
|
|
# Run periodic
|
|
task_id = task_manager.run_periodic(
|
|
interval_ms=30000,
|
|
func=my_function,
|
|
*args,
|
|
priority=TaskPriority.NORMAL,
|
|
on_complete=callback,
|
|
run_immediately=True
|
|
)
|
|
```
|
|
|
|
#### Task Control
|
|
|
|
```python
|
|
# Cancel
|
|
task_manager.cancel_task(task_id)
|
|
|
|
# Get status
|
|
status = task_manager.get_task_status(task_id)
|
|
# Returns: TaskStatus.PENDING, RUNNING, COMPLETED, FAILED, CANCELLED
|
|
|
|
# Wait for completion
|
|
task_manager.wait_for_task(task_id, timeout=10.0)
|
|
|
|
# Get all tasks
|
|
tasks = task_manager.get_all_tasks()
|
|
|
|
# Get task by ID
|
|
task = task_manager.get_task(task_id)
|
|
```
|
|
|
|
#### Signals
|
|
|
|
```python
|
|
# Connect to signals
|
|
task_manager.connect_signal('completed', on_completed)
|
|
task_manager.connect_signal('failed', on_failed)
|
|
task_manager.connect_signal('started', on_started)
|
|
task_manager.connect_signal('cancelled', on_cancelled)
|
|
task_manager.connect_signal('periodic', on_periodic)
|
|
```
|
|
|
|
#### Shutdown
|
|
|
|
```python
|
|
# Graceful shutdown
|
|
task_manager.shutdown(wait=True, timeout=30.0)
|
|
```
|
|
|
|
---
|
|
|
|
## Nexus API
|
|
|
|
### Class: `NexusAPI`
|
|
|
|
Client for Entropia Nexus API.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.nexus_api import get_nexus_api
|
|
|
|
nexus = get_nexus_api()
|
|
```
|
|
|
|
#### Search Methods
|
|
|
|
```python
|
|
# Search items
|
|
results = nexus.search_items("ArMatrix", limit=20)
|
|
|
|
# Search mobs
|
|
results = nexus.search_mobs("Atrox", limit=20)
|
|
|
|
# Search all types
|
|
results = nexus.search_all("Calypso", limit=30)
|
|
|
|
# Search by entity type
|
|
results = nexus.search_by_type("ArMatrix", entity_type="weapons", limit=20)
|
|
```
|
|
|
|
#### Detail Methods
|
|
|
|
```python
|
|
# Get item details
|
|
details = nexus.get_item_details("armatrix_lp-35")
|
|
|
|
# Get entity details
|
|
details = nexus.get_entity_details("atrox", entity_type="mobs")
|
|
|
|
# Get market data
|
|
market = nexus.get_market_data("armatrix_lp-35")
|
|
```
|
|
|
|
#### Batch Methods
|
|
|
|
```python
|
|
# Get multiple items
|
|
results = nexus.get_items_batch(["id1", "id2", "id3"])
|
|
|
|
# Get multiple market data
|
|
results = nexus.get_market_batch(["id1", "id2"])
|
|
```
|
|
|
|
#### Utility Methods
|
|
|
|
```python
|
|
# Clear cache
|
|
nexus.clear_cache()
|
|
|
|
# Check availability
|
|
if nexus.is_available():
|
|
results = nexus.search_items("query")
|
|
```
|
|
|
|
#### Data Classes
|
|
|
|
```python
|
|
@dataclass
|
|
class SearchResult:
|
|
id: str
|
|
name: str
|
|
type: str
|
|
category: Optional[str]
|
|
icon_url: Optional[str]
|
|
data: Dict[str, Any]
|
|
|
|
@dataclass
|
|
class ItemDetails:
|
|
id: str
|
|
name: str
|
|
description: Optional[str]
|
|
category: Optional[str]
|
|
weight: Optional[float]
|
|
tt_value: Optional[float]
|
|
decay: Optional[float]
|
|
ammo_consumption: Optional[int]
|
|
damage: Optional[float]
|
|
range: Optional[float]
|
|
accuracy: Optional[float]
|
|
durability: Optional[int]
|
|
requirements: Dict[str, Any]
|
|
materials: List[Dict[str, Any]]
|
|
raw_data: Dict[str, Any]
|
|
|
|
@dataclass
|
|
class MarketData:
|
|
item_id: str
|
|
item_name: str
|
|
current_markup: Optional[float]
|
|
avg_markup_7d: Optional[float]
|
|
avg_markup_30d: Optional[float]
|
|
volume_24h: Optional[int]
|
|
volume_7d: Optional[int]
|
|
buy_orders: List[Dict[str, Any]]
|
|
sell_orders: List[Dict[str, Any]]
|
|
last_updated: Optional[datetime]
|
|
raw_data: Dict[str, Any]
|
|
```
|
|
|
|
---
|
|
|
|
## Settings
|
|
|
|
### Class: `Settings`
|
|
|
|
User preferences and configuration management.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.settings import get_settings
|
|
|
|
settings = get_settings()
|
|
```
|
|
|
|
#### Default Settings
|
|
|
|
```python
|
|
DEFAULTS = {
|
|
'overlay_enabled': True,
|
|
'overlay_opacity': 0.9,
|
|
'overlay_theme': 'dark',
|
|
'hotkey_toggle': 'ctrl+shift+u',
|
|
'hotkey_search': 'ctrl+shift+f',
|
|
'hotkey_calculator': 'ctrl+shift+c',
|
|
'enabled_plugins': [...],
|
|
'icon_size': 24,
|
|
'accent_color': '#4a9eff',
|
|
'check_updates': True,
|
|
'data_retention_days': 30,
|
|
}
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Get setting
|
|
value = settings.get('key', default_value)
|
|
|
|
# Set setting
|
|
settings.set('key', value)
|
|
|
|
# Reset setting
|
|
settings.reset('key') # Single key
|
|
settings.reset() # All to defaults
|
|
|
|
# Plugin management
|
|
if settings.is_plugin_enabled('plugin_id'):
|
|
settings.enable_plugin('plugin_id')
|
|
settings.disable_plugin('plugin_id')
|
|
|
|
# Get all settings
|
|
all_settings = settings.all_settings()
|
|
|
|
# Save to disk
|
|
settings.save()
|
|
```
|
|
|
|
#### Signals
|
|
|
|
```python
|
|
# Connect to changes
|
|
settings.setting_changed.connect(on_setting_changed)
|
|
|
|
def on_setting_changed(key, value):
|
|
print(f"Setting {key} changed to {value}")
|
|
```
|
|
|
|
---
|
|
|
|
## Data Store
|
|
|
|
### Class: `DataStore`
|
|
|
|
Persistent key-value storage for plugins.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.data_store import get_data_store
|
|
|
|
data_store = get_data_store()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Store data
|
|
data_store.set('my_plugin.key', value)
|
|
data_store.set('my_plugin.nested', {'a': 1, 'b': 2})
|
|
|
|
# Retrieve data
|
|
value = data_store.get('my_plugin.key', default=None)
|
|
|
|
# Check existence
|
|
if data_store.has('my_plugin.key'):
|
|
print("Key exists!")
|
|
|
|
# Delete
|
|
data_store.delete('my_plugin.key')
|
|
|
|
# Get all keys for plugin
|
|
keys = data_store.get_plugin_keys('my_plugin')
|
|
|
|
# Get all data for plugin
|
|
data = data_store.get_plugin_data('my_plugin')
|
|
|
|
# Clear plugin data
|
|
data_store.clear_plugin_data('my_plugin')
|
|
|
|
# Save to disk
|
|
data_store.save()
|
|
```
|
|
|
|
---
|
|
|
|
## Audio Manager
|
|
|
|
### Class: `AudioManager`
|
|
|
|
Sound playback and volume control.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.audio import get_audio_manager
|
|
|
|
audio = get_audio_manager()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Play sound
|
|
audio.play_sound('hof') # Predefined
|
|
audio.play_sound('/path/to/custom.wav') # Custom
|
|
audio.play_sound('alert', blocking=True) # Wait for completion
|
|
|
|
# Predefined sounds: 'global', 'hof', 'skill_gain', 'alert', 'error'
|
|
|
|
# Volume control
|
|
audio.set_volume(0.8) # 0.0 to 1.0
|
|
volume = audio.get_volume() # Get current
|
|
|
|
# Mute
|
|
audio.mute()
|
|
audio.unmute()
|
|
is_muted = audio.toggle_mute()
|
|
is_muted = audio.is_muted()
|
|
|
|
# Check availability
|
|
if audio.is_available():
|
|
audio.play_sound('skill_gain')
|
|
|
|
# Get backend info
|
|
backend = audio.get_backend() # 'pygame', 'pyaudio', etc.
|
|
|
|
# Shutdown
|
|
audio.shutdown()
|
|
```
|
|
|
|
---
|
|
|
|
## HTTP Client
|
|
|
|
### Class: `HTTPClient`
|
|
|
|
Cached HTTP requests with rate limiting.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.http_client import get_http_client
|
|
|
|
http = get_http_client(
|
|
cache_dir="cache/http",
|
|
default_cache_ttl=3600,
|
|
rate_limit_delay=0.1,
|
|
max_retries=3,
|
|
backoff_factor=0.5
|
|
)
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# GET request
|
|
response = http.get(
|
|
url,
|
|
cache_ttl=300, # Cache for 5 minutes
|
|
headers={'Accept': 'application/json'},
|
|
timeout=30
|
|
)
|
|
|
|
# Response format
|
|
{
|
|
'status_code': 200,
|
|
'headers': {...},
|
|
'text': 'response body',
|
|
'json': {...}, # Parsed JSON if applicable
|
|
'cached': False,
|
|
'cache_time': None
|
|
}
|
|
|
|
# Clear cache
|
|
http.clear_cache()
|
|
|
|
# Get cache stats
|
|
stats = http.get_cache_stats()
|
|
```
|
|
|
|
---
|
|
|
|
## OCR Service
|
|
|
|
### Class: `OCRService`
|
|
|
|
Text recognition from screen captures.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.ocr_service import get_ocr_service
|
|
|
|
ocr = get_ocr_service()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Initialize (lazy, called automatically)
|
|
ocr.initialize()
|
|
|
|
# Recognize text
|
|
result = ocr.recognize(region=(x, y, width, height))
|
|
# Returns: {
|
|
# 'text': 'extracted text',
|
|
# 'confidence': 0.95,
|
|
# 'raw_results': [...],
|
|
# 'error': None
|
|
# }
|
|
|
|
# Check availability
|
|
if ocr.is_available():
|
|
result = ocr.recognize()
|
|
|
|
# Get available backends
|
|
backends = ocr.get_available_backends() # ['easyocr', 'pytesseract']
|
|
|
|
# Shutdown
|
|
ocr.shutdown()
|
|
```
|
|
|
|
---
|
|
|
|
## Screenshot Service
|
|
|
|
### Class: `ScreenshotService`
|
|
|
|
Screen capture functionality.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.screenshot import get_screenshot_service
|
|
|
|
screenshot = get_screenshot_service()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Capture full screen
|
|
image = screenshot.capture(full_screen=True)
|
|
|
|
# Capture region
|
|
image = screenshot.capture_region(x, y, width, height)
|
|
|
|
# Get last screenshot
|
|
image = screenshot.get_last_screenshot()
|
|
|
|
# Save screenshot
|
|
path = screenshot.save_screenshot(image, filename="screenshot.png")
|
|
|
|
# Check availability
|
|
if screenshot.is_available():
|
|
image = screenshot.capture()
|
|
|
|
# Get available backends
|
|
backends = screenshot.get_available_backends() # ['pil', 'pyautogui']
|
|
```
|
|
|
|
---
|
|
|
|
## Log Reader
|
|
|
|
### Class: `LogReader`
|
|
|
|
Read Entropia Universe chat logs.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.log_reader import get_log_reader
|
|
|
|
log_reader = get_log_reader()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Start reading
|
|
log_reader.start()
|
|
|
|
# Read lines
|
|
lines = log_reader.read_lines(count=50, filter_text="loot")
|
|
|
|
# Check availability
|
|
if log_reader.is_available():
|
|
lines = log_reader.read_lines()
|
|
|
|
# Get log path
|
|
path = log_reader.get_log_path()
|
|
|
|
# Stop reading
|
|
log_reader.stop()
|
|
```
|
|
|
|
---
|
|
|
|
## Window Manager
|
|
|
|
### Class: `WindowManager`
|
|
|
|
Windows-specific window management.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.window_manager import get_window_manager
|
|
|
|
wm = get_window_manager()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Check availability (Windows only)
|
|
if wm.is_available():
|
|
# Find EU window
|
|
eu_window = wm.find_eu_window()
|
|
|
|
if eu_window:
|
|
print(f"Title: {eu_window.title}")
|
|
print(f"Size: {eu_window.width}x{eu_window.height}")
|
|
print(f"Position: ({eu_window.x}, {eu_window.y})")
|
|
|
|
# Check if focused
|
|
if wm.is_eu_focused():
|
|
print("EU is active!")
|
|
|
|
# Get all windows
|
|
windows = wm.get_all_windows()
|
|
|
|
# Find by title
|
|
window = wm.find_window_by_title("Entropia Universe")
|
|
|
|
# Get foreground window
|
|
active = wm.get_foreground_window()
|
|
```
|
|
|
|
---
|
|
|
|
## Notification Manager
|
|
|
|
### Class: `NotificationManager`
|
|
|
|
Desktop notifications.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.notifications import get_notification_manager
|
|
|
|
notifications = get_notification_manager()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Initialize
|
|
notifications.initialize(app)
|
|
|
|
# Show notification
|
|
notifications.show(
|
|
title="Skill Gain!",
|
|
message="Rifle increased to 25.5",
|
|
duration_ms=3000
|
|
)
|
|
|
|
# Show with actions
|
|
notifications.show(
|
|
title="Global!",
|
|
message="You got a global!",
|
|
actions=[
|
|
{"label": "View", "callback": view_callback},
|
|
{"label": "Dismiss", "callback": dismiss_callback}
|
|
]
|
|
)
|
|
|
|
# Close all
|
|
notifications.close_all()
|
|
```
|
|
|
|
---
|
|
|
|
## Clipboard Manager
|
|
|
|
### Class: `ClipboardManager`
|
|
|
|
Clipboard operations.
|
|
|
|
#### Singleton Access
|
|
|
|
```python
|
|
from core.clipboard import get_clipboard_manager
|
|
|
|
clipboard = get_clipboard_manager()
|
|
```
|
|
|
|
#### Methods
|
|
|
|
```python
|
|
# Copy to clipboard
|
|
clipboard.copy("text to copy")
|
|
|
|
# Paste from clipboard
|
|
text = clipboard.paste()
|
|
|
|
# Check availability
|
|
if clipboard.is_available():
|
|
clipboard.copy("Hello!")
|
|
```
|
|
|
|
---
|
|
|
|
**API Reference Complete** 📚
|