34 lines
2.5 KiB
Python
34 lines
2.5 KiB
Python
"""Execute native equip cooldowns with invalid/sentinel spell metadata."""
|
|
from pathlib import Path
|
|
import subprocess,tempfile
|
|
root=Path(__file__).resolve().parents[2]
|
|
s=(root/'src/server/game/Entities/Player/Player.cpp').read_text()
|
|
a=s.index('void Player::ApplyEquipCooldown(');b=s.index('{',a);e=b+1;n=1
|
|
while n:n+=(s[e]=='{')-(s[e]=='}');e+=1
|
|
code=r'''
|
|
#include <cassert>
|
|
#include <chrono>
|
|
#include <vector>
|
|
using uint32=unsigned;using uint64=unsigned long long;
|
|
constexpr unsigned ITEM_FLAG_NO_EQUIP_COOLDOWN=1,ITEM_SPELLTRIGGER_ON_EQUIP=1,ITEM_SPELLTRIGGER_ON_USE=2,IN_MILLISECONDS=1000,SMSG_ITEM_COOLDOWN=1;
|
|
struct SpellInfo{unsigned id;};struct SpellProcEntry{};
|
|
struct Spells{SpellInfo spell{42};SpellInfo const*GetSpellInfo(unsigned id){return id==42?&spell:nullptr;}SpellProcEntry const*GetSpellProcEntry(unsigned){return nullptr;}}spells;auto sSpellMgr=&spells;
|
|
struct ItemEffect{unsigned SpellID,Trigger;};struct Proto{unsigned flags=0;std::vector<ItemEffect>Effects;unsigned GetFlags(){return flags;}};
|
|
struct Item{Proto proto;Proto*GetTemplate(){return &proto;}unsigned GetEntry(){return 5;}unsigned GetGUID(){return 9;}};
|
|
struct Aura{void AddProcCooldown(SpellProcEntry const*,std::chrono::steady_clock::time_point){}};
|
|
struct WorldPacket{WorldPacket(unsigned,unsigned){}template<class T>WorldPacket&operator<<(T){return *this;}};
|
|
struct History{unsigned adds=0,remaining=0;unsigned GetRemainingCooldown(SpellInfo const*s){assert(s);return remaining;}void AddCooldown(unsigned id,unsigned,std::chrono::seconds){assert(id==42);++adds;}};
|
|
struct Player{History history;unsigned packets=0;unsigned GetGUID(){return 1;}Aura*GetAura(unsigned,unsigned,unsigned){return nullptr;}History*GetSpellHistory(){return &history;}void SendDirectMessage(WorldPacket*){++packets;}void ApplyEquipCooldown(Item*);};
|
|
'''+s[a:e]+r'''
|
|
int main(){Player p;Item item;item.proto.Effects={{0,2},{0xFFFFFFFFu,2},{999999,2},{42,0},{42,2}};
|
|
p.ApplyEquipCooldown(&item);assert(p.history.adds==1 && p.packets==1);
|
|
p.history.remaining=31000;p.ApplyEquipCooldown(&item);assert(p.history.adds==1);
|
|
item.proto.flags=ITEM_FLAG_NO_EQUIP_COOLDOWN;p.ApplyEquipCooldown(&item);assert(p.history.adds==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('Native item equip cooldown: zero/sentinel/missing spells safely skipped, valid use cooldown preserved and longer/disabled cooldowns untouched passed')
|