Skip to content

Commit caab561

Browse files
committed
test: cover restart-town late peer visibility
1 parent 1287852 commit caab561

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

internal/minimal/shared_world_test.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5627,6 +5627,118 @@ func TestGameSessionFlowPracticeMobRestartTownPreservesSourcePracticeMobHPForOth
56275627
}
56285628
}
56295629

5630+
func TestGameSessionFlowPracticeMobRestartTownLateDestinationPeerSeesRecoveredOwnerAlive(t *testing.T) {
5631+
store := loginticket.NewFileStore(t.TempDir())
5632+
accounts := accountstore.NewFileStore(t.TempDir())
5633+
owner := peerVisibilityCharacter("PeerOne", 0x01030101, 0x02040101, 1100, 2100, 0, 101, 201)
5634+
owner.Points[bootstrapPlayerPointValueIndex] = 2
5635+
sourceWatcher := peerVisibilityCharacter("PeerTwo", 0x01030102, 0x02040102, 1300, 2300, 2, 102, 202)
5636+
lateTownWatcher := peerVisibilityCharacter("LateTownWatcher", 0x01030104, 0x02040104, 52090, 166620, 4, 104, 204)
5637+
lateTownWatcher.MapIndex = 21
5638+
issuePeerTicket(t, store, "peer-one", 0x11111111, owner)
5639+
issuePeerTicket(t, store, "peer-two", 0x22222222, sourceWatcher)
5640+
issuePeerTicket(t, store, "late-town-watcher", 0x44444444, lateTownWatcher)
5641+
if err := accounts.Save(accountstore.Account{Login: "peer-one", Empire: owner.Empire, Characters: cloneCharacters([]loginticket.Character{owner})}); err != nil {
5642+
t.Fatalf("seed owner account before late /restart_town visibility test: %v", err)
5643+
}
5644+
if err := accounts.Save(accountstore.Account{Login: "peer-two", Empire: sourceWatcher.Empire, Characters: cloneCharacters([]loginticket.Character{sourceWatcher})}); err != nil {
5645+
t.Fatalf("seed source watcher account before late /restart_town visibility test: %v", err)
5646+
}
5647+
if err := accounts.Save(accountstore.Account{Login: "late-town-watcher", Empire: lateTownWatcher.Empire, Characters: cloneCharacters([]loginticket.Character{lateTownWatcher})}); err != nil {
5648+
t.Fatalf("seed late town watcher account before late /restart_town visibility test: %v", err)
5649+
}
5650+
5651+
staticActorStore := staticstore.NewFileStore(t.TempDir() + "/static-actors.json")
5652+
interactionStore := interactionstore.NewFileStore(t.TempDir() + "/interaction-definitions.json")
5653+
runtime, err := newGameRuntimeWithAccountStoreAndContentStores(config.Service{LegacyAddr: ":13000", PublicAddr: "127.0.0.1"}, store, accounts, staticActorStore, interactionStore)
5654+
if err != nil {
5655+
t.Fatalf("unexpected game runtime error in late /restart_town visibility test: %v", err)
5656+
}
5657+
currentTime := time.Unix(1700000527, 0)
5658+
runtime.now = func() time.Time { return currentTime }
5659+
bundle := contentbundle.Bundle{SpawnGroups: []contentbundle.SpawnGroup{{
5660+
Ref: "practice.mob_late_town_visibility",
5661+
Name: "PracticeMobLateTownVisibility",
5662+
MapIndex: bootstrapMapIndex,
5663+
X: 1200,
5664+
Y: 2200,
5665+
RaceNum: 101,
5666+
CombatProfile: string(worldruntime.StaticActorCombatProfileTrainingDummy),
5667+
}}}
5668+
if _, err := runtime.ImportContentBundle(bundle); err != nil {
5669+
t.Fatalf("import content spawn-group bundle for late /restart_town visibility test: %v", err)
5670+
}
5671+
actors := runtime.StaticActors()
5672+
if len(actors) != 1 {
5673+
t.Fatalf("expected 1 runtime practice-mob actor after import for late /restart_town visibility test, got %#v", actors)
5674+
}
5675+
targetVID := uint32(actors[0].EntityID)
5676+
5677+
ownerFlow, ownerEnter := enterGameWithLoginTicket(t, runtime.SessionFactory(), "peer-one", 0x11111111)
5678+
if len(ownerEnter) != 8 {
5679+
t.Fatalf("expected 8 bootstrap frames for owner in late /restart_town visibility test, got %d", len(ownerEnter))
5680+
}
5681+
defer closeSessionFlow(t, ownerFlow)
5682+
sourceWatcherFlow, sourceWatcherEnter := enterGameWithLoginTicket(t, runtime.SessionFactory(), "peer-two", 0x22222222)
5683+
if len(sourceWatcherEnter) != 11 {
5684+
t.Fatalf("expected 11 bootstrap frames for source watcher in late /restart_town visibility test, got %d", len(sourceWatcherEnter))
5685+
}
5686+
defer closeSessionFlow(t, sourceWatcherFlow)
5687+
if queued := flushServerFrames(t, ownerFlow); len(queued) != 3 {
5688+
t.Fatalf("expected 3 queued peer-visibility frames for owner after source watcher joins in late /restart_town visibility test, got %d", len(queued))
5689+
}
5690+
5691+
advance := func(duration time.Duration) {
5692+
currentTime = currentTime.Add(duration)
5693+
}
5694+
drivePracticeMobOwnerToZeroHPAfterDelayedRetaliation(t, ownerFlow, sourceWatcherFlow, targetVID, owner.VID, advance)
5695+
5696+
restartOut, err := ownerFlow.HandleClientFrame(decodeSingleFrame(t, chatproto.EncodeClientChat(chatproto.ClientChatPacket{Type: chatproto.ChatTypeTalking, Message: "/restart_town"})))
5697+
if err != nil {
5698+
t.Fatalf("unexpected /restart_town error in late visibility test: %v", err)
5699+
}
5700+
if len(restartOut) != 6 {
5701+
t.Fatalf("expected 6 self frames from /restart_town late visibility setup, got %d", len(restartOut))
5702+
}
5703+
if queued := flushServerFrames(t, sourceWatcherFlow); len(queued) != 1 {
5704+
t.Fatalf("expected source watcher to receive 1 queued owner delete after /restart_town late visibility setup, got %d", len(queued))
5705+
}
5706+
5707+
lateTownFlow, lateTownEnter := enterGameWithLoginTicket(t, runtime.SessionFactory(), "late-town-watcher", 0x44444444)
5708+
defer closeSessionFlow(t, lateTownFlow)
5709+
if len(lateTownEnter) != 8 {
5710+
t.Fatalf("expected late destination peer to receive 5 self frames plus 3 recovered-owner peer frames, got %d", len(lateTownEnter))
5711+
}
5712+
ownerAdd, err := worldproto.DecodeCharacterAdd(decodeSingleFrame(t, lateTownEnter[5]))
5713+
if err != nil {
5714+
t.Fatalf("decode recovered owner add for late destination peer: %v", err)
5715+
}
5716+
if ownerAdd.VID != owner.VID || ownerAdd.X != 52070 || ownerAdd.Y != 166600 {
5717+
t.Fatalf("expected late destination peer to see recovered owner alive at empire town position, got %+v", ownerAdd)
5718+
}
5719+
ownerInfo, err := worldproto.DecodeCharacterAdditionalInfo(decodeSingleFrame(t, lateTownEnter[6]))
5720+
if err != nil {
5721+
t.Fatalf("decode recovered owner info for late destination peer: %v", err)
5722+
}
5723+
if ownerInfo.VID != owner.VID || ownerInfo.Name != owner.Name {
5724+
t.Fatalf("expected late destination peer info for recovered owner %s/%d, got %+v", owner.Name, owner.VID, ownerInfo)
5725+
}
5726+
if queued := flushServerFrames(t, lateTownFlow); len(queued) != 0 {
5727+
t.Fatalf("expected late destination peer to receive no queued dead-state follow-up for recovered owner, got %d", len(queued))
5728+
}
5729+
ownerQueued := flushServerFrames(t, ownerFlow)
5730+
if len(ownerQueued) != 3 {
5731+
t.Fatalf("expected recovered owner to receive 3 queued late-peer entry frames, got %d", len(ownerQueued))
5732+
}
5733+
latePeerAdd, err := worldproto.DecodeCharacterAdd(decodeSingleFrame(t, ownerQueued[0]))
5734+
if err != nil {
5735+
t.Fatalf("decode late destination peer add for recovered owner: %v", err)
5736+
}
5737+
if latePeerAdd.VID != lateTownWatcher.VID {
5738+
t.Fatalf("expected recovered owner to see late destination peer vid %d, got %+v", lateTownWatcher.VID, latePeerAdd)
5739+
}
5740+
}
5741+
56305742
func TestGameSessionFlowPracticeMobRestartTownUsesOwnedEmpireCreatePositionTableOnSameSocket(t *testing.T) {
56315743
testCases := []struct {
56325744
name string

0 commit comments

Comments
 (0)