Перейти к содержанию

Спавн машины


Рекомендуемые сообщения

Хочу сделать спавн машины в гта 3, это возможно?

У меня пока что только такая идея - найти ид машины которая стоит в гараже, поставить бряк на доступ?

Ссылка на комментарий
Поделиться на другие сайты

Это возможно, это совершенно точно. Но решения у меня нет, т.к. я этим читом не занимался. Могу дать только подсказки.

Решение твой задачи может быть очень даже непростым делом. По поводу идеи, даже если ты найдёшь адрес некоторого ID (кстати непонятно какого так как их, скорее всего, может быть несколько у машины), то скорее это не прокатит, т.к. ты не разберёшься с рутиной дизассемблерного кода.

1. Способ.

Насколько я помню, у игры есть читы чтобы получить ту или иную машину. Поэтому есть вариант проследить в отладке как это происходит. Здесь уже должен быть некоторый участок кода, который обрабатывает ввод от пользователя. Можно определить этот ввод в отладчике (как делать объяснять не буду, это долго) и выйти на нужный код, который создаёт машину. Главное добраться до этого кода, а там уже можно что-нибудь придумать.

2. Способ.

Могу предположить с большой вероятностью, что создание того или иного объекта в этой игре зависит от данных - сценариев (некоторого формата в оперативной памяти подгружаемых при начале уровня) и кода обрабатывающий эти сценарии (некоторые сценарии должны постоянно обрабатываться на истинность тех или иных условий)... Если в некотором сценарии для уровня будет директива "создать такую-то тачку по таким-то координатам после того как произойдёт что-то", то код "создаст такую-то тачку". Понять весь этот процесс возможно будет довольно тяжело. У тебя должно быть как минимум два сложных пути создания спавна. Изменить сценарий в памяти или изменить машинный код обработки сценариев. Что будет сложнее это уже зависит от игры. Изменив сценарий это ещё не значит, что его часть поступит на обработку, поэтому сценарий надо менять определённым образом (я без понятия каким). Оба способа должны вывести на функцию принимающую аргументы создания того или иного объекта в игре по тем или иным параметрам. Эту функцию предположительно надо чётко выполнить и тачка должна появиться.

Конечно, я не знаю как в этой игре всё на самом деле, но в своих предположениях я опирался на логику разработки игры. Если в игре что-то должно происходить, то это гораздо легче описывается сценариями и эти сценарии должны обрабатываться с вызовом функций.

Ссылка на комментарий
Поделиться на другие сайты

Машины в ГТА 3 - это объекты, которые, если ездят по улицам, принадлежат глобальному объекту игрового мира. Если на них едет игрок - машина принадлежит объекту игрока. Если же машина стоит в гараже - она принадлежит гаражу, который, в свою очередь, принадлежит миру. То есть, для того, чтобы заспавнить машину в каком-либо из гаражей, нужно сначала найти все объекты/структуры гаражей, затем найти структуру того гаража, рядом с которым ты находишься, затем только уже в этой структуре искать меняющийся ID машины, которые ты будешь туда попеременно загонять. В каком-то из старых трейнеров точно была фишка добавления машины в любой из гаражей. Следовательно, сделать это можно. Более простой способ, как описал MasterGH - изучать под отладкой, что происходит при вызове чита спавна машины.

Ссылка на комментарий
Поделиться на другие сайты

Xipho

ID машины в гараже нашел, а процедуру вызова машины по координатам нельзя из этого сделать?

Нельзя. Этот ID уже появился. Конструктор (инструкции машинного кода) уже создал этот ID. Конструктор для этого ID уже отработал своё и более работать не будет. По этому ID ты не выйдешь на конструктор поставив бряк.

Чтобы сделать чит надо быть серьёзным реверсером - программистом с багажом практики у которого есть время копаться в этом.

Ссылка на комментарий
Поделиться на другие сайты

Не факт. Если этот ID в разные загрузки игры один и тот же, возможно, это не дескриптор уже созданного объекта, а как бы одна из характеристик (модель машины). Тут может быть два варианта, если это ID заполняется один раз при создании объекта машины - тогда да, это сложно сделать, но, опять таки, исследуя код, реализующий встроенный в игру чит спавна машины, можно выйти на конструктор этого объекта и прореверсить передаваемые ему параметры. Я склоняюсь к тому, что именно этот подход применен, ибо он наиболее логичен. Второй вариант - при каждом обращении к объекту считывается его ID и подставляется нужная модель машины. В этом случае можно ID просто подменить, но таков подход не оптимален для быстродействия, следовательно, он наименее вероятен.

Ссылка на комментарий
Поделиться на другие сайты

C бОльшей уверенностью скажу что 2 Способ от MasterGH верный

PS Если найду исходники моего давнего трейнера для GTA IV выложу тут, спавн тачек присутствует :)

Ссылка на комментарий
Поделиться на другие сайты

Трейнер я так понимаю будет лучше делать на LUAEnigne?

Не увидел этот вопрос... Это уже второстепенный вопрос. Сначала надо понять что нужно реализовать, а затем уже думать на чём делать. Так что такой вопрос задавать без исследования рано. Возможно и на АА сделать можно.

Не факт. Если этот ID в разные загрузки игры один и тот же, возможно, это не дескриптор уже созданного объекта, а как бы одна из характеристик (модель машины). Тут может быть два варианта, если это ID заполняется один раз при создании объекта машины - тогда да, это сложно сделать, но, опять таки, исследуя код, реализующий встроенный в игру чит спавна машины, можно выйти на конструктор этого объекта и прореверсить передаваемые ему параметры. Я склоняюсь к тому, что именно этот подход применен, ибо он наиболее логичен. Второй вариант - при каждом обращении к объекту считывается его ID и подставляется нужная модель машины.

Я думаю ты запутался :) Вот попробуй найти указатель на машину, когда герой в неё садиться и выходит. Сесть в другую машину, чтобы найти указатель другой машины. Сравнивать структуры машин в поисках ID. Затем если найдёшь эти ID и поставишь бряк на доступ, то на конструктор ты не выйдешь, даже если поднимешься до корневого элемента в дереве вызовов...

C бОльшей уверенностью скажу что 2 Способ от MasterGH верный

PS Если найду исходники моего давнего трейнера для GTA IV выложу тут, спавн тачек присутствует :)

Когда найдёшь и покажешь, тогда тебе и поверим... иначе всё останется туманной теорией :)

Ссылка на комментарий
Поделиться на другие сайты

Не не не )) Я ж написал про анализ реализации встроенного в игру чита спавна машины )) Я считаю, что этот чит как раз таки вызывает конструктор машины, передавая в него параметром ID модели машины, ведь это наиболее логичный вариант, не так ли? )))

Ссылка на комментарий
Поделиться на другие сайты

Ну, в принципе, это может быть и название модели. Хотя, скорее, какой-то краткий идентификатор модели, по которому при ее создании считываются характеристики из файлов игры типа handling.cfg.

К примеру,

class Car {
int weight;
int handlingfactor;
int maxspeed;
public Car (int modelid){
this.weight = GetInfoFromFile(handling.cfg);
this.handlingfactor = GetInfoFromFile(handling.cfg);
this.maxspeed = GetInfoFromFile(handling.cfg);
}
}

Ясное дело, пример сильно утрирован, ибо на практике и методов и параметров будет гораздо больше, да и класс сам, возможно, будет дочерним, скажем к классу Vehicle (транспортное средство), ведь может быть еще и велосипед, и мотоцикл. Поскольку разными читами вызывается один и тот же конструктор, но в итоге даются разные машины в зависимости от введенного чита, я думаю, такой подход вполне логичен. Впрочем, у меня нет под рукой игры, чтобы проверить свои догадки.

Ссылка на комментарий
Поделиться на другие сайты

Ну, вот ещё информация. Поискал я ответы в Интернете и нашёл. Просто я знал, что моддинг к GTA очень развивается...

На странице SVN "проекта по созданию модов" есть функция создания машины.

Ссылка для скачивания для клиента SVN:

http://gta4modding.googlecode.com/svn/trunk/

static void CreateCar(u32 nameHash, f32 x, f32 y, f32 z, Vehicle *pVehicle, b8 unknownTrue) { 

NativeInvoke::Invoke<scriptVoid>("CREATE_CAR", nameHash, x, y, z, pVehicle, unknownTrue);
}

Эта функция как и другие, как очевидно, используются для модинга.

Ну и ещё есть одна:

static void GetCarModel(Vehicle vehicle, eModel *pValue) { 
NativeInvoke::Invoke<NATIVE_GET_CAR_MODEL, ScriptVoid>(vehicle, pValue);
}

Разберёмся, что требуется для создания машины и как работает GetCarModel. Т.е. мы разберём технологию спавна "на поверхности", но не так глубоко как хотелось бы. Пока мне не понятно как эта инфа была кем-то сотсавлена и изучена. Одно понятно, что этот человек действительно Гуру создания модов, а читов и подавно. Могу его только сильно уважать. Его никнейм Aru.

Все машины в первую очередь создаются по скриптам(на самом деле это что-то вроде своего языка программирования в опкодах), а затем уже машинным кодом.

Вот пример из GTAIV создания машины, скрипт декомпилирован из особых опкодов(составленных разработчиками игр) в текстовый формат:

.native HAS_MODEL_LOADED // in=1, out=1
.iftrue
PushD 8
Var
RefGet
PushD 9
Var
PushD 0
Add
RefGet
PushD 9
Var
PushD 4
Add
RefGet
PushD 9
Var
PushD 8
Add
RefGet
PushD 23
LocalVar
PushD 1
.native CREATE_CAR // in=6, out=0

Вот более понятный вид,но уже из Санд-Андреас:

Загружаем модель машины, проверяем что она загрузилась, размещаем модель в игре:

:Createcar
wait 0
Model.Load(#SULTAN)

:Createcar_3
wait 100
if
Model.Available(#SULTAN).
jf @Createcar_3
$9 = Car.Create(#SULTAN, 2488.917, -1658.0735, 13.3549)
0229: set_car $9 color_to 31 0

Функции ниже это обвертки C++ или Паскальные:

Разберём параметры функций (источник "Seemann")

static void GetCarModel(Vehicle vehicle, eModel *pValue) { 
NativeInvoke::Invoke<NATIVE_GET_CAR_MODEL, ScriptVoid>(vehicle, pValue);
}

//Vehicle vehicle : хендл машины
//eModel *pValue : переменная-приемник, куда будет записано ID модели.

значения параметров косвенно можно определить по названию функции. Если функция называется GetCarModel (в переводе получить модель машины), значит должно быть как минимум 2 параметра:

1. хендл машины и

2. переменная-приемник, куда будет записано ID модели.

Хендл машины - это переменная с ее "именем", позволяющим отличить от другой машины. Хендл получается как раз из следующей функции:

CreateCar. Её параметры можно понять по названию:

static void CreateCar(u32 nameHash, f32 x, f32 y, f32 z, Vehicle *pVehicle, b8 unknownTrue) { 

NativeInvoke::Invoke<scriptVoid>("CREATE_CAR", nameHash, x, y, z, pVehicle, unknownTrue);
}

//u32 nameHash : хэш имени модели (http://www.gtamodding.com/index.php?title=List_of_models_hashes), например Например, для

//AMBULANCE хэш равен 1171614426 или 0x45D56ADA
//f32 x, f32 y, f32 z : это координаты места, где будет создана машина. Например, 100.10 -986.12 55.0
//Vehicle *pVehicle : Переменная с типом Vehicle, в которую будет записан хендл созданной машины (см. выше)
//b8 unknownTrue : Неизвестный параметр. В оригинальных скриптах всегда равен 1 или True.

Пример вызова функций на Паскале:


var
_mycar:Vehicle;
_mymodel: u32;

CreateCar(1171614426, 100.10, -986.12, 55.0, _mycar, true);

Можно догадаться чему будет равен результат теперь:

GetCarModel(_mycar; _mymodel);

Более подробно как я уже писал смотрим:

GTAModding.ru Wiki - ссылка

обсуждение вопроса создания машины (там в основном Паскаль): ссылка

хеши (или уникальные ID) моделей: здесь

------------

Вопрос о том можно ли подобное создать на Cheat Engine. Ответ да, можно... Есть сложные пути, а есть и простые. О сложных путях было написано уже до этого поста. А простой путь это найти необходииые Lua- модули с описанием CreateCar. Вызывать эту функцию из LUA-Engine...

-------------

А вот пример, от самого Aru (там есть и спавн машины и другие читы:)


#include "Scripting.h"
#include "../ScriptHook/Log.h"

#include <windows.h>

// Pull in all our scripting functions/types
using namespace Scripting;

CustomFiberThread::CustomFiberThread()
{
// Give your own name here!
SetName("CustomFiberThread");
}

// Some helper functions

Player CustomFiberThread::GetPlayer()
{
Player playerIndex = ConvertIntToPlayerIndex(GetPlayerId());
return playerIndex;
}

Scripting::Ped CustomFiberThread::GetPlayerPed()
{
Ped ped;
GetPlayerChar(GetPlayer(), &ped);
return ped;
}


void CustomFiberThread::SpawnCar(eModel model)
{
RequestModel(model);

while(!HasModelLoaded(model))
{
Wait(0);
}

LogInfo("Car model available... spawning it!");

Ped ped = GetPlayerPed();

Vehicle vehicle;
f32 x,y,z;

GetCharCoordinates(ped, &x, &y, &z);

CreateCar(model, x, y, z, &vehicle, true);

MarkModelAsNoLongerNeeded(model);

}

void CustomFiberThread::ChangePlayerSkin(eModel model)
{
RequestModel(model);

while(!HasModelLoaded(model))
{
Wait(0);
}

LogInfo("Skin model available... spawning it!");

eInteriorRoomKey roomKey;

GetKeyForCharInRoom(GetPlayerPed(), &roomKey);

ChangePlayerModel(GetPlayer(), model);

SetRoomForCharByKey(GetPlayerPed(), roomKey);

MarkModelAsNoLongerNeeded(model);

}

void CustomFiberThread::TeleportToWaypoint(Scripting::Ped &ped)
{
Blip b = GetFirstBlipInfoId(BLIP_WAYPOINT);
if(b.IsValid())
{
Vector3 v;
GetBlipCoords(b, &v);

LogInfo("Teleporting to %f, %f", v.X, v.Y);

// Thanks to Prince-Link for this magical Z coord detection code...
SetCharCoordinates(ped, v.X, v.Y, v.Z);
while(v.Z == 0.0f) // The chance that ground Z is 0.0 _exactly_ is really small
{
GetGroundZFor3DCoord(v.X, v.Y, 1000, &v.Z);
Wait(0);
}

SetCharCoordinates(ped, v.X, v.Y, v.Z);
}
else
{
LogError("No way point found to teleport to.");
}

}


// The real script

void CustomFiberThread::RunScript()
{
// This is a fiber thread, so we use an loop to run the contents of this script.
// The thread will terminate when we return from this function.

while(IsThreadAlive())
{

if ((GetAsyncKeyState(VK_F4) & 1) != 0)
{
LogInfo("Teleporting player to way point");

TeleportToWaypoint( GetPlayerPed() );
}
else if ((GetAsyncKeyState(VK_F5) & 1) != 0)
{
LogInfo("Spawning a random car");

Vehicle vehicle;
u32 modelHash;
ScriptAny unknown;

f32 x,y,z;
GetCharCoordinates(GetPlayerPed(), &x, &y, &z);

GetRandomCarModelInMemory(1, &modelHash, &unknown);
CreateCar(modelHash, x, y, z, &vehicle, true);
}
else if ((GetAsyncKeyState(VK_F6) & 1) != 0)
{
LogInfo("Granting player $1000");

AddScore(GetPlayer(), 1000);
}
else if ((GetAsyncKeyState(VK_F7) & 1) != 0)
{
LogInfo("Requested a MODEL_BANSHEE spawn");

SpawnCar(MODEL_BANSHEE);
}
else if ((GetAsyncKeyState(VK_F8) & 1) != 0)
{
LogInfo("Changing the player skin");

ChangePlayerSkin(MODEL_IG_JOHNNYBIKER);
}
else if ((GetAsyncKeyState(VK_F9) & 1) != 0)
{
LogInfo("Changing the player skin back to Niko's");

ChangePlayerSkin(MODEL_PLAYER);
}

// Call Wait() so we can process other scripts/game code
// You must call Wait(...) in your loop code for a fiber thread!
Wait(100);

}


}

#include "CustomFiberThread.h"

Данный код компилируется в модуль dll. При аттаче этого модуля к процессу игры (можно сделать и с помощью Cheat Engine), можно активировать hot-keys и тем самым включать читы. Для спавна машины надо нажать F7. Скрипты Aru можно найти в Интернете.


{
RequestModel(model); // создать модель машины, укажите model - машины, например MODEL_BANSHEE, другие модели ищите в исходниках Aru
while(!HasModelLoaded(model)) // дождаться когда модель инициализируется
{
Wait(0);
}
LogInfo("Car model available... spawning it!"); // лог
Ped ped = GetPlayerPed(); // получить описатель главного героя

Vehicle vehicle; // создать какой-то описатель
f32 x,y,z; // координаты

GetCharCoordinates(ped, &x, &y, &z); // получить координаты героя
CreateCar(model, x, y, z, &vehicle, true); // создать машину и возвратить vehicle, если он пригодиться позже
MarkModelAsNoLongerNeeded(model); // с моделью машины уже отработали, надо её отметить как ненужную
}
void CustomFiberThread::SpawnCar(eModel model)

Ссылка на комментарий
Поделиться на другие сайты

Дааа... Помню те времена, когда я на Sanny Builder спавнил вертолёты себе на крышу в San Andreas, кстати cleo скрипты могут помочь вам в исследованиях.

Ссылка на комментарий
Поделиться на другие сайты

Вот если бы всё вышеописанное прикрутить к русским локализациям EFLC было бы зашибись... дело в том, что скрипты выше для компиляции требуют модуль dll от этого самого Aru, а он не подцепляется к русским версиям игры. А исходников этой dll нет, есть только .h хедеры

Ссылка на комментарий
Поделиться на другие сайты

Если про GTAIV, то для компиляции своей dll-ки нужен файл "ScriptHook.lib", а ScriptHook.dll не требуется.

В примере проекта из SVN (на который я указывал ссылку) этот файл ScriptHook.libимеется.

Можно скомпилировать пример из SVN например SampleCustom, получится SampleCustom.dll. Её кладём в директории игры и используем асилоадер или просто загружаем эту SampleCustom.dll через Cheat Engine загрузчик без выполнения каких-либо определённых функций в ней. Активируем клавиши и играем со спавном. Разве не так должно быть? Просто я этого не делал, поэтому точно не знаю.

Ссылка на комментарий
Поделиться на другие сайты

Ну да, видимо так. И вот в этой либке прописаны адреса всех вызываемых функций, а адреса вызовов функций меняются в зависимости от версии игры. В либке прописываются все адреса для всех версий, кроме русских. Как-то так видимо, точно не знаю как там всё устроено... Российские игроки вынуждены ставить английские патчи, а иначе не судьба поиграть с модами и читами((

Ссылка на комментарий
Поделиться на другие сайты

В общем, только что собрал я SampleCustom.dll. При запуске игры создаётся лог, что собранная нами dll попыталась определить версию игры, но не смогла. Далее крах игры. Врядли эта проблема решаема без исходников либки. Можно ради интереса запустить разные поддерживаемые версии игры и проанализировать чем запуск двух версий отличается друг от друга. Но это будет сложно(

Ссылка на комментарий
Поделиться на другие сайты

Приаттач твою SampleCustom.dll в архиве в посте. Что-то я свою SampleCustom.dll собрать не могу из-за ошибок в настройках проекта портированного на VS2010. Завтра я проверю её под отладкой.

---

Да и кстати в АА-скриптах CE есть команда "LOADLIBRARY(filename)". Попробуй её. Нужно заранее приаттачить процесс игры. В filename указать полный путь.

Ссылка на комментарий
Поделиться на другие сайты

Приаттачил. А какая разница чем аттачить, CE или загрузчиком игры (я использую xliveless)? DLL ведь аттачится без проблем, но код внутри неё или в lib-файле сообщает о неопределнной версии игры.

SampleCustom.rar

Ссылка на комментарий
Поделиться на другие сайты

Может быть и нет разницы...

Какое у тебя сообщение вылазит из этих:

.rdata:1001C308 aUsingGameVer_0 db 'Using game version 1.0.1',0
.rdata:1001C308 ; DATA XREF: sub_100050D0:loc_10005176o
.rdata:1001C321 align 4
.rdata:1001C324 aInitialization db 'Initialization failed -- Unknown game version',0
.rdata:1001C324 ; DATA XREF: sub_100050D0+99o
.rdata:1001C352 align 4
.rdata:1001C354 ; char aFailedToDetect[]
.rdata:1001C354 aFailedToDetect db 'Failed to detect game version',0
.rdata:1001C354 ; DATA XREF: sub_100050D0:loc_10005152o
.rdata:1001C372 align 4
.rdata:1001C374 ; char aUsingGameVersi[]
.rdata:1001C374 aUsingGameVersi db 'Using game version 1.0.2',0
.rdata:1001C374 ; DATA XREF: sub_100050D0+5Bo
.rdata:1001C38D align 10h
.rdata:1001C390 ; char aAutoDetectingG[]
.rdata:1001C390 aAutoDetectingG db 'Auto detecting game version',0
.rdata:1001C390 ; DATA XREF: sub_100050D0+2Do
.rdata:1001C3AC ; char aProcessBaseAdd[]
.rdata:1001C3AC aProcessBaseAdd db 'Process base address: 0x%x',0

Наверно, это "Failed to detect game version" ?

----------------

Меня что-то глюкнуло. Оказывается *.Lib файл это файл содержащий информацию экспорта и импорта относительно ScriptHook.dll описания. Файл нужен для компоновщика чтобы построить SampleCustom.dll корректно работающего с функциями ScriptHook.dll.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.