Files
slgserver/CLAUDE.md
2025-11-19 14:16:28 +08:00

247 lines
8.4 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a Three Kingdoms strategy game (SLG) server written in Go, featuring a microservices architecture with WebSocket-based real-time communication. The game includes army management, city building, coalition systems, and turn-based combat mechanics.
## Build Commands
Build all servers for Linux deployment:
```bash
cd shell
./build.bat # Cross-compiles for Linux even on Windows
```
Individual server builds (from project root):
```bash
go build -o bin/slgserver main/slgserver.go # Main game logic server
go build -o bin/loginserver main/loginserver.go # Authentication server
go build -o bin/chatserver main/chatserver.go # Chat/messaging server
go build -o bin/gateserver main/gateserver.go # Gateway/proxy server
go build -o bin/httpserver main/httpserver.go # HTTP API server
```
Run servers individually (from bin directory):
```bash
./slgserver # Port 8001
./loginserver # Port 8003
./chatserver # Port 8002
./gateserver # Port 8004
./httpserver # Port 8088
```
## Configuration
All configuration is in [data/conf/env.ini](data/conf/env.ini):
- Database connection settings (MySQL)
- Server ports and addresses
- XORM logging and SQL debugging
- WebSocket proxy routes for gateserver
- Server ID for multi-server support
Configuration is loaded via the `config` package using `spf13/viper`.
## Architecture
### Microservices Structure
The system consists of 5 independent servers:
1. **slgserver** - Core game logic server handling:
- Army operations (conscription, movement, combat)
- City management (facilities, resources, building)
- Coalition/alliance systems
- National map and territory control
- General (hero) management and skills
2. **loginserver** - Authentication and session management:
- User login/logout with password hashing
- Session token generation and validation
- Server list for multi-server support
3. **chatserver** - Real-time messaging:
- Chat groups and channels
- Message queuing and delivery
- Broadcast notifications
4. **gateserver** - Gateway and routing:
- Central entry point for clients
- WebSocket proxy to backend services
- Connection lifecycle management
- Routes requests to slg/chat/login servers based on message prefix
5. **httpserver** - HTTP REST API (Gin framework):
- Alternative HTTP endpoints for web clients
- Account operations via REST
### WebSocket Message Protocol
All servers use a custom WebSocket message format defined in [net/conn.go](net/conn.go):
```go
// Request
{
"seq": 12345, // Message sequence number
"name": "army.myList", // Route: <group>.<handler>
"msg": {...}, // Payload
"proxy": "slg" // Target service (for gateserver routing)
}
// Response
{
"seq": 12345,
"name": "army.myList",
"code": 0, // Response code (0 = OK)
"msg": {...}
}
```
Message routing uses dot notation: `<group>.<handler>`. The router ([net/router.go](net/router.go)) supports:
- Grouped routes with middleware
- Per-route and per-group middleware
- Wildcard handlers (`*`)
### Data Layer Architecture
**Database**: MySQL accessed via XORM ORM ([db/conn.go](db/conn.go))
- Connection pooling with configurable limits
- Automatic database creation on first run
- SQL logging to file for debugging
**In-Memory Managers**: Core game state is cached in memory for performance:
- `mgr.AMgr` - Army manager ([logic/mgr/army_mgr.go](server/slgserver/logic/mgr/army_mgr.go))
- `mgr.RCMgr` - Role city manager
- `mgr.NMMgr` - National map manager
- `mgr.GMgr` - General manager
- `mgr.SkillMgr` - Skill manager
- `mgr.UnionMgr` - Coalition/alliance manager
Managers maintain indexed maps (by ID, by RID, by CityId) loaded at startup. Database writes happen via XORM but reads primarily from cache.
**Static Configuration**: JSON files loaded at startup:
- [data/conf/json/facility/](data/conf/json/facility/) - Building definitions
- [data/conf/json/general/](data/conf/json/general/) - Hero stats and attributes
- [data/conf/json/skill/](data/conf/json/skill/) - Skill effects
- [data/conf/json/basic.json](data/conf/json/basic.json) - Game constants
- [data/conf/json/map_build.json](data/conf/json/map_build.json) - Map structure
Loaded via `static_conf` package during `run.Init()`.
### Game Logic Patterns
**Model-Controller-Logic Pattern**:
- `model/` - Database entities with `ToProto()` methods
- `controller/` - WebSocket handlers, parse requests, validate
- `logic/` - Business logic, game rules, calculations
- `proto/` - Protocol buffers/data transfer objects
**Key Systems**:
1. **Army System** ([server/slgserver/logic/army_war.go](server/slgserver/logic/army_war.go)):
- Turn-based combat with 10 max rounds
- Position-based strategy (3 general positions per army)
- Attributes: force, defense, strategy, speed, destroy
- Facility bonuses from cities
- Battle results stored as war reports
2. **City/Facility System**:
- Cities have multiple facility slots
- Each facility type provides bonuses (TypeForce, TypeDefense, etc.)
- Upgrade system with resource costs and time delays
- Facilities loaded from JSON config
3. **General/Skill System**:
- Generals have arms (兵种), levels, experience
- Skills categorized: 主动 (active), 被动 (passive), 追击 (pursuit), 指挥 (command)
- Conscription system for recruiting troops
4. **Coalition System**:
- Player alliances with leadership structure
- Must load before other systems (dependency in `run.Init()`)
### Middleware Pipeline
WebSocket handlers support middleware ([middleware/](middleware/)):
- `ElapsedTime()` - Request timing
- `Log()` - Request/response logging
- `CheckLogin()` - Session validation (checks `uid` property on connection)
- `CheckRole()` - Role validation (checks `role` property)
- `CheckRid()` - Role ID validation
Middleware wraps handlers in reverse order (last added = innermost).
### Connection State Management
WebSocket connections ([net/conn.go](net/conn.go), [net/serverconn.go](net/serverconn.go)) maintain properties:
- `uid` - User ID (set after login)
- `role` - Role object (set after role selection)
- Properties stored in sync.Map for concurrent access
The `ConnMgr` singleton tracks all active connections.
## Development Workflow
1. **Modify game logic**: Edit files in `server/slgserver/logic/`
2. **Add new routes**: Register in `server/slgserver/run/init.go``initRouter()`
3. **Add new models**: Create in `model/`, implement `ToProto()`, add to manager
4. **Update static config**: Edit JSON files in `data/conf/json/`, reload on startup
5. **Database changes**: Models use XORM tags, schema auto-syncs if configured
## Server Initialization Order
Critical: The initialization sequence in [server/slgserver/run/init.go](server/slgserver/run/init.go) must be followed:
1. Test/create database (`db.TestDB()`)
2. Load static configs (facilities, generals, skills, etc.)
3. Set server ID from config
4. `logic.BeforeInit()` - Pre-initialization hooks
5. Load managers in dependency order:
- NMMgr (national map)
- UnionMgr (coalitions - **must load first**)
- RAttrMgr, RCMgr, RBMgr, RFMgr (role data)
- SkillMgr, GMgr (generals/skills)
- AMgr (armies - depends on generals)
6. `logic.Init()` and `logic.AfterInit()`
7. Register routers (only after full initialization)
## Common Patterns
**Getting a user's role from connection**:
```go
r, _ := req.Conn.GetProperty("role")
role := r.(*model.Role)
```
**Accessing managers**:
```go
army, ok := mgr.AMgr.Get(armyId)
general, ok := mgr.GMgr.Get(rid, generalId)
```
**Database operations with XORM**:
```go
// Query
db.MasterDB.Table(model.Army{}).Where("rid=?", rid).Find(&armies)
// Insert
db.MasterDB.Table(model.Army{}).Insert(army)
// Update
db.MasterDB.Table(model.Army{}).ID(armyId).Cols("soldiers").Update(army)
```
**Response codes**: Use constants from [constant/code.go](constant/code.go) (OK, DBError, InvalidParam, etc.)
## Multi-Server Support
The `logic.server_id` config enables running multiple game servers with separate databases. Table names are suffixed with server ID (e.g., `tb_role_1`).
## Deployment Notes
- Build script cross-compiles for Linux (CGO_ENABLED=0, GOOS=linux)
- Servers run independently, start all 5 for full functionality
- Gateserver acts as reverse proxy, client connects only to port 8004
- Configuration file must be in working directory or specify path