Keep takeoff clearance until actual ascent, blacklist rejected dynamic bridges, and diagnose group ground-path rejection. Synchronize native Wintergrasp client mount permission with battle state and fix duplicate Zangarmarsh graveyard ownership. Add regression tests and generic testbot aura inspection.
41 lines
2.1 KiB
Python
41 lines
2.1 KiB
Python
"""Exercise ZM graveyard ownership with production registration and member setup."""
|
|
from pathlib import Path
|
|
import subprocess, tempfile
|
|
root = Path(__file__).resolve().parents[2]
|
|
header = (root / "src/server/scripts/OutdoorPvP/OutdoorPvPZM.h").read_text()
|
|
script = (root / "src/server/scripts/OutdoorPvP/OutdoorPvPZM.cpp").read_text()
|
|
source = (root / "src/server/game/OutdoorPvP/OutdoorPvP.cpp").read_text()
|
|
member = next(line for line in header.splitlines() if " m_Graveyard" in line and "State" not in line)
|
|
a = script.index(" m_Graveyard =", script.index("bool OutdoorPvPZM::SetupOutdoorPvP"))
|
|
b = script.index("\n", script.index("AddCapturePoint(",a))
|
|
setup = script[a:b]
|
|
a = source.index("void OutdoorPvP::AddCapturePoint(")
|
|
b = source.index("\nOPvPCapturePoint* OutdoorPvP::GetCapturePoint",a)
|
|
registration = source[a:b]
|
|
code = r'''
|
|
#include <map>
|
|
#include <memory>
|
|
#include <cassert>
|
|
#define TC_LOG_ERROR(...) ((void)0)
|
|
struct OutdoorPvP;
|
|
int destroyed=0;
|
|
struct OPvPCapturePoint {unsigned m_capturePointSpawnId=0; virtual ~OPvPCapturePoint(){++destroyed;}};
|
|
struct OPvPCapturePointZM_Graveyard:OPvPCapturePoint {explicit OPvPCapturePointZM_Graveyard(OutdoorPvP*){}};
|
|
struct OutdoorPvP {
|
|
using OPvPCapturePointMap=std::map<unsigned,std::unique_ptr<OPvPCapturePoint>>;
|
|
OPvPCapturePointMap m_capturePoints;
|
|
virtual ~OutdoorPvP()=default;
|
|
void AddCapturePoint(OPvPCapturePoint* cp);
|
|
};
|
|
''' + registration + "struct OutdoorPvPZM: OutdoorPvP {\n" + member + "\nvoid setup(){\n" + setup + r'''
|
|
}
|
|
};
|
|
int main(){for(int i=0;i<100;++i){auto p=std::make_unique<OutdoorPvPZM>();p->setup();assert(p->m_capturePoints.size()==1);assert(p->m_capturePoints.begin()->second.get()==p->m_Graveyard);}assert(destroyed==100);}
|
|
'''
|
|
with tempfile.TemporaryDirectory(prefix="vcore-zm-ownership-") as directory:
|
|
path=Path(directory)
|
|
(path/"test.cpp").write_text(code)
|
|
subprocess.run(["c++","-std=c++17","-fsanitize=address","-fno-omit-frame-pointer",str(path/"test.cpp"),"-o",str(path/"test")],check=True)
|
|
subprocess.run([str(path/"test")],check=True)
|
|
print("ZM graveyard: 100 lifecycles, exactly one destruction each, AddressSanitizer PASS")
|