Skip to content

Sebastians-codes/NodewarBotApi

Repository files navigation

NodewarBot API

A Rocket-based REST API for managing Black Desert Online node war data, guild member profiles, and weapon metadata for the NodewarBot project. The service persists data in SQLite, exposes ingestion and query endpoints, and offloads OCR-based screenshot parsing to a companion Python script.

Highlights

  • Rust (Rocket 0.5) API with JSON endpoints for guild stats, player profiles, and weapons
  • SQLite weapons.db datastore auto-initialised with tables for weapons, node war logs, and profiles
  • Stats ingestion from node war screenshots via OpenCV + Tesseract (Python) pipeline
  • Multipart weapon upload flow that stores metadata locally and forwards images to an external uploader
  • Ready-to-run Docker image bundling Rust binary, Python runtime, and OCR dependencies

Project Layout

  • src/ – Rocket entrypoint (main.rs) and endpoint modules for weapons, node wars, and profiles
  • python_image_recognition/ – OCR script invoked during screenshot ingestion
  • weapons.db – SQLite database file; created/populated on first launch if missing
  • Dockerfile, docker-compose.yml – Container build and local orchestration definitions

Prerequisites (local development)

  • Rust toolchain (edition 2021)
  • Python 3.9+
  • SQLite 3
  • Tesseract OCR & OpenCV libraries (used by the Python helper)

Ubuntu/Debian example:

sudo apt-get update
sudo apt-get install -y tesseract-ocr libtesseract-dev libopencv-dev python3-opencv sqlite3
pip install numpy pytesseract opencv-python

Running Locally

  1. Ensure python on your PATH points to Python 3 and that the dependencies above are installed.
  2. Launch the API:
    cargo run
  3. Rocket serves on http://localhost:8000 by default (ROCKET_ADDRESS/PORT env vars override this).

The first launch creates the weapon, nodewar, and profile tables in weapons.db if they do not yet exist.

Docker Workflow

docker compose up --build

The compose file publishes port 8000, mounts a named volume for persisting weapons.db, and runs the compiled Rust binary inside a Python base image with OCR tooling pre-installed.

Configuration & Secrets

  • API keys are in-memory (AppState::valid_api_keys) and default to api_key_1 and api_key_2. Adjust them in src/main.rs before deploying.
  • handle_image_upload posts weapon images to http://localhost:8080/uploads and expects a plain-text response containing a line beginning with URL:. Provide a compatible uploader service or swap the implementation.
  • The Python OCR script is executed via python ./python_image_recognition/main.py <image_path> and must be reachable from the running container or host.

Database Schema

weapon : id INTEGER PRIMARY KEY, name TEXT, accuracy, evasion, damage_reduction, power, defence, durability, image_url

nodewar : per-war player stats (name, base, stick, castle, horse, structure, kills, deaths, guild_id, date)

profile : guild member profile data (name, ap, aap, dp, discord_id, class_name, spec, guild_id)

API Overview

Rocket accepts and returns JSON (unless noted). All endpoints live under /weapon, /nodewar, or /profile.

Auth Wrapper

Most weapon endpoints accept a JSON envelope shaped as:

{
  "api_key": "api_key_1",
  "data": { /* endpoint-specific payload */ }
}

Supply one of the valid keys in every request that requires authorization.

Weapon Endpoints

  • GET /weapon/ – returns all stored weapons. Include a JSON body with the auth wrapper and an empty data object.
  • GET /weapon/<id> – fetch a single weapon by numeric ID. Include the auth wrapper body.
  • POST /weapon/ – multipart form upload. Fields:
    • api_key: valid key
    • data: JSON string matching { "name": "...", "accuracy": 0, "evasion": 0, "damage_reduction": 0, "power": 0, "defence": 0, "durability": 0 }
    • image: file upload sent to the external uploader; the returned URL is stored in image_url Responds with the created weapon JSON.

Node War Endpoints

  • POST /nodewar/ – multipart form ingestion of screenshot stats
    • api_key: valid key
    • guild_id: numeric guild identifier
    • image: screenshot file The server saves the file, runs the OCR script, and stores each parsed player row (skipping duplicates for the current date). Responds with the parsed rows.
  • GET /nodewar/<guild_id> – aggregate totals for a guild: total kills/deaths, KDA, structures destroyed, and count of unique war dates.
  • GET /nodewar/top/<guild_id> – per-player KDA leaderboard ordered descending.
  • GET /nodewar/<player_name>/<guild_id> – detailed history for a player within a guild, including per-war breakdowns and aggregate sums.
  • GET /nodewar/clear – deletes all rows from the nodewar table (no auth). Use cautiously.

Profile Endpoints

  • GET /profile/id/<discord_id> – fetch a profile by Discord ID.
  • GET /profile/name/<name>/<guild_id> – case-insensitive profile lookup by name within a guild.
  • POST /profile/ – JSON body matching PlayerProfile (name, ap, aap, dp, discord_id, class_name, spec, guild_id). Rejects missing combat stats and conflicts on duplicate name/Discord ID.

Screenshot Ingestion Notes

  • The OCR pipeline expects the in-game “Family Name / Node War” scoreboard layout. Low-quality or modified HUD captures may trigger a Bad ScreenShot error.
  • Parsed rows are tagged with the current date. The API skips inserting multiple entries for the same player on the same day.
  • Ensure pytesseract can locate the Tesseract binary (TESSDATA_PREFIX may be required in custom environments).

Development Tips

  • Run cargo fmt / cargo clippy for style and lint checks during contributions.
  • When modifying the OCR script, rebuild the Docker image to bake updated Python dependencies.
  • Replace the hard-coded API keys and external uploader URL before deploying to production.

Troubleshooting

  • Upload failed with status: start or configure the image uploader expected at http://localhost:8080/uploads.
  • Bad ScreenShot / UnprocessableEntity on /nodewar/: verify screenshot clarity and that the Python dependencies (OpenCV, Tesseract) are installed correctly.
  • SQLite locking errors: reduce concurrent writes or investigate long-running readers; the connection is shared via a Rocket-managed async mutex.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published