reaper
-
Автор темы
- #1
Сегодня я собираюсь вам научить и поговорить с вами о Glow(Свечения) обьектов.
Если вы не знаете, что я имею в виду, это эффект контура, который вы можете увидеть на скриншотах.Он применяется к различным объектам, таким как игроки, оружие и здания. В этом сообщении мы найдем диспетчера объектов свечения в IDA, добавив необходимые классы в наш код и, наконец, изменив цвета и получив эффект в любое время.
Стоит отметить, что существует множество способов найти диспетчера объектов свечения. Я решил использовать этот, поскольку он прост и работает в нескольких играх Source. Все, что нам нужно сделать, это найти ссылку на строку, в данном случае «EntityGlowEffects» в CGlowObjectManager :: RenderGlowEffects. Начнем с Team Fortress 2.
Один строковый поиск в client.so позже, и мы нашли CGlowObjectManager :: RenderGlowEffects. Теперь мы можем проверить, не вызвана ли эта функция где-нибудь. Если это так, первым переданным им аргументом будет диспетчер объектов свечения. Разумеется, есть единственная ссылка на эту функцию. Следуйте за ним, и мы нашли именно то, что искали.
Вот и все. Через несколько секунд мы нашли менеджера объектов свечения на 0x2001180 с client.so. Извиняюсь, если вы ожидаете магии прерывания. Я планировал включить весь раздел, где мы разрываем RenderGlowEffects и читаем аргументы из стека, но я не хотел слишком усложнять что-то столь же простое, как это. Возможно, в следующий раз.
Для целей данного руководства мы можем просто использовать смещение от базового адреса библиотеки.
Далее, мы должны реализовать необходимые классы. Нам не нужно слишком беспокоиться по большинству функций CUtlMemory и CUtlVector, поэтому минимальных структур просто для доступа к элементам будет достаточно.
Далее, фактический управляющий объектом свечения. Это в основном без изменений из Source SDK с несколькими незначительными изменениями.
Нам нужно где-то выполнить наши модификации. FrameStageNotify в IBaseClientDLL всегда безопасная ставка. Наш код будет выполняться на этапе FRAME_RENDER_START и установит цвет контура для каждого зарегистрированного лица в зеленый цвет.
Мы также должны установить m_bGlowEnabled (в настоящее время 0xDA1) на сущности или они будут светиться только в течение первых 10 секунд после нереста. Убедитесь, что не установить это на местных игроков, мертвых игроков или на каких-либо бездействующих лиц, чтобы избежать от крашов.
Если вы просто хотите, чтобы объекты светились, вам нужно только заставить m_bGlowEnabled использовать true. У вас не будет никакого контроля над цветом без вышеуказанного кода, но игроки и здания уже окрашены в соответствии с их командами.
Теперь, когда все работает по назначению, вы можете сбросить смещение и создать хорошую подпись, чтобы выжить в будущих обновлениях.
Это все для Team Fortress 2, время для перехода на Counter-Strike: Global Offensive. Откройте client_client.so и, опять же, найдите строку EntityGlowEffects и следуйте ссылке на CGlowObjectManager :: RenderGlowEffects.
Как и ожидалось, RenderGlowEffects вызывается из DoPostScreenSpaceEffects, но на этот раз он немного отличается. Указатель, который мы ищем, возвращается из функции GlowObjectManager, поэтому мы можем либо вызвать функцию, либо посмотреть немного дальше, и найти базовый адрес возврата. Это полностью зависит от вас, так как оба достигают такого же эффекта.
Теперь, прежде чем вы попытаетесь использовать тот же код из примера Team Fortress 2, стоит знать, что структура GlowObjectDefinition_t изменилась с тех пор. Я понятия не имею, что такое некоторые из этих новых переменных, поэтому мы можем просто добавить байты заполнения и позволить движку справиться с этим. Просто не меняйте ни одного из них, и со мной все будет в порядке.
На этот раз нам нужно только выполнить итерацию уже зарегистрированных объектов свечения. Вы можете добавить свои собственные определения объектов свечения в список, если есть свободные слоты. Не забудьте удалить их из списка при удалении объекта или сбое игры.
В этой игре объект свечения дает вам прямой указатель на объект вместо дескриптора, который делает вещи еще проще. Вам нужно только установить m_bShouldGlow (в настоящее время 0x3048) для объектов, получающих из CDynamicProp - наиболее полезных для цыплят.
Если будут какие-либо вопросы, спросите меня.
Если вы не знаете, что я имею в виду, это эффект контура, который вы можете увидеть на скриншотах.Он применяется к различным объектам, таким как игроки, оружие и здания. В этом сообщении мы найдем диспетчера объектов свечения в IDA, добавив необходимые классы в наш код и, наконец, изменив цвета и получив эффект в любое время.
Один строковый поиск в client.so позже, и мы нашли CGlowObjectManager :: RenderGlowEffects. Теперь мы можем проверить, не вызвана ли эта функция где-нибудь. Если это так, первым переданным им аргументом будет диспетчер объектов свечения. Разумеется, есть единственная ссылка на эту функцию. Следуйте за ним, и мы нашли именно то, что искали.
Для целей данного руководства мы можем просто использовать смещение от базового адреса библиотеки.
Код:
glowobjectmanager = reinterpret_cast<CGlowObjectManager*>(client_so_addr + 0x2001180);
Код:
template <class T, class I = int> class CUtlMemory {
public:
T& operator[](int i) {
return m_pMemory[i];
};
T* m_pMemory;
int m_nAllocationCount;
int m_nGrowSize;
};
Код:
template <class T, class A = CUtlMemory<T>> class CUtlVector {
public:
typedef A CAllocator;
T& operator[](int i) {
return m_Memory[i];
};
CAllocator m_Memory;
int m_Size;
T* m_pElements;
};
Код:
#define END_OF_FREE_LIST -1
#define ENTRY_IN_USE -2
Код:
struct GlowObjectDefinition_t {
CBaseHandle m_hEntity;
Vector m_vGlowColor;
float m_flGlowAlpha;
bool m_bRenderWhenOccluded;
bool m_bRenderWhenUnoccluded;
int m_nSplitScreenSlot;
int m_nNextFreeSlot;
};
Код:
class CGlowObjectManager {
public:
CUtlVector<GlowObjectDefinition_t> m_GlowObjectDefinitions;
int m_nFirstFreeSlot;
};
Код:
or (int index = 0; index < glowobjectmanager->m_GlowObjectDefinitions.m_Size; index++) {
GlowObjectDefinition_t& glowobject = glowobjectmanager->m_GlowObjectDefinitions[index];
if (glowobject.m_nNextFreeSlot != ENTRY_IN_USE)
continue;
glowobject.m_vGlowColor = Vector(0.f, 1.f, 0.f);
}
Если вы просто хотите, чтобы объекты светились, вам нужно только заставить m_bGlowEnabled использовать true. У вас не будет никакого контроля над цветом без вышеуказанного кода, но игроки и здания уже окрашены в соответствии с их командами.
Код:
for (int index = 1; index < entitylist->GetHighestEntityIndex(); index++) {
C_BaseEntity* entity = static_cast<C_BaseEntity*>(entitylist->GetClientEntity(index));
if (!entity || index == engine->GetLocalPlayer() || entity->IsDormant())
continue;
switch (entity->GetClientClass()->m_nClassID) {
case CTFPlayer:
case CObjectSentrygun:
case CObjectTeleporter:
case CObjectDispenser:
entity->SetGlowEnabled(!entity->IsDormant() && entity->GetLifeState() == LIFE_ALIVE);
break;
}
}
Код:
glowobjectmanager = *reinterpret_cast<CGlowObjectManager**>(FindPattern("bin/client.so", "C1 E0 05 03 05") + 5);
Код:
typedef CGlowObjectManager* (*GlowObjectManager_t) ();
glowobjectmanager = reinterpret_cast<GlowObjectManager_t>(client_client_so_addr + 0xDD21E0)();
Код:
struct GlowObjectDefinition_t {
C_BaseEntity* m_pEntity;
Vector m_vGlowColor;
float m_flGlowAlpha;
char __unknown00[8];
float m_flBloomAmount;
char __unknown01[4];
bool m_bRenderWhenOccluded;
bool m_bRenderWhenUnoccluded;
bool m_bFullBloomRender;
char __unknown02;
int m_nFullBloomStencilTestValue;
char __unknown03[4];
int m_nSplitScreenSlot;
int m_nNextFreeSlot;
};
В этой игре объект свечения дает вам прямой указатель на объект вместо дескриптора, который делает вещи еще проще. Вам нужно только установить m_bShouldGlow (в настоящее время 0x3048) для объектов, получающих из CDynamicProp - наиболее полезных для цыплят.
Код:
for (int index = 0; index < glowobjectmanager->m_GlowObjectDefinitions.m_Size; index++) {
GlowObjectDefinition_t& glowobject = glowobjectmanager->m_GlowObjectDefinitions[index];
if (glowobject.m_nNextFreeSlot != ENTRY_IN_USE)
continue;
C_BaseEntity* entity = glowobject.m_pEntity;
if (entity->GetClientClass()->m_nClassID == CChicken)
entity->SetShouldGlow(true);
glowobject.m_vGlowColor = Vector(1.0f, 1.0f, 1.0f);
glowobject.m_flGlowAlpha = 1.0f;
glowobject.m_bRenderWhenOccluded = true;
glowobject.m_flBloomAmount = 1.0f;
}