Автор Тема: Выкладываем наработки по анализу кода, дизассемблированные базы, адреса  (Прочитано 65216 раз)

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 603
  • Репутация: +93/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Добавлю из своего. На дорогах доступен не весь транспорт сразу, а максимум 25 рандомных машин из-за оптимизации. Это приводит к частому повторению на дорогах. Раньше я пытался парковать разные машины по городу, чтобы "взбодрить" этот список. Но можно увеличить 25 до 127 (байтовое ограничение) и выделить новый кусок памяти под расширенный лист. Хотя достаточно и 110, в оригинале 107 машин + 3 свободных слота. Не уверен, почему в коде чаще всего используется удвоенное значение 25 * 2 = 50, возможно лучше тогда поставить значение, кратное 25, например 50 или 100. Я поставил себе 125, чтобы все существующие машины (без типа ignore) могли появляться на дорогах в любое время. Вроде работает, вот адреса, которые нужно пропатчить.

Код: C++
  1. BYTE CarListLimit = 25;                                   // первоначальный лимит
  2. DWORD * CarList;                                          // новый блок памяти
  3.  
  4. template<typename T>void Patch(DWORD Address, T Value) {
  5.         auto Pointer = (T *)Address;
  6.         unsigned long Protect;
  7.         VirtualProtect(Pointer, sizeof(T), PAGE_READWRITE, &Protect);
  8.         * Pointer = Value;
  9.         VirtualProtect(Pointer, sizeof(T), Protect, &Protect);
  10. }
  11.  
  12. // CStreaming_InitChannels
  13.         CarList = new DWORD[CarListLimit * 2];            // 50  0x860F38
  14.         Patch(0x410674, (DWORD)CarList);
  15.         Patch(0x41067C, (DWORD)&CarList[2]);
  16.         Patch(0x410684, (DWORD)&CarList[4]);
  17.         Patch(0x41068C, (DWORD)&CarList[6]);
  18.         Patch(0x410694, (DWORD)&CarList[8]);
  19.         Patch(0x41069D, (BYTE)(CarListLimit * 2));        // 50
  20.         Patch(0x410795, (DWORD)(CarListLimit));           // 25
  21. // CStreaming::AddToLoadedVehiclesList(int)
  22.         Patch(0x408B68, (DWORD)CarList);
  23.         Patch(0x408BA0, (DWORD)CarList);
  24.         Patch(0x408C17, (DWORD)CarList);
  25.         Patch(0x408C51, (DWORD)CarList);
  26.         Patch(0x408B7F, (BYTE)(CarListLimit * 2));        // 50
  27.         Patch(0x408B8F, (BYTE)(CarListLimit * 2));        // 50
  28.         Patch(0x408BD5, (BYTE)(CarListLimit * 2));        // 50
  29.         Patch(0x408BE5, (BYTE)(CarListLimit * 2));        // 50
  30.         Patch(0x408C21, (BYTE)(CarListLimit * 2));        // 50
  31.         Patch(0x408C4D, (BYTE)(CarListLimit * 2));        // 50
  32. // CStreaming::RemoveLoadedVehicle
  33.         Patch(0x408AC8, (DWORD)CarList);
  34.         Patch(0x408B15, (DWORD)CarList);
  35.         Patch(0x408AAF, (BYTE)(CarListLimit * 2));        // 50
  36.         Patch(0x408AC4, (BYTE)(CarListLimit * 2));        // 50
  37. // CStreaming::ProcessLoadingChannel
  38.         Patch(0x40BFC5, (DWORD)CarList);
  39.         Patch(0x40BFCF, (BYTE)(CarListLimit * 2));        // 50
  40. // CRunningScript::ProcessCommands900To999
  41.         Patch(0x45A707, (DWORD)CarList);
  42.         Patch(0x45A753, (BYTE)(CarListLimit * 2));        // 50
  43.         Patch(0x45A761, (BYTE)(CarListLimit * 2));        // 50
  44.  
« Последнее редактирование: Июня 08, 2023, 06:44:41 am от xanser »

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 603
  • Репутация: +93/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Аналогично можно увеличить лимит парковки, на карте изначально 185 парковочных мест. Замечено кстати, что припаркованные машины в зоне видимости могут препятствовать приезду спецслужб в это место. Причем спецтранспорт создается на горизонте, но потом решает развернуться и свалить.

Код: C++
  1. DWORD ParkedLimit = 1000;  // лимит парковки на карте = 185
  2. DWORD ParkedInView = 127;  // лимит парковки в зоне видимости = 10, максимум = 127
  3.  
  4. template<typename T>void Patch(DWORD Address, T Value) {
  5.         auto Pointer = (T *)Address;
  6.         unsigned long Protect;
  7.         VirtualProtect(Pointer, sizeof(T), PAGE_READWRITE, &Protect);
  8.         * Pointer = Value;
  9.         VirtualProtect(Pointer, sizeof(T), Protect, &Protect);
  10. }
  11. struct RwV3d {
  12.     float x, y, z;
  13. };
  14. class CCarGenerator {
  15. public:
  16.     DWORD id;
  17.     RwV3d pos;
  18.     DWORD angle;
  19.     WORD  color1;
  20.     WORD  color2;
  21.     BYTE  forceSpawn;
  22.     BYTE  alarm;
  23.     BYTE  doorLock;
  24.     BYTE  field_1B;
  25.     WORD  minDelay;
  26.     WORD  maxDelay;
  27.     DWORD timeNextGen;
  28.     DWORD ProcessedVehicleHandle;
  29.     WORD  enabled;
  30.     BYTE  field_2A;
  31.     BYTE  field_2B;
  32. };
  33.         CCarGenerator * CarGenerator;                   // новый блок парковки
  34.         CarGenerator = new CCarGenerator[ParkedLimit];  // выделение памяти на 1000 машин
  35. // перенаправление со старого блока на новый
  36.         Patch(0x4537A9, (DWORD)CarGenerator);
  37.         Patch(0x5A6C5F, (DWORD)CarGenerator);
  38.         Patch(0x5A6CC3, (DWORD)CarGenerator);
  39.         Patch(0x5A69DB, (DWORD)CarGenerator);
  40.         Patch(0x5A6B16, (DWORD)CarGenerator);
  41.         Patch(0x5A69E6, (DWORD)&CarGenerator->pos.x);
  42.         Patch(0x5A6B22, (DWORD)&CarGenerator->pos.x);
  43.         Patch(0x5A69F1, (DWORD)&CarGenerator->pos.y);
  44.         Patch(0x5A6B2A, (DWORD)&CarGenerator->pos.y);
  45.         Patch(0x5A69FC, (DWORD)&CarGenerator->pos.z);
  46.         Patch(0x5A6B35, (DWORD)&CarGenerator->pos.z);
  47.         Patch(0x5A6A07, (DWORD)&CarGenerator->angle);
  48.         Patch(0x5A6B40, (DWORD)&CarGenerator->angle);
  49.         Patch(0x5A6A14, (DWORD)&CarGenerator->color1);
  50.         Patch(0x5A6B4C, (DWORD)&CarGenerator->color1);
  51.         Patch(0x5A6A21, (DWORD)&CarGenerator->color2);
  52.         Patch(0x5A6B5C, (DWORD)&CarGenerator->color2);
  53.         Patch(0x5A6A2A, (DWORD)&CarGenerator->forceSpawn);
  54.         Patch(0x5A6B65, (DWORD)&CarGenerator->forceSpawn);
  55.         Patch(0x5A6A33, (DWORD)&CarGenerator->alarm);
  56.         Patch(0x5A6B6E, (DWORD)&CarGenerator->alarm);
  57.         Patch(0x5A6A3C, (DWORD)&CarGenerator->doorLock);
  58.         Patch(0x5A6B77, (DWORD)&CarGenerator->doorLock);
  59.         Patch(0x5A6A49, (DWORD)&CarGenerator->minDelay);
  60.         Patch(0x5A6B85, (DWORD)&CarGenerator->minDelay);
  61.         Patch(0x5A6A56, (DWORD)&CarGenerator->maxDelay);
  62.         Patch(0x5A6B95, (DWORD)&CarGenerator->maxDelay);
  63.         Patch(0x5A6A61, (DWORD)&CarGenerator->timeNextGen);
  64.         Patch(0x5A6BA1, (DWORD)&CarGenerator->timeNextGen);
  65.         Patch(0x5A6A6C, (DWORD)&CarGenerator->ProcessedVehicleHandle);
  66.         Patch(0x5A6BAC, (DWORD)&CarGenerator->ProcessedVehicleHandle);
  67.         Patch(0x5A6A79, (DWORD)&CarGenerator->enabled);
  68.         Patch(0x5A6BB8, (DWORD)&CarGenerator->enabled);
  69.         Patch(0x5A6A85, (DWORD)&CarGenerator->field_2A);
  70.         Patch(0x5A6BC1, (DWORD)&CarGenerator->field_2A);
  71.  
  72.         Patch(0x5A6C16, (DWORD)ParkedLimit);   // перезапись лимита парковки
  73.         Patch(0x5A71D0, (BYTE)ParkedInView);   // перезапись лимита парковки в зоне видимости

Оффлайн daniel_360

  • Прохожий
  • *
  • Сообщений: 124
  • Репутация: +13/-0
    • daniel360465
    • Просмотр профиля
Недавние находки:
Код: Text
  1. 0A8C: write_memory 0x61A695 size 5 value 0x90 virtual_protect 1 // Отключение смещения времени на 6 часов после сохранения

Проверка на то, что актёр сидит:
Код: Text
  1. 0A96: 0@ = actor $PLAYER_ACTOR struct
  2. 000A: 0@ += 0x150
  3. 05E0: 1@ = read_memory 0@ size 1 virtual_protect 1
  4. if
  5. 0039:   1@ == 24 // @ == int
  6. jf @1
« Последнее редактирование: Мая 31, 2025, 09:28:41 pm от daniel_360 »

Оффлайн daniel_360

  • Прохожий
  • *
  • Сообщений: 124
  • Репутация: +13/-0
    • daniel360465
    • Просмотр профиля
Код: Text
  1. 0A8C: write_memory 0x5B8BF7 size 6 value 0x90 virtual_protect 1 // Отключение выдачи брони игроку, при посадке в Enfrocer
  2. 0A8C: write_memory 0x5B8A9A size 6 value 0x90 virtual_protect 1 // Отключение выдачи дробовика игроку, при посадке в Police Car
  3. 0A8C: write_memory 0x5B8BB6 size 6 value 0x90 virtual_protect 1 // Отключение выдачи здоровья игроку, при посадке в Ambulance
  4. 0A8C: write_memory 0x5B8AB6 size 1 value 0x0 virtual_protect 1 // Отключение выдачи денег игроку, при посадке в Taxi, Kaufman, Zebra, Cabbie
  5. 0A8C: write_memory 0x5B89CD size 1 value 0 virtual_protect 1 // Отключение выдачи клюшки для гольфа игроку, при посадке в Caddy
« Последнее редактирование: Мая 31, 2025, 11:27:30 pm от daniel_360 »

Оффлайн daniel_360

  • Прохожий
  • *
  • Сообщений: 124
  • Репутация: +13/-0
    • daniel360465
    • Просмотр профиля
Включение/Выключение фар у машин (не работает на байках и в дневное время):
0 - включить все.
5 - выключить передние.
160 - выключить задние.
189 - выключить все.
Код: Text
  1. 0A97: 4@ = car 3@ struct
  2. 000A: 4@ += 0x2B0 // light status
  3. 0A8C: write_memory 4@ size 1 value 189 virtual_protect 1

Оффлайн daniel_360

  • Прохожий
  • *
  • Сообщений: 124
  • Репутация: +13/-0
    • daniel360465
    • Просмотр профиля
Скрипт, который устраняет баг смены камеры и повышенной скорострельности при использовании опкода 0464: put_actor $2485 into_turret_on_car $2468 at_car_offset 0.4242 -0.0679 1.1322 position 3 angle 270.0 with_weapon 27. Желательно делать в цикле.
Код: Text
  1. :Cam_1
  2. wait 0
  3. 0A8D: 0@ = read_memory 0x7E481C size 1 virtual_protect 1 // 0x7E481C - Current camera mode
  4. if
  5. 8039:   not 0@ == 45 // 45 - Heli-Cannon 1st-Person
  6. jf @Cam_1
  7. 0AA6: call_method 0x46B90D struct 0x7E4688 num_params 3 pop 0 0 0 45 // 0x46B90D - Set weapon mode, 0x7E4688 - Offset CCamera, 45 - Heli-Cannon 1st-Person  
  8. 0A96: 1@ = actor $PLAYER_ACTOR struct
  9. 000A: 1@ += 0x244 // Ped state
  10. 0A8C: write_memory 1@ size 4 value 12 virtual_protect 1 // 12 (0x0C) - first person aiming  
  11. jump @Cam_1

Оффлайн aleks926820

  • Прохожий
  • *
  • Сообщений: 50
  • Репутация: +15/-0
    • Просмотр профиля
0x7838D8 - частота звука двигателя на последней передаче.
За звук двигателя отвечает функция cAudioManager::ProcessPlayersVehicleEngine.
Кусок дизассемблированного кода из базы для вайса версии 1.0:
v30 = 27 * dword_7838D8 + v48 + 22050; -- расчет окончательной частоты звука для последней передачи.
...
cAudioManager::AddPlayerCarSample(120, v30, v24 + 384, v51, 64, 1)-- воспроизведение звука (?)

К слову AddPlayerCarSample вызывается 4 раза в разных местах функции, видимо это сделано для реализации звука двигателя для разных ситуаций (предположительно!) по типу разгона, остановки, пробуксовки на месте или в воздухе. Если наладить чтение частоты из регистра edi, то можно использовать значение для создания тахометра.
« Последнее редактирование: Июня 23, 2025, 05:06:08 am от aleks926820 »