fix: improve endgame clock and gameplay stability
This commit is contained in:
1 parent
ce6aabfc55
commit
658298ee86
46 files changed
+1915
-99
No files matched your search
@@ -0,0 +1,105 @@
|
||||
package gameserver
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
kcplib "gac-hkrpg-go/pkg/kcp"
|
||||
)
|
||||
|
||||
// A single UDP datagram can contain multiple complete KCP messages. Each
|
||||
// handler must receive its own payload even when the receive buffer is reused.
|
||||
func TestConsumeKeepsBatchedPacketBodiesIndependent(t *testing.T) {
|
||||
const firstID, secondID uint16 = 65000, 65001
|
||||
for _, id := range []uint16{firstID, secondID} {
|
||||
if _, ok := rawHandlers[id]; ok {
|
||||
t.Fatalf("test handler %d already registered", id)
|
||||
}
|
||||
if _, ok := typedHandlers[id]; ok {
|
||||
t.Fatalf("test handler %d already registered", id)
|
||||
}
|
||||
if _, ok := dummyResponses[id]; ok {
|
||||
t.Fatalf("test command %d has dummy response", id)
|
||||
}
|
||||
}
|
||||
got := map[uint16]string{}
|
||||
rawHandlers[firstID] = func(_ *Session, body []byte) error { got[firstID] = string(body); return nil }
|
||||
rawHandlers[secondID] = func(_ *Session, body []byte) error { got[secondID] = string(body); return nil }
|
||||
defer delete(rawHandlers, firstID)
|
||||
defer delete(rawHandlers, secondID)
|
||||
|
||||
const conv, token uint32 = 77, 88
|
||||
segment := func(seq uint32, frame []byte) []byte {
|
||||
out := make([]byte, kcplib.Overhead+len(frame))
|
||||
binary.LittleEndian.PutUint32(out[0:], conv)
|
||||
binary.LittleEndian.PutUint32(out[4:], token)
|
||||
out[8] = kcplib.CmdPush
|
||||
binary.LittleEndian.PutUint16(out[10:], 128)
|
||||
binary.LittleEndian.PutUint32(out[16:], seq)
|
||||
binary.LittleEndian.PutUint32(out[24:], uint32(len(frame)))
|
||||
copy(out[kcplib.Overhead:], frame)
|
||||
return out
|
||||
}
|
||||
first := (&NetPacket{CmdType: firstID, Body: []byte("first")}).Encode()
|
||||
second := (&NetPacket{CmdType: secondID, Body: []byte("other")}).Encode()
|
||||
datagram := append(segment(0, first), segment(1, second)...)
|
||||
s := NewSession(func([]byte) error { return nil }, conv, token)
|
||||
defer s.Close()
|
||||
if err := s.Consume(datagram); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if got[firstID] != "first" || got[secondID] != "other" {
|
||||
t.Fatalf("batched payloads corrupted: %#v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsumeOutOfOrderFragmentsAndFollowingPacket(t *testing.T) {
|
||||
const firstID, secondID uint16 = 65002, 65003
|
||||
for _, id := range []uint16{firstID, secondID} {
|
||||
if _, ok := rawHandlers[id]; ok {
|
||||
t.Fatalf("test handler %d already registered", id)
|
||||
}
|
||||
if _, ok := typedHandlers[id]; ok {
|
||||
t.Fatalf("test handler %d already registered", id)
|
||||
}
|
||||
if _, ok := dummyResponses[id]; ok {
|
||||
t.Fatalf("test command %d has dummy response", id)
|
||||
}
|
||||
}
|
||||
got := map[uint16][]byte{}
|
||||
rawHandlers[firstID] = func(_ *Session, body []byte) error { got[firstID] = append([]byte(nil), body...); return nil }
|
||||
rawHandlers[secondID] = func(_ *Session, body []byte) error { got[secondID] = append([]byte(nil), body...); return nil }
|
||||
defer delete(rawHandlers, firstID)
|
||||
defer delete(rawHandlers, secondID)
|
||||
const conv, token uint32 = 77, 88
|
||||
segment := func(seq uint32, fragment byte, frame []byte) []byte {
|
||||
out := make([]byte, kcplib.Overhead+len(frame))
|
||||
binary.LittleEndian.PutUint32(out[0:], conv)
|
||||
binary.LittleEndian.PutUint32(out[4:], token)
|
||||
out[8], out[9] = kcplib.CmdPush, fragment
|
||||
binary.LittleEndian.PutUint16(out[10:], 128)
|
||||
binary.LittleEndian.PutUint32(out[16:], seq)
|
||||
binary.LittleEndian.PutUint32(out[24:], uint32(len(frame)))
|
||||
copy(out[kcplib.Overhead:], frame)
|
||||
return out
|
||||
}
|
||||
payload := bytes.Repeat([]byte("first-fragment-"), 120)
|
||||
frame := (&NetPacket{CmdType: firstID, Body: payload}).Encode()
|
||||
following := (&NetPacket{CmdType: secondID, Body: []byte("next")}).Encode()
|
||||
s := NewSession(func([]byte) error { return nil }, conv, token)
|
||||
defer s.Close()
|
||||
if err := s.Consume(segment(1, 0, frame[800:])); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(got) != 0 {
|
||||
t.Fatal("dispatched an incomplete out-of-order message")
|
||||
}
|
||||
combined := append(segment(0, 1, frame[:800]), segment(2, 0, following)...)
|
||||
if err := s.Consume(combined); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(got[firstID], payload) || string(got[secondID]) != "next" {
|
||||
t.Fatal("fragmented or following packet body was corrupted")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user