Files
koring-launcher/README.md
T

179 lines
7.3 KiB
Markdown
Raw Normal View History

2026-06-20 02:34:10 +08:00
# Koring Launcher
2026-06-19 23:50:40 +08:00
2026-06-28 03:37:07 +08:00
Minecraft launcher built with Electron + React 19 + TypeScript + Node.js (@xmcl).
2026-06-19 23:50:40 +08:00
2026-06-20 02:34:10 +08:00
## Quick Start
2026-06-19 23:50:40 +08:00
2026-06-20 02:34:10 +08:00
```bash
pnpm install
2026-06-28 03:37:07 +08:00
pnpm dev # full app (frontend + electron)
pnpm dev:renderer # frontend only (vite, port 1420)
pnpm dev:main # electron main process only
2026-06-20 02:34:10 +08:00
```
## Build
```bash
2026-06-28 03:37:07 +08:00
pnpm build # production build (vite + tsc)
2026-07-11 23:33:44 +08:00
pnpm dist:dev # dev icon + Windows installer
pnpm dist:beta # beta icon + Windows installer
pnpm dist:run # production icon + Windows installer
2026-06-28 03:37:07 +08:00
pnpm dist:mac # build macOS DMG
pnpm dist:linux # build Linux AppImage
2026-06-20 02:34:10 +08:00
```
## Architecture
```
src/ Frontend (React 19 + Vite 7 + Tailwind v4 + shadcn/ui + Zustand)
2026-06-28 03:37:07 +08:00
electron/ Main process (Node.js/TypeScript, @xmcl/* packages)
2026-06-20 02:34:10 +08:00
public/ Static assets (icons, fonts, images)
2026-07-11 23:33:44 +08:00
build/ Build resources (generated, gitignored)
2026-06-20 02:34:10 +08:00
```
**IPC Flow:**
2026-06-28 03:37:07 +08:00
Frontend → `ipcRenderer.invoke()``ipcMain.handle()` → main process → `webContents.send()` → Frontend
2026-06-20 02:34:10 +08:00
## Project Structure
```
src/
2026-06-28 03:37:07 +08:00
├── api/ # Frontend API layer (IPC wrappers)
│ ├── ipc.ts # Core IPC utilities
2026-06-20 02:34:10 +08:00
│ ├── background.ts # Background control
│ ├── install.ts # Minecraft install
│ ├── launch.ts # Game launch
│ ├── auth.ts # Microsoft/offline auth
│ ├── mods.ts # Modrinth/CurseForge
│ └── instance.ts # Instance management
├── stores/ # Zustand state stores
├── components/
│ ├── background/ # Background layer (z-0)
│ ├── system/ # Title bar + window controls (z-100)
│ └── ui/ # shadcn/ui components
├── layouts/
│ └── RootLayout.tsx # Three-layer page structure
├── pages/
│ ├── Home.tsx # Main page
│ └── Debug.tsx # Debug tools
├── lib/
2026-07-11 23:33:44 +08:00
│ ├── mode.ts # Build mode constants (DEFAULT_BG, LOGO_SVG, APP_ICON)
2026-06-20 02:34:10 +08:00
│ └── utils.ts # cn() helper
└── App.tsx # Root component with state router
2026-06-28 03:37:07 +08:00
electron/
2026-07-11 23:33:44 +08:00
├── main.ts # Electron entry, window management, splash→main transition
2026-06-28 03:37:07 +08:00
├── preload.ts # Context bridge (window.electronAPI)
├── config.ts # YAML config management
├── auth.ts # Auth data persistence
├── core/ # @xmcl/* integrations
│ ├── auth.ts # Microsoft OAuth, Xbox Live, MC auth
│ ├── installer.ts # @xmcl/installer
│ ├── launcher.ts # @xmcl/core game launcher
│ ├── modrinth.ts # Modrinth/CurseForge API
│ └── instance.ts # Instance management
├── handlers/ # IPC handlers
│ ├── config.ts # Config load/save
│ ├── auth.ts # Auth operations
│ ├── install.ts # Install operations
│ ├── launch.ts # Game launch
│ ├── mods.ts # Mod operations
│ ├── instance.ts # Instance operations
│ ├── background.ts # Background operations
│ ├── task.ts # Task system
│ ├── system.ts # System info
2026-07-11 23:33:44 +08:00
│ └── window.ts # Window controls + splash management
2026-06-28 03:37:07 +08:00
└── types/
└── electron.d.ts # TypeScript declarations
2026-06-20 02:34:10 +08:00
```
## Three-Layer Page Structure
```
┌──────────────────────────────────────┐
│ z-index: 100 System Layer │ pointer-events: none
│ ┌──────────────────────────────┐ │
│ │ TitleBar (frosted glass) │ │ pointer-events: auto
│ │ WindowControls (25px btns) │ │
│ └──────────────────────────────┘ │
├──────────────────────────────────────┤
│ z-index: 1 Content Layer │ pointer-events: auto
│ All page content │
├──────────────────────────────────────┤
│ z-index: 0 Background Layer │ pointer-events: none
│ Image / color / gradient / blur │
└──────────────────────────────────────┘
```
## Splash Screen
- Standalone HTML/CSS (`splash.html`), no React/Vite dependency
- Loads instantly while Vite dev server starts
- Window: 480×320, no decorations, transparent, locked size
- Auto-adapts to system dark mode (`prefers-color-scheme`)
- Logo: `filter: invert(1)` in dark mode
2026-07-11 23:33:44 +08:00
- Startup: splash shows first → main loads behind → transition after `ready-to-show` + 1.5s minimum
2026-06-20 02:34:10 +08:00
## Icon System
2026-07-11 23:33:44 +08:00
Three icon variants in `public/icons/`:
2026-06-20 02:34:10 +08:00
2026-07-11 23:33:44 +08:00
```
public/icons/
dev/icon.ico, icon.png # Development
beta/icon.ico, icon.png # Testing
run/icon.ico, icon.png # Production release
```
**Build-time switching:**
```bash
pnpm icon:dev # copies public/icons/dev/ → build/
pnpm icon:beta # copies public/icons/beta/ → build/
pnpm icon:run # copies public/icons/run/ → build/
```
`electron-builder.yml` reads icons from `build/` (`buildResources: build`).
2026-06-20 02:34:10 +08:00
**Frontend usage:**
```tsx
2026-07-11 23:33:44 +08:00
import { APP_ICON, DEFAULT_BG, LOGO_SVG, BUILD_MODE, isDev } from "@/lib/mode";
2026-06-20 02:34:10 +08:00
<img src={APP_ICON} />
2026-07-11 23:33:44 +08:00
<img src={LOGO_SVG} />
<img src={DEFAULT_BG} />
2026-06-20 02:34:10 +08:00
{isDev && <span>Dev Mode</span>}
```
2026-06-28 03:37:07 +08:00
## IPC Handlers
2026-06-20 02:34:10 +08:00
2026-06-28 03:37:07 +08:00
- `config:*` — Config load/save
- `auth:*` — Microsoft OAuth, offline login
2026-06-20 02:34:10 +08:00
- `install:*` — Minecraft install, mod loader, version lists
- `launch:*` — Game launch, diagnose
- `mods:*` — Modrinth/CurseForge search, install
- `instance:*` — Instance CRUD
- `background:*` — Background image/color/blur/animation/theme
2026-06-28 03:37:07 +08:00
- `task:*` — Task system progress
- `system:*` — System info
2026-07-11 23:33:44 +08:00
- `window:*` — Minimize/maximize/close + splash management
- `dialog:*` — File picker
2026-06-20 02:34:10 +08:00
## Key Gotchas
2026-06-28 03:37:07 +08:00
- **@xmcl packages run in main process**: `@xmcl/core`, `@xmcl/installer` require `fs`/`child_process`. All run in Electron main process.
2026-06-20 02:34:10 +08:00
- **Path alias**: `@/` maps to `src/`.
2026-07-11 23:33:44 +08:00
- **Window dragging**: Use CSS `WebkitAppRegion: "drag"` as inline style (Electron only respects CSS property, not HTML attributes).
2026-06-28 03:37:07 +08:00
- **Transparent windows**: `transparent: true` + `frame: false` in BrowserWindow options.
2026-07-11 23:33:44 +08:00
- **Mutable win ref**: `electron/main.ts` uses a mutable `win` object — all handlers read `win.mainWindow` at runtime (not captured at registration time).
- **Asset paths**: Use `import.meta.env.BASE_URL` prefix for public assets (e.g., `${import.meta.env.BASE_URL}background.png`). Absolute paths like `/background.png` break in packaged app.
- **Config**: YAML format (`Koring.yml`) stored next to executable. Sparse save (only non-default values).
- **Auth**: JSON file (`koring-auth.json`) stored next to executable.
2026-06-20 02:34:10 +08:00
## Tech Stack
| Layer | Technology |
|-------|-----------|
| Frontend | React 19, Vite 7, Tailwind CSS v4, shadcn/ui, Zustand |
2026-06-28 03:37:07 +08:00
| Main Process | Node.js, TypeScript, @xmcl/* packages |
| Build | pnpm, Vite, electron-builder |