Files
Viano-Core/tests/clientless/test_travel_cost_journey.py
T

51 lines
3.4 KiB
Python

"""Exercise production executor journey initialization, retry stability and leader inheritance."""
from pathlib import Path
import subprocess,tempfile
root=Path(__file__).resolve().parents[2]
s=(root/'src/server/game/World/ClientlessActionExecutorMgr.cpp').read_text()
a=s.index('bool ClientlessActionExecutorMgr::StartAction(')
b=s.index(' record.StopAtNode = false;',a)
method=s[a:b]+' return true;\n}\n'
code=r'''
#include "ClientlessTravelCost.h"
#include <cassert>
#include <cstdlib>
#include <unordered_map>
using uint32=unsigned;
#define TC_LOG_INFO(...) ((void)0)
struct Guid{unsigned id;unsigned GetCounter()const{return id;}};
struct Group{unsigned leader=29;Guid GetLeaderGUID(){return {leader};}}group;
struct Player{unsigned id=29;Guid GetGUID(){return {id};}Group*GetGroup(){return &group;}};
struct ClientlessAction{std::string Name="travel_to_node";std::unordered_map<std::string,std::string>Parameters{{"node","destination"}};};
enum class ClientlessActionExecutionState{Idle,Completed,Failed,SelectingTarget};
struct Graph{unsigned draws=0;auto NewJourneyCosts(){return ClientlessTravelCost::Sample({},++draws,.2f);}}graph;auto sClientlessTravelGraphMgr=&graph;
struct ClientlessActionExecutorMgr{
struct Record{ClientlessTravelCost::Profile JourneyCosts;std::string JourneyCostKey;bool HasJourneyCosts=false;struct{ClientlessActionExecutionState State=ClientlessActionExecutionState::Idle;}Status;};
std::unordered_map<unsigned,Record>_records;
bool StartAction(Player*,ClientlessAction const&,Record&);
};
'''+method+r'''
int main(){
ClientlessActionExecutorMgr m;Player leader;ClientlessAction action;auto& r=m._records[29];
m.StartAction(&leader,action,r);auto original=r.JourneyCosts;assert(graph.draws==1);
r.Status.State=ClientlessActionExecutionState::Failed;m.StartAction(&leader,action,r);
assert(graph.draws==1&&r.JourneyCosts.Factors==original.Factors);
r.Status.State=ClientlessActionExecutionState::SelectingTarget;m.StartAction(&leader,action,r);assert(graph.draws==1);
action.Parameters["node"]="another-destination";m.StartAction(&leader,action,r);assert(graph.draws==2);
r.Status.State=ClientlessActionExecutionState::Completed;m.StartAction(&leader,action,r);assert(graph.draws==3);
Player follower;follower.id=31;action.Parameters["route_source"]="29";auto& peer=m._records[31];
// Preferences are already inherited before a shared route is available.
m.StartAction(&follower,action,peer);assert(graph.draws==3&&peer.JourneyCosts.Factors==r.JourneyCosts.Factors);
action.Parameters.erase("route_source");peer.Status.State=ClientlessActionExecutionState::SelectingTarget;
m.StartAction(&follower,action,peer);assert(graph.draws==3&&peer.JourneyCosts.Seed==r.JourneyCosts.Seed);
// A forged/stale source from another group is not inherited.
group.leader=99;action.Parameters["route_source"]="29";peer.Status.State=ClientlessActionExecutionState::Completed;
m.StartAction(&follower,action,peer);assert(graph.draws==4&&peer.JourneyCosts.Seed!=r.JourneyCosts.Seed);
}
'''
with tempfile.TemporaryDirectory(prefix='vcore-journey-costs-') 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('Production journey initialization: new trip/new draw, stable retries, delayed leader route and group-safe modal inheritance passed.')