This commit is contained in:
gpatruno
2026-07-18 16:26:08 +02:00
parent 49c444e8b9
commit 2614d679c8
85 changed files with 8074 additions and 710 deletions
+67 -11
View File
@@ -29,7 +29,7 @@ CLIENT_ORIGIN=http://localhost:5173
SESSION_SECRET=dev-secret
STARTING_BALANCE=10000
STARTING_OSU=100
JACKPOT_ROUND_SECONDS=60
JACKPOT_ROUND_SECONDS=30
JACKPOT_MAX_ITEMS=3
```
@@ -40,28 +40,84 @@ JACKPOT_MAX_ITEMS=3
| Admin | `admin` | `admin123` |
| Player| `player` | `player123`|
Local seed defaults; override admin via `ADMIN_USERNAME` / `ADMIN_PASSWORD`. In Docker, those env vars in `.env.prod` are required and applied on every start.
New registrations receive **100.00** starting credits and **100 osu** (`STARTING_BALANCE` / `STARTING_OSU` in `server/.env`; credits stored in cents).
## Features
- Login / register (username + password)
- Inventory: sort by recent or value, multi-select and sell at market value
- **Feed Drop**: toggle in nav — live left column of latest case unboxes + player
- **Inventory**: sort by recent or value, multi-select sell at **instance** value (float/wear), bulk **Sell below** threshold, **favorites** (★ — cannot be sold or auto-sold; can still be bet in battles)
- **Auto-sell**: optional threshold (shared with bulk sell); on **case opens**, credits are applied after the reel finishes; on **battle wins**, items taken from other players below the threshold are sold immediately
- **Wear (float)**: each case drop gets a random float `01` and paint seed; grades FN / MW / FT / WW / BS (CS ranges). Catalog `marketValue` is the **Field-Tested** reference; instance `valueCents` scales by float within the wear band (FN up to +50%, MW +1530%, FT mid ≈ catalog, WW down to 40%, BS lower)
- **Feed Drop**: toggle in nav — live left column of latest case unboxes + MultiPlayers Battle winners
- Cases page: browse and open crates (CS-style reel, result rolled server-side)
- **Bet Item** hub:
- **MultiPlayers Case** — live shared pot, up to 3 items, win chance by value, Socket.IO sync
- **Case keys** (per crate): **1 key****x10**; each **100 opens** of that case earns +1 key up to **x20** (keys 1→11, +1 open per key: x11…x20); from **x20** onward each next key costs **200, 300, 400…** opens (100 × tier) and adds +1 max open (x21, x22…) — no cap
- **Battle** hub (`/battle`):
- **MultiPlayers Case** — live shared pot preview on the hub (top items, pot total, players), up to 3 items, win chance by value, Socket.IO sync
- **1vX Case** — custom rooms (player/item limits, min value), spectate in-progress
- **Coinflip** — stub (coming soon)
- **Shop**: spend osu on credit packs; watch an ad every 1 min for 100.00200.00 cr
- Profile (via username in the nav): avatar, bio, password, stats
- Leaderboard: richest players (balance + inventory market value)
- **Shop** (nav balance pill → `/shop`): spend osu on credit packs; watch an ad every 1 min for 100.00200.00 cr
- Profile (username in nav): avatar, bio, password, stats, logout
- **Presence**: online status (Socket.IO), total play time, last connection — shown on own and public profiles
- **Achievements** (`/achievements`, also from profile): 10 starter badges unlocked by play (cases, battles, catalog, prestige, shop, playtime); earned badges appear on the profile
- **Leaderboard**: richest players (balance + inventory value); click a row to open a public **player profile** (`/player/:username`) with stats and inventory
- Admin: manage cases, items, images (URL or upload), drop weights, enable/disable cases
## Docker (production)
```bash
# Build & push to Docker Hub (foufure/casegambling)
docker login
./scripts/docker-build-push.sh
# optional version tag:
./scripts/docker-build-push.sh v1.0.0
# Run
cp .env.prod.example .env.prod # edit secrets / CLIENT_ORIGIN / ADMIN_*
docker compose --env-file .env.prod up -d
```
Set **`ADMIN_USERNAME`** and **`ADMIN_PASSWORD`** in `.env.prod` (required). On each container start the admin account is created or updated from these values.
App listens on `HOST_PORT` (default **3009** → container 3001). Data: volume `casegambling_data` (SQLite), uploads: `casegambling_uploads`.
### Backup / restore
**On the Docker prod server** (export DB to bring home):
```bash
# Copy these two scripts onto the server next to docker-compose.yml, then:
./scripts/docker-db-export.sh
# → backups/casegambling-… (+ .tar.gz)
# Optional: restore a backup into Docker
./scripts/docker-db-import.sh ./backups/casegambling-YYYYMMDD-HHMMSS.tar.gz
```
**On your laptop** (local `server/prisma/dev.db`):
```bash
# Import the archive you copied from prod (stop `npm run dev` first)
./scripts/local-db-import.sh ./backups/casegambling-YYYYMMDD-HHMMSS.tar.gz
npm run db:push # sync schema if needed
npm run dev
# Export local DB (e.g. to push back to Docker)
./scripts/local-db-export.sh
./scripts/docker-db-import.sh ./backups/casegambling-….tar.gz
```
Typical **prod → local** flow: `docker-db-export.sh` on the server → `scp` the `.tar.gz``local-db-import.sh` on the laptop.
## Notes
- Balances and prices are integers in **cents**; **osu** is a separate demo currency for the shop
- Catalog item price = Field-Tested reference; each inventory row stores `floatValue`, `wear`, `paintSeed`, `valueCents`, `favorite`
- Per-user auto-sell settings: `autoSellEnabled`, `autoSellThresholdCents` (default threshold **10.00** cr)
- Case key progress stored in `CaseKeyProgress` (per user + case); backfill: `npm run db:backfill-case-keys --prefix server`
- Inventory items locked while deposited in a bet; unlocked or transferred on resolve
- `Transaction` types include `open_case`, `seed_credit`, `seed_osu`, `sell_item`, `shop_purchase`, `ad_reward`, `jackpot_bet`, `jackpot_win`, `duel_bet`, `duel_win`
- Avatars stored under `server/uploads/` and served at `/uploads`
- Real-time state via Socket.IO (`jackpot`, `duel:{id}`, `duels` rooms)
- Avatars / uploads under `server/uploads/` (volume in Docker)
- Real-time via Socket.IO; Docker Hub image name is lowercase: `foufure/casegambling`
- Max **10** simultaneous browser windows/tabs per account (Socket.IO); override with `MAX_SOCKETS_PER_USER`
- Swap `DATABASE_URL` to PostgreSQL later without changing app logic