Files
MrixsCraft/README.md
2026-06-09 18:14:59 +03:00

328 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# 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
```