Update GaCy-GO

This commit is contained in:
CAtlas0784 committed 2026-10-28 18:54:43 +07:00
1 parent da8a32f60d
commit 0cbe460e49
345 files changed
+98202 -77559

No files matched your search

+51 -57
View File
@@ -1,15 +1,11 @@
package gameserver
import (
"os"
"path/filepath"
"strconv"
"strings"
"testing"
"gac-hkrpg-go/internal/common"
goproto "gac-hkrpg-go/protocol/proto"
"google.golang.org/protobuf/proto"
)
func TestCurrencyWarsEntranceUsesCapturedRoomConditionWithoutMutatingScene(t *testing.T) {
@@ -43,7 +39,42 @@ func TestCurrencyWarsEntranceUsesCapturedRoomConditionWithoutMutatingScene(t *te
}
}
func TestUnimplementedCurrencyWarsRequestsRemainSuppressed(t *testing.T) {
func TestCurrencyWarsSelectedEnemyBranchUsesSavedOneBasedChoice(t *testing.T) {
first := &goproto.KKBGIPCAGGH{IFIIOIIKJHO: 91}
second := &goproto.KKBGIPCAGGH{IFIIOIIKJHO: 92}
for _, tc := range []struct {
name string
selection uint32
branches []*goproto.KKBGIPCAGGH
want *goproto.KKBGIPCAGGH
wantErr string
}{
{name: "select first offered branch", selection: 1, branches: []*goproto.KKBGIPCAGGH{first, second}, want: first},
{name: "select second offered branch", selection: 2, branches: []*goproto.KKBGIPCAGGH{first, second}, want: second},
{name: "selection is required", selection: 0, branches: []*goproto.KKBGIPCAGGH{first}, wantErr: "outside"},
{name: "selection must be offered", selection: 2, branches: []*goproto.KKBGIPCAGGH{first}, wantErr: "outside"},
{name: "selected branch cannot be empty", selection: 1, branches: []*goproto.KKBGIPCAGGH{nil}, wantErr: "is empty"},
{name: "no offered branches", selection: 1, wantErr: "no offered plans"},
} {
t.Run(tc.name, func(t *testing.T) {
got, err := cwSelectedEnemyBranch(&goproto.MDJBBILMHLC{MOADBALHMFD: tc.selection, BPDABHGFBFO: tc.branches})
if tc.wantErr != "" {
if err == nil || !strings.Contains(err.Error(), tc.wantErr) {
t.Fatalf("branch error = %v; want %q", err, tc.wantErr)
}
return
}
if err != nil {
t.Fatalf("resolve selected branch: %v", err)
}
if got != tc.want {
t.Fatalf("selected plan = %p; want %p", got, tc.want)
}
})
}
}
func TestCurrencyWarsBattleAndRefreshRequestsUseTypedHandlers(t *testing.T) {
for _, name := range []string{
"GridFightEnterBattleStageCsReq",
"GridFightRefreshShopCsReq",
@@ -53,14 +84,17 @@ func TestUnimplementedCurrencyWarsRequestsRemainSuppressed(t *testing.T) {
if !ok {
t.Fatalf("protocol command table is missing %s", name)
}
if !isDangerCmd(uint16(id)) {
t.Fatalf("unsupported CW request %s is not protected from an empty response", name)
if typedHandlers[uint16(id)] == nil {
t.Fatalf("implemented CW request %s has no typed handler", name)
}
if typedHandlers[uint16(id)] != nil || rawHandlers[uint16(id)] != nil {
t.Fatalf("unsupported CW request %s unexpectedly has a handler", name)
if rawHandlers[uint16(id)] != nil {
t.Fatalf("CW request %s is registered through an untyped handler", name)
}
if _, ok := dummyResponses[uint16(id)]; ok {
t.Fatalf("unsupported CW request %s unexpectedly has a dummy response", name)
t.Fatalf("CW request %s unexpectedly has a dummy response", name)
}
if !isDangerCmd(uint16(id)) {
t.Fatalf("CW request %s is not protected from dispatcher auto-replies", name)
}
if _, ok := goproto.RspIDByReqID[uint32(id)]; !ok {
t.Fatalf("test request %s has no paired response to protect", name)
@@ -74,14 +108,13 @@ func TestUnimplementedCurrencyWarsRequestsRemainSuppressed(t *testing.T) {
}
}
func TestCurrencyWarsStartGameplayLogsRequestedModeWithoutReply(t *testing.T) {
func TestCurrencyWarsStartGameplayUsesCurrentTypedRequestHandler(t *testing.T) {
id := uint16(goproto.CmdIDByName["GridFightStartGamePlayCsReq"])
handler := rawHandlers[id]
if handler == nil {
t.Fatal("CW start request must have a mode-observation handler")
if typedHandlers[id] == nil {
t.Fatal("CW start request must have a typed gameplay handler")
}
if typedHandlers[id] != nil {
t.Fatal("CW start request must not send an unverified typed response")
if rawHandlers[id] != nil {
t.Fatal("CW start request must not use an untyped mode-observation handler")
}
if _, ok := dummyResponses[id]; ok {
t.Fatal("CW start request must not receive an empty response")
@@ -89,47 +122,8 @@ func TestCurrencyWarsStartGameplayLogsRequestedModeWithoutReply(t *testing.T) {
if !isDangerCmd(id) {
t.Fatal("CW start request must remain protected from dispatcher auto-replies")
}
if err := handler(nil, nil); err == nil {
t.Fatal("empty start request must not be misreported as Standard Gambit")
}
oldWD, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
if err := os.Chdir(t.TempDir()); err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = os.Chdir(oldWD) })
for _, tc := range []struct {
name string
overclock bool
wantMode string
divisionID uint32
}{
{name: "standard", wantMode: "standard", divisionID: 42},
{name: "overclock", overclock: true, wantMode: "overclock", divisionID: 42},
} {
t.Run(tc.name, func(t *testing.T) {
req := &goproto.GridFightStartGamePlayCsReq{DivisionId: tc.divisionID, IsOverlock: tc.overclock}
payload, err := proto.Marshal(req)
if err != nil {
t.Fatal(err)
}
// A nil session makes any accidental attempt to send a response fail.
if err := handler(nil, payload); err != nil {
t.Fatalf("observe mode: %v", err)
}
logData, err := os.ReadFile(filepath.Join("gameserver.log"))
if err != nil {
t.Fatal(err)
}
log := string(logData)
if !strings.Contains(log, "CW_START_GAMEPLAY observed mode="+tc.wantMode+" division="+strconv.FormatUint(uint64(tc.divisionID), 10)) || !strings.Contains(log, "response_suppressed=true reason=run_state_unverified") {
t.Fatalf("mode diagnostic missing or malformed: %s", log)
}
})
if _, ok := goproto.RspIDByReqID[uint32(id)]; !ok {
t.Fatal("CW start request has no paired response in the current protocol table")
}
}