mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
392 lines
12 KiB
Markdown
392 lines
12 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
Erupe is a community-maintained server emulator for Monster Hunter Frontier written in Go. It reverse-engineers the game server protocol to enable self-hosted Monster Hunter Frontier servers, supporting multiple game versions (Season 6.0 through ZZ) and platforms (PC, PS3, PS Vita, Wii U).
|
|
|
|
**Module name:** `erupe-ce`
|
|
**Go version:** 1.25+
|
|
**Current branch purpose:** Clean transition from 9.2.0 to future 9.3.0 release
|
|
|
|
## Build and Development Commands
|
|
|
|
### Building and Running
|
|
|
|
```bash
|
|
# Build the server
|
|
go build
|
|
|
|
# Build and produce binary
|
|
go build -o erupe-ce
|
|
|
|
# Run without building
|
|
go run .
|
|
|
|
# Run with hot reload during development
|
|
go run main.go
|
|
```
|
|
|
|
### Testing
|
|
|
|
```bash
|
|
# Run all tests
|
|
go test -v ./...
|
|
|
|
# Run tests for specific package
|
|
go test -v ./server/channelserver/...
|
|
|
|
# Run specific test
|
|
go test -v ./server/channelserver/... -run TestName
|
|
|
|
# Check for race conditions (important!)
|
|
go test -v -race ./...
|
|
|
|
# Generate test coverage
|
|
go test -v -cover ./...
|
|
go test ./... -coverprofile=/tmp/coverage.out
|
|
go tool cover -html=/tmp/coverage.out -o /tmp/coverage.html
|
|
```
|
|
|
|
### Code Quality
|
|
|
|
```bash
|
|
# Format code (ALWAYS run before committing)
|
|
gofmt -w .
|
|
|
|
# Lint code
|
|
golangci-lint run ./...
|
|
|
|
# Fix linting issues automatically
|
|
golangci-lint run ./... --fix
|
|
```
|
|
|
|
### Database Operations
|
|
|
|
```bash
|
|
# Connect to PostgreSQL
|
|
psql -U postgres -d erupe
|
|
|
|
# Apply schema patches (must be done in order)
|
|
psql -U postgres -d erupe -f patch-schema/01_patch.sql
|
|
psql -U postgres -d erupe -f patch-schema/02_patch.sql
|
|
# ... continue in order
|
|
|
|
# With password from environment
|
|
PGPASSWORD='password' psql -U postgres -d erupe -f schema.sql
|
|
```
|
|
|
|
### Docker Development
|
|
|
|
```bash
|
|
# Start database and pgadmin
|
|
docker compose up db pgadmin
|
|
|
|
# Start server (after configuring database)
|
|
docker compose up server
|
|
|
|
# Full stack
|
|
docker compose up
|
|
```
|
|
|
|
### Log Analysis
|
|
|
|
The project includes a comprehensive log analyzer tool in `tools/loganalyzer/`:
|
|
|
|
```bash
|
|
# Build log analyzer
|
|
cd tools/loganalyzer
|
|
go build -o loganalyzer
|
|
|
|
# Filter logs by level
|
|
./loganalyzer filter -f ../../logs/erupe.log -level error
|
|
|
|
# Analyze errors with stack traces
|
|
./loganalyzer errors -f ../../logs/erupe.log -stack -detailed
|
|
|
|
# Track player connections
|
|
./loganalyzer connections -f ../../logs/erupe.log -sessions
|
|
|
|
# Real-time log monitoring
|
|
./loganalyzer tail -f ../../logs/erupe.log -level error
|
|
|
|
# Generate statistics
|
|
./loganalyzer stats -f ../../logs/erupe.log -detailed
|
|
```
|
|
|
|
## Architecture
|
|
|
|
### Three-Server Architecture
|
|
|
|
Erupe uses a multi-server architecture that mirrors the original Monster Hunter Frontier server design:
|
|
|
|
1. **Sign Server** (Port 53312)
|
|
- Handles authentication and account management
|
|
- Located in `server/signserver/`
|
|
- Two versions: legacy (signserver) and modern HTTP-based (signv2server)
|
|
- Creates sign sessions with tokens for channel server authentication
|
|
|
|
2. **Entrance Server** (Port 53310)
|
|
- Manages world/server selection and character list
|
|
- Located in `server/entranceserver/`
|
|
- Routes players to available channel servers
|
|
- Maintains server availability information
|
|
|
|
3. **Channel Servers** (Ports 54001+)
|
|
- Handle actual gameplay sessions, quests, and player interactions
|
|
- Located in `server/channelserver/`
|
|
- Multiple instances can run simultaneously
|
|
- Organized by world types (Newbie, Normal, Cities, Tavern, Return, MezFes)
|
|
|
|
### Channel Server Internal Architecture
|
|
|
|
The channel server is the most complex component:
|
|
|
|
**Session Management** ([sys_session.go](server/channelserver/sys_session.go))
|
|
|
|
- Each player connection creates a `Session` struct
|
|
- Sessions handle packet queuing, encryption, and client state
|
|
- Uses goroutines for send/receive loops
|
|
- Thread-safe with mutex locks
|
|
|
|
**Handler System** ([handlers_table.go](server/channelserver/handlers_table.go))
|
|
|
|
- Packet handlers registered in `handlerTable` map
|
|
- Maps `network.PacketID` to `handlerFunc`
|
|
- Handlers organized by feature in separate files:
|
|
- `handlers_quest.go` - Quest system
|
|
- `handlers_guild.go` - Guild operations
|
|
- `handlers_stage.go` - Stage/room management
|
|
- `handlers_character.go` - Character data
|
|
- `handlers_*.go` - Feature-specific handlers
|
|
|
|
**Stage System** ([sys_stage.go](server/channelserver/sys_stage.go))
|
|
|
|
- Stages are game rooms/areas where players interact
|
|
- Thread-safe stage creation, entry, movement, and destruction
|
|
- Stage locking/unlocking for privacy
|
|
- Stage binary data for synchronizing state between players
|
|
|
|
**Semaphore System** ([sys_semaphore.go](server/channelserver/sys_semaphore.go))
|
|
|
|
- Resource locking mechanism for shared game resources
|
|
- Used for quests, events, and multiplayer coordination
|
|
- Global and local semaphores
|
|
|
|
**Special Event Systems**
|
|
|
|
- Raviente: Large-scale raid event (in `Server.raviente`)
|
|
- Diva Defense, Hunter's Festa, VS Tournament (handlers in `handlers_event.go`, `handlers_festa.go`, `handlers_tournament.go`)
|
|
|
|
### Network Layer
|
|
|
|
**Packet Structure** ([network/mhfpacket/](network/mhfpacket/))
|
|
|
|
- Packet definitions in `msg_*.go` files
|
|
- Each packet type implements `MHFPacket` interface
|
|
- Packets prefixed by type: `MSG_SYS_*`, `MSG_MHF_*`, `MSG_CA_*`
|
|
- Binary packet handling in `network/binpacket/`
|
|
|
|
**Encryption** ([network/crypt_packet.go](network/crypt_packet.go))
|
|
|
|
- Custom encryption layer wrapping connections
|
|
- Different crypto for different server types
|
|
|
|
**Compression** ([server/channelserver/compression/](server/channelserver/compression/))
|
|
|
|
- Delta compression (`deltacomp`) for bandwidth optimization
|
|
- Null compression (`nullcomp`) for debugging
|
|
|
|
### Common Utilities
|
|
|
|
**ByteFrame** ([common/byteframe/](common/byteframe/))
|
|
|
|
- Buffer for reading/writing binary data
|
|
- Provides methods for reading/writing various data types
|
|
- Critical for packet construction and parsing
|
|
|
|
**PascalString** ([common/pascalstring/](common/pascalstring/))
|
|
|
|
- Length-prefixed string format used by game protocol
|
|
- Different variants for different string types
|
|
|
|
**Client Context** ([network/clientctx/](network/clientctx/))
|
|
|
|
- Stores client version and capabilities
|
|
- Used for multi-version support
|
|
|
|
## Database Schema Management
|
|
|
|
**Schema Types:**
|
|
|
|
- **Initialization Schema:** Bootstraps database to version 9.1.0 (in `schemas/`)
|
|
- **Patch Schemas:** Development updates in `patch-schema/` (numbered, apply in order)
|
|
- **Update Schemas:** Production-ready consolidated updates (for releases)
|
|
- **Bundled Schemas:** Demo data templates in `schemas/bundled-schema/` (shops, events, gacha)
|
|
|
|
**Important:** Patch schemas are subject to change during development. They get consolidated into update schemas on release. Apply patches in numerical order.
|
|
|
|
## Configuration System
|
|
|
|
Configuration uses Viper and is defined in `config/config.go`. The `ErupeConfig` global variable holds runtime configuration loaded from `config.json`.
|
|
|
|
**Key configuration sections:**
|
|
|
|
- `DevMode` and `DevModeOptions` - Development flags and debugging
|
|
- `GameplayOptions` - Gameplay modifiers (NP/RP caps, boost times, quest allowances)
|
|
- `Database` - PostgreSQL connection settings
|
|
- `Sign`, `SignV2`, `Entrance`, `Channel` - Server enable/disable and ports
|
|
- `Discord` - Discord bot integration
|
|
- `Logging` - File logging with rotation (uses lumberjack)
|
|
|
|
## Concurrency Patterns
|
|
|
|
**Critical:** This codebase heavily uses goroutines and shared state. Always:
|
|
|
|
1. Use mutexes when accessing shared state:
|
|
- Server-level: `s.server.Lock()` / `s.server.Unlock()`
|
|
- Stage-level: `s.server.stagesLock.Lock()` / `s.server.stagesLock.Unlock()`
|
|
- Session-level: `s.Lock()` / `s.Unlock()`
|
|
|
|
2. Use RWMutex for read-heavy operations:
|
|
- `s.server.stagesLock.RLock()` for reads
|
|
- `s.server.stagesLock.Lock()` for writes
|
|
|
|
3. Test with race detector:
|
|
|
|
```bash
|
|
go test -race ./...
|
|
```
|
|
|
|
4. Common concurrency scenarios:
|
|
- Stage access: Always lock `s.server.stagesLock` when reading/writing stage map
|
|
- Session broadcasts: Iterate sessions under lock
|
|
- Database operations: Use transactions for multi-step operations
|
|
|
|
## Packet Handler Development
|
|
|
|
When adding new packet handlers:
|
|
|
|
1. Define packet structure in `network/mhfpacket/msg_*.go`
|
|
2. Implement `Build()` and `Parse()` methods
|
|
3. Add handler function in appropriate `handlers_*.go` file
|
|
4. Register in `handlerTable` map in `handlers_table.go`
|
|
5. Use helper functions:
|
|
- `doAckBufSucceed(s, ackHandle, data)` - Success response with data
|
|
- `doAckBufFail(s, ackHandle, data)` - Failure response
|
|
- `stubEnumerateNoResults(s, ackHandle)` - Empty enumerate response
|
|
- `stubGetNoResults(s, ackHandle)` - Empty get response
|
|
|
|
Example handler pattern:
|
|
|
|
```go
|
|
func handleMsgMhfYourPacket(s *Session, p mhfpacket.MHFPacket) {
|
|
pkt := p.(*mhfpacket.MsgMhfYourPacket)
|
|
|
|
// Process packet
|
|
resp := byteframe.NewByteFrame()
|
|
resp.WriteUint32(someValue)
|
|
|
|
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
|
}
|
|
```
|
|
|
|
## Testing Practices
|
|
|
|
- Use table-driven tests for multiple scenarios
|
|
- Mock database operations where appropriate
|
|
- Test concurrent access patterns with goroutines
|
|
- Test both success and error paths
|
|
- Add tests in `*_test.go` files next to source files
|
|
|
|
## Common Pitfalls
|
|
|
|
1. **Thread Safety:** Always consider concurrent access. If unsure, add locks.
|
|
2. **Database Queries:** Use parameterized queries (`$1`, `$2`) to prevent SQL injection
|
|
3. **Error Handling:** Never ignore errors - log them or handle appropriately
|
|
4. **Session State:** Be careful with session state during disconnects
|
|
5. **Packet Ordering:** Some packets have ordering requirements - check client expectations
|
|
6. **Binary Data:** Always use `byteframe` for binary reads/writes to ensure correct endianness
|
|
|
|
## Commit and PR Guidelines
|
|
|
|
**Commit message format:**
|
|
|
|
- `feat: description` - New features
|
|
- `fix: description` - Bug fixes
|
|
- `refactor: description` - Code refactoring
|
|
- `docs: description` - Documentation
|
|
- `chore: description` - Maintenance tasks
|
|
|
|
**Before committing:**
|
|
|
|
1. Run `gofmt -w .`
|
|
2. Run tests: `go test -v ./...`
|
|
3. Check for race conditions: `go test -race ./...`
|
|
4. Update CHANGELOG.md under "Unreleased" section
|
|
|
|
**PR Requirements:**
|
|
|
|
- Clear description of changes
|
|
- Test coverage for new features
|
|
- No race conditions
|
|
- Passes all existing tests
|
|
- Updated documentation if needed
|
|
|
|
## Remote Server Operations
|
|
|
|
Environment variables for remote operations are stored in `.env` (gitignored). Copy from `.env.example` if needed.
|
|
|
|
### Fetch Logs
|
|
|
|
```bash
|
|
# Load environment and fetch logs
|
|
source .env
|
|
scp -r $SERVER:$REMOTE_LOGS/* $LOCAL_LOGS/
|
|
```
|
|
|
|
### Deploy
|
|
|
|
```bash
|
|
# Build for Linux, upload, and restart
|
|
source .env
|
|
GOOS=linux GOARCH=amd64 go build -o erupe-ce
|
|
scp erupe-ce $SERVER:$REMOTE_BIN
|
|
ssh $SERVER "cd $REMOTE_DIR && sudo systemctl restart erupe"
|
|
```
|
|
|
|
### Quick Commands
|
|
|
|
```bash
|
|
# Check server status
|
|
source .env && ssh $SERVER "systemctl status erupe"
|
|
|
|
# Tail remote logs
|
|
source .env && ssh $SERVER "tail -f $REMOTE_LOGS/erupe.log"
|
|
|
|
# View recent errors
|
|
source .env && ssh $SERVER "grep -E 'level.*(error|warn)' $REMOTE_LOGS/erupe.log | tail -50"
|
|
```
|
|
|
|
## Discord Integration
|
|
|
|
Optional Discord bot in `server/discordbot/` provides:
|
|
|
|
- Real-time server activity notifications
|
|
- Player connection/disconnection events
|
|
- Quest completions and event notifications
|
|
|
|
Configured via `Discord` section in config.json.
|
|
|
|
## Multi-Version Support
|
|
|
|
The codebase supports multiple game client versions through:
|
|
|
|
- `ClientMode` configuration setting
|
|
- Client context detection
|
|
- Version-specific packet handling
|
|
- Binary file compatibility (quests/scenarios in `bin/`)
|
|
|
|
Primary focus: G10-ZZ (ClientMode), with varying support for older versions.
|