Получение Текстуры Объекта

Anti...

Участник
Автор темы
242
18
Версия MoonLoader
.026-beta
Здраствуйте, искал по всему форуму, не нашёл, или слепой.

У меня цель получить название текстуры самповского объекта по его id.
На объект может быть наложена текстура другого объекта со стороны сервера, её мне нужно получить.

image_2024-02-28_12-19-52.png

Ну вот, например, объект АК47 (модель 355) могу наложить на него в Texture Studio цвет и текстуру, цвет я получаю следующим способом, но КАК же мне получить название текстуры?:

Получение цвета объекта:
function sampGetObjectMaterialColor(id, slot)
        local CNetGame = ffi.cast("uintptr_t*", samp + 0x21A0F8)
        local objectPool = ffi.cast("int(__thiscall*)(void*)", samp + 0x2E00)(ffi.cast("void*", CNetGame[0]))
        local CObject = ffi.cast("int(__thiscall*)(void*, int)", samp + 0x2DD0)(ffi.cast("void*", objectPool), id)
        local m_color = ffi.cast("uint32_t*", CObject + 0x217 + 0x40 + slot * 0x4)[0]
   
        print(m_color) -- u32 Потом конвентировать и получится в формате 0xFFffffff
end

Обращался за помощью к разным людям, которые вроде в этом деле шарят, но детали мне не раскрыли, или просто я тупой не понял (так и есть, эту хуйню я не понимаю).
Есть вот такие зацепки:
Накладывание текстуры объекту - https://www.blast.hk/threads/13380/post-1339311
Рендер модели в текстуру - https://www.blast.hk/threads/13380/post-996590

Спрашивал у kin4stat, ответил:

1709249844012.png


Но так как я тупой, я не понял как это юзать и сделал вот так:
Lua:
ffi.cdef([[
    typedef unsigned long D3DCOLOR;
    typedef int BOOL;
    typedef unsigned short ID;

    struct RwLLLink {
        struct RwLLLink *next;
        struct RwLLLink *prev;
    };

    typedef struct RwTexture RwTexture;
    struct RwTexture {
        void *raster;
        void *dict;
        struct RwLLLink lInDictionary;
        char name[32];
        char mask[32];
        unsigned filterAddressing;
        int refCount;
    };

    struct CSprite2d {
        RwTexture *m_pTexture;
    };

    typedef struct ObjectMaterial ObjectMaterial;
    struct ObjectMaterial {
        struct CSprite2d* m_pSprite[16];
    };

    typedef struct CObject CObject;
    struct CObject {
        ObjectMaterial m_material;
    };

]]);

local CObjectPool = ffi.cast('int(__thiscall*)(void*)', samp + 0x2E00)
local CObject = ffi.cast('CObject*(__thiscall*)(void*, int)', samp + 0x2DD0)

function getObjectMaterialTexture(objectId)
    local CNetGame = ffi.cast('uintptr_t*', samp + 0x21A0F8)
    local objectPool = CObjectPool(ffi.cast('void*', CNetGame[0]))
    local cobject = CObject(ffi.cast('void*', objectPool), tonumber(objectId))

    if cobject.m_material.m_pSprite ~= nil then
        for i = 0, 15 do
            local sprite = cobject.m_material.m_pSprite[i]
            if sprite ~= nil and sprite.m_pTexture ~= nil then
                local textureName = ffi.string(sprite.m_pTexture.name)
                print("Texture name " .. objectId .. ": " .. textureName)
                return textureName
            end
        end
    end
return nil
end

А выводит непонятно что: [ML] (script) test2.lua: Texture name 1: èý
 
Последнее редактирование:
Решение
Как это склепать? Я в этих структурах и указателях не понимаю 😅 Для меня это что-то новое в луа
Сделал за тебя. Вроде как структуры идентичны на всех версиях сампа то что будет работать на любой. Тестил на R3. И как ты мне писал это нужно для рендера. Значит функция скорее всего будет использоваться для всех объектов каждый кадр и возможно не раз. Поэтому оптимизировал отбросив всё лишнее
Lua:
local memory = require 'memory'
local object_pool = sampGetObjectPoolPtr()

function sampgetObjectTextureName(id, slot)
    if memory.getuint32(object_pool + 0x4 + id * 0x4) ~= 0 then
        local material = memory.getuint32(memory.getuint32(object_pool + 0xFA4 + id * 0x4) + 0x217 + slot * 0x4)
        if material ~= 0 then...

Tema05

Известный
1,429
396
Здраствуйте, искал по всему форуму, не нашёл, или слепой.

У меня цель получить название текстуры самповского объекта по его id.
На объект может быть наложена текстура другого объекта со стороны сервера, её мне нужно получить.

Посмотреть вложение 233351
Ну вот, например, объект АК47 (модель 355) могу наложить на него в Texture Studio цвет и текстуру, цвет я получаю следующим способом, но КАК же мне получить название текстуры?:

Получение цвета объекта:
function sampGetObjectMaterialColor(id, slot)
        local CNetGame = ffi.cast("uintptr_t*", samp + 0x21A0F8)
        local objectPool = ffi.cast("int(__thiscall*)(void*)", samp + 0x2E00)(ffi.cast("void*", CNetGame[0]))
        local CObject = ffi.cast("int(__thiscall*)(void*, int)", samp + 0x2DD0)(ffi.cast("void*", objectPool), id)
        local m_color = ffi.cast("uint32_t*", CObject + 0x217 + 0x40 + slot * 0x4)[0]
 
        print(m_color) -- u32 Потом конвентировать и получится в формате 0xFFffffff
end

Обращался за помощью к разным людям, которые вроде в этом деле шарят, но детали мне не раскрыли, или просто я тупой не понял (так и есть, эту хуйню я не понимаю).



Спрашивал у kin4stat, ответил:

Посмотреть вложение 233352

Но так как я тупой, я не понял как это юзать и сделал вот так:
Lua:
ffi.cdef([[
    typedef unsigned long D3DCOLOR;
    typedef int BOOL;
    typedef unsigned short ID;

    struct RwLLLink {
        struct RwLLLink *next;
        struct RwLLLink *prev;
    };

    typedef struct RwTexture RwTexture;
    struct RwTexture {
        void *raster;
        void *dict;
        struct RwLLLink lInDictionary;
        char name[32];
        char mask[32];
        unsigned filterAddressing;
        int refCount;
    };

    struct CSprite2d {
        RwTexture *m_pTexture;
    };

    typedef struct ObjectMaterial ObjectMaterial;
    struct ObjectMaterial {
        struct CSprite2d* m_pSprite[16];
    };

    typedef struct CObject CObject;
    struct CObject {
        ObjectMaterial m_material;
    };

]]);

local CObjectPool = ffi.cast('int(__thiscall*)(void*)', samp + 0x2E00)
local CObject = ffi.cast('CObject*(__thiscall*)(void*, int)', samp + 0x2DD0)

function getObjectMaterialTexture(objectId)
    local CNetGame = ffi.cast('uintptr_t*', samp + 0x21A0F8)
    local objectPool = CObjectPool(ffi.cast('void*', CNetGame[0]))
    local cobject = CObject(ffi.cast('void*', objectPool), tonumber(objectId))

    if cobject.m_material.m_pSprite ~= nil then
        for i = 0, 15 do
            local sprite = cobject.m_material.m_pSprite[i]
            if sprite ~= nil and sprite.m_pTexture ~= nil then
                local textureName = ffi.string(sprite.m_pTexture.name)
                print("Texture name " .. objectId .. ": " .. textureName)
                return textureName
            end
        end
    end
return nil
end

А выводит непонятно что: [ML] (script) test2.lua: Texture name 1: èý
Так у тебя структура CObject состоит только из 1 поля ObjectMaterial. А структура ObjectMaterial внутри CObject не по 0 оффсету находится.
Также ты походу структуры из разных мест слепил. У тебя выходит что m_pSprite это указатель на структуру с указателем m_pTexture.
Код:
union {
    struct CSprite2d* m_pSprite[16];
    struct RwTexture* m_pTextBackground[16];
};
Хотя судя по объединению union в полной структуре ObjectMaterial они должны указывать на одно и то же. По крайней мере если использовать RwTexture вместо CSprite2d поле name как раз содержит имя текстуры.
Screenshot_13.png
 
Последнее редактирование:
  • Нравится
  • Вау
Реакции: Anti... и why ega

Anti...

Участник
Автор темы
242
18
Так у тебя структура CObject состоит только из 1 поля ObjectMaterial. А структура ObjectMaterial внутри CObject не по 0 оффсету находится.
Также ты походу структуры из разных мест слепил. У тебя выходит что m_pSprite это указатель на структуру с указателем m_pTexture.
Код:
union {
    struct CSprite2d* m_pSprite[16];
    struct RwTexture* m_pTextBackground[16];
};
Хотя судя по объединению union в полной структуре ObjectMaterial они должны указывать на одно и то же. По крайней мере если использовать RwTexture вместо CSprite2d поле name как раз содержит имя текстуры.
Посмотреть вложение 233358
Как это склепать? Я в этих структурах и указателях не понимаю 😅 Для меня это что-то новое в луа
 

Tema05

Известный
1,429
396
Как это склепать? Я в этих структурах и указателях не понимаю 😅 Для меня это что-то новое в луа
Сделал за тебя. Вроде как структуры идентичны на всех версиях сампа то что будет работать на любой. Тестил на R3. И как ты мне писал это нужно для рендера. Значит функция скорее всего будет использоваться для всех объектов каждый кадр и возможно не раз. Поэтому оптимизировал отбросив всё лишнее
Lua:
local memory = require 'memory'
local object_pool = sampGetObjectPoolPtr()

function sampgetObjectTextureName(id, slot)
    if memory.getuint32(object_pool + 0x4 + id * 0x4) ~= 0 then
        local material = memory.getuint32(memory.getuint32(object_pool + 0xFA4 + id * 0x4) + 0x217 + slot * 0x4)
        if material ~= 0 then
            return true, memory.tostring(material + 0x10, 32)
        end
    end

    return false
end

local result, name = sampgetObjectTextureName(0, 0)
Тебе вроде ещё цвет нужен был. Не тестил но должно быть так
Lua:
function sampgetObjectMaterialColor(id, slot)
    if memory.getuint32(object_pool + 0x4 + id * 0x4) ~= 0 then
        return true, memory.getuint32(memory.getuint32(object_pool + 0xFA4 + id * 0x4) + 0x257 + slot * 0x4)
    end

    return false
end
 
Последнее редактирование:
  • Вау
Реакции: Anti...

andrewtomik123

Новичок
17
0
Сделал за тебя. Вроде как структуры идентичны на всех версиях сампа то что будет работать на любой. Тестил на R3. И как ты мне писал это нужно для рендера. Значит функция скорее всего будет использоваться для всех объектов каждый кадр и возможно не раз. Поэтому оптимизировал отбросив всё лишнее
Lua:
local memory = require 'memory'
local object_pool = sampGetObjectPoolPtr()

function sampgetObjectTextureName(id, slot)
    if memory.getuint32(object_pool + 0x4 + id * 0x4) ~= 0 then
        local material = memory.getuint32(memory.getuint32(object_pool + 0xFA4 + id * 0x4) + 0x217 + slot * 0x4)
        if material ~= 0 then
            return true, memory.tostring(material + 0x10, 32)
        end
    end

    return false
end

local result, name = sampgetObjectTextureName(0, 0)
Тебе вроде ещё цвет нужен был. Не тестил но должно быть так
Lua:
function sampgetObjectMaterialColor(id, slot)
    if memory.getuint32(object_pool + 0x4 + id * 0x4) ~= 0 then
        return true, memory.getuint32(memory.getuint32(object_pool + 0xFA4 + id * 0x4) + 0x257 + slot * 0x4)
    end

    return false
end
глянь пожалуйста лс