Вопрос Отлов телепортов в тумане войны

Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
бля я понял почему там 0. потому что там блядь еще не выставлен контрол поинт. ты хукаешь создание партикли - получаешь НОВОСОЗДАННУЮ партиклю. естественно она пустая и там нихуя нет. хукай SetControlPoint и там уже чекай. вот и создается иллюзия, что вроде в реклассе есть, а по факту везде 0 xD. у меня такая же хуйня, думаю думаю а потом башку включил и понял эту простую истину
БЛДЯДЬ. Самый рофл, что у меня подобные мысли были, но я их проигнорировал -- помнишь, может, я где-то тут писал про хук OnAddEntity, там такое же было.
Господи, как же тупо. Ну, может еще кому-то этот тред поможет. Спасибо, кстати.
 
Начинающий
Статус
Оффлайн
Регистрация
10 Май 2019
Сообщения
19
Реакции[?]
22
Поинты[?]
2K
Ребятки уже порешали вопросы, я не успел :sob:, но ситуация с неинициализированным объектом бьет по ментальному здоровью.
Кроме хука другой функции можно еще предложить сделать
Пожалуйста, авторизуйтесь для просмотра ссылки.
, но это просто творческий вариант насрать в код, а так SetControlPoint ??
 
Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
А, забыл о результатах отписать. Не уверен, что нашел именно SetControlPoint, но с этой функой всё работает.
36 функция в вмт CParticleCollection. Сига до вмт, если кому нужна: "48 8D ? ? ? ? ? 48 89 ? ? 48 8B ? 48 89".

C++:
class CParticleSystemDefinition {
public:
    char pad_0000[512];
    CParticleCollection* CParticleCollectionPtr; //0x0200
};

class InfoStruct {
public:
    const char* name;
};

class WHC_InfoForResourceTypeIParticleSystemDefinition {
public:
    CParticleSystemDefinition* systemDefinition;
    InfoStruct* info;
    char pad_0000[0x200];
};

class CParticleCollection {
public:
    virtual CSchemaClassBinding* Schema_DynamicBinding(void) = 0;
    virtual void* GetOwner(void) = 0;
    virtual void SetAssociatedObj(void*) = 0;
    virtual void* GetAssociatedObj() = 0;
    virtual void SetSomethingElse(void*) = 0;
    virtual void* GetSomethingElse() = 0;
    virtual bool IsValid(void) = 0;
    virtual bool IsFullyValid(void) = 0;
    virtual void* GetDefinition(void) = 0;
    virtual CParticleCollection* GetParentCollection(void) = 0;
    virtual CParticleCollection* GetFirstChildCollection(void) = 0;
    virtual CParticleCollection* GetNextSiblingCollection(void) = 0;
    virtual CParticleCollection* GetNextCollectionUsingSameDef(void) = 0;
    virtual bool UsesPowerOfTwoFrameBufferTexture(bool) = 0;
    virtual void sub_105ED0() = 0;
    virtual void sub_1062B0() = 0;
    virtual void sub_1064A0() = 0;
    virtual void SetOrientationFLU() = 0;
    virtual void sub_105C60() = 0;
    virtual void sub_107C90() = 0;
    virtual void sub_1073F0() = 0;
    virtual Vector* GetControlPointPosition(int ControlPoint) = 0; // 21
    virtual void sub_105861() = 0;
    virtual void* GetControlPointObject(int ControlPoint) = 0;
    virtual void sub_105D00() = 0;
    virtual void sub_105740() = 0;
    virtual void sub_1056B0() = 0;
    virtual void sub_105700() = 0;
    virtual void sub_12DDA0() = 0;
    virtual void FullRestart(void) = 0;
    virtual void Simulate(float dt) = 0;
    virtual void SleepingSimulate(float dt) = 0;
    virtual void SkipToTime(float time) = 0;
    virtual float GetSimulationTime(void) = 0;
    virtual bool IsFinished(void) = 0;
    virtual float GetNextSleepTime(void) = 0;
    virtual void UpdateNextSleepTime(void) = 0;
    virtual void sub_106350() = 0;
    virtual void sub_106390() = 0;
    virtual void sub_106450() = 0;
    virtual void sub_1063D0() = 0;
    virtual void sub_106410() = 0;
    virtual void sub_105F40() = 0;
    virtual void sub_124A80() = 0;
    virtual void sub_1249B0() = 0;
    virtual void sub_126AA0() = 0;
    virtual bool IsBoundsValid(void) = 0;
    virtual Vector* GetMinBounds(void) = 0;
    virtual Vector* GetMaxBounds(void) = 0;
    virtual void sub_105830() = 0;
    virtual void sub_105840() = 0;
    virtual void SetMinBounds(Vector min) = 0;
    virtual void SetMaxBounds(Vector max) = 0;
    virtual void BloatBoundsUsingControlPoint(void) = 0;
    virtual void DrawDebug(void* IRenderContext, void const* CSceneObject, void* ISceneView, void* ISceneLayer, int, int) = 0;
    virtual void StartEmission(bool) = 0;
    virtual void StopEmission(bool, bool, bool, bool) = 0;
    virtual bool IsEmissionStopped(void) = 0;
    virtual bool IsEmitting(void) = 0;
    virtual float GetMinimumTimeStepModifier(void) = 0;
    virtual void StartQueuedEmission(void) = 0;
    virtual void SetDormant(bool state) = 0;
    virtual bool IsDormant(void) = 0;
    virtual void sub_105950() = 0;
    virtual void sub_105980() = 0;
    virtual void sub_105990() = 0;
    virtual void sub_133E00() = 0;
    virtual void sub_12E910() = 0;
    virtual void sub_12A3E0() = 0;
    virtual void sub_12A420() = 0;
    virtual void SetQueuedStartEmission(bool state) = 0;
    virtual bool GetQueuedStartEmission(void) = 0;
    virtual bool IsFrozen(void) = 0;
    virtual void SetFrozen(bool state) = 0;
    virtual void sub_12FCD0() = 0;
    virtual void sub_130990() = 0;
    virtual void sub_1241D0() = 0;
    virtual void DESTRUCTOR() = 0;
    virtual void DESTRUCTOR_2() = 0;
    virtual void sub_123F70() = 0;
    virtual void sub_105770() = 0;
    virtual void sub_1057A0() = 0;
    virtual void sub_12A290() = 0;
    virtual void SetOwningSceneObject(void* CSceneParticleObject) = 0;
    virtual void* GetOwningSceneObject(void) = 0;
    virtual void SetMaterialOverride() = 0;
    virtual bool GetRenderingEnabled(void) = 0;
    virtual void SetRenderingEnabled(bool state) = 0;
    virtual bool InEndCap(void) = 0;
    virtual int GetFlags(void) = 0;
    virtual void SetFlags(int ParticleCollectionFlags_t) = 0;
    virtual void RemoveFlags(int ParticleCollectionFlags_t) = 0;
    virtual void GetSecondarySceneObjects() = 0;
    virtual bool HasAttribute(int) = 0;
    virtual void SetMinimumTimeStepModifier(float min) = 0;
    virtual void GetPerformanceData(void** ParticleCollectionPerf_t) = 0;
    virtual void OnSleepingStateChanged(bool) = 0;
    virtual void ValidateSystem(bool*, void* CUtlString) = 0;
    virtual int GetSystemParticleCount(void) = 0;
    virtual int GetSystemMaxParticleCount(void) = 0;
    virtual int GetTotalSystemCount(void) = 0;
    virtual void sub_1248F0() = 0;
    virtual void sub_1244B0() = 0;
    virtual void sub_124040() = 0;
    virtual void sub_1056F0() = 0;
};

Сам хук:
C++:
typedef WHC_InfoForResourceTypeIParticleSystemDefinition*(__fastcall* SetControlPoint)(CParticleCollection* thisptr, int idk);
SetControlPoint oSetControlPoint;
WHC_InfoForResourceTypeIParticleSystemDefinition* hkSetControlPoint(CParticleCollection* thisptr, int idk) {
    WHC_InfoForResourceTypeIParticleSystemDefinition* ret = (WHC_InfoForResourceTypeIParticleSystemDefinition*)oSetControlPoint(thisptr, idk);
 
    cout << "\nParticle Created" << endl;
    cout << ret->info->name << endl;
    cout << "Pos X " << thisptr->GetControlPointPosition(0)->x << ", Y " << thisptr->GetControlPointPosition(0)->y << ", Z " << thisptr->GetControlPointPosition(0)->z << endl;

    return ret;
}
Бтв @Liberalist был прав, GetControlPointPosition принимает не индекс партикля, а... индекс контрол-поинта? Короче, 0.
 
Последнее редактирование:
Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Короче шляпу я какую-то хукал. Не знаю, че это за функция. Хоть она и работает, там не вся инфа есть. IsDormant там не заполнен, что делает для меня функцию бесполезной. Хотел брать положение и IsDormant партикли "че-то там dota_base_atack", ну короче когда лес фармят.
Нашел SetParticleControlEnt, но она из client.dll, т.е. видимо какая-то обертка. А дальше реверсить в падлу, она тоже бесполезная.
Там в глубине есть индекс энтити (что очевидно), но всё равно координаты из дорманта не получить -- ни у энтити (что очевидно), ни у партикли -- последнее положение не в тумане показывается.
Но если вдруг она кому-то нужна:
IDA => client.dll => function string associate => Strings => "SetParticleControlEnt", первый хреф.
Листай вниз, пока не увидишь "iIndex". Выше будет lea rax, он тебе и нужен.
.text:0000000180EBD521 48 8D 05 D8 5A 02 00 lea rax, sub_180EE3000
.text:0000000180EBD528 C7 42 48 01 00 00 00 mov dword ptr [rdx+48h], 1
.text:0000000180EBD52F 48 89 42 38 mov [rdx+38h], rax
.text:0000000180EBD533 48 8D 05 86 6B FD FF lea rax, ThisOne <<
.text:0000000180EBD53A 48 89 42 40 mov [rdx+40h], rax
.text:0000000180EBD53E 48 8D 05 6B E8 60 01 lea rax, aIindex_4 ; "iIndex"
.text:0000000180EBD545 48 89 42 28 mov [rdx+28h], rax
.text:0000000180EBD549 48 8B C3 mov rax, rbx
.text:0000000180EBD54C 48 8B 5C 24 40 mov rbx, [rsp+38h+arg_0]

Даблкликай, листай в самый низ функи.
.text:0000000180E943D1 E8 EA 34 12 01 call SetParticleControlEnt <<
.text:0000000180E943D6
.text:0000000180E943D6 loc_180E943D6: ; CODE XREF: ThisOne +122↑j
.text:0000000180E943D6 ; ThisOne +14E↑j ...
.text:0000000180E943D6 4C 8D 9C 24 80 00 00 00 lea r11, [rsp+98h+var_18]
.text:0000000180E943DE 49 8B 5B 20 mov rbx, [r11+20h]
.text:0000000180E943E2 49 8B 6B 28 mov rbp, [r11+28h]
.text:0000000180E943E6 49 8B 73 30 mov rsi, [r11+30h]
.text:0000000180E943EA 49 8B 7B 38 mov rdi, [r11+38h]
.text:0000000180E943EE 49 8B E3 mov rsp, r11
.text:0000000180E943F1 41 5F pop r15
.text:0000000180E943F3 41 5E pop r14
.text:0000000180E943F5 41 5C pop r12
.text:0000000180E943F7 C3 retn

Рабочая на данный момент сига:
"E8 ? ? ? ? 4C 8D ? ? ? ? ? ? 49 8B ? ? 49 8B ? ? 49 8B ? ? 49 8B ? ? 49 8B ? 41 ? 41 ? 41 ? C3 CC"

Хук:
C++:
typedef void(__fastcall* SetParticleControlEntFn)(CParticleSystemMgr* thisptr, void* CNewParticleEffect, int a3, int particleIndex, int a5, void* attachType, void* a7, void* a8, void* a9);
SetParticleControlEntFn oSetParticleControlEnt;
void SetParticleControlEnt(CParticleSystemMgr* thisptr, CNewParticleEffect* CNewParticleEffect, int a3, int particleIndex, int a5, void* attachType, void* a7, void* a8, void* a9) {
    // Ну и тут из полезного -- энтитя, CNewParticleEffect, CParticleCollection, и  CParticleSystemMgr.
    // Еще вроде a3 -- это индекс энтити, но чет пару раз рандомно крашило с ним.

    CBaseEntity* BaseEntity = CNewParticleEffect->ParticlesListPtr->C_BaseEntityOuterHelperPtr->BaseEntity;
    CParticleCollection* ParticleCollection = CNewParticleEffect->CParticleCollectionPtr;

    oSetParticleControlEnt(thisptr, CNewParticleEffect, a3, particleIndex, a5, attachType, a7, a8, a9);
}
Классы:
C++:
class C_BaseEntityOuterHelper {
public:
    char pad_0000[8]; //0x0000
    CBaseEntity* BaseEntity; //0x0008
};

class ParticlesList { // В падлу разбираться, что за класс, название от балды дал
public:
    char pad_0000[8]; //0x0000
    C_BaseEntityOuterHelper* C_BaseEntityOuterHelperPtr; //0x0008
};

class CNewParticleEffect {
public:
    char pad_0000[32]; //0x0000
    CParticleCollection* CParticleCollectionPtr; //0x0020
    char pad_0028[48]; //0x0028
    ParticlesList* ParticlesListPtr; //0x0058
};

Кстати, если кто-нибудь подскажет, где лежит чертов SetParticleControl, я... ну... спасибо скажу, лол.
Столько всего реализовал, а банальный кружок вокруг энтити нарисовать не могу.
Пробовал его найти пару раз -- нашел всё, что угодно, но не его, и чет плюнул.

ЗЫ: Щас старый хук юзаю, из прошлого поста, он хоть что-то может. Беру имя партикли и рисую её на миникарте и в мире.
Только не все партикли работают. У некоторых "последняя видимая позиция энтити" в GetControlPointPosition.
Хрен его знает, от чего это зависит. И получается, просто все "геройские" партикли (particles/units/heroes/hero_name) рисовать не вариант. Условный старшторм Мираны будет хрен пойми где высираться. Получается, мне нужно все абилки всех героев протестить в лобби, правильная ли у них позиция, и занести их в файл? :D Вроде LWSS так делает, но это жопная боль.
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Короче шляпу я какую-то хукал. Не знаю, че это за функция. Хоть она и работает, там не вся инфа есть. IsDormant там не заполнен, что делает для меня функцию бесполезной. Хотел брать положение и IsDormant партикли "че-то там dota_base_atack", ну короче когда лес фармят.
Нашел SetParticleControlEnt, но она из client.dll, т.е. видимо какая-то обертка. А дальше реверсить в падлу, она тоже бесполезная.
Там в глубине есть индекс энтити (что очевидно), но всё равно координаты из дорманта не получить -- ни у энтити (что очевидно), ни у партикли -- последнее положение не в тумане показывается.
Но если вдруг она кому-то нужна:
IDA => client.dll => function string associate => Strings => "SetParticleControlEnt", первый хреф.
Листай вниз, пока не увидишь "iIndex". Выше будет lea rax, он тебе и нужен.
.text:0000000180EBD521 48 8D 05 D8 5A 02 00 lea rax, sub_180EE3000
.text:0000000180EBD528 C7 42 48 01 00 00 00 mov dword ptr [rdx+48h], 1
.text:0000000180EBD52F 48 89 42 38 mov [rdx+38h], rax
.text:0000000180EBD533 48 8D 05 86 6B FD FF lea rax, ThisOne <<
.text:0000000180EBD53A 48 89 42 40 mov [rdx+40h], rax
.text:0000000180EBD53E 48 8D 05 6B E8 60 01 lea rax, aIindex_4 ; "iIndex"
.text:0000000180EBD545 48 89 42 28 mov [rdx+28h], rax
.text:0000000180EBD549 48 8B C3 mov rax, rbx
.text:0000000180EBD54C 48 8B 5C 24 40 mov rbx, [rsp+38h+arg_0]

Даблкликай, листай в самый низ функи.
.text:0000000180E943D1 E8 EA 34 12 01 call SetParticleControlEnt <<
.text:0000000180E943D6
.text:0000000180E943D6 loc_180E943D6: ; CODE XREF: ThisOne +122↑j
.text:0000000180E943D6 ; ThisOne +14E↑j ...
.text:0000000180E943D6 4C 8D 9C 24 80 00 00 00 lea r11, [rsp+98h+var_18]
.text:0000000180E943DE 49 8B 5B 20 mov rbx, [r11+20h]
.text:0000000180E943E2 49 8B 6B 28 mov rbp, [r11+28h]
.text:0000000180E943E6 49 8B 73 30 mov rsi, [r11+30h]
.text:0000000180E943EA 49 8B 7B 38 mov rdi, [r11+38h]
.text:0000000180E943EE 49 8B E3 mov rsp, r11
.text:0000000180E943F1 41 5F pop r15
.text:0000000180E943F3 41 5E pop r14
.text:0000000180E943F5 41 5C pop r12
.text:0000000180E943F7 C3 retn

Рабочая на данный момент сига:
"E8 ? ? ? ? 4C 8D ? ? ? ? ? ? 49 8B ? ? 49 8B ? ? 49 8B ? ? 49 8B ? ? 49 8B ? 41 ? 41 ? 41 ? C3 CC"

Хук:
C++:
typedef void(__fastcall* SetParticleControlEntFn)(CParticleSystemMgr* thisptr, void* CNewParticleEffect, int a3, int particleIndex, int a5, void* attachType, void* a7, void* a8, void* a9);
SetParticleControlEntFn oSetParticleControlEnt;
void SetParticleControlEnt(CParticleSystemMgr* thisptr, CNewParticleEffect* CNewParticleEffect, int a3, int particleIndex, int a5, void* attachType, void* a7, void* a8, void* a9) {
    // Ну и тут из полезного -- энтитя, CNewParticleEffect, CParticleCollection, и  CParticleSystemMgr.
    // Еще вроде a3 -- это индекс энтити, но чет пару раз рандомно крашило с ним.

    CBaseEntity* BaseEntity = CNewParticleEffect->ParticlesListPtr->C_BaseEntityOuterHelperPtr->BaseEntity;
    CParticleCollection* ParticleCollection = CNewParticleEffect->CParticleCollectionPtr;

    oSetParticleControlEnt(thisptr, CNewParticleEffect, a3, particleIndex, a5, attachType, a7, a8, a9);
}
Классы:
C++:
class C_BaseEntityOuterHelper {
public:
    char pad_0000[8]; //0x0000
    CBaseEntity* BaseEntity; //0x0008
};

class ParticlesList { // В падлу разбираться, что за класс, название от балды дал
public:
    char pad_0000[8]; //0x0000
    C_BaseEntityOuterHelper* C_BaseEntityOuterHelperPtr; //0x0008
};

class CNewParticleEffect {
public:
    char pad_0000[32]; //0x0000
    CParticleCollection* CParticleCollectionPtr; //0x0020
    char pad_0028[48]; //0x0028
    ParticlesList* ParticlesListPtr; //0x0058
};

Кстати, если кто-нибудь подскажет, где лежит чертов SetParticleControl, я... ну... спасибо скажу, лол.
Столько всего реализовал, а банальный кружок вокруг энтити нарисовать не могу.
Пробовал его найти пару раз -- нашел всё, что угодно, но не его, и чет плюнул.

ЗЫ: Щас старый хук юзаю, из прошлого поста, он хоть что-то может. Беру имя партикли и рисую её на миникарте и в мире.
Только не все партикли работают. У некоторых "последняя видимая позиция энтити" в GetControlPointPosition.
Хрен его знает, от чего это зависит. И получается, просто все "геройские" партикли (particles/units/heroes/hero_name) рисовать не вариант. Условный старшторм Мираны будет хрен пойми где высираться. Получается, мне нужно все абилки всех героев протестить в лобби, правильная ли у них позиция, и занести их в файл? :D Вроде LWSS так делает, но это жопная боль.
ты мог бы чисто теоритически сравнивать коорды партикли с последним местом появления сущности(последние известные коорды сущности) - если совпадает, значит смысла нет рисовать партикль на минимапе(ибо этот партикль будет рисоваться в жопе. а точнее не в жопе а там где была сущность в последний раз). в противном случае можешь рисовать. меня тоже иногда заебывает когда всякие эффекты вампиризма просто посреди карты показываются(потому что там сущность была видна в последний раз) а не там где она лес фармит(ну это просто с дефолтным dota_use_particle_fow 0).
SetParticleControl чтобы найти джаваскрипт в помощь. Particles.SetParticleControl( integer iIndex, integer iPoint, js_value vPosVal )
если не ошибаюсь то это виртуалка прост у какого-то из классов партикли. ее же сразу и хукнуть можешь
 
Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
ты мог бы чисто теоритически сравнивать коорды партикли с последним местом появления сущности(последние известные коорды сущности) - если совпадает, значит смысла нет рисовать партикль на минимапе(ибо этот партикль будет рисоваться в жопе. а точнее не в жопе а там где была сущность в последний раз). в противном случае можешь рисовать. меня тоже иногда заебывает когда всякие эффекты вампиризма просто посреди карты показываются(потому что там сущность была видна в последний раз) а не там где она лес фармит(ну это просто с дефолтным dota_use_particle_fow 0).
SetParticleControl чтобы найти джаваскрипт в помощь. Particles.SetParticleControl( integer iIndex, integer iPoint, js_value vPosVal )
если не ошибаюсь то это виртуалка прост у какого-то из классов партикли. ее же сразу и хукнуть можешь
Получается, нужно куда-то, и, что самое главное, когда-то, записывать последние координаты энтити.
Знаю, что где-то там есть виртуальная функа SetDormant. В принципе, если её хукнуть, можно записывать коорды энтити в момент её ухода в туман.
А, или можно в хуке создания партикли чекать, что за герой (это я уже делаю), потом смотреть его IsDormant (это я тоже делаю), и если да, то сравнивать с его позицией, т.е. "последней позицией". Ну, он в тумане же. Да, хороший вариант. Спасибо, что подсказал.

А насчет SetParticleControl -- ну я так и делал, очевидно, я же SetParticleControlEnt там же и нашел :D
Там вроде очевидный паттерн -- идет хреф, ниже функа, где "iIndex", и два хрефа. У других функций, один из них -- тот, что нужен.
А вот у SetParticleControl там какой-то мусор. Ну может и не мусор, но там видно, что это не они, да и хук просто не срабатывает.
Ладно, хрен с ним, лучше буду particles.dll реверсить, чем эту оберточную шляпу.
 
Последнее редактирование:
Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Ну и тогда сразу спрошу, может у тебя появится идея получше. Насчет партикли атаки в тумане войны. Ну т.е. когда юнит лес фармит.
Проблема с ним в том, что у него дормант не заполнен. И вообще, он будет колбекаться при ЛЮБОЙ атаке кем-либо кого-либо.
Что, сам понимаешь, шляпа. В теории, я могу просто ручками разметить всю карту на "свою" и "чужую", или даже координаты всех крип-спавнов записать (при нажатии на Alt появляются ректы спавнбоксов, а это партикли -- я, в принципе, могу их коорды брать), ну и дальше очевидно -- чекаю, в каких коордах партикль атаки, и если в нужных -- рисую на миникарте\в мире\высираю уведомление мб.
Но тут проблемы две. Первая -- ну это ваще какой-то костыль, еще и боль в моей жопе.
Вторая -- а если мой керри фармит вражеский лес? Ну чет такое.
Я вот, что думаю. Когда итерировал энтитей и записывал их в файл (чет тестил), видел там крипспавны.
Попробую, короче, брать координаты этих спавнов и смотреть, какая в них инфа в дорманте есть.
Ну как бы очевидно, что если там есть IsDormant (и, наверное, коорд там может не быть, если кто-то этот спавн еще не видел из тиммейтов), то это лютая имба, и я могу просто коорды спавна округлить до небольшого квадратика (ну типа квадрат вокруг спавна), и в хуке чекать, где создается партикль атаки. Ну и если он внутри спавнбокса и он в дорманте -- рисовать алерт, там, ну ты понял.
Только я сильно сомневаюсь, что всё будет вот так просто. По хорошему, мне бы в нетчан смотреть.
Я уже его нашел, зареверсил, хукнул. Но там чет протобаффы какие-то, вот этот вот всё. Сложно, короче.
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Ну и тогда сразу спрошу, может у тебя появится идея получше. Насчет партикли атаки в тумане войны. Ну т.е. когда юнит лес фармит.
Проблема с ним в том, что у него дормант не заполнен. И вообще, он будет колбекаться при ЛЮБОЙ атаке кем-либо кого-либо.
Что, сам понимаешь, шляпа. В теории, я могу просто ручками разметить всю карту на "свою" и "чужую", или даже координаты всех крип-спавнов записать (при нажатии на Alt появляются ректы спавнбоксов, а это партикли -- я, в принципе, могу их коорды брать), ну и дальше очевидно -- чекаю, в каких коордах партикль атаки, и если в нужных -- рисую на миникарте\в мире\высираю уведомление мб.
Но тут проблемы две. Первая -- ну это ваще какой-то костыль, еще и боль в моей жопе.
Вторая -- а если мой керри фармит вражеский лес? Ну чет такое.
Я вот, что думаю. Когда итерировал энтитей и записывал их в файл (чет тестил), видел там крипспавны.
Попробую, короче, брать координаты этих спавнов и смотреть, какая в них инфа в дорманте есть.
Ну как бы очевидно, что если там есть IsDormant (и, наверное, коорд там может не быть, если кто-то этот спавн еще не видел из тиммейтов), то это лютая имба, и я могу просто коорды спавна округлить до небольшого квадратика (ну типа квадрат вокруг спавна), и в хуке чекать, где создается партикль атаки. Ну и если он внутри спавнбокса и он в дорманте -- рисовать алерт, там, ну ты понял.
Только я сильно сомневаюсь, что всё будет вот так просто. По хорошему, мне бы в нетчан смотреть.
Я уже его нашел, зареверсил, хукнул. Но там чет протобаффы какие-то, вот этот вот всё. Сложно, короче.
я не тестил, ты уверен что у сущности в тумане войны GetAbsOrigin() не работает? мне кажется он и должен возвращать последнюю известную позицию героя. посмотри потести. сомневаюсь что там позиция в 0 сбрасывается когда сущность в туман уходит(опять же не тестил не знаю просто предполагаю).
тоже не тестил, но посмотри, привязана ли партикля фарма в тумане к какой-то сущности или же к коордам. ну а так я ваще хуй знает как это все сделать. сиди тести смотри хули.
но все же я думаю подход с нетчаном будет гораздо мощнее.
протобафы доты на гитхабе есть
Пожалуйста, авторизуйтесь для просмотра ссылки.

через protoc от гугла компилишь(и потом инклюдишь: в проект добавляешь существующие файлы - .cc + .h которые тебе нужны(+остальные .cc и .h которые этим хедерам нужны. они там друг от друга зависят), закидываешь рядом с хедерами папку google из protobuf-3.18.1\src\google но не инклюдишь ее в проект), билдишь libprotobuf и наслаждаешься поеданием говна от уебков из гугла
1638888645200.png
1638888661200.png
1638888754100.png
потом линкуешь либу и инклюдишь что надо(.h)
C++:
module;
#pragma comment(lib,"libprotobuf64.lib")
export module dota.protobuf.include;

export import <base_gcmessages.pb.h>;
...
а так всякое говно вспомогательное в поисковике можешь найти. например как из CSVCMsg_PacketEntities распарсить optional bytes entity_data = 7;
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Последнее редактирование:
Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
я не тестил, ты уверен что у сущности в тумане войны GetAbsOrigin() не работает?
Сори, что как идиот изъяснялся -- опять не спал третьи сутки. Не, AbsOrigin ГЕРОЯ возвращает последнюю позицию, как и должен.
привязана ли партикля фарма в тумане к какой-то сущности
Ага, привязана. К WorldEnt :D Гейб, видимо, не настолько мудак.
Короче, я всё потестил со всех сторон, попробовал разные варианты -- всё херня. Спасибо, что надоумил таки с протобаффами разобраться-- там рили всё просто. (Я надеюсь, как заинклюдить депсы от гугла ты пишешь "для потомков", потому что я конечно тот еще кодер, но не настолько же...)
Опщем, через пару дней буду пробовать. Как сделаю -- отпишу о результатах. Или, что еще лучше, отдельный тред в соседнем разделе с гайдами запилю.
Энивей, спасибо за неоценимую помощь <З
 
Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Дошли руки до нетчана. Хукнул, смотрю. Вроде что-то приходит.
Но я, видимо, что-то не так делаю. Прототип функции:
C++:
INetChannel* thisptr, NetMessageHandle_t* messageHandle, void* msg, NetChannelBufType_t const* type, int bits, int messageNum
msg не void* должен быть, а google::protobuf::Message*, но пока пусть так. Открываю его в реклассе -- там какой-то хлам, который еще и меняется постоянно. Выглядит, как какой-то рандом, из которого я ничего полезного не получу.
Вроде индекс правильный, 87. В классе рядом ничего другого подходящего нет.

Пытаюсь сделать
C++:
CUtlString string;
string.m_Memory.m_pMemory = new uint8_t[4096];
string.m_Memory.m_nAllocationCount = 4096;
string.m_Memory.m_nGrowSize = 4096;
pProtobufBinding->ToString( msg, &string );
Получаю краш. При это остальное вроде работает. И name, и group возвращают осмысленную инфу.

C++:
info = sdk.networkMessages->GetNetMessageInfo(messageHandle);
name = info->pProtobufBinding->GetName();
group = info->pProtobufBinding->GetGroup();
Короче, херня какая-то с нетчаном у меня выходит..
Алсо, для чего тут протобафы доты с гитхаба, и куда его приладить, я так и не понял.
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Дошли руки до нетчана. Хукнул, смотрю. Вроде что-то приходит.
Но я, видимо, что-то не так делаю. Прототип функции:
C++:
INetChannel* thisptr, NetMessageHandle_t* messageHandle, void* msg, NetChannelBufType_t const* type, int bits, int messageNum
msg не void* должен быть, а google::protobuf::Message*, но пока пусть так. Открываю его в реклассе -- там какой-то хлам, который еще и меняется постоянно. Выглядит, как какой-то рандом, из которого я ничего полезного не получу.
Вроде индекс правильный, 87. В классе рядом ничего другого подходящего нет.

Пытаюсь сделать

C++:
CUtlString string;
string.m_Memory.m_pMemory = new uint8_t[4096];
string.m_Memory.m_nAllocationCount = 4096;
string.m_Memory.m_nGrowSize = 4096;
pProtobufBinding->ToString( msg, &string );
Получаю краш. При это остальное вроде работает. И name, и group возвращают осмысленную инфу.

C++:
info = sdk.networkMessages->GetNetMessageInfo(messageHandle);
name = info->pProtobufBinding->GetName();
group = info->pProtobufBinding->GetGroup();
Короче, херня какая-то с нетчаном у меня выходит..
Алсо, для чего тут протобафы доты с гитхаба, и куда его приладить, я так и не понял.
C++:
...
export
class CProtobufBinding : public VClass
{
    static inline constexpr auto ToString_VFTable_Index = 2;
public:
    std::string ToString(google::protobuf::Message* msg)
    {
        CUtlString str{};
        std::string result;
        result = CallVFunc<ToString_VFTable_Index, const char*>(msg, &str);
        return result;
    }
};
...
import <netmessages.pb.h>;
...
    static inline constexpr auto PostReceivedMessage_VFTable_Index = 87;
    class RecvMessageHook : public BaseVMTHook<RecvMessageHook, PostReceivedMessage_VFTable_Index>
    {
    public:
        static return_type __fastcall Hook(
            CNetworkChannel* rcx,
            CNetworkSerializerPB* rdx,
            google::protobuf::Message* r8,
            NetChannelBufType_t* r9
        ) noexcept
        {
            try {
                if (rcx == CEngineClient::GetInstance()->GetGameNetChannel()) {
                    static std::vector<std::int16_t> message_log_blacklist =
                    {
                        CNetworkMessages::GetInstance()->FindMessageByName("CNETMsg_Tick")->messageID,
                        CNetworkMessages::GetInstance()->FindMessageByName("CSVCMsg_PacketEntities")->messageID
                    };
                    static auto metadata_msg_id =
                        CNetworkMessages::GetInstance()->FindMessageByName("CDOTAMatchMetadata")//так, по хуйне сообщение тестил не обращай внимания
                            ->messageID;
                  
                    static auto matchdata_msg_id =
                        CNetworkMessages::GetInstance()->FindMessageByName("CMsgDOTAMatch")
                            ->messageID;
                    if (
                        const auto msg_id = rdx->messageID;
                        std::ranges::find(message_log_blacklist, msg_id) ==
                        message_log_blacklist.end()
                        )
                    {
                          Logger::LogInfo("Receiving %s\n", rdx->unscopedName);
                          if (msg_id == metadata_msg_id) {
                              const auto& result = rdx->protobufBinding->ToString(r8);
                              Logger::LogInfo("CDOTAMatchMetadata: \n%s\n", result.c_str());
                          }
                          else if (msg_id == matchdata_msg_id) {
                              const auto& result = rdx->protobufBinding->ToString(r8);
                              Logger::LogInfo("CMsgDOTAMatch: \n%s\n", result.c_str());
                          }
                    }
                }
            }
            catch (...)
            {
                Logger::LogInfo("Got exception in network recv hook!\n");
            }
            return CallOriginal(rcx, rdx, r8, r9);
        }
 
Последнее редактирование:
Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
C++:
...
export
class CProtobufBinding : public VClass
{
    static inline constexpr auto ToString_VFTable_Index = 2;
public:
    std::string ToString(google::protobuf::Message* msg)
    {
        CUtlString str{};
        std::string result;
        result = CallVFunc<ToString_VFTable_Index, const char*>(msg, &str);
        return result;
    }
};
...
import <netmessages.pb.h>;
...
    static inline constexpr auto PostReceivedMessage_VFTable_Index = 87;
    class RecvMessageHook : public BaseVMTHook<RecvMessageHook, PostReceivedMessage_VFTable_Index>
    {
    public:
        static return_type __fastcall Hook(
            CNetworkChannel* rcx,
            CNetworkSerializerPB* rdx,
            google::protobuf::Message* r8,
            NetChannelBufType_t* r9
        ) noexcept
        {
            try {
                if (rcx == CEngineClient::GetInstance()->GetGameNetChannel()) {
                    static std::vector<std::int16_t> message_log_blacklist =
                    {
                        CNetworkMessages::GetInstance()->FindMessageByName("CNETMsg_Tick")->messageID,
                        CNetworkMessages::GetInstance()->FindMessageByName("CSVCMsg_PacketEntities")->messageID
                    };
                    static auto metadata_msg_id =
                        CNetworkMessages::GetInstance()->FindMessageByName("CDOTAMatchMetadata")//так, по хуйне сообщение тестил не обращай внимания
                            ->messageID;
                 
                    static auto matchdata_msg_id =
                        CNetworkMessages::GetInstance()->FindMessageByName("CMsgDOTAMatch")
                            ->messageID;
                    if (
                        const auto msg_id = rdx->messageID;
                        std::ranges::find(message_log_blacklist, msg_id) ==
                        message_log_blacklist.end()
                        )
                    {
                          Logger::LogInfo("Receiving %s\n", rdx->unscopedName);
                          if (msg_id == metadata_msg_id) {
                              const auto& result = rdx->protobufBinding->ToString(r8);
                              Logger::LogInfo("CDOTAMatchMetadata: \n%s\n", result.c_str());
                          }
                          else if (msg_id == matchdata_msg_id) {
                              const auto& result = rdx->protobufBinding->ToString(r8);
                              Logger::LogInfo("CMsgDOTAMatch: \n%s\n", result.c_str());
                          }
                    }
                }
            }
            catch (...)
            {
                Logger::LogInfo("Got exception in network recv hook!\n");
            }
            return CallOriginal(rcx, rdx, r8, r9);
        }
Как у тебя красиво сделано, спизжу себе пару идей. А так, я всё это в общем-то и делаю. Ну, кроме ToString, попробую потом его так заюзать.
Стало быть, все вкусности в msg лежат? Не стал сильно пытаться разобраться, потому что вдруг я не туда воюю.
Щас PrepareUnitOrders доделаю (собака сутулая на Габене зачем-то сделала её не виртуальной, плюс сига, минус стабильность), да к нетчану вернусь.
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Как у тебя красиво сделано, спизжу себе пару идей. А так, я всё это в общем-то и делаю. Ну, кроме ToString, попробую потом его так заюзать.
Стало быть, все вкусности в msg лежат? Не стал сильно пытаться разобраться, потому что вдруг я не туда воюю.
Щас PrepareUnitOrders доделаю (собака сутулая на Габене зачем-то сделала её не виртуальной, плюс сига, минус стабильность), да к нетчану вернусь.
да там все данные в мсг а этот мсг как раз с протобафов гугла. CMsgDOTAMatch тот же например в dota_gcmessages_common.proto описан.
 
Сверху Снизу