Une implémentation moderne d'un serveur Minecraft écrite en Go
Performance, concurrence et simplicité
Fonctionnalités • Architecture • Installation • Optimisations • Roadmap
Ce projet est une implémentation complète d'un serveur Minecraft utilisant le protocole officiel de Minecraft Java Edition. Il est conçu pour être performant, modulaire et facilement extensible grâce aux capacités de concurrence native de Go.
- Performance : Exploitation maximale du multi-threading Go
- Compatibilité : Support du protocole Minecraft officiel
- Modularité : Architecture claire et extensible
- Simplicité : Code lisible et maintenable
- États de connexion : Handshake, Status, Login, Play
- Gestion des paquets : Système complet d'encodage/décodage
- Chiffrement : Implémentation CFB8 avec RSA pour l'authentification
- Compression : Support de la compression des paquets
- Keep-alive : Maintien des connexions actives
- Authentification Mojang : Vérification des comptes via l'API officielle
- Chiffrement AES : Communication sécurisée client-serveur
- Vérification des tokens : Validation des clés d'authentification
- Profils joueurs : Gestion des UUID et propriétés (skins, capes)
- Connexion/Déconnexion : Événements complets de session
- Métadonnées : Gestion des informations joueur (nom, UUID, skin)
- Modes de jeu : Support des différents GameModes
- Capacités : Gestion du vol, invulnérabilité, etc.
- Position et rotation : Tracking complet des mouvements
- Chunks : Génération et gestion des chunks 16x16x256
- Slices : Découpage vertical en sections de 16 blocs
- Blocs : Système de placement et récupération
- Génération SuperFlat : Générateur de monde plat basique
- Height Maps : Cartes de hauteur pour l'optimisation
- Système de chat : Messages formatés avec couleurs
- Commandes console :
stop,send,vers - Broadcasting : Diffusion de messages à tous les joueurs
- Formatage : Support des codes couleur Minecraft
- Scheduler : Exécution de tâches périodiques et différées
- Multi-threading : Gestion asynchrone des tâches
- Keep-alive automatique : Maintenance des connexions
- Messages de plugin : Canaux de communication personnalisés
- Brand detection : Détection du client utilisé
- Système d'événements : Architecture event-driven
apis/ → Interfaces et contrats publics
├── server/ → Interface principale du serveur
├── ents/ → Entités (joueurs, mobs)
├── game/ → Éléments de jeu (blocs, chunks, modes)
├── cmds/ → Système de commandes
├── logs/ → Système de logging
└── task/ → Gestionnaire de tâches
impl/ → Implémentations concrètes
├── server/ → Logique principale du serveur
├── conn/ → Gestion des connexions réseau
├── prot/ → Implémentation du protocole
├── game/ → Logique de jeu et monde
└── auth/ → Authentification et sécurité
Client ←→ Network ←→ Packets ←→ Game Logic ←→ World State
↓
Authentication ←→ Mojang API
↓
Player Management ←→ Events
- Go 1.13 ou supérieur
- Connexion Internet (pour l'authentification Mojang)
# Cloner le repository
git clone https://github.com/GoLangMc/minecraft-server.git
cd minecraft-server
# Installer les dépendances
go mod download
# Compiler et lancer
go run main.go
# Ou avec des paramètres personnalisés
go run main.go -host 0.0.0.0 -port 25565Le serveur utilise actuellement une configuration par défaut :
- Host :
0.0.0.0 - Port :
25565 - Mode : Creative
- Difficulté : Peaceful
- Monde : SuperFlat
-
Pool de workers pour les chunks
// Paralléliser la génération de chunks type ChunkWorkerPool struct { workers int chunkQueue chan ChunkRequest resultChan chan ChunkResult }
-
Goroutines par joueur
// Une goroutine dédiée par connexion joueur go handlePlayerConnection(player, conn)
-
Lock-free data structures
- Utiliser
sync.Mappour les associations joueur-connexion - Channels pour la communication inter-goroutines
- Atomic operations pour les compteurs
- Utiliser
// Serveur principal
type Server struct {
networkPool *WorkerPool // Pool pour réseau
chunkPool *WorkerPool // Pool pour chunks
playerPool *WorkerPool // Pool pour joueurs
eventBus *EventBus // Bus d'événements async
}// Pool de buffers pour éviter les allocations
var bufferPool = sync.Pool{
New: func() interface{} {
return make([]byte, 1024)
},
}// Déchargement automatique des chunks non utilisés
type ChunkManager struct {
loadedChunks map[ChunkPos]*Chunk
lastAccess map[ChunkPos]time.Time
unloadTimer *time.Timer
}- Compression des chunks stockés en mémoire
- Delta compression pour les mises à jour de position
- Sérialisation binaire optimisée
type CacheLayer struct {
chunkCache *LRUCache
playerCache *LRUCache
packetCache *LRUCache
}// Traitement par lots des paquets
type PacketBatcher struct {
packets []Packet
timer *time.Timer
flush func([]Packet)
}// Métriques de performance en temps réel
type ServerMetrics struct {
PacketsPerSecond int64
PlayersOnline int32
ChunksLoaded int32
MemoryUsage int64
}type Inventory struct {
Slots []*ItemStack
Size int
HotbarIdx int
}
type ItemStack struct {
Material Material
Count int
NBT *NBTCompound
}type Entity interface {
Tick()
GetPosition() Position
SetPosition(Position)
GetVelocity() Vector3
OnCollision(Entity)
}
type Mob interface {
Entity
GetHealth() float64
SetHealth(float64)
GetAI() AI
}type RedstoneComponent interface {
GetPowerLevel() int
SetPowerLevel(int)
UpdatePower()
}
type BlockState struct {
Material Material
Properties map[string]interface{}
Redstone RedstoneComponent
}type WorldGenerator interface {
GenerateChunk(x, z int) *Chunk
GetBiome(x, z int) Biome
GenerateOres(chunk *Chunk)
GenerateStructures(chunk *Chunk)
}
// Générateurs spécialisés
type NoiseGenerator struct {
Seed int64
Octaves []NoiseOctave
}type Plugin interface {
OnEnable() error
OnDisable() error
OnPlayerJoin(event PlayerJoinEvent)
OnBlockPlace(event BlockPlaceEvent)
}
type PluginManager struct {
plugins map[string]Plugin
eventBus *EventBus
scheduler *TaskScheduler
}type PlayerData struct {
UUID string
Inventory *Inventory
Position Position
Stats map[string]int64
}
type WorldStorage interface {
SaveChunk(*Chunk) error
LoadChunk(x, z int) (*Chunk, error)
SavePlayerData(*PlayerData) error
LoadPlayerData(uuid string) (*PlayerData, error)
}type WebAdmin struct {
server *http.Server
wsHandler *websocket.Handler
auth AuthProvider
}
// API REST pour management
type AdminAPI struct {
Players PlayersEndpoint
Server ServerEndpoint
Worlds WorldsEndpoint
Plugins PluginsEndpoint
}type Permission struct {
Node string
Default bool
Description string
}
type PermissionProvider interface {
HasPermission(player Player, node string) bool
GrantPermission(player Player, node string)
RevokePermission(player Player, node string)
}type MultiWorldManager struct {
worlds map[string]*World
defaultWorld string
generators map[string]WorldGenerator
}type Economy interface {
GetBalance(player Player) float64
Deposit(player Player, amount float64) bool
Withdraw(player Player, amount float64) bool
Transfer(from, to Player, amount float64) bool
}- Go version : Migrer vers Go 1.21+ pour les génériques
- Bibliothèques : Mise à jour vers les versions récentes
- UUID library : Remplacer par
google/uuid
// Avant
type PlayerMap map[uuid.UUID]ents.Player
// Après (avec génériques)
type SafeMap[K comparable, V any] struct {
mu sync.RWMutex
m map[K]V
}func (s *Server) HandleConnection(ctx context.Context, conn net.Conn) {
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
// Logique de connexion avec timeout
}import "log/slog"
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
logger.Info("Player joined",
"player", player.Name(),
"uuid", player.UUID(),
"ip", conn.RemoteAddr(),
)# Lancer les tests unitaires
go test ./...
# Tests avec couverture
go test -cover ./...
# Benchmarks
go test -bench=. ./...# Profile CPU
go test -cpuprofile=cpu.prof -bench=.
# Profile mémoire
go test -memprofile=mem.prof -bench=.
# Analyse avec pprof
go tool pprof cpu.prof- Suivre
gofmtetgoimports - Utiliser
golangci-lintpour la qualité - Documenter toutes les fonctions publiques
- Tests unitaires obligatoires pour les nouvelles fonctionnalités
- Connexions simultanées : 500+ joueurs
- TPS : 20 ticks constants
- Latence : < 50ms pour les actions locales
- Mémoire : < 2GB pour 100 joueurs
- CPU : < 80% sur 4 cores
type ServerStats struct {
PlayersOnline int32
TPS float64
MemoryUsage int64
PacketsSent int64
PacketsReceived int64
ChunksLoaded int32
}- Pas de persistance : Données perdues au redémarrage
- Génération basique : Seulement SuperFlat
- Pas d'entités : Aucun mob ou animal
- Inventaire simplifié : Système incomplet
- Un seul monde : Pas de support multi-monde
- Pas de plugins : Système d'extension limité
- Actuellement supporté : Version non spécifiée (semble être 1.14+)
- À préciser : Quelle version exacte de Minecraft
- Clients Minecraft Java Edition officiels
- Possibilité d'étendre pour d'autres clients
Les contributions sont les bienvenues ! Voir les issues GitHub pour les tâches prioritaires.
- Fork le projet
- Créer une branche feature (
git checkout -b feature/AmazingFeature) - Commit les changements (
git commit -m 'Add some AmazingFeature') - Push la branche (
git push origin feature/AmazingFeature) - Ouvrir une Pull Request
Développé avec ❤️ par la communauté GoLangMC