You are not logged in.
Пока что тольок задумал способ "добавления" места в структуры фиксированного размера (будь то 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
Да, все просто, но а если игра сама захочет создать/разрушить CPed?
Offline
Метод, в общем, логичный.
Неиспользуемое поле в CPed - найти не вопрос. Как вариант - использовать поля CPlacement, которые используются только в статических объектах.
Проблема с созданием/удалением объекта решается перехватом конструктора и деструктора (~5 точек)
Offline
5 раз? Можно ли просто "пропатчить" конструктор и деструктор?
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Можно, но это тоже получится не меньше четырех точек (а делать это будет сложнее).
С одной стороны, приятно, что можно ограничиться только CPed (т.е. не нужно трогать CPlayerPed и CEmergencyPed), с дургой стороны, у CPed три конструктора и один деструктор (что и дает нам четыре точки)
Offline
А чем отличаются эти конструкторы?
И сколько их у 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
Вот CLEO-версия
*извращенец*
{$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
Здравствуйте.
Решил всё это дело перенести в отдельный плугин, правда с изменениями.
Идея такая: выделяем под пул (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
Метод оказался полностью рабочим, я его уже задействовал в ImVehFt:

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
Да, всё это идёт в отдельной dll.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
mfisto, да.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk
Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv
Offline
Ты подключаешь файлы 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
Пример с педами. При создании педа выбирается случайное имя, которое позже рисуется на экране.
Не могу прикрепить файл, вот, в общем 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
Поправил
Offline