97 lines
3.8 KiB
Python
97 lines
3.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Verify the MVP reconnect state-retention QA gate is covered."""
|
|
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
ROADMAP = ROOT / "AGRARIAN_DEVELOPMENT_ROADMAP.md"
|
|
QA_DOC = ROOT / "Docs" / "QA" / "MvpQaGates.md"
|
|
NETWORKING = ROOT / "Docs" / "MultiplayerNetworkingDesign.md"
|
|
GAME_MODE_H = ROOT / "Source" / "AgrarianGame" / "AgrarianGameGameMode.h"
|
|
GAME_MODE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianGameGameMode.cpp"
|
|
PERSISTENCE_H = ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.h"
|
|
PERSISTENCE_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianPersistenceSubsystem.cpp"
|
|
SAVE_GAME_H = ROOT / "Source" / "AgrarianGame" / "AgrarianSaveGame.h"
|
|
INVENTORY_CPP = ROOT / "Source" / "AgrarianGame" / "AgrarianInventoryComponent.cpp"
|
|
DISCONNECT_VERIFY = ROOT / "Scripts" / "verify_disconnect_reconnect_handling.py"
|
|
IDENTITY_VERIFY = ROOT / "Scripts" / "verify_player_identity_persistence.py"
|
|
STATS_VERIFY = ROOT / "Scripts" / "verify_player_stats_persistence.py"
|
|
INVENTORY_VERIFY = ROOT / "Scripts" / "verify_inventory_persistence.py"
|
|
TWO_CLIENT_VERIFY = ROOT / "Scripts" / "verify_two_client_connection_gate.py"
|
|
|
|
REQUIRED = {
|
|
QA_DOC: [
|
|
"## Reconnect State Retention",
|
|
"Logout",
|
|
"RestartPlayer",
|
|
"transform, safe player identity, survival",
|
|
"RestoreSavedItems",
|
|
],
|
|
NETWORKING: [
|
|
"## Disconnect And Reconnect",
|
|
"player reconnect snapshot",
|
|
"preserves transform, survival, care history, and",
|
|
"inventory through `UAgrarianPersistenceSubsystem::SavePlayerSnapshot`",
|
|
"normal MVP spawn point",
|
|
],
|
|
GAME_MODE_H: [
|
|
"virtual void RestartPlayer(AController* NewPlayer) override;",
|
|
"virtual void Logout(AController* Exiting) override;",
|
|
],
|
|
GAME_MODE_CPP: [
|
|
"Super::RestartPlayer(NewPlayer)",
|
|
"Persistence->RestorePlayerSnapshot(AgrarianCharacter)",
|
|
"Persistence->SavePlayerSnapshot(AgrarianCharacter)",
|
|
"Super::Logout(Exiting)",
|
|
],
|
|
PERSISTENCE_H: [
|
|
"bool SavePlayerSnapshot(const AAgrarianGameCharacter* Character) const;",
|
|
"bool RestorePlayerSnapshot(AAgrarianGameCharacter* Character) const;",
|
|
],
|
|
PERSISTENCE_CPP: [
|
|
"SavedPlayer.Transform = Character->GetActorTransform();",
|
|
"SavedPlayer.Survival = SurvivalComponent->Survival;",
|
|
"SavedPlayer.CareHistory = SurvivalComponent->CareHistory;",
|
|
"SavedPlayer.Inventory = InventoryComponent->Items;",
|
|
"Character->SetActorTransform(SavedPlayer->Transform",
|
|
"InventoryComponent->RestoreSavedItems(SavedPlayer->Inventory);",
|
|
"return UniqueId->ToString();",
|
|
],
|
|
SAVE_GAME_H: [
|
|
"struct FAgrarianSavedPlayer",
|
|
"FAgrarianSavedPlayerIdentity Identity;",
|
|
"FTransform Transform;",
|
|
"FAgrarianSurvivalSnapshot Survival;",
|
|
"TArray<FAgrarianItemStack> Inventory;",
|
|
],
|
|
INVENTORY_CPP: [
|
|
"UAgrarianInventoryComponent::RestoreSavedItems",
|
|
"BroadcastInventoryChanged()",
|
|
],
|
|
DISCONNECT_VERIFY: ["PASS: MVP disconnect/reconnect snapshot handling"],
|
|
IDENTITY_VERIFY: ["player identity persistence"],
|
|
STATS_VERIFY: ["player stats persist"],
|
|
INVENTORY_VERIFY: ["inventory persistence"],
|
|
TWO_CLIENT_VERIFY: ["Two-Client Connection"],
|
|
ROADMAP: [
|
|
"[x] Can reconnect and retain state.",
|
|
],
|
|
}
|
|
|
|
|
|
def main() -> None:
|
|
missing: list[str] = []
|
|
for path, snippets in REQUIRED.items():
|
|
text = path.read_text(encoding="utf-8")
|
|
for snippet in snippets:
|
|
if snippet not in text:
|
|
missing.append(f"{path.relative_to(ROOT)} missing {snippet!r}")
|
|
if missing:
|
|
raise SystemExit("FAILED: " + "; ".join(missing))
|
|
print("OK: reconnect state-retention QA gate is tied to logout/restart snapshots and persistence coverage.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|