Página 4 de 4

GSX - Garage Save eXtender

Enviado: 19 Mai 2018, 16:29
por Fabio
0x56A23ADE lua_sethook+0x14e in lua51.dll (+0x23ade)

Esse erro estava acontecendo quando eu estava usando (void**) como tipo de CVehicle.

Como está seu lib/gsx.lua? Será que eu não fiz alguma coisa errada na hora de dar update? :hmm:

Deve estar assim:

Código: Selecionar tudo

local ffi = require 'ffi'

ffi.cdef[[

typedef uint32_t GSXCVehicle;

typedef struct { float x, y, z; } CVector;

typedef struct __attribute__((packed, aligned(1))) {
	CVector pos;
	uint32_t handling_flags;
	uint8_t flags;
	uint8_t field_11;
	uint16_t model;
	uint16_t carmods[15];
	uint8_t colour[4];
	uint8_t radio_station;
	uint8_t extra1;
	uint8_t extra2;
	uint8_t bomb_type;
	uint8_t paintjob;
	uint8_t nitro_count;
	uint8_t angleX;
	uint8_t angleY;
	uint8_t angleZ;
	uint8_t field_3F;
} CStoredCar;
typedef struct __attribute__((packed, aligned(1))) { GSXCVehicle veh; int32_t status; size_t when; } journalNews;
typedef struct __attribute__((packed, aligned(1))) { GSXCVehicle veh; int32_t status; } apiCarNotify;
typedef struct __attribute__((packed, aligned(1))) { GSXCVehicle veh; int32_t status; CStoredCar *gameStoredData; } externalCallbackStructure;
typedef void(__cdecl externalCbFun_t)(const externalCallbackStructure*);
int __cdecl addNotifyCallback(externalCbFun_t fun);
int __cdecl addNotifyTempCallback(externalCbFun_t fun);
void __cdecl removeNotifyCallback(int cbRef);
void __cdecl removeNotifyTempCallback(int cbRef);
int __cdecl getNewCarGrgForeach(size_t *i, apiCarNotify *out);
void __cdecl setDataToSaveLaterVehPtr(GSXCVehicle veh, const char *name, int size, void *ptr, bool forceCopyNow);
void __cdecl pushDirectlyToSavedData(GSXCVehicle veh, const char *name, int size, void *ptr);
int __cdecl dataToSaveLaterExists(GSXCVehicle veh, const char *name);
void __cdecl removeToLoadDataVehPtr(GSXCVehicle veh, const char *name);
void __cdecl removeToSaveLaterVehPtr(GSXCVehicle veh, const char *name);
int __cdecl dataToLoadExists(GSXCVehicle veh, const char *name);
void*  __cdecl getLoadDataByVehPtr(GSXCVehicle veh, const char *name);
const char*  __cdecl GSX_getCompileTime();
const char*  __cdecl GSX_getVersionString();
float __cdecl GSX_getVersionNum();
int __cdecl getDataToLoadSize(GSXCVehicle veh, const char *name);
int __cdecl getDataToSaveSize(GSXCVehicle veh, const char *name);
]]


local gsxAsi = ffi.load("gsx.asi")

return gsxAsi

Adicionado após 1 minuto 33 segundos:
Ao que parece o moonloader não registra as exceptions que ocorreram na biblioteca de Lua.

GSX - Garage Save eXtender

Enviado: 19 Mai 2018, 18:24
por Um_Geek

Código: Selecionar tudo

Esse erro estava acontecendo quando eu estava usando (void**) como tipo de CVehicle.

Era isto mesmo
Antes:

Código: Selecionar tudo

typedef void* CVehicle;

Agora:

Código: Selecionar tudo

typedef uint32_t GSXCVehicle;

agora esta funcionando. Você poderia até adicionar este lib gsx.lua no download do gsx.asi, assim não tem risco de quem faz outros mods lua acabar criando um próprio o que poderia estragar com outros mods por compatibilidade, assim também poderia o manter atualizado conforme atualizasse o gsx :peepo6:

GSX - Garage Save eXtender

Enviado: 19 Mai 2018, 18:34
por Fabio
Um_Geek escreveu: agora esta funcionando.

:herp:

Um_Geek escreveu: Você poderia até adicionar este lib gsx.lua no download do gsx.asi, assim não tem risco de quem faz outros mods lua acabar criando um próprio o que poderia estragar com outros mods por compatibilidade, assim também poderia o manter atualizado conforme atualizasse o gsx :peepo6:

Mas está lá no download @[email protected]

gsx\developers\API\moonloader\lib\
:hm:

GSX - Garage Save eXtender

Enviado: 19 Mai 2018, 19:33
por Um_Geek
Vi aqui agora, eu tinha baixado ontem a noite e só arrastei o gsx.asi para a pasta do jogo :facep:
estou tentando encaixar no mod que estou fazendo atualmente, se der certo vai ficar maneirinho.

GSX - Garage Save eXtender

Enviado: 19 Mai 2018, 23:50
por Fabio
Um_Geek escreveu: Vi aqui agora, eu tinha baixado ontem a noite e só arrastei o gsx.asi para a pasta do jogo :facep:
estou tentando encaixar no mod que estou fazendo atualmente, se der certo vai ficar maneirinho.

Qualquer coisa avise por favor. :pacman:

GSX - Garage Save eXtender

Enviado: 23 Mai 2018, 02:11
por Fabio
Atualização:

Ao verificar o mod do @Um_Geek (/f5-scripts-codigos/t464-lua-pintar-veiculos-usando-cores-rgb), encontrei uma possível situação de crash no GSX.asi, já foi corrigida e o download está atualizado.

GSX - Garage Save eXtender

Enviado: 02 Jul 2018, 13:39
por Um_Geek
Mais um mod usando o gsx, este salva danos das portas e pneus, alem de salvar se deixou a porta aberta.
Eu devo ter editado umas 5 vezes no gist por causa desta tabulação
SpoilerAbrir

Código: Selecionar tudo

script_author("Um_Geek");
script_url("https://gta-geek.blogspot.com.br/");
script_version_number(0.0);

local ffi = require "ffi";
local memory = require "memory";
local gsx = nil;
local gsxCbRef = -1;
local gsxStrData = "cardam"; 

-- #################################################################################################################
-- gsx.asi by Fabio
-- https://forum.mixmods.com.br/f5-scripts-codigos/t214-gsx-garage-save-extender
-- #################################################################################################################
function loadGSXLibrary()
	if doesFileExist(getGameDirectory().."\\gsx.asi") then 
		ffi.cdef[[
			typedef uint32_t GSXCVehicle;
			typedef struct { float x, y, z; } CVector;
			typedef struct __attribute__((packed, aligned(1))) {
				CVector pos;uint32_t handling_flags;uint8_t flags;uint8_t field_11;uint16_t model;uint16_t carmods[15];uint8_t colour[4];
				uint8_t radio_station;uint8_t extra1;uint8_t extra2;uint8_t bomb_type;uint8_t paintjob;uint8_t nitro_count;uint8_t angleX;
				uint8_t angleY;uint8_t angleZ;uint8_t field_3F;
			} CStoredCar;
			typedef struct __attribute__((packed, aligned(1))) { GSXCVehicle veh; int32_t status; size_t when; } journalNews;
			typedef struct __attribute__((packed, aligned(1))) { GSXCVehicle veh; int32_t status; } apiCarNotify;
			typedef struct __attribute__((packed, aligned(1))) { GSXCVehicle veh; int32_t status; CStoredCar *gameStoredData; } externalCallbackStructure;
			typedef void(__cdecl externalCbFun_t)(const externalCallbackStructure*);
			int __cdecl addNotifyCallback(externalCbFun_t fun);
			int __cdecl addNotifyTempCallback(externalCbFun_t fun);
			void __cdecl removeNotifyCallback(int cbRef);
			void __cdecl removeNotifyTempCallback(int cbRef);
			int __cdecl getNewCarGrgForeach(size_t *i, apiCarNotify *out);
			void __cdecl setDataToSaveLaterVehPtr(GSXCVehicle veh, const char *name, int size, void *ptr, bool forceCopyNow);
			void __cdecl pushDirectlyToSavedData(GSXCVehicle veh, const char *name, int size, void *ptr);
			int __cdecl dataToSaveLaterExists(GSXCVehicle veh, const char *name);
			void __cdecl removeToLoadDataVehPtr(GSXCVehicle veh, const char *name);
			void __cdecl removeToSaveLaterVehPtr(GSXCVehicle veh, const char *name);
			int __cdecl dataToLoadExists(GSXCVehicle veh, const char *name);
			void*  __cdecl getLoadDataByVehPtr(GSXCVehicle veh, const char *name);
			const char*  __cdecl GSX_getCompileTime();
			const char*  __cdecl GSX_getVersionString();
			float __cdecl GSX_getVersionNum();
			int __cdecl getDataToLoadSize(GSXCVehicle veh, const char *name);
			int __cdecl getDataToSaveSize(GSXCVehicle veh, const char *name);
		]]
		return ffi.load("gsx.asi");
	end 
	return nil;
end 
-- #################################################################################################################

function callback(c)
	local dataToLoadExists = ffi.cast("int (*)(int,const char*)",gsx.dataToLoadExists);
	local getDataToLoadSize = ffi.cast("int (*)(int,const char*)",gsx.getDataToLoadSize);
	local getLoadDataByVehPtr = ffi.cast("int (*)(int,const char*)",gsx.getLoadDataByVehPtr);
    local pushDirectlyToSavedData = ffi.cast("int (*)(int,const char*,int,int)",gsx.pushDirectlyToSavedData);
	if c.status==1 then
        local Json = store(c);
        if Json~=nil then
			local size = {}; 
			local Str = Json;
            for j = 1, #Str do size[j] = Str:sub(j,j) end;
            local pStr = memory.strptr(Json);
            pushDirectlyToSavedData(c.veh,gsxStrData,#size,pStr);
		end
	else
		if dataToLoadExists(c.veh,gsxStrData)==1 then
			local ptr = getLoadDataByVehPtr(c.veh,gsxStrData);
			local size = getDataToLoadSize(c.veh,gsxStrData);
			restore(c,memory.tostring(ptr,size,false)); 
		end
	end
end

function store(c)
	local h = getVehiclePointerHandle(c.veh);
	if isThisModelACar(getCarModel(h)) then
		local t = {
			healt = getCarHealth(h),
			tires={},
			doors={},
			doorsdam = {}
		};
		for i=0, 6 do if isCarTireBurst(h,i) then t.tires[i] = i end end;
		for i=2, 5 do 
			t.doors[i] = isCarDoorFullyOpen(h,i); 
			t.doorsdam[i] = isCarDoorDamaged(h,i);
		end
		return encodeJson(t);
	end 
	return nil
end

function restore(c,s)
	local h = getVehiclePointerHandle(c.veh);
	if isThisModelACar(getCarModel(h)) then
		local t = decodeJson(s);
		setCarHealth(h,t.healt);
		for i=0, 3 do 
			if t.tires[i]  then 
				memory.write(c.veh+(1445+i),1,1,false);
			end 
		end
		for i=2, 5 do 
			if t.doorsdam[i]==true then damageCarDoor(h,i) end;
			if t.doors[i]==true then openCarDoor(h,i) end;
		end
	end
end

function onExitScript()
	if gsxCbRef~=-1 then gsx.removeNotifyCallback(gsxCbRef);gsxCbRef=-1; end;
end

function onScriptTerminate()
	if gsxCbRef~=-1 then gsx.removeNotifyCallback(gsxCbRef);gsxCbRef=-1; end;
end 

function main()
	gsx = loadGSXLibrary();
	gsxCbRef = gsx.addNotifyCallback(callback);
	while true do wait(80) end;
end

Código: Selecionar tudo

https://gist.github.com/UmGeek/6fdff6e506b8b9ec85a49d033474443f

GSX - Garage Save eXtender

Enviado: 03 Jul 2018, 20:41
por Fabio
Tem integração com o github, não precisa colar o código.

GSX - Garage Save eXtender

Enviado: 04 Jul 2018, 00:19
por Um_Geek
Fabio escreveu: Tem integração com o github, não precisa colar o código.
Notei isto quando colei o link do gist, mas eu só queria o link. eu devia ter editado como link mesmo em vez de por o link do gist no code para não aparecer o iframe do gist :philo:

Re: GSX - Garage Save eXtender

Enviado: 08 Jan 2019, 03:30
por Fabio
Adicionado o valor reservado _hash aos dados nº1, ele é um inteiro de 64 bits (8 bytes).

Exemplo rápido em cleo (não é um exemplo que mostra com precisão o valor por não considerar o little endian):

Código: Selecionar tudo

{$CLEO}

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

while true
   wait 0
   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 "_hash" [email protected] -> [email protected]   
   
   if [email protected] <> 0
   jf continue
   
   0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0
   [email protected] += 4                                   
   0A8D: [email protected] = read_memory [email protected] size 4 virtual_protect 0
   0AD1: show_formatted_text_highpriority "%.8X %.8X" time 2000  [email protected] [email protected]
end

Re: GSX - Garage Save eXtender

Enviado: 09 Jan 2019, 15:44
por Um_Geek
estou testando isto, se der certo vou usar como ponte entre o gsx e o mod que eu esteja fazendo.
Usa 4 comandos set,get,serial e data.

no caso data armazena informações de coordenadas e data de onde e quando o carro foi salvo a primeira vez, alem do modelo do dono caso ele tenha sido roubado.

set e get salvam e recebe como string.
fiz um exemplo mais ou menos que vai junto.

Re: GSX - Garage Save eXtender

Enviado: 09 Jan 2019, 20:14
por Fabio
Um_Geek escreveu:
09 Jan 2019, 15:44
estou testando isto, se der certo vou usar como ponte entre o gsx e o mod que eu esteja fazendo.
Usa 4 comandos set,get,serial e data.

no caso data armazena informações de coordenadas e data de onde e quando o carro foi salvo a primeira vez, alem do modelo do dono caso ele tenha sido roubado.

set e get salvam e recebe como string.
fiz um exemplo mais ou menos que vai junto.

Uma observação, não sei como está fazendo, mas quando for escrever strings é preciso colocar um null terminator (já deve ir com a string usada no call, então é só usar strlen(str) + 1) caso o tamanho não seja fixo, se estiver usando com tamanho conhecido (fixado por você ou informando ao strncpy usando get size do GSX), pode usar sem null terminator mesmo.

Re: GSX - Garage Save eXtender

Enviado: 09 Jan 2019, 22:17
por Um_Geek
Fabio escreveu:
09 Jan 2019, 20:14
Uma observação, não sei como está fazendo, mas quando for escrever strings é preciso colocar um null terminator (já deve ir com a string usada no call, então é só usar strlen(str) + 1) caso o tamanho não seja fixo, se estiver usando com tamanho conhecido (fixado por você ou informando ao strncpy usando get size do GSX), pode usar sem null terminator mesmo.

Estou usando o tamanho da ´#string´ como tamanho da memoria e uso o getDataToLoadSizedo gsx para pegar o tamanho na hora da leitura. tudo que é salvo por este recurso é colocado em uma table e convertida em json antes de ser salva, até agora não tive problemas.

Código: Selecionar tudo

local pNotifyCallbac = gsx.addNotifyCallback(function(c)
    local sid = string.format("SID%i",c.veh)
    if c.status==1 then
        local zdata = encodeJson(t_data[sid])
        if zdata ~= nil then
            local pdata = memory.strptr(zdata);
            pushDirectlyToSavedData(c.veh,i_data,#zdata,pdata);
        end
    else
        if dataToLoadExists(c.veh,i_data) == 1 then
            local pdata = getLoadDataByVehPtr(c.veh,i_data)
            local size = getDataToLoadSize(c.veh,i_data) 
            t_data[sid] = decodeJson(memory.tostring(pdata,size,false))
        end
    end
    loading = not c.status==1
end)

Re: GSX - Garage Save eXtender

Enviado: 10 Jan 2019, 01:37
por Fabio
Um_Geek escreveu:
09 Jan 2019, 22:17
Fabio escreveu:
09 Jan 2019, 20:14
Uma observação, não sei como está fazendo, mas quando for escrever strings é preciso colocar um null terminator (já deve ir com a string usada no call, então é só usar strlen(str) + 1) caso o tamanho não seja fixo, se estiver usando com tamanho conhecido (fixado por você ou informando ao strncpy usando get size do GSX), pode usar sem null terminator mesmo.

Estou usando o tamanho da ´#string´ como tamanho da memoria e uso o getDataToLoadSizedo gsx para pegar o tamanho na hora da leitura. tudo que é salvo por este recurso é colocado em uma table e convertida em json antes de ser salva, até agora não tive problemas.

Código: Selecionar tudo

local pNotifyCallbac = gsx.addNotifyCallback(function(c)
    local sid = string.format("SID%i",c.veh)
    if c.status==1 then
        local zdata = encodeJson(t_data[sid])
        if zdata ~= nil then
            local pdata = memory.strptr(zdata);
            pushDirectlyToSavedData(c.veh,i_data,#zdata,pdata);
        end
    else
        if dataToLoadExists(c.veh,i_data) == 1 then
            local pdata = getLoadDataByVehPtr(c.veh,i_data)
            local size = getDataToLoadSize(c.veh,i_data) 
            t_data[sid] = decodeJson(memory.tostring(pdata,size,false))
        end
    end
    loading = not c.status==1
end)

Parece tudo certo, entretanto, os endereços dos veículos podem repetir em momentos diferentes para veículos diferentes, pois são endereços de índices de uma pool. Quando o jogo destrói alguma entidade, ele marca em um outro array na pool que aquele lugar está livre, então outra entidade poderá ser armazenada nesse mesmo lugar. Digo isso por causa destas linhas especificamente:

Código: Selecionar tudo

local sid = string.format("SID%i",c.veh)


local zdata = encodeJson(t_data[sid])
        if zdata ~= nil then

É uma boa oportunidade para testar a _hash, lembrando que ela é um uint64_t, seria interessante converte-la para string de hex para usar de forma parecida a que você já está usando.

Re: GSX - Garage Save eXtender

Enviado: 10 Jan 2019, 11:24
por Um_Geek
Fabio escreveu:
10 Jan 2019, 01:37
É uma boa oportunidade para testar a _hash, lembrando que ela é um uint64_t, seria interessante converte-la para string de hex para usar de forma parecida a que você já está usando.

Não é bem o caso, este "sid" é usado como um endereço de índice de uma tabela. quando abre a garagem os dados são copiados do gsx para esta tabela e quando fecha ele passa da tabela para o gsx. com estes dados na tabela posso checar com mais frequência estes dados sem ficar solicitando do gsx.

Fabio escreveu:
10 Jan 2019, 01:37
Quando o jogo destrói alguma entidade, ele marca em um outro array na pool que aquele lugar está livre, então outra entidade poderá ser armazenada nesse mesmo lugar.

Fiz um pequeno "faxineiro" para remover as entradas de veículos inexistentes.