# Dereth Tracker Dereth Tracker is a real-time telemetry service for the world of Dereth. It collects player data, stores it in a SQLite database, and provides a live map interface along with a sample data generator for testing. ## Table of Contents - [Overview](#overview) - [Features](#features) - [Requirements](#requirements) - [Installation](#installation) - [Configuration](#configuration) - [Usage](#usage) - [API Reference](#api-reference) - [Frontend](#frontend) - [Database Schema](#database-schema) - [Contributing](#contributing) ## Overview This project provides: - A FastAPI backend with endpoints for receiving and querying telemetry data. - SQLite-based storage for snapshots and live state. - A live, interactive map using static HTML, CSS, and JavaScript. - A sample data generator script (`generate_data.py`) for simulating telemetry snapshots. ## Features - **WebSocket /ws/position**: Stream telemetry snapshots (protected by a shared secret). - **GET /live**: Fetch active players seen in the last 30 seconds. - **GET /history**: Retrieve historical telemetry data with optional time filtering. - **GET /debug**: Health check endpoint. - **Live Map**: Interactive map interface with panning, zooming, and sorting. - **Sample Data Generator**: `generate_data.py` sends telemetry snapshots over WebSocket for testing. ## Requirements - Python 3.9 or newer - pip - (Optional) virtual environment tool (venv) Python packages: - fastapi - uvicorn - pydantic - pandas - matplotlib - websockets # required for sample data generator ## Installation 1. Clone the repository: ```bash git clone https://github.com/yourusername/dereth-tracker.git cd dereth-tracker ``` 2. Create and activate a virtual environment: ```bash python3 -m venv venv source venv/bin/activate # Windows: venv\Scripts\activate ``` 3. Install dependencies: ```bash pip install fastapi uvicorn pydantic pandas matplotlib websockets ``` ## Configuration - Update the `SHARED_SECRET` in `main.py` to match your plugin (default: `"your_shared_secret"`). - The SQLite database file `dereth.db` is created in the project root. To change the path, edit `DB_FILE` in `db.py`. - To limit the maximum database size, set the environment variable `DB_MAX_SIZE_MB` (default: 2048 MB). ## Usage Start the server using Uvicorn: ```bash uvicorn main:app --reload --host 0.0.0.0 --port 8000 ``` ## NGINX Proxy Configuration If you cannot reassign the existing `/live` and `/trails` routes, you can namespace this service under `/api` (or any other prefix) and configure NGINX accordingly. Be sure to forward WebSocket upgrade headers so that `/ws/live` and `/ws/position` continue to work. Example: ```nginx location /api/ { proxy_pass http://127.0.0.1:8765/; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket support proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_cache_bypass $http_upgrade; } ``` Then the browser client (static/script.js) will fetch `/api/live/` and `/api/trails/` to reach this new server. - Live Map: `http://localhost:8000/` (or `http:///api/` if behind a prefix) ### Frontend Configuration - In `static/script.js`, the constant `API_BASE` controls where live/trails data and WebSocket `/ws/live` are fetched. By default: ```js const API_BASE = '/api'; ``` Update `API_BASE` if you mount the service under a different path or serve it at root. ### Debugging WebSockets - Server logs now print every incoming WebSocket frame in `main.py`: - `[WS-PLUGIN RX] : ` for plugin messages on `/ws/position` - `[WS-LIVE RX] : ` for browser messages on `/ws/live` - Use these logs to verify messages and troubleshoot handshake failures. ### Styling Adjustments - Chat input bar is fixed at the bottom of the chat window (`.chat-form { position:absolute; bottom:0; }`). - Input text and placeholder are white for readability (`.chat-input, .chat-input::placeholder { color:#fff; }`). - Incoming chat messages forced white via `.chat-messages div { color:#fff !important; }`. ## API Reference ### WebSocket /ws/position Stream telemetry snapshots over a WebSocket connection. Provide your shared secret either as a query parameter or WebSocket header: ``` ws://:/ws/position?secret= ``` or ``` X-Plugin-Secret: ``` After connecting, send JSON messages matching the `TelemetrySnapshot` schema. For example: ```json { "type": "telemetry", "character_name": "Dunking Rares", "char_tag": "moss", "session_id": "dunk-20250422-xyz", "timestamp": "2025-04-22T13:45:00Z", "ew": 123.4, "ns": 567.8, "z": 10.2, "kills": 42, "deaths": 1, "rares_found": 2, "prismatic_taper_count": 17, "vt_state": "Combat", "kills_per_hour": "N/A", "onlinetime": "00:05:00" } ``` ### Chat messages You can also send chat envelopes over the same WebSocket to display messages in the browser. Fields: - `type`: must be "chat" - `character_name`: target player name - `text`: message content - `color` (optional): CSS color string (e.g. "#ff8800"); if sent as an integer (0xRRGGBB), it will be converted to hex. Example chat payload: ```json { "type": "chat", "character_name": "MyCharacter", "text": "Hello world!", "color": "#88f" } ``` ### GET /live Returns active players seen within the last 30 seconds: ```json { "players": [ { ... } ] } ``` ### GET /history Retrieve historical snapshots with optional `from` and `to` ISO8601 timestamps: ``` GET /history?from=2025-04-22T12:00:00Z&to=2025-04-22T13:00:00Z ``` Response: ```json { "data": [ { ... } ] } ``` ## Frontend - **Live Map**: `static/index.html` – Real-time player positions on a map. ## Database Schema - **telemetry_log**: Stored history of snapshots. - **live_state**: Current snapshot per character (upserted). ## Contributing Contributions are welcome! Feel free to open issues or submit pull requests.