Finish capital waiting travel and adaptive flight entry up to 10,000 yards. Preserve checked vertical climbs, recover blocked ground departures and find validated dry landings. Retain group routes and Undercity arrival constraints. Restore defense from native combat references, coordinate instance rendezvous and browser reentry, finalize clientless sessions before map destruction and transfer Halaa capture-point ownership safely. Include the associated regression tests, investigation reports and reusable diagnostic scripts. Keep generated runtime evidence and server binaries local through scoped ignore rules. Validation/build/live evidence is recorded in the session checkpoint and individual reports.
47 lines
3.4 KiB
Python
47 lines
3.4 KiB
Python
"""Run the production group-wide instance leave protection predicate."""
|
|
from pathlib import Path
|
|
import subprocess,tempfile
|
|
root=Path(__file__).resolve().parents[2]
|
|
s=(root/"src/server/game/World/AdventureBehaviorMgr.cpp").read_text()
|
|
a=s.index("bool AdventureBehaviorMgr::ProtectInstanceGroupLeave(")
|
|
b=s.index("bool AdventureBehaviorMgr::PauseForLogout",a)
|
|
code=r'''
|
|
#include "AdventureInstancePolicy.h"
|
|
#include <cassert>
|
|
#include <unordered_map>
|
|
#include <string>
|
|
using uint32=unsigned;
|
|
namespace GameTime{time_t GetGameTime(){return 1000;}}
|
|
struct Group;
|
|
struct Map{bool dungeon=false;bool IsDungeon()const{return dungeon;}};
|
|
struct Guid{unsigned id;unsigned GetCounter()const{return id;}};
|
|
struct Player{unsigned id;Group* group=nullptr;Map map;bool online=true;bool IsInWorld()const{return online;}Group* GetGroup(){return group;}Map* GetMap(){assert(online);return ↦}Guid GetGUID(){return {id};}};
|
|
struct Reference{Player* player=nullptr;Reference* following=nullptr;Player* GetSource(){return player;}Reference* next(){return following;}};
|
|
struct Group{Reference* first=nullptr;Reference* GetFirstMember(){return first;}};
|
|
struct Location{unsigned InstanceMap=671;} location;
|
|
struct Locations{Location const* Find(std::string const& key){return key=="instance"?&location:nullptr;}} locations;auto sAdventureLocationMgr=&locations;
|
|
struct AdventureBehaviorMgr{struct Record{AdventureInstancePolicy::Visit Instance;std::string Intent,Location;time_t Deadline=0;};std::unordered_map<unsigned,Record> _records;bool ProtectInstanceGroupLeave(Player*)const;};
|
|
'''+s[a:b]+r'''
|
|
int main(){AdventureBehaviorMgr m;Player late{1},leader{2};assert(!m.ProtectInstanceGroupLeave(&late));
|
|
Reference second{&leader,nullptr},first{&late,&second};Group group{&first};late.group=leader.group=&group;
|
|
assert(!m.ProtectInstanceGroupLeave(&late));leader.map.dungeon=true;
|
|
assert(m.ProtectInstanceGroupLeave(&late)); // human leader inside, no behavior record
|
|
leader.online=false;assert(!m.ProtectInstanceGroupLeave(&late));leader.online=true;leader.map.dungeon=false;
|
|
auto& r=m._records[2];r.Instance.Active=true;
|
|
for(auto phase:{AdventureInstancePolicy::Phase::Travel,AdventureInstancePolicy::Phase::Preparing,AdventureInstancePolicy::Phase::Entering,AdventureInstancePolicy::Phase::Inside,AdventureInstancePolicy::Phase::Returning}){
|
|
r.Instance.Stage=phase;assert(m.ProtectInstanceGroupLeave(&late));}
|
|
r.Instance.Stage=AdventureInstancePolicy::Phase::Rest;r.Intent="raid";r.Location="instance";r.Deadline=2000;
|
|
assert(!m.ProtectInstanceGroupLeave(&late)); // finished visit must not retain protection
|
|
r.Instance.Active=false;assert(m.ProtectInstanceGroupLeave(&late)); // pending retry/en-route
|
|
r.Intent="instance";assert(m.ProtectInstanceGroupLeave(&late));
|
|
r.Deadline=1000;assert(!m.ProtectInstanceGroupLeave(&late));
|
|
r.Deadline=2000;r.Location="unknown";assert(!m.ProtectInstanceGroupLeave(&late));
|
|
r.Location="instance";r.Intent="profession";assert(!m.ProtectInstanceGroupLeave(&late));
|
|
first.following=nullptr;assert(!m.ProtectInstanceGroupLeave(&late));}
|
|
'''
|
|
with tempfile.TemporaryDirectory(prefix="vcore-instance-group-protection-") as d:
|
|
p=Path(d);(p/"test.cpp").write_text(code)
|
|
subprocess.run(["c++","-std=c++17","-I"+str(root/"src/server/game/World"),str(p/"test.cpp"),"-o",str(p/"test")],check=True)
|
|
subprocess.run([str(p/"test")],check=True)
|
|
print("Instance group protection: travel/preparing/entering/inside/return, human leader, offline, retry, expiry and finished visit PASS")
|