Files
Viano-Core/tests/clientless/test_clientless_skill_preparation.py
T
Nico 04aa87fcfc
clang PCH / build (push) Waiting to run
GCC PCH / build (push) Canceled after 0s
Add profile-driven AdventureBot character generation
2026-10-28 11:30:47 +01:00

41 lines
2.5 KiB
Python

"""Execute native tier-based skill preparation before world insertion."""
from pathlib import Path
import subprocess,tempfile
root=Path(__file__).resolve().parents[2]
s=(root/'src/server/game/World/ClientlessCharacterFactory.cpp').read_text()
a=s.index('bool ClientlessCharacterFactory::PrepareSkillRank(')
code=r'''
#include <cassert>
#include <unordered_map>
using uint32=unsigned;constexpr unsigned MAX_SKILL_STEP=16;
struct RC{unsigned MinLevel=5,SkillTierID=1;}rc;
struct DBC {bool available=true;RC*GetSkillRaceClassInfo(unsigned,unsigned,unsigned){return available?&rc:nullptr;}}sDBCManager;
struct Tier{unsigned Value[16]={75,150,225,300,375,450,525};}tier;
struct Store{bool available=true;Tier*LookupEntry(unsigned){return available?&tier:nullptr;}}sSkillTiersStore;
struct Player{
bool inWorld=false;unsigned level=60,step=0,value=0,cap=0;int writes=0;
bool IsInWorld(){return inWorld;}unsigned getRace(){return 1;}unsigned getClass(){return 1;}unsigned getLevel(){return level;}
unsigned GetSkillStep(unsigned){return step;}unsigned GetPureSkillValue(unsigned){return value;}unsigned GetPureMaxSkillValue(unsigned){return cap;}
void SetSkill(unsigned,unsigned s,unsigned v,unsigned c){++writes;step=s;value=v;cap=c;}
};
struct ClientlessCharacterFactory{static bool PrepareSkillRank(Player*,unsigned,unsigned);};
'''+s[a:]+r'''
int main(){
Player p;using F=ClientlessCharacterFactory;
assert(F::PrepareSkillRank(&p,186,1));assert(p.step==1 && p.value==75 && p.cap==75);
assert(F::PrepareSkillRank(&p,186,5));assert(p.step==5 && p.value==375 && p.cap==375);
auto previous=p.writes;assert(F::PrepareSkillRank(&p,186,1));assert(p.step==5 && p.writes==previous);
assert(!F::PrepareSkillRank(&p,186,0));assert(!F::PrepareSkillRank(&p,186,17));assert(!F::PrepareSkillRank(&p,186,8));
p.inWorld=true;assert(!F::PrepareSkillRank(&p,186,6));p.inWorld=false;
p.level=4;assert(!F::PrepareSkillRank(&p,186,6));p.level=60;
sDBCManager.available=false;assert(!F::PrepareSkillRank(&p,186,6));sDBCManager.available=true;
sSkillTiersStore.available=false;assert(!F::PrepareSkillRank(&p,186,6));
assert(p.writes==previous);assert(!F::PrepareSkillRank(nullptr,186,1));
}
'''
with tempfile.TemporaryDirectory() as d:
p=Path(d);(p/'test.cpp').write_text(code)
subprocess.run(['g++','-std=c++17',str(p/'test.cpp'),'-o',str(p/'test')],check=True)
subprocess.run([str(p/'test')],check=True)
print('Production offline skill preparation: native tier caps, no downgrading, rank/level/race/tier gates and no modification of online players passed')