#1 11-05-2012 20:36

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Создание своего буфера в игровой структуре

Пока что тольок задумал способ "добавления" места в структуры фиксированного размера (будь то CPed, или CVehicle).
Пока что думаю сделать так (всё это можно сделать, изменяя игровые процедуры):
1) При создании педа (CPed::CPed) создавать новый буфер, указатель на него записать в структуру. Жертвуем полем структуры в 4 байт.
2) При удалении (CPed::~CPed) удаляем буфер.
3) Поле структуры, которым пожертвовали, теперь "перенести" в созданный буфер, т.е., заменить все ссылки к нему.

В общем, выглядит всё просто, есть ли тут какие-то неполадки, возможные сбои?


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#2 12-05-2012 09:54

Jack Daniel's
Registered: 05-07-2011
Posts: 211

Re: Создание своего буфера в игровой структуре

Да, все просто, но а если игра сама захочет создать/разрушить CPed?

Offline

#3 12-05-2012 11:35

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Создание своего буфера в игровой структуре

Метод, в общем, логичный.
Неиспользуемое поле в CPed - найти не вопрос. Как вариант - использовать поля CPlacement, которые используются только в статических объектах.

Проблема с созданием/удалением объекта решается перехватом конструктора и деструктора (~5 точек)

Offline

#4 15-05-2012 12:41

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

5 раз? Можно ли просто "пропатчить" конструктор и деструктор?


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#5 15-05-2012 13:57

listener
From: Vice City
Registered: 09-11-2006
Posts: 616
Website

Re: Создание своего буфера в игровой структуре

Можно, но это тоже получится не меньше четырех точек (а делать это будет сложнее).
С одной стороны, приятно, что можно ограничиться только CPed (т.е. не нужно трогать CPlayerPed и CEmergencyPed), с дургой стороны, у CPed три конструктора и один деструктор (что и дает нам четыре точки)

Offline

#6 25-05-2012 22:52

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

А чем отличаются эти конструкторы?
И сколько их у CVehicle?

PS речь идёт о классах СА.


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#7 26-05-2012 19:05

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

Вот CLEO-версия grin *извращенец*

{$CLEO}
{
RwMalloc = 0x72F420
RwFree   = 0x72F430
  refs to CPed.field_780 (turretPosMode)
0x5111E4 - mov     ecx, [ebp+780h]  , get
0x5E7EA8 - mov     [esi+780h], edx  , set
}
0AC6: 0@ = label @ctor offset
0AC6: 1@ = label @ctorJmp offset
0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5E812B then_jump 0x5E8131 offset_jump_in_asm 1@
0AC6: 0@ = label @dtor offset
0AC6: 1@ = label @dtorJmp offset
0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5E8656 then_jump 0x5E865F offset_jump_in_asm 1@
0AC6: 0@ = label @field_780_get offset
0AC6: 1@ = label @field_780_getJmp offset
0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5111E4 then_jump 0x5111EA offset_jump_in_asm 1@
0AC6: 0@ = label @field_780_set offset
0AC6: 1@ = label @field_780_setJmp offset
0AB1: call_scm_func @asmdef 4 asm_inj 0@ jump_from 0x5E7EA8 then_jump 0x5E7EAE offset_jump_in_asm 1@
0A93:

:ctor
hex
    89 48 0C 89 48 10
    B8 20 F4 72 00     // mov eax, 0x72F420
    6A 64              // push 0x64
    FF D0              // call eax
    89 30              // mov [eax], esi
    89 86 80 07 00 00  // mov [esi+780h], eax
    83 C4 04           // add esp, 4
end

:ctorJmp
hex
    E9 00 00 00 00
end

:dtor
hex
    83 C4 04
    8B 86 80 07 00 00  // mov eax, [esi+780h]
    85 C0              // test eax, eax
    74 0B              // jz short 0xB
    50                 // push eax
    B8 30 F4 72 00     // mov eax, 0x72F430
    FF D0              // call eax
    83 C4 04           // add esp, 4
    8A 86 77 04 00 00
    A8 01
end

:dtorJmp
hex
    E9 00 00 00 00
end

:field_780_get
hex
    8B 8D 80 07 00 00 // mov ecx, [ebp+780h]
    8B 49 04          // mov ecx, [ecx+4]
end

:field_780_getJmp
hex
    E9 00 00 00 00
end

:field_780_set
hex
    8B B6 80 07 00 00 // mov esi, [esi+780h]
    89 56 04          // mov [esi+4], edx
end

:field_780_setJmp
hex
    E9 00 00 00 00
end


:asmdef
0A8C: write_memory 1@ size 1 value 0xE9 virtual_protect 1
0085: 4@ = 1@
4@ += 5
0062: 0@ -= 4@
1@ += 1
0A8C: write_memory 1@ size 4 value 0@ virtual_protect 1
0085: 4@ = 3@
4@ += 5
0062: 2@ -= 4@
3@ += 1
0A8C: write_memory 3@ size 4 value 2@ virtual_protect 1
0AB2: ret 0

Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#8 19-01-2014 20:30

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

Здравствуйте.
Решил всё это дело перенести в отдельный плугин, правда с изменениями.
Идея такая: выделяем под пул (CVehicle) массив указателей (размер массива - кол-во элементов в пуле). Этот указатель указывает на дополнительные буферы для структуры.
Информация об этих буферах хранится в списке (list).
В конструкторе (CVehicle::CVehicle) проходимся по этим буферам и инициализируем их. В деструкторе - деинициализация.
В общем, получилось такое:

// Переменные
void **vehicleAdditional;
unsigned int vehiclePluginsSize;

struct tStructPluginDesc
{
    unsigned int size;
    unsigned int userId;
    void *constructor;
    void *destructor;
};

list<tStructPluginDesc*>vehiclePlugins;
// Функции
void AllocateAdditionalData()
{
    vehicleAdditional = new void*[(*(CPool<void *> **)0xB74494)->m_Size];
    vehiclePluginsSize = 0;
}

void ReleaseVehicleAdditional()
{
    delete[] vehicleAdditional;
    for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i)
        delete i._Ptr->_Myval;
}

unsigned int plugin::StructPlugins::RegisterVehiclePlugin(unsigned int size, unsigned int userId, void *constructor, void *destructor)
{
    tStructPluginDesc *plugin = new tStructPluginDesc;
    plugin->size = size;
    plugin->userId = userId;
    plugin->constructor = constructor;
    plugin->destructor = destructor;
    vehiclePlugins.push_back(plugin);
    unsigned int result = vehiclePluginsSize;
    vehiclePluginsSize += size;
    return result;
}

void *plugin::StructPlugins::GetVehiclePlugin(CVehicle *vehicle, unsigned int id)
{
    unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18;
    return (void *)((unsigned int)vehicleAdditional[vehicleId] + id);
}

void *FindVehiclePluginByUserId(CVehicle *vehicle, unsigned int userId)
{
    unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18;
    unsigned int size = 0;
    for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i)
    {
        if(i._Ptr->_Myval->userId == userId)
            return (void *)((unsigned int)vehicleAdditional[vehicleId] + size);
        size += i._Ptr->_Myval->size;
    }
    return NULL;
}

void __fastcall OnVehicleConstructor(CVehicle *vehicle)
{
    unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18;
    vehicleAdditional[vehicleId] = new __int8[vehiclePluginsSize];
    unsigned int size = 0;
    for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i)
    {
        ((void (*)(CVehicle *, void *))i._Ptr->_Myval->constructor)(vehicle, (void *)((unsigned int)vehicleAdditional[vehicleId] + size));
        size += i._Ptr->_Myval->size;
    }
};

void __fastcall OnVehicleDestructor(CVehicle *vehicle)
{
    unsigned int vehicleId = ((unsigned int)vehicle - (unsigned int)(*(CPool<void> **)0xB74494)->m_Objects) / 0xA18;
    unsigned int size = 0;
    for(auto i = vehiclePlugins.begin(); i != vehiclePlugins.end(); ++i)
    {
        ((void (*)(CVehicle *, void *))i._Ptr->_Myval->destructor)(vehicle, (void *)((unsigned int)vehicleAdditional[vehicleId] + size));
        size += i._Ptr->_Myval->size;
    }
    delete vehicleAdditional[vehicleId];
};

Ну и использоваться будет примерно так (пример - структура для хранения информации о запасе бензина):

// Регистрация буфера
struct tVehicleGasolineData
{
    float gasolineState;
    float fuelCapacity;
    unsigned int timeLastRefueled;   
};

unsigned int gGasolineDataId;

void VehicleGasolineDataConstructor(CVehicle *vehicle, tVehicleGasolineData *gasoline)
{
    gasoline->gasolineState = 1.0;
    gasoline->fuelCapacity = 1.0;
    gasoline->timeLastRefueled = 0;
}

void VehicleGasolineDataDestructor(CVehicle *vehicle, tVehicleGasolineData *gasoline)
{

}

void RegisterGasolineStruct()
{
    gGasolineDataId = plugin::StructPlugins::RegisterVehiclePlugin(sizeof(tVehicleGasolineData), 0xABCDEF, VehicleGasolineDataConstructor, VehicleGasolineDataDestructor); 
}
//Пример использование буфера
float SetVehicleGasolineState(CVehicle *vehicle, float state)
{
    ((tVehicleGasolineData *)plugin::StructPlugins::GetVehiclePlugin(vehicle, gGasolineDataId))->gasolineState = state;
}

Есть ли замечания по поводу такой реализации?)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#9 02-02-2014 15:14

mfisto
From: Russia Perm
Registered: 01-02-2008
Posts: 558
Website

Re: Создание своего буфера в игровой структуре

Ну наконец-то мечта сбудется, а то я вообще использовал на каждую существующую тачку свой скрипт для хранения значений!


I know everything and nothing...

Offline

#10 02-02-2014 15:33

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

Метод оказался полностью рабочим, я его уже задействовал в ImVehFt:
ky4n.th.png h4b8.th.png a5yv.th.png

Last edited by DK22Pac (02-02-2014 15:34)


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#11 02-02-2014 16:31

mfisto
From: Russia Perm
Registered: 01-02-2008
Posts: 558
Website

Re: Создание своего буфера в игровой структуре

А ты планируешь плагин отдельно выпустить? Было бы здорово!


I know everything and nothing...

Offline

#12 02-02-2014 17:46

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

Да, всё это идёт в отдельной dll.


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#13 02-02-2014 17:52

mfisto
From: Russia Perm
Registered: 01-02-2008
Posts: 558
Website

Re: Создание своего буфера в игровой структуре

Ты имеешь ввиду файл plugin.dll, который появился по-моему в newopcodes.cleo?


I know everything and nothing...

Offline

#14 02-02-2014 20:46

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

mfisto, да.


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#15 03-02-2014 15:00

mfisto
From: Russia Perm
Registered: 01-02-2008
Posts: 558
Website

Re: Создание своего буфера в игровой структуре

Тогда возникает вопрос, как добавить новые ячейки структуры в этом плагине? Или это еще пока не сделано?


I know everything and nothing...

Offline

#16 03-02-2014 16:30

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

Ты подключаешь файлы plugin.dll (хедеры) к себе в проект, и вызываешь функцию регистрации своих "ячеек".


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#17 23-02-2014 05:44

DK22Pac
From: Ukraine
Registered: 26-03-2010
Posts: 447
Website

Re: Создание своего буфера в игровой структуре

Пример с педами. При создании педа выбирается случайное имя, которое позже рисуется на экране.
rev3.png
Не могу прикрепить файл, вот, в общем pedNames.txt


Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Offline

#18 23-02-2014 15:09

Seemann
Registered: 07-08-2006
Posts: 2,155

Re: Создание своего буфера в игровой структуре

Поправил

Offline

Board footer

Powered by FluxBB