EU-Utility/docs/API_REFERENCE.md

12 KiB

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

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

# 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

# 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

# Check availability
if api.ocr_available():
    # Read text from screen region
    text = api.recognize_text((100, 100, 200, 50))
    print(f"Found: {text}")

Screenshot

# 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)

# 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

# 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

# Play sound
api.play_sound("assets/sounds/alert.wav", volume=0.7)

# Simple beep
api.beep()

Notifications

# Show toast
api.show_notification(
    title="Loot Alert",
    message="Found something valuable!",
    duration=3000,
    sound=True
)

Clipboard

# Copy
api.copy_to_clipboard("TT: 100 PED")

# Paste
text = api.paste_from_clipboard()

Event Bus (Pub/Sub)

# 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

# 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

# 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

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

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

# 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

# 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

# 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

# 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

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

# 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

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

# 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:

@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:

def get_stats(params):
    return {"kills": 100}

ext.register_endpoint("stats", get_stats, methods=["GET"])

# Unregister
ext.unregister_endpoint("stats")

Incoming Webhooks

# 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:

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

# 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

# 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)

# 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

# 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

# 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:

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:

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

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

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


Need Help?