Update main repo
This commit is contained in:
327
README.md
Normal file
327
README.md
Normal file
@@ -0,0 +1,327 @@
|
||||
# MrixsCraft
|
||||
|
||||
Private Minecraft server project with a web-based launcher. Consists of two independent Go repositories unified via git submodules:
|
||||
|
||||
- **`server/`** — backend (Go + net/http + PostgreSQL)
|
||||
- **`launcher/`** — desktop launcher (Go + Fyne GUI)
|
||||
|
||||
Domain: `minecraft.mrixs.me` · CDN: `cdn.mrixs.me`
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────┐ HTTP/API ┌──────────────┐
|
||||
│ Launcher │ ◄──────────────► │ Server │
|
||||
│ (Go+Fyne) │ Yggdrasil+REST │ (Go+pgx) │
|
||||
└─────────────┘ └──────┬──────┘
|
||||
│
|
||||
┌──────┴──────┐
|
||||
│ PostgreSQL │
|
||||
│ 16 │
|
||||
└─────────────┘
|
||||
cdn.mrixs.me minecraft.mrixs.me
|
||||
┌──────────┐ ┌────────────────┐
|
||||
│ Caddy │ │ Caddy │
|
||||
│ file srv │ │ reverse proxy │
|
||||
│ (CAS) │ │ + HTTPS │
|
||||
└──────────┘ └────────────────┘
|
||||
```
|
||||
|
||||
**Infrastructure (Docker Compose):** Caddy · Go backend · PostgreSQL 16 · Watchtower (auto-update)
|
||||
|
||||
---
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
MC-server/
|
||||
├── .gitmodules # Submodules: launcher, server
|
||||
├── docs/
|
||||
│ ├── state.md # Project status and detailed architecture
|
||||
│ ├── launcher/Specification.md # Launcher specification (RU)
|
||||
│ └── server/Specification.md # Server specification (RU)
|
||||
├── launcher/ # Git submodule — MrixsCraft-launcher
|
||||
│ ├── cmd/launcher/main.go
|
||||
│ └── internal/
|
||||
│ ├── auth/ # Yggdrasil client
|
||||
│ ├── config/ # Launcher settings & system paths
|
||||
│ ├── fetcher/ # HTTP downloader with SHA-1 verification
|
||||
│ ├── java/ # JRE detection/download
|
||||
│ ├── launch/ # Manifest parsing, game launch, classpath assembly
|
||||
│ ├── selfupdate/# Binary auto-updater (SHA-256)
|
||||
│ └── ui/ # Fyne GUI (screens, components, theme)
|
||||
└── server/ # Git submodule — MrixsCraft-server
|
||||
├── cmd/
|
||||
│ ├── server/main.go # HTTP routes, middleware, graceful shutdown
|
||||
│ └── ci-release/main.go # CI release uploader
|
||||
├── Dockerfile # Multi-stage (~20 MB)
|
||||
├── docker-compose.yml # Caddy + backend + postgres + watchtower
|
||||
├── Caddyfile # Reverse proxy, CDN, HTTPS
|
||||
├── .gitea/workflows/ci.yml # CI: lint → test → build → docker push
|
||||
├── migrations/
|
||||
│ ├── 001_init.sql # Full schema: 6 tables + indexes
|
||||
│ └── 002_migration_history.sql # Migration tracking
|
||||
└── internal/
|
||||
├── admin/ # Modpack CRUD, file upload, manifests
|
||||
├── api/ # Public API: auth, skins, capes, launcher
|
||||
├── auth/ # Yggdrasil: authenticate/refresh/validate
|
||||
├── cas/ # Content-Addressable Storage (SHA-1)
|
||||
├── config/ # ENV configuration
|
||||
├── database/ # PostgreSQL (pgx/pgxpool), data models
|
||||
├── middleware/ # CORS, Logging, Recovery, RateLimiter
|
||||
├── session/ # Background expired-session cleanup
|
||||
└── templates/ # Go html/template (dark theme)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Component | Technology |
|
||||
|-----------|-----------|
|
||||
| Language | Go 1.25 (server) · Go 1.22 (launcher) |
|
||||
| HTTP | net/http (stdlib) |
|
||||
| Database | PostgreSQL 16 + pgx/v5 |
|
||||
| Hashing | SHA-1 (CAS) · SHA-256 (launcher releases) · bcrypt (passwords) |
|
||||
| GUI | Fyne v2.4.5 |
|
||||
| Auth | Custom Yggdrasil server + authlib-injector |
|
||||
| Proxy | Caddy 2 (auto-HTTPS) |
|
||||
| Containers | Docker + Docker Compose |
|
||||
| Registry | Gitea Container Registry |
|
||||
| CI/CD | Gitea Actions |
|
||||
| Auto-update | Watchtower |
|
||||
|
||||
---
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Go 1.25+ (server) / Go 1.22+ (launcher)
|
||||
- Docker & Docker Compose (production)
|
||||
- PostgreSQL 16 (if running without Docker)
|
||||
|
||||
### Clone with Submodules
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules gitea.mrixs.me:mrixs/mrixscraft.git MC-server
|
||||
```
|
||||
|
||||
If already cloned without submodules:
|
||||
|
||||
```bash
|
||||
git submodule update --init --recursive
|
||||
```
|
||||
|
||||
### Server
|
||||
|
||||
```bash
|
||||
cd server/
|
||||
|
||||
# Configure
|
||||
cp .env.example .env
|
||||
# edit .env: DATABASE_URL, JWT_SECRET, etc.
|
||||
|
||||
# Run locally
|
||||
go run ./cmd/server
|
||||
|
||||
# Or via Docker Compose
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
**Required environment variables:**
|
||||
|
||||
| Variable | Default | Required |
|
||||
|----------|---------|----------|
|
||||
| `SERVER_PORT` | `8080` | No |
|
||||
| `DATABASE_URL` | — | **Yes** |
|
||||
| `CAS_DIR` | `/var/www/cdn/files` | No |
|
||||
| `JWT_SECRET` | — | **Yes** |
|
||||
|
||||
### Launcher
|
||||
|
||||
```bash
|
||||
cd launcher/
|
||||
go build -o mrixscraft-launcher ./cmd/launcher
|
||||
./mrixscraft-launcher
|
||||
```
|
||||
|
||||
Or: `go run ./cmd/launcher`
|
||||
|
||||
---
|
||||
|
||||
## Server API
|
||||
|
||||
### Yggdrasil (Mojang-compatible)
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| POST | `/authserver/authenticate` | Login with credentials |
|
||||
| POST | `/authserver/refresh` | Refresh token |
|
||||
| POST | `/authserver/validate` | Validate token (204) |
|
||||
| POST | `/authserver/invalidate` | Invalidate token |
|
||||
| POST | `/authserver/signout` | Sign out (delete all sessions) |
|
||||
| GET | `/sessionserver/session/minecraft/profile/{uuid}` | Player profile with textures |
|
||||
|
||||
### Public API
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| POST | `/api/web/register` | Player registration |
|
||||
| POST | `/api/web/login` | Website login |
|
||||
| POST | `/api/web/profile/skin` | Upload skin (PNG) |
|
||||
| POST | `/api/web/profile/cape` | Upload cape (PNG) |
|
||||
| DELETE | `/api/web/profile/skin` | Delete skin |
|
||||
| GET | `/api/web/profile/{uuid}` | Player profile |
|
||||
|
||||
### Launcher API
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/launcher/latest` | Latest launcher version |
|
||||
| GET | `/api/servers.json` | Active modpack list |
|
||||
| GET | `/api/instances/{slug}/manifest.json` | Modpack manifest |
|
||||
|
||||
### CAS (File Server)
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/files/{sha1}` | File by SHA-1 hash |
|
||||
| GET | `/files/launcher/{version}/{os}/{arch}/{filename}` | Launcher binary |
|
||||
| GET | `/skins/{hash}` | Skin/cape by hash |
|
||||
|
||||
### Admin (Bearer token + role=admin)
|
||||
| Method | Path | Description |
|
||||
|--------|------|-------------|
|
||||
| GET | `/api/admin/modpacks` | List modpacks |
|
||||
| POST | `/api/admin/modpacks` | Create modpack |
|
||||
| PUT | `/api/admin/modpacks/{id}` | Update modpack |
|
||||
| DELETE | `/api/admin/modpacks/{id}` | Deactivate modpack |
|
||||
| POST | `/api/admin/modpacks/{slug}/upload` | Upload files (≤500 MB) |
|
||||
| POST | `/api/admin/modpacks/{slug}/manifest` | Generate manifest.json |
|
||||
| POST | `/api/admin/launcher/release` | Upload launcher release (X-CI-Token) |
|
||||
| GET | `/admin` | Web admin interface (requires admin role) |
|
||||
|
||||
---
|
||||
|
||||
## Content-Addressable Storage (CAS)
|
||||
|
||||
All files (mods, libraries, assets) are stored by their SHA-1 hash:
|
||||
|
||||
```
|
||||
/var/www/cdn/files/ab/abcdef1234... (first 2 chars as subdirectory)
|
||||
```
|
||||
|
||||
- **Immutable** — files are never overwritten
|
||||
- **Cache-Control:** `public, max-age=31536000, immutable` (1 year)
|
||||
- **Deduplication** — automatic (same hash = same file)
|
||||
- **Concurrent-safe** — per-hash `sync.Mutex` prevents race conditions
|
||||
- **Verification** — constant-time SHA-1 comparison
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
7 tables:
|
||||
|
||||
| Table | Purpose |
|
||||
|-------|---------|
|
||||
| `users` | Players (username, email, password_hash, uuid, role) |
|
||||
| `player_textures` | Skins & capes (skin_hash, cape_hash → CAS) |
|
||||
| `yggdrasil_sessions` | Auth sessions (access_token, client_token, expires_at) |
|
||||
| `modpacks` | Modpacks/servers (slug, name, minecraft_version, java_version, server_ip) |
|
||||
| `global_files` | CAS file registry (sha1 PK, size_bytes, file_name, mime_type) |
|
||||
| `launcher_releases` | Launcher releases (version, os, arch, sha256, file_path) |
|
||||
| `migration_history` | Applied migration tracking |
|
||||
|
||||
Migrations are applied manually: `psql $DATABASE_URL -f migrations/001_init.sql`
|
||||
|
||||
---
|
||||
|
||||
## Launcher Client File Structure
|
||||
|
||||
| OS | Root Directory |
|
||||
|----|---------------|
|
||||
| Windows | `%APPDATA%\MrixsCraft\` |
|
||||
| macOS | `~/Library/Application Support/MrixsCraft/` |
|
||||
| Linux | `~/.MrixsCraft/` |
|
||||
|
||||
```
|
||||
MrixsCraft/
|
||||
├── launcher.json # Settings (RAM, server URL, window)
|
||||
├── session.json # Yggdrasil tokens
|
||||
├── authlib-injector.jar # Auth interceptor
|
||||
├── Java/{8,17,21}/ # Portable JREs
|
||||
├── assets/ # Game assets
|
||||
├── libraries/ # Shared libraries (LWJGL, etc.)
|
||||
└── instances/{slug}/ # Isolated modpack clients
|
||||
├── mods/
|
||||
├── mods_backup/ # Unknown mods moved here (soft delete)
|
||||
├── config/
|
||||
└── resourcepacks/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Server
|
||||
cd server/
|
||||
go test ./... -v -race -cover
|
||||
|
||||
# Launcher — no tests (GUI testing is impractical)
|
||||
```
|
||||
|
||||
Server test coverage: `cas`, `auth`, `api`, `session` packages.
|
||||
|
||||
---
|
||||
|
||||
## CI/CD
|
||||
|
||||
Gitea Actions pipeline (`.gitea/workflows/ci.yml`):
|
||||
|
||||
```
|
||||
lint (go vet + gofmt) → test (race detector) → build → docker push (master only)
|
||||
```
|
||||
|
||||
Images: `gitea.mrixs.me/mrixs/mrixscraft-server:latest` + `:sha`
|
||||
|
||||
Watchtower on VPS polls every 5 minutes and auto-deploys new images.
|
||||
|
||||
---
|
||||
|
||||
## Known TODOs
|
||||
|
||||
### Server
|
||||
- Full-text file search in DB
|
||||
- SIGHUP config reload (requires `config.Atomic` refactor)
|
||||
|
||||
### Launcher
|
||||
- PLAY button wired to `launch.Prepare` + `Game.Start` (stub)
|
||||
- Server list hardcoded (not loaded from `/api/servers.json`)
|
||||
- Java auto-download not implemented
|
||||
- Skin avatar rendering (8×64 face crop)
|
||||
- News/patchnotes on MainScreen
|
||||
- `servers.dat` NBT manipulation
|
||||
|
||||
### Infrastructure
|
||||
- CI deploy step (SSH + docker compose up) — needs secrets
|
||||
- Automatic Go migration runner (currently manual)
|
||||
- Backup script not in cron
|
||||
|
||||
---
|
||||
|
||||
## Commands Reference
|
||||
|
||||
```bash
|
||||
# Server
|
||||
cd server/
|
||||
go build -o mrixscraft-server ./cmd/server
|
||||
go test ./...
|
||||
go run ./cmd/server
|
||||
docker compose up -d
|
||||
|
||||
# Launcher
|
||||
cd launcher/
|
||||
go build -o mrixscraft-launcher ./cmd/launcher
|
||||
go run ./cmd/launcher
|
||||
```
|
||||
Reference in New Issue
Block a user