Implement multiplayer persistence and vanilla lighting
This commit is contained in:
parent
8f7cacf9d9
commit
cae06eb97e
47 changed files with 3784 additions and 465 deletions
130
internal/server/server_test.go
Normal file
130
internal/server/server_test.go
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
||||
"regionio/internal/world"
|
||||
)
|
||||
|
||||
func TestPlayerRegistrySupportsFourPlayersAndEnforcesLimit(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
cfg.MaxPlayers = 4
|
||||
srv, err := NewWithCache(cfg, world.NewCache(-1, world.GenerateFlat))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var sends atomic.Int32
|
||||
var sessions []*PlayerSession
|
||||
for _, name := range []string{"Alice", "Bob", "Carol", "Dave"} {
|
||||
profile := Profile{Name: name, UUID: OfflineUUID(name)}
|
||||
session, err := srv.RegisterPlayer(profile, func(int32, []byte) error {
|
||||
sends.Add(1)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("register %s: %v", name, err)
|
||||
}
|
||||
sessions = append(sessions, session)
|
||||
}
|
||||
if got := srv.PlayerCount(); got != 4 {
|
||||
t.Fatalf("player count = %d, want 4", got)
|
||||
}
|
||||
if _, err := srv.RegisterPlayer(Profile{Name: "Eve", UUID: OfflineUUID("Eve")}, nil); !errors.Is(err, ErrServerFull) {
|
||||
t.Fatalf("fifth player error = %v, want ErrServerFull", err)
|
||||
}
|
||||
|
||||
srv.Broadcast(1, []byte("packet"))
|
||||
if got := sends.Load(); got != 4 {
|
||||
t.Fatalf("broadcast sends = %d, want 4", got)
|
||||
}
|
||||
for _, session := range sessions {
|
||||
srv.UnregisterPlayer(session)
|
||||
}
|
||||
if got := srv.PlayerCount(); got != 0 {
|
||||
t.Fatalf("player count after disconnect = %d, want 0", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcurrentFourPlayerTransformsAndChunkBroadcast(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
cfg.WorldDir = ""
|
||||
cfg.MaxPlayers = 4
|
||||
srv, err := NewWithCache(cfg, world.NewCache(-1, world.GenerateFlat))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var sends [4]atomic.Int32
|
||||
sessions := make([]*PlayerSession, 4)
|
||||
for i, name := range []string{"Alice", "Bob", "Carol", "Dave"} {
|
||||
i := i
|
||||
sessions[i], err = srv.RegisterPlayer(Profile{Name: name, UUID: OfflineUUID(name)}, func(int32, []byte) error {
|
||||
sends[i].Add(1)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
srv.SetPlayerViewDistance(sessions[i], 2)
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
for i, session := range sessions {
|
||||
i, session := i, session
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for step := 0; step < 500; step++ {
|
||||
srv.SetPlayerTransform(session, float64(i*16+step), 80, float64(-step), float32(step%360), 10, step%2 == 0)
|
||||
_ = srv.PlayerSnapshots()
|
||||
srv.BroadcastChunk(int32(step>>4), int32(-step>>4), 1, nil)
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
if got := len(srv.PlayerSnapshots()); got != 4 {
|
||||
t.Fatalf("snapshot count = %d, want 4", got)
|
||||
}
|
||||
|
||||
for i, session := range sessions {
|
||||
x := float64(i * 160)
|
||||
srv.SetPlayerTransform(session, x, 80, 0, 0, 0, true)
|
||||
before := sends[i].Load()
|
||||
srv.BroadcastChunk(0, 0, 2, nil)
|
||||
got := sends[i].Load() - before
|
||||
if i == 0 && got != 1 {
|
||||
t.Fatalf("near player received %d packets, want 1", got)
|
||||
}
|
||||
if i > 0 && got != 0 {
|
||||
t.Fatalf("far player %d received %d packets, want 0", i, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlayerRegistryRejectsDuplicateName(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
srv, err := NewWithCache(cfg, world.NewCache(-1, world.GenerateFlat))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
first := Profile{Name: "Alice", UUID: OfflineUUID("Alice")}
|
||||
if _, err := srv.RegisterPlayer(first, nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
duplicate := Profile{Name: "ALICE", UUID: OfflineUUID("ALICE")}
|
||||
if _, err := srv.RegisterPlayer(duplicate, nil); !errors.Is(err, ErrDuplicatePlayer) {
|
||||
t.Fatalf("duplicate error = %v, want ErrDuplicatePlayer", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerRejectsNegativeCacheLimit(t *testing.T) {
|
||||
cfg := DefaultConfig()
|
||||
cfg.MaxCachedChunks = -1
|
||||
if _, err := NewWithCache(cfg, world.NewCache(-1, world.GenerateFlat)); err == nil {
|
||||
t.Fatal("negative cache limit was accepted")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue