Начинающий
- Статус
- Оффлайн
- Регистрация
- 13 Окт 2022
- Сообщения
- 47
- Реакции
- 0
В общем. Скины добавляются. В меню закупки и в меню игры видно, но в руках скин не отображается
В чем может быть проблема?
C++:
#include <vector>
#include <algorithm>
#include <cstdint>
#include "skinchanger.hpp"
#include <CS2/SDK/SDK.hpp>
#include <CS2/SDK/Interface/IEngineToClient.hpp>
#include <CS2/SDK/Interface/IGameEvent.hpp>
#include <CS2/SDK/Update/CCSGOInput.hpp>
#include <CS2/SDK/FunctionListSDK.hpp>
#include <GameClient/CEntityCache/CEntityCache.hpp>
#include <CS2/SDK/Types/CEntityData.hpp>
#include <CS2/SDK/Cstrike15/CCSPlayerInventory.hpp>
#include <CS2/SDK/Cstrike15/CCSInventoryManager.hpp>
#include <CS2/SDK/Econ/CEconItem.hpp>
#include <CS2/SDK/Econ/CEconItemDefinition.hpp>
#include <CS2/SDK/GCSDK/CGCClientSharedObjectTypeCache.hpp>
#include <CS2/SDK/GCSDK/CGCClientSharedObjectCache.hpp>
#include <CS2/SDK/GCSDK/GCSDKTypes/SOID_t.hpp>
#include <CS2/SDK/GCSDK/GCSDKTypes/EconItemConstants.hpp>
#include <CS2/SDK/GCSDK/GCSDKTypes/ESOCacheEvent.hpp>
enum loadout_slot_t {
LOADOUT_SLOT_C4 = 1,
LOADOUT_SLOT_CLOTHING_APPEARANCE = 46,
LOADOUT_SLOT_CLOTHING_CUSTOMPLAYER = 38,
LOADOUT_SLOT_CLOTHING_EYEWEAR = 42,
LOADOUT_SLOT_CLOTHING_FACEMASK = 40,
LOADOUT_SLOT_CLOTHING_HANDS = 41,
LOADOUT_SLOT_CLOTHING_HAT = 43,
LOADOUT_SLOT_CLOTHING_LOWERBODY = 44,
LOADOUT_SLOT_CLOTHING_TORSO = 45,
LOADOUT_SLOT_COUNT = 57,
LOADOUT_SLOT_EQUIPMENT0 = 32,
LOADOUT_SLOT_EQUIPMENT1 = 33,
LOADOUT_SLOT_EQUIPMENT2 = 34,
LOADOUT_SLOT_EQUIPMENT3 = 35,
LOADOUT_SLOT_EQUIPMENT4 = 36,
LOADOUT_SLOT_EQUIPMENT5 = 37,
LOADOUT_SLOT_FIRST_ALL_CHARACTER = 54,
LOADOUT_SLOT_FIRST_AUTO_BUY_WEAPON = 0,
LOADOUT_SLOT_FIRST_COSMETIC = 41,
LOADOUT_SLOT_FIRST_PRIMARY_WEAPON = 8,
LOADOUT_SLOT_FIRST_WHEEL_EQUIPMENT = 32,
LOADOUT_SLOT_FIRST_WHEEL_GRENADE = 26,
LOADOUT_SLOT_FIRST_WHEEL_WEAPON = 2,
LOADOUT_SLOT_FLAIR0 = 55,
LOADOUT_SLOT_GRENADE0 = 26,
LOADOUT_SLOT_GRENADE1 = 27,
LOADOUT_SLOT_GRENADE2 = 28,
LOADOUT_SLOT_GRENADE3 = 29,
LOADOUT_SLOT_GRENADE4 = 30,
LOADOUT_SLOT_GRENADE5 = 31,
LOADOUT_SLOT_HEAVY0 = 20,
LOADOUT_SLOT_HEAVY1 = 21,
LOADOUT_SLOT_HEAVY2 = 22,
LOADOUT_SLOT_HEAVY3 = 23,
LOADOUT_SLOT_HEAVY4 = 24,
LOADOUT_SLOT_HEAVY5 = 25,
LOADOUT_SLOT_INVALID = 4294967295,
LOADOUT_SLOT_LAST_ALL_CHARACTER = 56,
LOADOUT_SLOT_LAST_AUTO_BUY_WEAPON = 1,
LOADOUT_SLOT_LAST_COSMETIC = 41,
LOADOUT_SLOT_LAST_PRIMARY_WEAPON = 25,
LOADOUT_SLOT_LAST_WHEEL_EQUIPMENT = 37,
LOADOUT_SLOT_LAST_WHEEL_GRENADE = 31,
LOADOUT_SLOT_LAST_WHEEL_WEAPON = 25,
LOADOUT_SLOT_MELEE = 0,
LOADOUT_SLOT_MISC0 = 47,
LOADOUT_SLOT_MISC1 = 48,
LOADOUT_SLOT_MISC2 = 49,
LOADOUT_SLOT_MISC3 = 50,
LOADOUT_SLOT_MISC4 = 51,
LOADOUT_SLOT_MISC5 = 52,
LOADOUT_SLOT_MISC6 = 53,
LOADOUT_SLOT_MUSICKIT = 54,
LOADOUT_SLOT_PET = 39,
LOADOUT_SLOT_PROMOTED = 4294967295,
LOADOUT_SLOT_RIFLE0 = 14,
LOADOUT_SLOT_RIFLE1 = 15,
LOADOUT_SLOT_RIFLE2 = 16,
LOADOUT_SLOT_RIFLE3 = 17,
LOADOUT_SLOT_RIFLE4 = 18,
LOADOUT_SLOT_RIFLE5 = 19,
LOADOUT_SLOT_SECONDARY0 = 2,
LOADOUT_SLOT_SECONDARY1 = 3,
LOADOUT_SLOT_SECONDARY2 = 4,
LOADOUT_SLOT_SECONDARY3 = 5,
LOADOUT_SLOT_SECONDARY4 = 6,
LOADOUT_SLOT_SECONDARY5 = 7,
LOADOUT_SLOT_SMG0 = 8,
LOADOUT_SLOT_SMG1 = 9,
LOADOUT_SLOT_SMG2 = 10,
LOADOUT_SLOT_SMG3 = 11,
LOADOUT_SLOT_SMG4 = 12,
LOADOUT_SLOT_SMG5 = 13,
LOADOUT_SLOT_SPRAY0 = 56
};
class CSharedObject {
public:
virtual ~CSharedObject() = default;
};
#define MAX_PLAYERS 64
constexpr uint32_t hash_32_fnv1a_const(const char* str, uint32_t hash = 0x811C9DC5) {
while (*str) {
hash ^= static_cast<uint32_t>(*str++);
hash *= 0x01000193;
}
return hash;
}
static constexpr auto player_death = hash_32_fnv1a_const("player_death");
static constexpr auto attacker_hash = hash_32_fnv1a_const("attacker");
static constexpr auto userid_hash = hash_32_fnv1a_const("userid");
static constexpr auto weapon_hash = hash_32_fnv1a_const("weapon");
void skin_changer::OnFrameStageNotify(int frameStage)
{
OutputDebugStringA(("[SkinChanger] FrameStage: " + std::to_string(frameStage) + "\n").c_str());
if (frameStage != 6) return;
CCSPlayerInventory* pInventory = CCSPlayerInventory::Get();
if (!pInventory) {
OutputDebugStringA("[SkinChanger] Inventory is null\n");
return;
}
CGameEntitySystem* pEntitySystem = SDK::Interfaces::GameEntitySystem();
if (!pEntitySystem) {
OutputDebugStringA("[SkinChanger] EntitySystem is null\n");
return;
}
const uint64_t steamID = pInventory->GetOwner().m_id;
CCSPlayerController* pLocalController = CGameEntitySystem_GetLocalPlayerController(-1);
if (!pLocalController) {
OutputDebugStringA("[SkinChanger] LocalController is null\n");
return;
}
C_CSPlayerPawn* pLocalPawn = pLocalController->m_hPawn().Get<C_CSPlayerPawn>();
if (!pLocalPawn) {
OutputDebugStringA("[SkinChanger] LocalPawn is null\n");
return;
}
auto pViewModelServices = pLocalPawn->m_pViewModelServices();
if (!pViewModelServices) return;
C_CSGOViewModel* pViewModel = pViewModelServices->m_hViewModel()[0].Get<C_CSGOViewModel>();
if (!pViewModel) return;
int highestIndex = 0;
CGameEntitySystem_GetHighestEntityIndex(pEntitySystem, highestIndex);
for (int i = MAX_PLAYERS + 1; i <= highestIndex; ++i) {
C_BaseEntity* pEntity = reinterpret_cast<C_BaseEntity*>(CGameEntitySystem_GetBaseEntity(pEntitySystem, i));
if (!pEntity || !pEntity->IsBasePlayerWeapon()) continue;
C_CSWeaponBase* pWeapon = reinterpret_cast<C_CSWeaponBase*>(pEntity);
if (pWeapon->GetOriginalOwnerXuid() != steamID) continue;
auto pAttrContainer = pWeapon->m_AttributeManager();
if (!pAttrContainer) continue;
C_EconItemView* pWeaponItemView = pAttrContainer->m_Item();
if (!pWeaponItemView) continue;
CEconItemDefinition* pWeaponDef = pWeaponItemView->GetStaticData();
if (!pWeaponDef) continue;
CGameSceneNode* pWeaponNode = pWeapon->m_pGameSceneNode();
if (!pWeaponNode) continue;
int defIndex = pWeaponItemView->m_iItemDefinitionIndex();
if (defIndex >= 43 && defIndex <= 49) continue;
C_EconItemView* pLoadoutItem = nullptr;
if (pWeaponDef->IsWeapon()) {
for (int i = 0; i <= 56; ++i) {
C_EconItemView* pItemView = pInventory->GetItemInLoadout(pWeapon->m_iOriginalTeamNumber(), i);
if (!pItemView) continue;
if (pItemView->m_iItemDefinitionIndex() == pWeaponDef->m_nDefIndex()) {
pLoadoutItem = pItemView;
break;
}
}
}
else {
pLoadoutItem = pInventory->GetItemInLoadout(pWeapon->m_iOriginalTeamNumber(), pWeaponDef->LoadoutSlot());
}
if (!pLoadoutItem) continue;
if (std::find(g_vecAddedItemsIDs.begin(), g_vecAddedItemsIDs.end(), pLoadoutItem->m_iItemID()) == g_vecAddedItemsIDs.end()) continue;
CEconItemDefinition* pLoadoutDef = pLoadoutItem->GetStaticData();
if (!pLoadoutDef) continue;
const bool isKnife = pLoadoutDef->IsKnife(false);
const bool isGlove = pLoadoutDef->IsGlove(false);
if (!isKnife && pLoadoutDef->m_nDefIndex() != pWeaponDef->m_nDefIndex()) continue;
pWeaponItemView->m_bDisallowSOC() = false;
pWeaponItemView->m_iItemID() = pLoadoutItem->m_iItemID();
pWeaponItemView->m_iItemIDHigh() = pLoadoutItem->m_iItemIDHigh();
pWeaponItemView->m_iItemIDLow() = pLoadoutItem->m_iItemIDLow();
pWeaponItemView->m_iAccountID() = static_cast<uint32_t>(steamID);
if (isKnife) {
pWeaponItemView->m_iItemDefinitionIndex() = pLoadoutDef->m_nDefIndex();
const char* knifeModel = pLoadoutDef->m_pszModelName();
C_BaseModelEntity_SetModel(pWeapon, knifeModel);
if (pViewModel && pViewModel->m_hWeapon().Get() == pWeapon) {
C_BaseModelEntity_SetModel(pViewModel, knifeModel);
}
OutputDebugStringA("[SkinChanger] Knife model applied\n");
}
else if (!isGlove) {
CGameSceneNode_SetMeshGroupMask(pWeaponNode, 1ULL);
if (pViewModel && pViewModel->m_hWeapon().Get() == pWeapon) {
auto vmNode = pViewModel->m_pGameSceneNode();
if (vmNode) CGameSceneNode_SetMeshGroupMask(vmNode, 1ULL);
}
}
}
int gloveSlot = LOADOUT_SLOT_CLOTHING_HANDS;
C_EconItemView* pGloveItem = pInventory->GetItemInLoadout(pLocalPawn->m_iTeamNum(), gloveSlot);
if (!pGloveItem) return;
if (std::find(g_vecAddedItemsIDs.begin(), g_vecAddedItemsIDs.end(), pGloveItem->m_iItemID()) == g_vecAddedItemsIDs.end()) return;
auto pGloveDef = pGloveItem->GetStaticData();
if (!pGloveDef || !pGloveDef->IsGlove(false)) return;
OutputDebugStringA("[SkinChanger] Applying GLOVES\n");
auto& econGloves = pLocalPawn->m_EconGloves();
econGloves.m_iItemID() = pGloveItem->m_iItemID();
econGloves.m_iItemIDHigh() = pGloveItem->m_iItemIDHigh();
econGloves.m_iItemIDLow() = pGloveItem->m_iItemIDLow();
econGloves.m_iAccountID() = static_cast<uint32_t>(steamID);
econGloves.m_iItemDefinitionIndex() = pGloveDef->m_nDefIndex();
econGloves.m_bInitialized() = true;
OutputDebugStringA("[SkinChanger] Glove attributes set, updating network properties\n");
auto pSOCData = pInventory->GetSOCDataForItem(pGloveItem->m_iItemID());
if (pSOCData) {
pInventory->SOUpdated(pInventory->GetOwner(), reinterpret_cast<const CSharedObject*>(pSOCData), GCSDK::eSOCacheEvent_Incremental);
OutputDebugStringA("[SkinChanger] SOC cache updated for gloves\n");
}
OutputDebugStringA("[SkinChanger] FrameStageNotify finished\n");
}
void skin_changer::OnPreFireEvent(IGameEvent* pEvent) {
if (!pEvent) return;
const char* eventName = IGameEvent_GetName(pEvent);
if (!eventName) return;
if (hash_32_fnv1a_const(eventName) != player_death) return;
CCSPlayerController* attacker = IGameEvent_GetPlayerController(pEvent, reinterpret_cast<void*>(attacker_hash));
CCSPlayerController* victim = IGameEvent_GetPlayerController(pEvent, reinterpret_cast<void*>(userid_hash));
if (!attacker || !victim || attacker == victim) return;
CCSPlayerController* localController = CGameEntitySystem_GetLocalPlayerController(-1);
if (!localController || attacker != localController) return;
C_CSPlayerPawn* pLocalPawn = localController->m_hPawn().Get<C_CSPlayerPawn>();
if (!pLocalPawn) return;
auto pWeaponServices = pLocalPawn->m_pWeaponServices();
if (!pWeaponServices) return;
auto pActiveWeapon = pWeaponServices->m_hActiveWeapon().Get<C_CSWeaponBase>();
if (!pActiveWeapon) return;
auto pAttrContainer = pActiveWeapon->m_AttributeManager();
if (!pAttrContainer) return;
auto pWeaponItemView = pAttrContainer->m_Item();
if (!pWeaponItemView) return;
auto pWeaponDefinition = pWeaponItemView->GetStaticData();
if (!pWeaponDefinition || !pWeaponDefinition->IsKnife(true)) return;
auto pWeaponVData = pWeaponItemView->GetBasePlayerWeaponVData();
if (!pWeaponVData) {
OutputDebugStringA("Error: pWeaponVData is null\n");
return;
}
const char* weaponName = pWeaponVData->m_szName();
if (!weaponName) {
OutputDebugStringA("Error: weaponName is null\n");
return;
}
IGameEvent_SetString(pEvent, reinterpret_cast<void*>(weapon_hash), weaponName);
}
void skin_changer::OnEquipItemInLoadout(int team, int slot, uint64_t itemID) {
if (std::find(g_vecAddedItemsIDs.begin(), g_vecAddedItemsIDs.end(), itemID) == g_vecAddedItemsIDs.end())
return;
auto pInventoryManager = CCSInventoryManager_Get();
auto pInventory = CCSPlayerInventory::Get();
if (!pInventoryManager || !pInventory) return;
auto pItemToEquip = pInventory->GetItemViewForItem(itemID);
auto pItemInLoadout = pInventory->GetItemInLoadout(team, slot);
if (!pItemToEquip || !pItemInLoadout) return;
auto pLoadoutDef = pItemInLoadout->GetStaticData();
if (!pLoadoutDef) return;
if (pLoadoutDef->IsGlove(false) || pLoadoutDef->IsKnife(false) ||
pLoadoutDef->m_nDefIndex() == pItemToEquip->m_iItemDefinitionIndex())
return;
uint64_t defaultItemID = (static_cast<uint64_t>(0xF) << 60) | pItemToEquip->m_iItemDefinitionIndex();
CCSInventoryManager_EquipItemInLoadout(pInventoryManager, team, slot, defaultItemID);
}
void skin_changer::OnSetModel(C_BaseModelEntity* pEntity, const char*& model) {
if (!pEntity) return;
auto pViewModel = dynamic_cast<C_BaseViewModel*>(pEntity);
if (!pViewModel || !pViewModel->m_hWeapon().IsValid()) return;
auto pInventory = CCSPlayerInventory::Get();
if (!pInventory) return;
const GCSDK::SOID_t owner = pInventory->GetOwner();
const uint64_t steamID = owner.m_id;
auto pWeapon = pViewModel->m_hWeapon().Get<C_CSWeaponBase>();
if (!pWeapon || !pWeapon->IsBasePlayerWeapon() || pWeapon->GetOriginalOwnerXuid() != steamID)
return;
auto pAttrContainer = pWeapon->m_AttributeManager();
if (!pAttrContainer) return;
auto pWeaponItemView = pAttrContainer->m_Item();
if (!pWeaponItemView) return;
auto pWeaponDefinition = pWeaponItemView->GetStaticData();
if (!pWeaponDefinition) return;
auto pLoadoutItemView = pInventory->GetItemInLoadout(pWeapon->m_iOriginalTeamNumber(), pWeaponDefinition->LoadoutSlot());
if (!pLoadoutItemView) return;
if (std::find(g_vecAddedItemsIDs.begin(), g_vecAddedItemsIDs.end(), pLoadoutItemView->m_iItemID()) == g_vecAddedItemsIDs.end())
return;
auto pLoadoutDef = pLoadoutItemView->GetStaticData();
if (!pLoadoutDef || !pLoadoutDef->IsKnife(true)) return;
model = pLoadoutDef->m_pszModelName();
}
void skin_changer::AddEconItemToList(CEconItem* pItem) {
if (!pItem) return;
g_vecAddedItemsIDs.emplace_back(pItem->m_ulID);
}
void skin_changer::Shutdown() {
auto pInventory = CCSPlayerInventory::Get();
if (!pInventory) return;
for (uint64_t id : g_vecAddedItemsIDs) {
auto pSOCData = pInventory->GetSOCDataForItem(id);
if (!pSOCData) continue;
pInventory->RemoveEconItem(pSOCData);
}
g_vecAddedItemsIDs.clear();
}
void skin_changer::AddSkinOnInject() {
OutputDebugStringA("[SkinChanger] AddSkinOnInject called - Adding Sport Gloves | Vice\n");
auto pInventory = CCSPlayerInventory::Get();
if (!pInventory) {
OutputDebugStringA("[SkinChanger] Inventory is null\n");
return;
}
auto pInventoryManager = CCSInventoryManager_Get();
if (!pInventoryManager) {
OutputDebugStringA("[SkinChanger] InventoryManager is null\n");
return;
}
CEconItem* pNewItem = CEconItem::Create();
if (!pNewItem) {
OutputDebugStringA("[SkinChanger] Failed to create CEconItem\n");
return;
}
pNewItem->m_unDefIndex = 5030; // Спортивные перчи
pNewItem->m_unAccountID = static_cast<uint32_t>(pInventory->GetOwner().m_id);
pNewItem->m_ulID = static_cast<uint64_t>(rand() + 1);
pNewItem->m_unOrigin = 24;
pNewItem->m_nQuality = 3;
pNewItem->m_unLevel = 1;
pNewItem->m_nRarity = 6;
float paintKit = 10048.0f; //vice
float wear = 0.0001f;
float seed = 1.0f;
int stattrak = 0;
pNewItem->SetPaintKit(paintKit);
pNewItem->SetPaintWear(wear);
pNewItem->SetPaintSeed(seed);
pNewItem->SetStatTrak(stattrak);
if (!pInventory->AddEconItem(pNewItem)) {
OutputDebugStringA("[SkinChanger] Failed to add CEconItem to inventory\n");
delete pNewItem;
return;
}
g_vecAddedItemsIDs.push_back(pNewItem->m_ulID);
OutputDebugStringA(("[SkinChanger] Added glove item ID: " + std::to_string(pNewItem->m_ulID) + "\n").c_str());
int gloveSlot = LOADOUT_SLOT_CLOTHING_HANDS;
int teamCT = 3;
int teamT = 2;
if (!CCSInventoryManager_EquipItemInLoadout(pInventoryManager, teamCT, gloveSlot, pNewItem->m_ulID)) {
OutputDebugStringA("[SkinChanger] Failed to equip glove for CT\n");
}
else {
OutputDebugStringA("[SkinChanger] Equipped glove for CT successfully\n");
}
if (!CCSInventoryManager_EquipItemInLoadout(pInventoryManager, teamT, gloveSlot, pNewItem->m_ulID)) {
OutputDebugStringA("[SkinChanger] Failed to equip glove for T\n");
}
else {
OutputDebugStringA("[SkinChanger] Equipped glove for T successfully\n");
}
auto pSOCData = pInventory->GetSOCDataForItem(pNewItem->m_ulID);
if (!pSOCData) {
OutputDebugStringA("[SkinChanger] Failed to get SOC data for glove\n");
}
else {
pInventory->SOUpdated(pInventory->GetOwner(), reinterpret_cast<const CSharedObject*>(pSOCData), GCSDK::eSOCacheEvent_Incremental);
OutputDebugStringA("[SkinChanger] Updated SOC cache for glove\n");
}
OutputDebugStringA("[SkinChanger] added \n");
}
В чем может быть проблема?
Последнее редактирование:

