EU-Utility/docs/API_REFERENCE.md

633 lines
12 KiB
Markdown

# EU-Utility API Reference
**Version:** 2.2.0
**Last Updated:** 2026-02-15
---
## Overview
EU-Utility provides a comprehensive three-tier API architecture:
| API | Purpose | Audience |
|-----|---------|----------|
| **PluginAPI** | Access core services | Plugin developers |
| **WidgetAPI** | Create overlay widgets | Widget developers |
| **ExternalAPI** | Third-party integrations | External apps, bots |
---
## PluginAPI
The PluginAPI provides access to all core EU-Utility services.
### Getting Started
```python
from core.api import get_api
class MyPlugin(BasePlugin):
def initialize(self):
self.api = get_api()
def on_event(self, event):
self.api.show_notification("Event", str(event))
```
### Services Available
#### Log Reader
```python
# Read recent log lines
lines = api.read_log_lines(100)
# Read since timestamp
recent = api.read_log_since(datetime.now() - timedelta(minutes=5))
```
#### Window Manager
```python
# Get EU window info
window = api.get_eu_window()
if window:
print(f"EU at {window['x']}, {window['y']}")
print(f"Size: {window['width']}x{window['height']}")
# Check focus
if api.is_eu_focused():
api.play_sound("alert.wav")
# Bring EU to front
api.bring_eu_to_front()
```
#### OCR Service
```python
# Check availability
if api.ocr_available():
# Read text from screen region
text = api.recognize_text((100, 100, 200, 50))
print(f"Found: {text}")
```
#### Screenshot
```python
# Capture screen
img = api.capture_screen((0, 0, 1920, 1080), "screenshot.png")
# Check availability
if api.screenshot_available():
img = api.capture_screen()
```
#### Nexus API (Item Database)
```python
# Search items
items = api.search_items("omegaton", limit=5)
for item in items:
print(f"{item['Name']}: {item['Value']} PED")
# Get item details
details = api.get_item_details(12345)
```
#### HTTP Client
```python
# GET request with caching
result = api.http_get("https://api.example.com/data", cache=True)
if result['success']:
data = result['data']
# POST request
result = api.http_post("https://api.example.com/save", {"key": "value"})
```
#### Audio
```python
# Play sound
api.play_sound("assets/sounds/alert.wav", volume=0.7)
# Simple beep
api.beep()
```
#### Notifications
```python
# Show toast
api.show_notification(
title="Loot Alert",
message="Found something valuable!",
duration=3000,
sound=True
)
```
#### Clipboard
```python
# Copy
api.copy_to_clipboard("TT: 100 PED")
# Paste
text = api.paste_from_clipboard()
```
#### Event Bus (Pub/Sub)
```python
# Subscribe to events
def on_loot(event):
print(f"Loot: {event.data}")
sub_id = api.subscribe("loot", on_loot)
# Publish event
api.publish("my_plugin.event", {"key": "value"})
# Unsubscribe
api.unsubscribe(sub_id)
```
#### Data Store
```python
# Store data
api.set_data("kill_count", 100)
# Retrieve data
count = api.get_data("kill_count", default=0)
# Delete
api.delete_data("kill_count")
```
#### Task Manager
```python
# Run in background
def heavy_work(data):
return process(data)
def on_done(result):
print(f"Done: {result}")
task_id = api.run_task(
heavy_work,
my_data,
callback=on_done
)
# Cancel task
api.cancel_task(task_id)
```
---
## WidgetAPI
The WidgetAPI manages overlay widgets - floating UI components.
### Getting Started
```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),
position=(100, 100)
)
widget.show()
```
### Widget Configuration
```python
from core.api import WidgetConfig, WidgetType
config = WidgetConfig(
name="my_widget",
title="My Widget",
widget_type=WidgetType.MINI,
size=(300, 200),
position=(100, 100),
opacity=0.95,
always_on_top=True,
locked=False,
resizable=True
)
```
### Widget Operations
```python
# Show/hide
widget.show()
widget.hide()
# Position
widget.move(500, 200)
x, y = widget.position
# Size
widget.resize(400, 300)
width, height = widget.size
# Opacity
widget.set_opacity(0.8)
# Lock/unlock (prevent dragging)
widget.set_locked(True)
# Minimize/restore
widget.minimize()
widget.restore()
# Close
widget.close()
```
### Widget Events
```python
# Handle events
widget.on('moved', lambda data: print(f"Moved to {data['x']}, {data['y']}"))
widget.on('resized', lambda data: print(f"Sized to {data['width']}x{data['height']}"))
widget.on('closing', lambda: print("Widget closing"))
widget.on('closed', lambda: print("Widget closed"))
widget.on('update', lambda data: print(f"Update: {data}"))
```
### Widget Management
```python
# Get widget
widget = widget_api.get_widget("loot_tracker")
# Show/hide specific widget
widget_api.show_widget("loot_tracker")
widget_api.hide_widget("loot_tracker")
# Close widget
widget_api.close_widget("loot_tracker")
# All widgets
widget_api.show_all_widgets()
widget_api.hide_all_widgets()
widget_api.close_all_widgets()
# Set all opacity
widget_api.set_all_opacity(0.8)
# Lock/unlock all
widget_api.lock_all()
widget_api.unlock_all()
```
### Layout Helpers
```python
# Arrange widgets
widget_api.arrange_widgets(layout="grid", spacing=10)
widget_api.arrange_widgets(layout="horizontal")
widget_api.arrange_widgets(layout="vertical")
widget_api.arrange_widgets(layout="cascade")
# Snap to grid
widget_api.snap_to_grid(grid_size=10)
```
### Widget Presets
```python
from core.api import WidgetConfig, WidgetType
# Register preset
preset = WidgetConfig(
name="preset",
title="Loot Tracker",
widget_type=WidgetType.MINI,
size=(250, 150),
opacity=0.9
)
widget_api.register_preset("loot_tracker", preset)
# Use preset
widget = widget_api.create_from_preset("loot_tracker", name="my_tracker")
```
### Persistence
```python
# Save all widget states
states = widget_api.save_all_states("widgets.json")
# Load states
widget_api.load_all_states("widgets.json")
```
---
## ExternalAPI
The ExternalAPI provides REST endpoints, webhooks, and third-party integrations.
### Getting Started
```python
from core.api import get_external_api
ext = get_external_api()
# Start server
ext.start_server(port=8080)
# Check status
print(ext.get_status())
```
### REST API Server
```python
# Start server with CORS
ext.start_server(
port=8080,
host="127.0.0.1",
cors_origins=["http://localhost:3000"]
)
# Stop server
ext.stop_server()
# Get URL
url = ext.get_url("api/v1/stats")
# Returns: http://127.0.0.1:8080/api/v1/stats
```
### API Endpoints
Using decorator:
```python
@ext.endpoint("stats", methods=["GET"])
def get_stats():
return {"kills": 100, "loot": "50 PED"}
@ext.endpoint("loot", methods=["POST"])
def record_loot(data):
save_loot(data)
return {"status": "saved"}
```
Programmatic:
```python
def get_stats(params):
return {"kills": 100}
ext.register_endpoint("stats", get_stats, methods=["GET"])
# Unregister
ext.unregister_endpoint("stats")
```
### Incoming Webhooks
```python
# Register webhook handler
def handle_discord(payload):
print(f"Discord: {payload}")
return {"status": "ok"}
ext.register_webhook(
name="discord",
handler=handle_discord,
secret="my_secret" # Optional HMAC verification
)
# Now POST to: http://localhost:8080/webhook/discord
```
With HMAC verification:
```python
import hmac
import hashlib
# Client side (Discord, etc.)
payload = {"event": "message"}
payload_str = json.dumps(payload, sort_keys=True)
signature = hmac.new(
secret.encode(),
payload_str.encode(),
hashlib.sha256
).hexdigest()
# Send with X-Signature header
headers = {'X-Signature': signature}
requests.post(url, json=payload, headers=headers)
```
### Outgoing Webhooks
```python
# POST to external webhook
result = ext.post_webhook(
"https://discord.com/api/webhooks/...",
{"content": "Hello from EU-Utility!"}
)
if result['success']:
print("Sent!")
else:
print(f"Error: {result['error']}")
```
### Authentication
```python
# Create API key
api_key = ext.create_api_key(
name="My Bot",
permissions=["read", "write"]
)
# Use in requests
headers = {'X-API-Key': api_key}
requests.get(url, headers=headers)
# Revoke
ext.revoke_api_key(api_key)
```
### IPC (Inter-Process Communication)
```python
# Register handler
def on_browser_message(data):
print(f"From browser: {data}")
ext.register_ipc_handler("browser", on_browser_message)
# Send message
ext.send_ipc("browser", {"action": "refresh"})
```
### File Watcher
```python
# Watch file for changes
def on_config_change():
print("Config changed!")
reload_config()
watch_id = ext.watch_file(
"config.json",
on_config_change,
interval=1.0
)
```
### Webhook History
```python
# Get recent webhook calls
history = ext.get_webhook_history(limit=10)
for entry in history:
print(f"{entry['name']}: {entry['timestamp']}")
```
### Server-Sent Events (SSE)
Clients can connect to `/events` for real-time updates:
```javascript
const evtSource = new EventSource("http://localhost:8080/events");
evtSource.addEventListener("message", (e) => {
console.log("Event:", JSON.parse(e.data));
});
```
---
## Error Handling
All APIs provide specific exceptions:
```python
from core.api import (
PluginAPIError,
ServiceNotAvailableError,
ExternalAPIError,
WebhookError
)
try:
text = api.recognize_text((0, 0, 100, 100))
except ServiceNotAvailableError:
print("OCR not available")
except PluginAPIError as e:
print(f"API error: {e}")
```
---
## API Versions
| Version | Features |
|---------|----------|
| 2.0 | Initial PluginAPI |
| 2.1 | Added Activity Bar |
| 2.2 | Three-tier API (Plugin, Widget, External) |
---
## Examples
### Discord Integration
```python
from core.api import get_api, get_external_api
class DiscordPlugin(BasePlugin):
def initialize(self):
self.api = get_api()
self.ext = get_external_api()
# Start server
self.ext.start_server(port=8080)
# Register webhook
self.ext.register_webhook(
"loot",
self.handle_loot_webhook
)
# Subscribe to events
self.api.subscribe("loot", self.on_loot)
def on_loot(self, event):
# Send to Discord
self.ext.post_webhook(
self.discord_url,
{"content": f"Loot: {event.data}"}
)
def handle_loot_webhook(self, payload):
# Handle incoming Discord webhook
if payload.get('type') == 'command':
return self.process_command(payload)
return {"status": "ignored"}
```
### Custom Widget
```python
from core.api import get_api, get_widget_api
from PyQt6.QtWidgets import QLabel, QVBoxLayout, QWidget
class LootWidgetPlugin(BasePlugin):
def initialize(self):
self.api = get_api()
self.widget_api = get_widget_api()
# Create widget
self.widget = self.widget_api.create_widget(
name="loot_display",
title="Recent Loot",
size=(300, 200)
)
# Set content
content = QWidget()
layout = QVBoxLayout(content)
self.loot_label = QLabel("No loot yet")
layout.addWidget(self.loot_label)
self.widget.set_content(content)
# Subscribe to loot events
self.api.subscribe("loot", self.on_loot)
# Show widget
self.widget.show()
def on_loot(self, event):
self.loot_label.setText(f"Last: {event.data}")
self.widget.flash()
```
---
## See Also
- [API Cookbook](API_COOKBOOK.md) - Detailed recipes and patterns
- [Plugin Development Guide](PLUGIN_DEVELOPMENT.md) - Building plugins
- [Widget Guide](WIDGET_GUIDE.md) - Creating widgets
- [External Integration](EXTERNAL_INTEGRATION.md) - Third-party integrations
---
**Need Help?**
- Discord: https://discord.gg/clawd
- Issues: https://git.lemonlink.eu/impulsivefps/EU-Utility/issues