feat(DRW-001) initial fixes
This commit is contained in:
@@ -4,6 +4,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- '**'
|
- '**'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: gitea.kawaii-alyssa.dev
|
REGISTRY: gitea.kawaii-alyssa.dev
|
||||||
@@ -41,6 +42,24 @@ jobs:
|
|||||||
name: Unit Tests
|
name: Unit Tests
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
# cargo build never touches a database (no compile-time-checked sqlx
|
||||||
|
# macros are used anywhere), but the tests do -- #[sqlx::test] spins up
|
||||||
|
# a real, freshly-migrated database per test, which needs an actual
|
||||||
|
# Postgres server to connect to and CREATE DATABASE against.
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
env:
|
||||||
|
POSTGRES_USER: test
|
||||||
|
POSTGRES_PASSWORD: test
|
||||||
|
POSTGRES_DB: test
|
||||||
|
ports:
|
||||||
|
- 5432:5432
|
||||||
|
options: >-
|
||||||
|
--health-cmd pg_isready
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
@@ -61,6 +80,8 @@ jobs:
|
|||||||
restore-keys: rust-${{ runner.os }}-
|
restore-keys: rust-${{ runner.os }}-
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
env:
|
||||||
|
DATABASE_URL: postgres://test:test@localhost:5432/test
|
||||||
run: cargo test --release --locked
|
run: cargo test --release --locked
|
||||||
|
|
||||||
docker:
|
docker:
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
/target
|
/target
|
||||||
/.claude
|
/.claude
|
||||||
|
/.idea
|
||||||
.env
|
.env
|
||||||
|
|||||||
@@ -1,35 +1,35 @@
|
|||||||
# 🎲 Dota Random
|
# 🎲 Dota Random 🌸
|
||||||
|
|
||||||
> "I-it's not like I made a whole randomizer just so YOU could have chaotic fun in your games or anything... b-baka."
|
> "I-it's not like I made a whole randomizer just so YOU could have chaotic fun in your games or anything... b-baka." 💢
|
||||||
|
|
||||||
Fine, FINE. Since you're making me explain it: this is a Dota 2 hero + item build randomizer. You pick how much chaos you want — scope it to melee heroes, lock item tags, disable half the randomness if you're a coward — and it rolls you a hero, a full item build (slot 1 is *always* boots, don't argue with me about it), neutral item candidates per stage, enchantments, and tells you when you're allowed to buy your Aghanim's. Not that I care if you actually use it properly.
|
Fine, FINE. Since you're making me explain it: this is a Dota 2 hero + item build randomizer. You pick how much chaos you want — scope it to melee heroes, lock item tags, disable half the randomness if you're a coward — and it rolls you a hero, a full item build (slot 1 is *always* boots, don't argue with me about it), neutral item candidates per stage, enchantments, and tells you when you're allowed to buy your Aghanim's. Not that I care if you actually use it properly. 🎀
|
||||||
|
|
||||||
It's not a toy. ...Okay it's kind of a toy. Shut up.
|
It's not a toy. ...Okay it's kind of a toy. Shut up. ✨
|
||||||
|
|
||||||
## What it actually does
|
## 🌷 What it actually does
|
||||||
|
|
||||||
- **Hero scope** — filter by attack type and/or primary attribute, or leave it wide open if you're feeling brave
|
- **Hero scope** — filter by attack type and/or primary attribute, or leave it wide open if you're feeling brave
|
||||||
- **Item scope** — restrict rolls to items carrying specific purpose tags (Physical Damage, Disable, Sustain, etc.)
|
- **Item scope** — restrict rolls to items carrying specific purpose tags (Physical Damage, Disable, Sustain, etc.)
|
||||||
- **Slot 1 is always boots** — every existing boots item in the game is eligible, including separate grades like Boots of Travel / Boots of Travel 2 and Dagon's five levels, each rolled as its own distinct outcome
|
- **Slot 1 is always boots** 👢 — every existing boots item in the game is eligible, including separate grades like Boots of Travel / Boots of Travel 2 and Dagon's five levels, each rolled as its own distinct outcome
|
||||||
- **Neutral items, honestly modeled** — each active tier suggests 2 real candidates, because the app can't actually control what drops in your match. You click whichever one you got, or browse the full tier if neither matches
|
- **Neutral items, honestly modeled** — each active tier suggests 2 real candidates, because the app can't actually control what drops in your match. You click whichever one you got, or browse the full tier if neither matches
|
||||||
- **Enchantments, guaranteed** — no RNG-within-RNG nonsense here. If enchantment rolling is on, you get one, scoped correctly to your hero's primary attribute (including the "works on literally any hero" ones — yes, those exist, no I didn't forget about them)
|
- **Enchantments, guaranteed** ⭐ — no RNG-within-RNG nonsense here. If enchantment rolling is on, you get one, scoped correctly to your hero's primary attribute (including the "works on literally any hero" ones — yes, those exist, no I didn't forget about them)
|
||||||
- **Aghanim's Scepter & Shard roll as normal items now** — no special-cased fake probability. You also get to say whether you're "allowed" to buy them mid-build or only after your 6 slots are full, for whenever they don't get rolled naturally
|
- **Aghanim's Scepter & Shard roll as normal items now** — no special-cased fake probability. You also get to say whether you're "allowed" to buy them mid-build or only after your 6 slots are full, for whenever they don't get rolled naturally
|
||||||
- **Reroll anything** — hero, a single item slot, a specific neutral tier, a specific enchantment tier. Rerolling your hero also refreshes your neutral items and enchantments, since a new hero deserves a fresh itemization pass, o-obviously
|
- **Reroll anything** 🔁 — hero, a single item slot, a specific neutral tier, a specific enchantment tier. Rerolling your hero also refreshes your neutral items and enchantments, since a new hero deserves a fresh itemization pass, o-obviously
|
||||||
- **Manual override, always available** — disable randomness for any slot/dimension and pick it yourself instead
|
- **Manual override, always available** — disable randomness for any slot/dimension and pick it yourself instead
|
||||||
|
|
||||||
## Stack
|
## 💐 Stack
|
||||||
|
|
||||||
Not that you need to know this to use it, but since you're being nosy:
|
Not that you need to know this to use it, but since you're being nosy:
|
||||||
|
|
||||||
| Layer | Tech |
|
| Layer | Tech |
|
||||||
|---|---|
|
|-------------|--------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| Backend | Rust, [axum](https://github.com/tokio-rs/axum), [sqlx](https://github.com/launchbadge/sqlx) (Postgres) |
|
| Backend | Rust, [axum](https://github.com/tokio-rs/axum), [sqlx](https://github.com/launchbadge/sqlx) (Postgres) |
|
||||||
| Frontend | React, TypeScript, Vite, Tailwind CSS |
|
| Frontend | React, TypeScript, Vite, Tailwind CSS |
|
||||||
| Database | PostgreSQL |
|
| Database | PostgreSQL |
|
||||||
| Data source | Scraped live from [Liquipedia](https://liquipedia.net/dota2/) via Python scripts (no hardcoded/stale game data, thank you very much) |
|
| Data source | Scraped live from [Liquipedia](https://liquipedia.net/dota2/) via Python scripts (no hardcoded/stale game data, thank you very much) |
|
||||||
| Deployment | Docker Compose + a Gitea Actions CI/CD pipeline |
|
| Deployment | Docker Compose + a Gitea Actions CI/CD pipeline |
|
||||||
|
|
||||||
## Getting it running (pay attention, I'm not repeating myself)
|
## 🌼 Getting it running (pay attention, I'm not repeating myself)
|
||||||
|
|
||||||
### 1. Database
|
### 1. Database
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ python scripts/scrape_items.py
|
|||||||
sqlx migrate run
|
sqlx migrate run
|
||||||
```
|
```
|
||||||
|
|
||||||
Yes, this means the roster stays current with whatever patch Liquipedia reflects. Rerun the scripts whenever you want fresh data. I'm not doing that part for you.
|
Yes, this means the roster stays current with whatever patch Liquipedia reflects. Rerun the scripts whenever you want fresh data. I'm not doing that part for you. 🌱
|
||||||
|
|
||||||
### 2. Backend
|
### 2. Backend
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ npm install
|
|||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
Runs on `:5173` with a dev proxy to the backend, so it just works. You're welcome.
|
Runs on `:5173` with a dev proxy to the backend, so it just works. You're welcome. 💗
|
||||||
|
|
||||||
### 4. Or just use Docker Compose
|
### 4. Or just use Docker Compose
|
||||||
|
|
||||||
@@ -79,9 +79,9 @@ Runs on `:5173` with a dev proxy to the backend, so it just works. You're welcom
|
|||||||
docker compose up
|
docker compose up
|
||||||
```
|
```
|
||||||
|
|
||||||
...if the images are actually built and pushed, which they will be, because there's a whole CI pipeline for it. I didn't half-ass this.
|
...if the images are actually built and pushed, which they will be, because there's a whole CI pipeline for it. I didn't half-ass this. ✨
|
||||||
|
|
||||||
## Project layout, since you'll get lost otherwise
|
## 🎀 Project layout, since you'll get lost otherwise
|
||||||
|
|
||||||
```
|
```
|
||||||
src/ Rust backend (axum handlers, roll logic, models)
|
src/ Rust backend (axum handlers, roll logic, models)
|
||||||
@@ -91,16 +91,16 @@ frontend/ React + TypeScript SPA
|
|||||||
.gitea/ CI/CD workflow
|
.gitea/ CI/CD workflow
|
||||||
```
|
```
|
||||||
|
|
||||||
## A note on the data
|
## 🌸 A note on the data
|
||||||
|
|
||||||
Heroes, items, and enchantments are scraped from Liquipedia's Dota 2 wiki, not hand-typed or pulled from memory — patches change too fast for that to stay accurate, and I refuse to ship stale data. The scrapers check each item's actual current status (active / removed / unreleased / hidden) rather than trusting whatever list happens to mention it, because apparently even wikis get this wrong sometimes.
|
Heroes, items, and enchantments are scraped from Liquipedia's Dota 2 wiki, not hand-typed or pulled from memory — patches change too fast for that to stay accurate, and I refuse to ship stale data. The scrapers check each item's actual current status (active / removed / unreleased / hidden) rather than trusting whatever list happens to mention it, because apparently even wikis get this wrong sometimes. 🧐
|
||||||
|
|
||||||
## Disclaimer
|
## 📎 Disclaimer
|
||||||
|
|
||||||
Part of this project — the whole frontend, a chunk of the Rust backend, the data scrapers, the CI/CD setup — was written with AI assistance. It's not like every line was hand-crafted by a lone genius at 3am. Mostly. I just don't like writing boilerplate code or code I already know how to write! Baka!
|
Part of this project — the whole frontend, a chunk of the Rust backend, the data scrapers, the CI/CD setup — was written with AI assistance. It's not like every line was hand-crafted by a lone genius at 3am. Mostly. I just don't like writing boilerplate code or code I already know how to write! Baka! 💢
|
||||||
|
|
||||||
## Author
|
## 🌷 Author
|
||||||
|
|
||||||
**ItzYumeii**
|
**ItzYumeii**
|
||||||
|
|
||||||
...I guess if you actually enjoy using this, that's... fine. Not that it matters to me or anything.
|
...I guess if you actually enjoy using this, that's... fine. Not that it matters to me or anything. 🩷
|
||||||
|
|||||||
Reference in New Issue
Block a user