Вопрос Не работает inventory changer

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Окт 2022
Сообщения
44
Реакции
0
В общем. Скины добавляются. В меню закупки и в меню игры видно, но в руках скин не отображается
C++:
Expand Collapse Copy
#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");
}


В чем может быть проблема?
 
Последнее редактирование:
Назад
Сверху Снизу