mamodron
-
Автор темы
- #1
Нам нужно подключить 3 функции:
В CInventoryManager::SetItemBackpackPosition
Игра вызывает эту функцию после подтверждения элемента. Игра отправляет запрос в GC, а ответ - это идентификатор инвентаря, но наш предмет является поддельным, поэтому нам нужно вручную указать идентификатор инвентаря.
GetLastInventoryID возвращает наивысшее значение идентификатора инвентаря в нашем инвентаре
В ScaleformUIImpl::UnkFunction
В CMatchEventsSubscription::BroadcastEvent
KeyValues
Код:
CMatchEventsSubscription::BroadcastEvent - 2
CInventoryManager::SetItemBackpackPosition - 26
ScaleformUIImpl::UnkFunction - 7
Код:
g_MatchFramework = **reinterpret_cast<CMatchFramework***>(Pattern::FindSignature("client.dll", "8B 0D ? ? ? ? 8B 11 FF 52 34 89 44 24 1C") + 0x2); //virtual function index 11
g_CSInventoryManager = *reinterpret_cast<CSInventoryManager**>(Pattern::FindSignature("client.dll", "B9 ?? ?? ?? ?? 8D 44 24 10 89 54 24 14") + 0x1);
g_ScaleformUIImpl = *reinterpret_cast<uintptr_t**>(Pattern::FindSignature("scaleformui.dll", "68 ? ? ? ? FF D0 5D") + 0x1);
Код:
typedef void(__thiscall* CMatchEventsSubscription_BroadcastEventFn)(void*, KeyValues* kv);
typedef bool(__thiscall* CInventoryManager_SetItemBackpackPositionFn)(void*, C_EconItemView*, int, int, bool);
typedef const char*(__thiscall* ScaleformUIImpl_UnkFunctionFn)(void*, int, int);
В CInventoryManager::SetItemBackpackPosition
Игра вызывает эту функцию после подтверждения элемента. Игра отправляет запрос в GC, а ответ - это идентификатор инвентаря, но наш предмет является поддельным, поэтому нам нужно вручную указать идентификатор инвентаря.
GetLastInventoryID возвращает наивысшее значение идентификатора инвентаря в нашем инвентаре
Код:
if (*item->GetInventory() == 0)
*item->GetInventory() = GameUtils::GetLastInventoryID() + 1;
Код:
uint32_t* C_EconItemView::GetInventory()
{
static auto inv_offset = *reinterpret_cast<uintptr_t*>(Pattern::FindSignature("client.dll", "8D 9E ? ? ? ? 8B 0B") + 2);
return reinterpret_cast<uint32_t*>((uintptr_t)this + inv_offset);
}
В ScaleformUIImpl::UnkFunction
Код:
auto ret = g_fnUnkFunction(pThis, a1, a2);
static auto GetLootListItemsCountReturnAddress = reinterpret_cast<uintptr_t>(Pattern::FindSignature("client.dll", "85 C0 0F 84 ? ? ? ? 8B C8 E8 ? ? ? ? 52 50 E8 ? ? ? ? 8B F0 83 C4 08 89 74 24 14"));
if (reinterpret_cast<uintptr_t>(_ReturnAddress()) == GetLootListItemsCountReturnAddress)
//save here item to variable where ret is item id (char*) in this case crate what we want to open, so convert it to uint64_t and call GetInventoryItemByItemID
Код:
C_EconItemView* CPlayerInventory::GetInventoryItemByItemID(int64_t ID)
{
static auto fnGetInventoryItemByItemID
= reinterpret_cast<C_EconItemView*(__thiscall*)(void*, int64_t)>(
Pattern::FindSignature("client.dll", "55 8B EC 8B 55 08 83 EC 10 8B C2")
);
auto econ = fnGetInventoryItemByItemID(this, ID);
if (!econ || !*(BYTE*)((uintptr_t)econ + 0x204))
return g_Valve.g_CSInventoryManager->FindOrCreateReferenceEconItem(ID);
else
return econ;
}
Код:
C_EconItemView* CSInventoryManager::FindOrCreateReferenceEconItem(int64_t ID)
{
static auto fnFindOrCreateReferenceEconItem
= reinterpret_cast<C_EconItemView*(__thiscall*)(void*, int64_t)>(
Pattern::FindSignature("client.dll", "55 8B EC 51 8B 55 0C 53 56")
);
return fnFindOrCreateReferenceEconItem(this, ID);
}
В CMatchEventsSubscription::BroadcastEvent
Код:
if (strstr(kv->GetName(), "ScaleformComponent_Inventory_CrateOpenError"))
{
auto LocalInventory = g_Valve.g_CSInventoryManager->GetLocalPlayerInventory();
auto Item = GameUtils::CreateEconItem();
*Item->GetAccountID() = LocalInventory->GetSteamID();
*Item->GetItemID() = GameUtils::GetLastID() + 1;
*Item->GetInventory() = 0;
*Item->GetFlags() = 0;
*Item->GetOriginalID() = 0;
auto ItemsToDrop = GameUtils::GetWeaponsForCrate(Crate->GetCrateSeries()); //Crate is C_EconItemView from ScaleformUIImpl::UnkFunction
float PaintKit = 0;
float Seed = 0;
float Wear = 0;
int DefIndex = 0;
int Stattrak = -1;
ItemRarity rarity = ITEM_RARITY_DEFAULT;
//here your own losu losu algorithm
//losu losu losu
*Item->GetDefIndex() = DefIndex;
Item->SetPaintKit(PaintKit);
if(stattrak != -1)
Item->SetStatTrak(stattrak);
Item->SetPaintSeed(Seed);
Item->SetPaintWear(Wear);
Item->SetQuality(ITEM_QUALITY_SKIN); //or ITEM_QUALITY_UNUSUAL for knifes/gloves
Item->SetRarity(rarity);
Item->SetOrigin(8);
Item->SetLevel(1);
Item->SetInUse(false);
LocalInventory->AddEconItem(Item, 1, 0, 1);
//Remove key and crate
auto key = LocalInventory->FindKeyToOpen(Crate);
if (key)
{
LocalInventory->RemoveItem(key->GetSOCData());
LocalInventory->RemoveItem(Crate->GetSOCData());
}
kv->InitKeyValues("ScaleformComponent_Inventory_CrateOpened");
kv->SetString("itemid", std::to_string(*Item->GetItemID()).c_str());
}
Код:
C_EconItemView* CPlayerInventory::FindKeyToOpen(C_EconItemView* crate)
{
for (int i = 0; i < this->GetInventoryItems()->GetSize(); i++)
{
auto ProbKey = *(this->GetInventoryItems()->GetMemory().OffsetBufferByIndex(i));
if (ProbKey)
{
if (ProbKey->ToolCanApplyTo(crate))
return ProbKey;
}
}
return nullptr;
}
Код:
bool C_EconItemView::ToolCanApplyTo(C_EconItemView* item)
{
static auto fnToolCanApplyTo = Pattern::FindSignature("client.dll", "55 8B EC 83 EC 18 53 56 8B F1 57 8B FA");
bool ret_val;
__asm
{
mov eax, this
add eax, 0xC
mov ecx, eax
mov eax, item
add eax, 0xC
mov edx, eax
push 0x4
call fnToolCanApplyTo
mov ret_val, al
add esp, 4
};
return ret_val;
}
Код:
struct UnkStruct
{
int ID;
C_EconItemView* item;
int unk;
int unk2;
int unk3;
};
const char* C_EconItemView::GetCrateSeries()
{
auto v15 = (DWORD*)GameUtils::GetItemSchema();
auto v16 = *(DWORD *)(v15[72] + 4 * 68);
static auto Address = Pattern::FindSignature("client.dll", "E8 ? ? ? ? 33 F6 83 C4 04");
static auto fnGetTypedAttributeValue = *reinterpret_cast<uintptr_t*>(Address + 1) + Address + 5;
UnkStruct unk{ 0,this,4,0,0 };
__asm
{
lea eax, [unk]
push eax
mov eax, this
add eax, 0xC
mov ecx, eax
mov edx, v16
call fnGetTypedAttributeValue
add esp, 4
};
static auto fnUnk
= reinterpret_cast<int(__thiscall*)(uintptr_t, int*)>(
Pattern::FindSignature("client.dll", "55 8B EC 8B 45 08 56 57 8B 30 8B 41 10 83 F8 FF 74 1E 8B 79 04 8D 0C 40 8B 54 CF 10 3B D6 7E 05")
);
auto ID = fnUnk((uintptr_t)v15 + 0x17C, &unk.ID);
auto v11 = *(DWORD*)((uintptr_t)v15 + 0x17C + 4) + 24 * ID;
return *reinterpret_cast<const char**>(v11 + 0x14);
}
Код:
CEconItem* C_EconItemView::GetSOCData()
{
static auto fnGetSOCData
= reinterpret_cast<CEconItem*(__thiscall*)(C_EconItemView*)>(
Pattern::FindSignature("client.dll", "55 8B EC 83 E4 F0 83 EC 18 56 8B F1 57 8B 86")
);
return fnGetSOCData(this);
}
Код:
struct WeaponDropInfo
{
int ItemDef;
int Paintkit;
int Rarity;
};
std::vector<WeaponDropInfo> GameUtils::GetWeaponsForCrate(const char* name)
{
std::vector<WeaponDropInfo> drop;
static auto fnGetLootListByName
= reinterpret_cast<uintptr_t(__thiscall*)(uintptr_t, const char*, signed int)>(
Pattern::FindSignature("client.dll", "55 8B EC 8B 45 08 89 45 08 56")
);
auto v2 = fnGetLootListByName(GameUtils::GetItemSchema() + 4, name, 0);
RecursiveAddLootToLootList(v2, drop);
return drop;
}
Код:
void GameUtils::RecursiveAddLootToLootList(uintptr_t v2, std::vector<WeaponDropInfo>& drop)
{
auto size = *(DWORD*)((*(int(__thiscall **)(int))(*(DWORD*)v2 + 4))(v2) + 12);
auto v9 = 0;
auto v8 = 0;
do
{
auto v4 = (DWORD*)(*(int(__thiscall **)(int))(*(DWORD*)v2 + 4))(v2);
auto v5 = v9 + *v4;
if (*(BYTE*)(v5 + 24))
{
static auto fnGetLootListInterfaceByIndex
= reinterpret_cast<uintptr_t(__thiscall*)(uintptr_t, uintptr_t)>(
Pattern::FindSignature("client.dll", "55 8B EC 8B 55 08 56 8B F1 85 D2 78 42 3B 96 ? ? ? ? 7D 3A 3B 96 ? ? ? ? 7F 32 83 FA FF 74 0E 8B 86 ? ? ? ? 6B CA 7C")
);
auto v7 = fnGetLootListInterfaceByIndex(GameUtils::GetItemSchema() + 4, *(DWORD *)v5);
RecursiveAddLootToLootList(v7, drop);
}
else
{
auto paintkit = *reinterpret_cast<int*>(v5 + 0x4);
auto itemdef = *reinterpret_cast<int*>(v5);
if (itemdef != 0)
{
auto set_rarity = std::string(*reinterpret_cast<const char**>(v2 + 0x18));
auto rarity = 0;
if (set_rarity.find("_common") != std::string::npos)
rarity = ITEM_RARITY_COMMON;
else if (set_rarity.find("_uncommon") != std::string::npos)
rarity = ITEM_RARITY_UNCOMMON;
else if (set_rarity.find("_rare") != std::string::npos)
rarity = ITEM_RARITY_RARE;
else if (set_rarity.find("_mythical") != std::string::npos)
rarity = ITEM_RARITY_MYTHICAL;
else if (set_rarity.find("_legendary") != std::string::npos)
rarity = ITEM_RARITY_LEGENDARY;
else if (set_rarity.find("_ancient") != std::string::npos)
rarity = ITEM_RARITY_ANCIENT;
else if (set_rarity.find("_immortal") != std::string::npos)
rarity = ITEM_RARITY_IMMORTAL;
drop.push_back(WeaponDropInfo{ itemdef, paintkit, rarity });
}
}
v9 += 28;
++v8;
} while (v8 < size);
}
KeyValues
Код:
typedef PVOID(__cdecl* oKeyValuesSystem)();
class KeyValues
{
public:
PVOID operator new(size_t iAllocSize)
{
static oKeyValuesSystem KeyValuesSystemFn = (oKeyValuesSystem)GetProcAddress(GetModuleHandle("vstdlib.dll"), "KeyValuesSystem");
auto KeyValuesSystem = KeyValuesSystemFn();
typedef PVOID(__thiscall* oAllocKeyValuesMemory)(PVOID, int);
return call_vfunc<oAllocKeyValuesMemory>(KeyValuesSystem, 1)(KeyValuesSystem, iAllocSize);
}
void operator delete(PVOID pMem)
{
static oKeyValuesSystem KeyValuesSystemFn = (oKeyValuesSystem)GetProcAddress(GetModuleHandle("vstdlib.dll"), "KeyValuesSystem");
auto KeyValuesSystem = KeyValuesSystemFn();
typedef void(__thiscall* oFreeKeyValuesMemory)(PVOID, PVOID);
call_vfunc<oFreeKeyValuesMemory>(KeyValuesSystem, 2)(KeyValuesSystem, pMem);
}
const char* GetName()
{
static oKeyValuesSystem KeyValuesSystemFn = (oKeyValuesSystem)GetProcAddress(GetModuleHandle("vstdlib.dll"), "KeyValuesSystem");
auto KeyValuesSystem = KeyValuesSystemFn();
auto a2 = (DWORD)this;
typedef const char*(__thiscall* oGetName)(PVOID, int);
return call_vfunc<oGetName>(KeyValuesSystem, 4)(KeyValuesSystem, *(BYTE*)(a2 + 3) | (*(WORD*)(a2 + 18) << 8));
}
KeyValues* FindKey(const char *keyName, bool bCreate = false);
void SetString(const char* keyName, const char* value);
void InitKeyValues(const char* name);
void SetUint64(const char* keyName, int value, int value2);
const char* GetString(const char *keyName, const char *defaultValue);
int GetInt(const char *keyName, int defaultValue);
void SetInt(const char *keyName, int Value);
};
Код:
KeyValues* KeyValues::FindKey(const char *keyName, bool bCreate)
{
static auto key_values_find_key = reinterpret_cast<KeyValues*(__thiscall*)(void*, const char*, bool)>(Pattern::FindSignature("client.dll", "55 8B EC 83 EC 1C 53 8B D9 85 DB"));
return key_values_find_key(this, keyName, bCreate);
}
void KeyValues::SetString(const char* keyName, const char* value)
{
auto key = FindKey(keyName, true);
if (key)
{
static auto key_values_set_string = reinterpret_cast<void(__thiscall*)(void*, const char*)>(Pattern::FindSignature("client.dll", "55 8B EC A1 ? ? ? ? 53 56 57 8B F9 8B 08 8B 01"));
key_values_set_string(key, value);
}
}
void KeyValues::InitKeyValues(const char* name)
{
static auto key_values = reinterpret_cast<void(__thiscall*)(void*, const char*)>(Pattern::FindSignature("client.dll", "55 8B EC 51 33 C0 C7 45 ? ? ? ? ? 56 8B F1 81 26 ? ? ? ? C6 46 03 ? 89 46 10 89 46 18 89 46 14 89 46 1C 89 46 04 89 46 08 89 46 0C FF 15 ? ? ? ? 6A 01 FF 75 08 8D 4D FC 8B 10 51 8B C8 FF 52 24 8B 0E 33 4D FC 81 E1 ? ? ? ? 31 0E 88 46 03"));
key_values(this, name);
}
void KeyValues::SetUint64(const char* keyName, int value, int value2)
{
static auto key_values_set_uint64 = reinterpret_cast<void(__thiscall*)(void*, const char*, int, int)>(Pattern::FindSignature("client.dll", "55 8B EC 56 6A 01 FF 75 08"));
key_values_set_uint64(this, keyName, value, value2);
}
const char* KeyValues::GetString(const char *keyName, const char *defaultValue)
{
static auto key_values_get_string = reinterpret_cast<const char*(__thiscall*)(void*, const char*, const char*)>(Pattern::FindSignature("client.dll", "55 8B EC 83 E4 C0 81 EC ? ? ? ? 53 8B 5D 08"));
return key_values_get_string(this, keyName, defaultValue);
}
int KeyValues::GetInt(const char *keyName, int defaultValue)
{
static auto key_values_get_int = reinterpret_cast<int(__thiscall*)(void*, const char*, int)>(Pattern::FindSignature("client.dll", "55 8B EC 6A ? FF 75 08 E8 ? ? ? ? 85 C0 74 45"));
return key_values_get_int(this, keyName, defaultValue);
}
void KeyValues::SetInt(const char *keyName, int Value)
{
auto key_int = FindKey(keyName, true);
if (key_int)
{
*reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(key_int) + 0xC) = Value;
*reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(key_int) + 0x10) = 2;
}
}