Página 1 de 5

GSX - Garage Save eXtender

Enviado: 24 Abr 2018, 11:48
por Fabio
Agora é possível adicionar mais informações nos carros que serão salvos nas garagens do jogo facilmente.



Para jogadores:
Agora será possível que outros mods salvem informações próprias nos carros que são salvos pela garagem, são possibilidades ilimitadas, por exemplo: mods de Auto Posto salvando quantidade de combustível, entre outras coisas.

O mod de salvar automaticamente placas dos carros foi feito como uma pequena demonstração do Garage Save eXtender.

Usos:
VehFuncs
Em andamento...


Para modders:
O GSX possui uma interface (aqui no sentido de programação do termo) para ser usada através de mods CLEO (feitos no Sanny Builder ou gta3script) e ASI.

É possível ser notificado de save/load de carros em garagens e então salvar ou carregar dados, pode ser através de scripts CLEO ou ASI.

O mod trabalha com "dois tipos de dados":
  1. Dados que já serão salvos no arquivo da forma como se apresentam e/ou já estavam salvos anteriormente (em caso de load game e/ou fechar e abrir garagem com um veículo).
  2. Dados que serão copiados para a memória específica do GSX no momento em que o carro for colocado em uma garagem e fechar a porta.

1. Esses dados já estão copiados para memória a própria do GSX e permanecerão os mesmos caso não sejam alterados pelos dados do 2º tipo ou não forem atualizados manualmente por algum script.

2. O GSX guarda apenas o endereço desse tipo de dado e o tamanho dele e quando o carro guardado, esse ponteiro (endereço de memória) será lido e a quantidade especificada no tamanho será copiada para a memória própria do GSX, caso já exista um dado pelo mesmo nome, será atualizado.

A identificação desses dados na memória do GSX é pelo nome atribuído a ele pelo scripter.

Imagem
Imagem



Explicando a API:

Explicando a APIAbrir

Código: Selecionar tudo

static const wchar_t *GSXPath = L"gsx.asi";

É o nome do arquivo do .asi, se preferir, pode inserir um arquivo de configuração que carrega esse nome, caso pense que alguém pode mudar o nome do .asi principal.

Código: Selecionar tudo

struct journalNews

É a struct interna que guarda registros de veículos salvos/carregados.

Código: Selecionar tudo

struct apiCarNotify

É a struct que deve ser enviada para a função getNewCarForeach para retornar um dos veículos recentemente adicionados ou carregados em uma garagem (veremos mais a frente).

Código: Selecionar tudo

struct externalCallbackStructure

É a struct que sua função de callback deve aceitar como parâmetro.

Código: Selecionar tudo

void(__cdecl externalCbFun_t)(const externalCallbackStructure*);

Forma de protótipo que sua função de callback deve ter.



As funções a seguir NÃO devem ser usadas na função WinMain.


Código: Selecionar tudo

void addNotifyCallback(externalCbFun_t fun);

Adiciona uma função sua na lista de callbacks do mod, será sempre chamada quando um carro for carregado ou salvo em uma garagem, é chamada uma vez por carro, então se sua garagem tiver dois carros, será chamada duas vezes e assim por diante.

Código: Selecionar tudo

void addNotifyTempCallback(externalCbFun_t fun);

Funcionamento quase igual a função acima, com a diferença que a lista de funções adicionadas por essa é limpa quando recarrega o save ou carrega outro save.

Código: Selecionar tudo

bool getNewCarForeach(size_t &i, apiCarNotify &out);

Caso não seja escolhida a forma de callbacks automáticos, pode usar esta que funciona sendo chamada manualmente e retorna um carro por vez (caso tenha algum mais recente que a última vez checada).

Código: Selecionar tudo

size_t i = 0;

...


void yourfunction()
{
 using namespace GSX;
 
 apiCarNotify out;
 while (GSXAPI::getNewCarForeach(i, out))
 {
 out.veh; // vehicle
 
 switch(out.status)
 {
 case GSX::LOAD_CAR:
 //
 break;
 
 case GSX::SAVE_CAR:
 //
 break;
 
 default:
 break;
 }
 }
}

void frameThings()
{
 ...
 yourfunction();
 ...
}

Código: Selecionar tudo

{$CLEO}

0AA2: [email protected] = load_library "grgsaveextra.asi" // IF and SET                                                                                  
0AA4: [email protected] = get_proc_address "getNewCarGrgForeach" library [email protected] // IF and SET 

const
   LOAD_CAR = 0
   SAVE_CAR = 1
end


while true
   wait 0        
   
   // Outras coisas
   
   0AC7: [email protected] = var [email protected] offset    // carInfo - 8 bytes
   0AC6: [email protected] = label @positionRegister offset   // 8 bytes
   while true
       0AA7: call_function [email protected] num_params 2 pop 2 [email protected] [email protected] retorno [email protected]  // getNewCarGrgForeach / GSX::getNewCarForeach(i, out)
       if [email protected] <> 0 
       jf break
                                                                 
       0AD0: show_formatted_text_lowpriority "Teste car %.8X status %d" time 1500 [email protected] [email protected]  // status: 0 carregado / 1 salvo       
       wait 2000
   end
   
   
   // Outras coisas
end

:carInfo
hex
   00 00 00 00  // veh ptr
   00 00 00 00  // status
end

:positionRegister
hex
    00 00 00 00 00 00 00 00
end


Código: Selecionar tudo

void setDataToSaveLater(CVehicle *veh, const char *name, int size, void *ptr, bool forceCopyNow);

Aqui precisa ser observado uma coisa, existem duas formas de salvar os dados no mod:
1ª - os dados serão salvos pelo GSX automaticamente quando o carro for salvo. Para isso acontecer, sempre que o carro for carregado é necessário chamar a função acima com o endereço atualizado do dado a ser salvo.
2ª - os dados são salvos instantaneamente, ficando disponível para as funções que testam se existe dado a ser carregado, etc. pode ser feito usando a função pushDirectlyToSavedData (explicação abaixo), ou usando true no parâmetro forceCopyNow.

OBS: ao usar setDataToSaveLater SEM usar true no parâmetro forceCopyNow e salvar o carro, será considerado um dado temporário que estará disponível a próxima vez que o carro ser carregado, mas se não for renovado através de qualquer uma das funções de salvar dados, ele não será salvo de novo.

Use a função de forçar cópia do dado imediatamente com cuidado, principalmente se estiver mexendo com dados grandes.

Código: Selecionar tudo

void pushDirectlyToSavedData(CVehicle *veh, const char *name, int size, void *ptr);

Salva o dado diretamente nos dados que podem ser carregados através de funções de load (Não atualiza o arquivo de save, ele só é atualizado quando o salvar o jogo).


Em andamento...




Downloads:
Download do GSX - Garage Save eXtender
Mod salvar placas dos carros automaticamente (depende do gsx.asi)

Source do mod de salvar as placas dos carros automaticamente:
SpoilerAbrir

Código: Selecionar tudo

//#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <injector\injector.hpp>
#include <injector\assembly.hpp>
#include <injector\calling.hpp>
#include <injector\saving.hpp>
#include <game_sa\CVehicle.h>
#include <game_sa\CMatrix.h>
#include <game_sa\RenderWare.h>
#include <string>
#include "CStoredCar.h"
#include "GSXAPI.h"

static auto getVehicleModelInfoByID = injector::cstd<CVehicleModelInfo*(int id)>::call<0x00403DA0>;
auto CustomCarPlate_TextureCreate = injector::thiscall<bool(CVehicle *, CVehicleModelInfo *)>::call<0x006D10E0>;

void callback(const GSX::externalCallbackStructure *test)
{
 using namespace GSX;

 if (test->veh)
 {
 switch (test->status)
 {
 case GSX::LOAD_CAR:
 {
 if (dataToLoadExists(test->veh, "carplate"))
 {
 const char *plateText = (const char *)getSavedData(test->veh, "carplate");

 if (plateText != nullptr)
 {
 CVehicleModelInfo *info = getVehicleModelInfoByID(test->veh->m_wModelIndex);

 strncpy(info->m_plateText, plateText, 8u);

 if (CustomCarPlate_TextureCreate(test->veh, info))
 {

 }
 else
 {
 //MessageBoxA(0, "error plate", "", 0);
 }
 }
 }

 break;
 }

 case GSX::SAVE_CAR:
 {
 if (test->veh->m_pCustomCarPlate)
 {
 setDataToSaveLater(test->veh, "carplate", 8, test->veh->m_pCustomCarPlate->name, true);
 }
 break;
 }

 default:
 break;
 }
 }
}

void onload(int id)
{
 static bool loaded = false;

 if (!loaded)
 {
 loaded = true;

 addNotifyCallback(callback);
 }
}

void inject()
{
 injector::save_manager::on_load(onload);
}

BOOL WINAPI DllMain(
 _In_  HINSTANCE hinstDLL,
 _In_  DWORD fdwReason,
 _In_  LPVOID lpvReserved
 ){
 if (fdwReason == DLL_PROCESS_ATTACH) inject();


 return true;
}

No download do GSX estão os arquivos da API para C++, Moonloader e alguns exemplos.

É possível usar em CLEO (exemplo bem simples, farei um melhor):

Código: Selecionar tudo

{$CLEO}

0AA2: [email protected] = load_library "gsx.asi" // IF and SET 
0AA4: [email protected] = get_proc_address "dataToSaveLaterExists" library [email protected] // IF and SET       
0AA4: [email protected] = get_proc_address "dataToLoadExists" library [email protected] // IF and SET 
0AA4: [email protected] = get_proc_address "getLoadDataByVehPtr" library [email protected] // IF and SET    
0AA4: [email protected] = get_proc_address "setDataPtrToSaveVehPtr" library [email protected] // IF and SET                                                                                 
0AA4: [email protected] = get_proc_address "pushDirectlyToSavedData" library [email protected] // IF and SET                                                                                 
0AA4: [email protected] = get_proc_address "getNewCarGrgForeach" library [email protected] // IF and SET 

while true
   wait 0        
   
   
   0AC7: [email protected] = var [email protected] offset    // carInfo - 8 bytes
   0AC6: [email protected] = label @positionRegister offset   // 8 bytes
   while true
       0AA7: call_function [email protected] num_params 2 pop 2 [email protected] [email protected] retorno [email protected] 
       if [email protected] <> 0 
       jf break
                                                             // status: 0 carregado / 1 salvo         
       0AD0: show_formatted_text_lowpriority "Teste car %.8X status %d" time 1500 [email protected] [email protected]    
       wait 2000
   end
                             
   
   if 0256: 0
   jf continue          
   if 00DF:   actor $PLAYER_ACTOR driving
   jf continue   
   
   0811: [email protected] = actor $PLAYER_ACTOR used_car
   0A97: [email protected] = car [email protected] struct
   
   //0AA7: call_function [email protected] num_params 2 pop 2 "carplate" [email protected] retorno [email protected]   
   0AA7: call_function [email protected] num_params 2 pop 2 "carplate" [email protected] retorno [email protected]

   if [email protected] <> 0
   then
       0AA7: call_function [email protected] num_params 2 pop 2  "carplate" [email protected] retorno [email protected]   
       0AD0: show_formatted_text_lowpriority "Teste %s opcode" time 10 [email protected]
   end
end


0A93: end_custom_thread           

:buflicenseplate
hex
   00 00 00 00 00 00 00 00 00 00 00
end 

:carInfo
hex
   00 00 00 00  // veh ptr
   00 00 00 00  // status
end

:positionRegister
hex
    00 00 00 00 00 00 00 00
end



Pequena documentação das funções exportadas pelo GSX.asiAbrir
Observação: o arquivo de save do GSX só é atualizado quando o jogo é salvo.

Estruturas:

Código: Selecionar tudo

struct externalCallbackStructure
{
	CVehicle *veh;
	int32_t status;
	CStoredCar *gameStoredData;
};

  • veh - ponteiro para estrutura do veículo.
  • status - status do veículo.
    • 0 Carregado
    • 1 Salvo
  • gameStoredData ponteiro para uma estrutura que o jogo usa nas garagens, na versão atual não recomendo usar elas, o hook do GSX funciona pouco antes de todos os dados do veículo serem aplicados a essa estrutura.


Código: Selecionar tudo

struct apiCarNotify
{
	CVehicle *veh;
	int32_t status;
};

  • veh - ponteiro para estrutura do veículo.
  • status - status do veículo.
    • 0 Carregado
    • 1 Salvo


Código: Selecionar tudo

void (__cdecl externalCbFun_t)(const externalCallbackStructure*)

Protótipo que uma função deve ter para ser enviada ao GSX, não possui retorno e recebe um ponteiro para uma estrutura constante externalCallbackStructure.


Código: Selecionar tudo

int __cdecl addNotifyCallback(externalCbFun_t fun)

Adiciona um callback que poderá ser chamado a qualquer momento enquanto o jogo estiver aberto, ideal para mods ASI e outros que não mudam de endereço ao recarregar o jogo.
Retorna referência para callback.

  • fun endereço da função.


Código: Selecionar tudo

void __cdecl removeNotifyCallback(int cbRef)

Remove um callback adicionado com a função addNotifyCallback.
  • cbRef referência do callback.


Código: Selecionar tudo

int __cdecl addNotifyTempCallback(externalCbFun_t fun)

Adiciona um callback que funciona como o anterior, entretanto ele é removido da lista quando o jogo recarrega.
Retorna referência para callback.
  • fun endereço da função.


Código: Selecionar tudo

void __cdecl removeNotifyTempCallback(int cbRef)

Remove um callback adicionado com a função addNotifyTempCallback.
  • cbRef referência do callback.


Código: Selecionar tudo

int __cdecl getNewCarGrgForeach(size_t *i, apiCarNotify *out)

O GSX guarda um pequeno histórico de veículos salvos e/ou carregados que pode ser conferido de um a um.

  • i ponteiro para uma variável que guardará o último item lido do histórico, recomendo deixar alocado 64 bits (8 bytes) para ela.
  • out envie o endereço para uma memória com tamanho de 8 bytes. O GSX gravará uma estrutura do tipo apiCarNotify nessa memória.

Essa função retorna 1 caso tenha veículo salvo/carregado, 0 caso não tenha.


Dados do tipo 2 (ponteiros para dados que serão copiados assim que o carro for guardado na garagem):

Código: Selecionar tudo

void __cdecl setDataToSaveLaterVehPtr(CVehicle *veh, const char *name, int size, void *ptr, bool forceCopyNow)

Adiciona um endereço para uma lista de dados a serem copiados quando o veículo for salvo em uma garagem.

ATENÇÃO: Tenha certeza que os dados estarão disponíveis no momento em que o carro estiver sendo salvo.

  • veh ponteiro para o veículo
  • name nome do dado a ser salvo (ATENÇÃO: substituirá dados com o mesmo nome)
  • size tamanho em bytes do dado.
  • ptr endereço do dado
  • forceCopyNow faz uma cópia interna do dado nesse exato momento para outra lista com os dados salvos.


Código: Selecionar tudo

int __cdecl getDataToSaveSize(CVehicle *veh, const char *name)

Retorna o tamanho de um dado adicionado com a função setDataToSaveLaterVehPtr.

  • veh ponteiro para o veículo
  • name nome do dado a ser procurado

Retorna o tamanho do dado caso encontrado, -1 caso não encontrado.


Código: Selecionar tudo

int __cdecl dataToSaveLaterExists(CVehicle *veh, const char *name)

Verifica se um dado com certo nome existe na lista de dados a serem copiados futuramente. (Dados adicionados com a função setDataToSaveLaterVehPtr)

  • veh ponteiro para o veículo
  • name nome do dado a ser procurado

Retorna true ou false.


Código: Selecionar tudo

void __cdecl removeToSaveLaterVehPtr(CVehicle *veh, const char *name)

Remove um dado adicionado pela função setDataToSaveLaterVehPtr.

  • veh ponteiro para o veículo
  • name nome do dado a ser removido


Dados do tipo 1 (dados que são copiados no momento em que a função é chamada):

Código: Selecionar tudo

void __cdecl pushDirectlyToSavedData(CVehicle *veh, const char *name, int size, void *ptr)

Copia o dado para a memória de dados salvos do GSX sobre o veículo.

  • veh ponteiro para o veículo
  • name nome do dado a ser salvo (ATENÇÃO: substituirá dados com o mesmo nome)
  • size tamanho em bytes do dado.
  • ptr endereço do dado


Código: Selecionar tudo

void __cdecl removeToLoadDataVehPtr(CVehicle *veh, const char *name)

Apaga dados que foram salvos anteriormente ou dados adicionados com a função pushDirectlyToSavedData ou com a setDataToSaveLaterVehPtr usando forceCopyNow como true.

  • veh ponteiro para o veículo
  • name nome do dado a ser removido


Código: Selecionar tudo

int __cdecl dataToLoadExists(CVehicle *veh, const char *name)

Verifica se existe um dado salvo anteriormente ou com a função pushDirectlyToSavedData ou com a setDataToSaveLaterVehPtr usando forceCopyNow como true.

  • veh ponteiro para o veículo
  • name nome do dado a ser procurado

Retorna true ou false.


Código: Selecionar tudo

void* __cdecl getLoadDataByVehPtr(CVehicle *veh, const char *name)

Retorna o ponteiro de um dado salvo anteriormente ou com a função pushDirectlyToSavedData ou com a setDataToSaveLaterVehPtr usando forceCopyNow como true.

ATENÇÃO: Esse endereço pode mudar caso os dados sejam alterados, copie o conteúdo dele logo após a função retornar.

  • veh ponteiro para o veículo
  • name nome do dado a ser procurado

Retorna o endereço do dado caso sucesso ou 0 caso não encontrado.


Código: Selecionar tudo

int __cdecl getDataToLoadSize(CVehicle *veh, const char *name)

Retorna o tamanho de um dado salvo anteriormente ou com a função pushDirectlyToSavedData ou com a setDataToSaveLaterVehPtr usando forceCopyNow como true.

  • veh ponteiro para o veículo
  • name nome do dado a ser procurado

Retorna o tamanho do dado caso encontrado, -1 caso não encontrado.


ATENÇÃO: As funções abaixo podem não existir em versões de testes iniciais:


Código: Selecionar tudo

const char * __cdecl GSX_getCompileTime()

Retorna a data e a hora que o GSX.asi foi compilado em string.


Código: Selecionar tudo

const char * __cdecl GSX_getVersionString()

Retorna a versão do GSX.asi em string.


Código: Selecionar tudo

float __cdecl GSX_getVersionNum()

Retorna a versão do GSX.asi em float. Recomendo usar a versão em string.


Nomes reservados para dados gravados pelo próprio GSX.asi:
_hash é uma hash criada na primeira detecção do carro pelo código.
- Sempre estará presente e com 8 bytes na atual versão.

Caso não seja encontrado ou tenha um tamanho diferente, por favor avise.




BMS: http://brmodstudio.forumeiros.com/t6959 ... aticamente



f16-utilidades/t2954-gsx-data-usar-gsx- ... nte#p25276

GSX - Garage Save eXtender

Enviado: 29 Abr 2018, 18:17
por Um_Geek
Compilei o codigo exemplo para cleo e não funcionou.

Código: Selecionar tudo

00000203&0: [0AC7] GET_VAR_POINTER l16(0)  -> 49910836
00000211&0: [0AC6] GET_LABEL_POINTER -478 -> 49911534
00000221&0: [0AA7] CALL_FUNCTION_RETURN 0x0 2 2 49910836 49911534

Parece que é nesta função

Código: Selecionar tudo

0AA4: [email protected] = get_proc_address "getNewCarGrgForeach" library [email protected] // IF and SET 
(...)
0AA7: call_function [email protected] num_params 2 pop 2 [email protected] [email protected] retorno [email protected] 

Imagem
Estou tentando usar com o ffi do lua, mas nem sei o que envia e retorna nas funções, alem do meu ida ser 5.0 não consigo ver estas coisas. ficaria mais fácil se as funções estivessem especificadas como nesta pagina.

**http://www.xmlsoft.org/html/libxml-pars ... mlReadFile

*libxml2.dll, torna possível usar xml mesmo com cleo e é uma dll comum do windows

GSX - Garage Save eXtender

Enviado: 29 Abr 2018, 20:34
por Fabio
Um_Geek escreveu:
29 Abr 2018, 18:17

Código: Selecionar tudo

00000203&0: [0AC7] GET_VAR_POINTER l16(0)  -> 4991083600000211&0: [0AC6] GET_LABEL_POINTER -478 -> 4991153400000221&0: [0AA7] CALL_FUNCTION_RETURN 0x0 2 2 49910836 49911534

Crash? CALL_FUNCTION_RETURN 0x0 a função não foi encontrada. E a lib, foi carregada? Pode postar a parte anterior do log?

Um_Geek escreveu:
29 Abr 2018, 18:17
Estou tentando usar com o ffi do lua, mas nem sei o que envia e retorna nas funções, alem do meu ida ser 5.0 não consigo ver estas coisas. ficaria mais fácil se as funções estivessem especificadas como nesta pagina.


Olhe o GSXAPI.cpp, o topo dele tem as definições das funções internas, mas vou dar uma melhorada no tópico.



Acabei de adicionar uma pequena documentação das funções exportadas no tópico, espero que esteja correto, fiz rapidamente.

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 15:02
por Um_Geek
Consegui usar, no entanto é meio complicado de usar para uma ferramenta que só salva e puxa dados, tenho que ficar alocando memoria pelo script, checar se o dado existe separadamente para depois carregar. as vezes também não funciona então recarregando o script funciona,acho que precisa de uma pausa para o gsx achar o valor salvo.

Não entendo bem da logica do c++,mas sera que não poderia ser resumido a isto?

SpoilerAbrir

Código: Selecionar tudo

bool exist << gsxGetExistValue(int *car, const char *name)

float value << gsxGetFloatValue(int *car, const char *name)
int value << gsxGetIntValue(int *car, const char *name)
string value << gsxGetStringValue(int *car, const char *name)

bool sucess << gsxSetFloatValue(int *car, const char *name, float *value)
bool sucess << gsxSetIntValue(int *car, const char *name, int *value)
bool sucess << gsxSetStringValue(int *car, const char *name, const char *value)

gsxRemoveValue(int *car, const char *name)

seria mais fácil adicionar funções dele até mesmo em mods simples.
são observações ao tentar usar as funções do gsx. Em lua tão teve nenhum crash durante os testes, só por erros bobos de leitura de memoria cometidos por mim mesmo

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 15:08
por Fabio
Um_Geek escreveu:
06 Mai 2018, 15:02
Consegui usar, no entanto é meio complicado de usar para uma ferramenta que só salva e puxa dados, tenho que ficar alocando memoria pelo script

Que tamanho de dado você está usando?

Um_Geek escreveu:
06 Mai 2018, 15:02
as vezes também não funciona então recarregando o script funciona,acho que precisa de uma pausa para o gsx achar o valor salvo.

Não... é tudo salvo e carregado no momento em que fecha ou abre a garagem, como está fazendo?

Um_Geek escreveu:
06 Mai 2018, 15:02
Não entendo bem da logica do c++,mas sera que não poderia ser resumido a isto?

SpoilerAbrir

Código: Selecionar tudo

bool exist << gsxGetExistValue(int *car, const char *name)

float value << gsxGetFloatValue(int *car, const char *name)
int value << gsxGetIntValue(int *car, const char *name)
string value << gsxGetStringValue(int *car, const char *name)

bool sucess << gsxSetFloatValue(int *car, const char *name, float *value)
bool sucess << gsxSetIntValue(int *car, const char *name, int *value)
bool sucess << gsxSetStringValue(int *car, const char *name, const char *value)

gsxRemoveValue(int *car, const char *name)

seria mais fácil adicionar funções dele até mesmo em mods simples

Ainda falta uma função para dados brutos.
Acho que você pode usar ffi.cast para converter os ponteiros.

Um_Geek escreveu:
06 Mai 2018, 15:02
são observações ao tentar usar as funções do gsx. Em lua tão teve nenhum crash durante os testes, só por erros bobos de leitura de memoria cometidos por mim mesmo

:philo:

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 15:25
por Um_Geek
Fabio escreveu: Que tamanho de dado você está usando?
Estou usando 8, já que é só um numero float de 3 digitos.

Não... é tudo salvo e carregado no momento em que fecha ou abre a garagem, como está fazendo?
Eu espero a garagem fechar e salvo, funciona ok se pegar o carro no momento, mas ao abrir o jogo e ir no carro o script morre no momento de buscar o valor suponho.

Talvez, mas não está especificado se são os valores a serem salvos ou os valores que já estavam salvos.
Não entendi, mas é só um esboço, get busca o valor, set salva e sobrescreve. caso não quisesse sobrescrever só usar a função para ver se existe. bem, eu não sei nada do funcionamento interno então não sei seria possível resumir assim.só sugestão mesmo.

Um_Geek escreveu:
06 Mai 2018, 15:02
são observações ao tentar usar as funções do gsx. Em lua não teve nenhum crash durante os testes, só por erros bobos de leitura de memoria cometidos por mim mesmo.

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 16:27
por Fabio
Um_Geek escreveu:
06 Mai 2018, 15:25
Estou usando 8, já que é só um numero float de 3 digitos.

:philo:

Eu precisaria ver o código para opinar, mas se estiver usando tipos numéricos de Lua, o tamanho é 8 mesmo para os floats.

Um_Geek escreveu:
06 Mai 2018, 15:25
Eu espero a garagem fechar e salvo, funciona ok se pegar o carro no momento, mas ao abrir o jogo e ir no carro o script morre no momento de buscar o valor suponho.

Você não está reutilizando a handle talvez? A handle/endereço do carro não é fixa.

Um_Geek escreveu:
06 Mai 2018, 15:25
Não entendi, mas é só um esboço, get busca o valor, set salva e sobrescreve. caso não quisesse sobrescrever só usar a função para ver se existe. bem, eu não sei nada do funcionamento interno então não sei seria possível resumir assim.só sugestão mesmo.

Quis dizer que vai precisar de duas cópias de cada função dessa para os tipos de dados que eu explico no tópico, mas é só um esboço então beleza.

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 18:24
por Um_Geek
Para salvar estou usando esta função.
SpoilerAbrir

Código: Selecionar tudo

function gsxSetFloatValue(car,name)
    local value = nil
    if gsx_lib_loaded_ok==true then 
        local res1,getLoadDataByVehPtr = getDynamicLibraryProcedure("getLoadDataByVehPtr",GSXLib)
        local res2,dataToLoadExists = getDynamicLibraryProcedure("dataToLoadExists",GSXLib)
        if res1==true and res2==true then 
			local ptr = getCarPointer(car)
			local sucess = callFunction(dataToLoadExists,2,1,ptr,name)
			if sucess~=nil then -- impedir erro de comparação (nil==numero)
				if sucess==1 then 
					local address = callFunction(getLoadDataByVehPtr,2,1,ptr,name)
					value = memory.getfloat(address,false)
				end
			end
        end
    end 
    return value
end 

Para recarregar uso esta.

SpoilerAbrir

Código: Selecionar tudo

function gsxGetFloatValue(car,name,data)
    local res,lib = loadDynamicLibrary("gsx.asi")
    if gsx_lib_loaded_ok==true then 
        local ptr = getCarPointer(car)
        local res1,setDataToSaveLaterVehPtr = getDynamicLibraryProcedure("setDataToSaveLaterVehPtr",GSXLib)
        if res1==true then
            local address = allocateMemory(8)
            memory.setfloat(address,data,false)
            callFunction(setDataToSaveLaterVehPtr,5,0,ptr,name,8,address,true)
            freeMemory(address)
        end
    end  
end

Da certo as vezes, algumas que falha, mas quando falha só usar o comando reloadall do lua que funciona.

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 21:51
por Fabio
É um pouco estranho funcionar as vezes só se recarregar o script. Teste um pouco melhor por favor. :philo:

SpoilerAbrir
Os nomes das suas funções estão um pouco confusos.

Get seta e set pega o valor? :hm:

Errr, você está mandando um endereço temporário para uma função que pede endereço permanente (ao menos até o carro ser salvo).

Código: Selecionar tudo

            memory.setfloat(address,data,false)
            callFunction(setDataToSaveLaterVehPtr,5,0,ptr,name,8,address,true)
            freeMemory(address)

Adicionado após 3 minutos :
Fabio escreveu:
24 Abr 2018, 11:48

Código: Selecionar tudo

void __cdecl setDataToSaveLaterVehPtr(CVehicle *veh, const char *name, int size, void *ptr, bool forceCopyNow)
Adiciona um endereço para uma lista de dados a serem copiados quando o veículo for salvo em uma garagem.

ATENÇÃO: Tenha certeza que os dados estarão disponíveis no momento em que o carro estiver sendo salvo.

  • veh ponteiro para o veículo

  • name nome do dado a ser salvo (ATENÇÃO: substituirá dados com o mesmo nome)

  • size tamanho em bytes do dado.

  • ptr endereço do dado

  • forceCopyNow faz uma cópia interna do dado nesse exato momento para outra lista com os dados salvos.

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 22:33
por Um_Geek
Editei o nome das funções ao colar aqui, então ficaram trocados. então salvar se refere ao momento que o jogo é salvo e não no momento de uso da função, isto não estava claro.

Quer dizer que tem um marcador permanente para carros salvos no jogo que não muda mesmo reiniciando o jogo? Testei o handler e o pointer e não são fixos, isto seria útil. :philo:

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 23:01
por Fabio
Um_Geek escreveu:
06 Mai 2018, 22:33
Editei o nome das funções ao colar aqui, então ficaram trocados. então salvar se refere ao momento que o jogo é salvo e não no momento de uso da função, isto não estava claro.

Não, se refere o momento em que o carro é salvo na garagem (quando a porta é fechada).

Um_Geek escreveu:
06 Mai 2018, 22:33
Quer dizer que tem um marcador permanente para carros salvos no jogo que não muda mesmo reiniciando o jogo?

Não. Eu uso a localização que o carro foi salvo para "marcar" eles.

GSX - Garage Save eXtender

Enviado: 06 Mai 2018, 23:15
por Um_Geek
Não, se refere o momento em que o carro é salvo na garagem (quando a porta é fechada).
No caso eu teria que alocar a memoria, colocar a referencia para ela em uma table, e depois de salvar usar freememory em vez de logo depois da função.

Entendi, da forma que eu estou usando precisaria checar se esta na garagem quando sai do carro. vou ver o que posso fazer para o mod salvar o que precisa. mas já valeu pela ajuda.

GSX - Garage Save eXtender

Enviado: 07 Mai 2018, 00:31
por Fabio
Um_Geek escreveu:
Não, se refere o momento em que o carro é salvo na garagem (quando a porta é fechada).
No caso eu teria que alocar a memoria, colocar a referencia para ela em uma table, e depois de salvar usar freememory em vez de logo depois da função.

Entendi, da forma que eu estou usando precisaria checar se esta na garagem quando sai do carro. vou ver o que posso fazer para o mod salvar o que precisa. mas já valeu pela ajuda.

Se for coisa pequena (no caso, é), usa a função de salvar direto. (Só lembrando que só é realmente salvo no ARQUIVO se o carro for guardado na garagem e o jogo salvo)

Código: Selecionar tudo

void pushDirectlyToSavedData(CVehicle *veh, const char *name, int size, void *ptr)

Se não precisar atualizar mais tarde e for um dado temporário, use a função acima mesmo.


Fabio escreveu:
24 Abr 2018, 11:48

Código: Selecionar tudo

void __cdecl pushDirectlyToSavedData(CVehicle *veh, const char *name, int size, void *ptr)
Copia o dado para a memória de dados salvos do GSX sobre o veículo.

  • veh ponteiro para o veículo

  • name nome do dado a ser salvo (ATENÇÃO: substituirá dados com o mesmo nome)

  • size tamanho em bytes do dado.

  • ptr endereço do dado

GSX - Garage Save eXtender

Enviado: 13 Mai 2018, 13:45
por Fabio
Talvez isso deixe mais compreensível o funcionamento:

Imagem

Atualizei o download, removi uma espécie de garbage collector que eu tinha feito. Por favor, testem o máximo que for possível.

GSX - Garage Save eXtender

Enviado: 13 Mai 2018, 15:17
por Junior_Djjr
Fabio escreveu:
13 Mai 2018, 13:45
Atualizei o download, removi uma espécie de garbage collector que eu tinha feito. Por favor, testem o máximo que for possível.
Tudo depende do VehFuncs porque ninguém usa isso ainda kkkkk
Aproveitei a atualização para atualizar o GSX nele (se bem que ninguém usa VehFuncs também, quase não tem carro adaptado ainda)