Files
CaseGambling/README.md
T
2026-07-25 20:04:34 +02:00

125 lines
6.4 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CaseOrion
CS-style case opening site with virtual credits, inventory, multiplayer item betting, shop, leaderboard, and an admin panel for cases / drops / rates.
## Stack
- **Server**: Node.js, Express, Prisma, SQLite, express-session, Socket.IO
- **Client**: React (Vite), React Router, Socket.IO client
## Setup
```bash
npm run install:all
npm run db:push
npm run db:seed
npm run dev
```
- App: http://localhost:5888
- API: http://localhost:3001
- LAN: http://\<your-lan-ip\>:5888 (Vite binds to `0.0.0.0`)
Create `server/.env` if missing:
```
DATABASE_URL="file:./dev.db"
PORT=3001
CLIENT_ORIGIN=http://localhost:5888
SESSION_SECRET=dev-secret
STARTING_BALANCE=10000
STARTING_OSU=100
JACKPOT_ROUND_SECONDS=30
JACKPOT_MAX_ITEMS=3
```
## Demo accounts
| Role | Username | Password |
|-------|----------|------------|
| 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 sell at **instance** value (float/wear), bulk **Sell below** threshold, **favorites** (★ — cannot be sold or auto-sold; can still be bet in battles), **Vault** staking (up to **3** slots by default; +1 per Vault Capacity skill) — shared timer; dividends auto-pay **every 5 min online** (10% value) / **10 min offline** (1%), scaled by float² wear and rarity (cap **500%** value / tick)
- **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)
- **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`):
- Create / join MultiPlayers pots — live shared pot, up to 3 items, win chance by value, Socket.IO sync
- Spectate in-progress battles from the hub
- **Shop** (`/shop`): buy **osu** with real money (mock checkout in dev, Stripe-ready), exchange osu for credit packs, or 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): starter badges unlocked by play (cases, battles, catalog, prestige, shop, playtime); earned badges appear on the profile
- **Prestige**: pay **1000000000000.00** cr to reset; earn **Pr** (1000 base + ~1000 per **250000000000.00** cr excess); spend Pr on a skill tree (Fortune, Yield, Polish, Bulk, PR Farmer, Quality, noTime, Refund, Respin, Vault Capacity, Offline/Online Yield)
- **Leaderboard**: richest players (balance + inventory value); click a row to open a public **player profile** (`/player/:username`) with stats and inventory
- Admin: overview dashboard, players (credit adjust), cases / items / drops (split pages, search filters)
## 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 the premium (real-money) currency — top-ups create `PaymentOrder` rows (`PAYMENTS_PROVIDER=mock|stripe`)
- Catalog item price = Field-Tested reference; each inventory row stores `floatValue`, `wear`, `paintSeed`, `valueCents`, `favorite`, optional vault `staked` / `stakedAt` / `lastYieldAt`
- 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; staked vault items cannot be sold, auto-sold, or bet
- Avatars / uploads under `server/uploads/` (volume in Docker)
- Real-time via Socket.IO; Docker Hub image name is lowercase: `foufure/casegambling`
- Max **2** simultaneous browser windows/tabs per account (Socket.IO); override with `MAX_SOCKETS_PER_USER`
- Swap `DATABASE_URL` to PostgreSQL later without changing app logic