fabio3 Posted February 24, 2019 Share Posted February 24, 2019 (edited) Garage Save eXtender (or GSX for short) is an ASI mod for GTA San Andreas that allows other mods to store more info/data for cars saved in garages. Showing the Vehicle License Plate Save mod: The data stored is identified by name and exclusive for the vehicle it belongs You can use the GSX in mods CLEO, C/C++, Lua or CLEO and C/C++ (Portuguese) GSX save files located in Documents/GTA San Andreas User Files/gsx Code examples included in download. Thread in Mixmods forum (Portuguese) Download GSX (+API and examples) Mods currently using GSX: Download License Plate Save Mod ASI (requires the gsx.asi) VehFuncs - new vehicle functions [Lua] Vehicle Paint using RGB colors (Portuguese) [Lua] Other vehicles painted with RGB colors (Portuguese) [Lua] Gas stations (Portuguese) Reserved data names: _hash Contains a unsigned 64bits integer hash for the vehicle TODO: Documentation of all functions More tests in GSX.asi Spoiler License Plate Save (with logging for debug) source code: Spoiler Requires: GSX API (included in GSX download) Plugin-SDK LINK/2012's Injector //#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" #include <fstream> static auto getVehicleModelInfoByID = injector::cstd<CVehicleModelInfo*(int id)>::call<0x00403DA0>; auto CustomCarPlate_TextureCreate = injector::thiscall<bool(CVehicle *, CVehicleModelInfo *)>::call<0x006D10E0>; std::fstream saveLicensePlateLog("saveLicensePlate.log", std::ios::out | std::ios::trunc); 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)) { //RwFrame; //RpClump; char testPlate[9] = { 0 }; strncpy(testPlate, plateText, 8u); testPlate[8] = 0; saveLicensePlateLog << std::to_string((uintptr_t)test->veh) << " GTA SA function CustomCarPlate_TextureCreate: OK " << testPlate << std::endl; } else { //MessageBoxA(0, "error plate", "", 0); saveLicensePlateLog << std::to_string((uintptr_t)test->veh) << " GTA SA function CustomCarPlate_TextureCreate: error" << std::endl; } } else { saveLicensePlateLog << std::to_string((uintptr_t)test->veh) << " plateText is nullptr " << std::endl; } } else { saveLicensePlateLog << std::to_string((uintptr_t)test->veh) << " GSX carplate not exists" << std::endl; } break; } case GSX::SAVE_CAR: { if (test->veh->m_pCustomCarPlate) { setDataToSaveLater(test->veh, "carplate", 8, test->veh->m_pCustomCarPlate->name, true); char testPlate[9] = {0}; strncpy(testPlate, test->veh->m_pCustomCarPlate->name, 8u); testPlate[8] = 0; saveLicensePlateLog << std::to_string((uintptr_t)test->veh) << " saving license plate " << testPlate << std::endl; } else { saveLicensePlateLog << std::to_string((uintptr_t)test->veh) << " veh->m_pCustomCarPlate is nullptr" << std::endl; } break; } default: saveLicensePlateLog << "GSX unknow status" << std::endl; break; } } else { saveLicensePlateLog << "GSX Veh is nullptr" << std::endl; } } void onload(int id) { static bool loaded = false; if (!loaded) { saveLicensePlateLog << "ASI date/time: " __DATE__ " " __TIME__ << std::endl; 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; } Edited April 16, 2020 by fabio3 Junior_Djjr, Hovac, NickyBellic and 6 others 8 1 Link to comment https://gtaforums.com/topic/925563-garage-save-extender/ Share on other sites More sharing options...
lockout18yt Posted September 9, 2021 Share Posted September 9, 2021 Hey! Do you know why this could be crashing with GTA Underground? I'm thinking because of the added cars, but maybe that's not it. Any help would be appreciated! Link to comment https://gtaforums.com/topic/925563-garage-save-extender/#findComment-1071639666 Share on other sites More sharing options...
gui7814 Posted October 15, 2024 Share Posted October 15, 2024 I Don't Know Why But the Game Crashes When I Try to Use the Function dataToLoadExists by CLEO My Script: {$CLEO} 0AA2: 0@ = load_library "gsx.asi" // IF and SET 0AA4: 6@ = get_proc_address "getNewCarGrgForeach" library 0@ // IF and SET 0AA4: 7@ = get_proc_address "getLoadDataByVehPtr" library 0@ // IF and SET 0AA4: 8@ = get_proc_address "dataToLoadExists" library 0@ // IF and SET 0AA4: 10@ = get_proc_address "pushDirectlyToSavedData" library 0@ // IF and SET const LOAD_CAR = 0 SAVE_CAR = 1 end while true wait 0 // Other things 0AC7: 13@ = var 16@ offset // carInfo - 8 bytes 0AC6: 14@ = label @positionRegister offset // 8 bytes while true 0AA7: call_function 6@ num_params 2 pop 2 13@ 14@ retorno 15@ // getNewCarGrgForeach / GSX::getNewCarForeach(i, out) if 15@ <> 0 jf break if 17@ == 0 then 23@ = call_function_return {address} 8@ {numParams} 2 {pop} 2 {funcParams} 16@ 'TESTVAR' if 23@ == 1 then 22@ = call_function_return {address} 7@ {numParams} 2 {pop} 2 {funcParams} 16@ 'TESTVAR' if 22@ <> 0 then 0AD0: show_formatted_text_lowpriority "Test Var %i" time 4000 22@ end end end if 17@ == 1 then call_function {address} 10@ {numParams} 5 {pop} 5 {funcParams} 16@ 'TESTVAR' 1 4 true print_string {text} "Value Saved!" {time} 4000 end end // Other things 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 SCRLOG Log: 00000135&0: [0AC7] GET_VAR_POINTER l16(0) -> 27048020 00000143&0: [0AC6] GET_LABEL_POINTER -403 -> 196535771 00000153&0: [0AA7] CALL_FUNCTION_RETURN 0x6D754490 2 2 27048020 196535771 -> 1 00000172&0: [00D6] IF 0 00000176&0: [8039] NOT l15(1) == 0 // TRUE 00000183&1: [004D] GOTO_IF_FALSE -388 00000190&1: [00D6] IF 0 00000194&0: [0039] l17(0) == 0 // TRUE 00000201&1: [004D] GOTO_IF_FALSE -316 00000208&1: [0AA7] CALL_FUNCTION_RETURN 0x6D750AD0 2 2 147401896 "TESTVAR" Link to comment https://gtaforums.com/topic/925563-garage-save-extender/#findComment-1072445247 Share on other sites More sharing options...
gui7814 Posted October 18, 2024 Share Posted October 18, 2024 Ok, I managed to solve the problem, I just had to invert the order of the parameters in the functions Here is the code: {$CLEO} 0AA2: 0@ = load_library "gsx.asi" // IF and SET 0AA4: 6@ = get_proc_address "getNewCarGrgForeach" library 0@ // IF and SET 0AA4: 7@ = get_proc_address "getLoadDataByVehPtr" library 0@ // IF and SET 0AA4: 8@ = get_proc_address "dataToLoadExists" library 0@ // IF and SET 0AA4: 10@ = get_proc_address "pushDirectlyToSavedData" library 0@ // IF and SET const LOAD_CAR = 0 SAVE_CAR = 1 end while true wait 0 // Other things 0AC7: 13@ = var 16@ offset // carInfo - 8 bytes 0AC6: 14@ = label @positionRegister offset // 8 bytes while true 0AA7: call_function 6@ num_params 2 pop 2 13@ 14@ retorno 15@ // getNewCarGrgForeach / GSX::getNewCarForeach(i, out) if 15@ <> 0 jf break if 17@ == 1 then print_string 'Value Saved!' 2000 else call_function_return {address} 8@ {numParams} 2 {pop} 2 {funcParams} "TESTVAR" 16@ 23@ print_string 'Value Loaded!' 2000 if 23@ <> 0 then call_function_return {address} 7@ {numParams} 2 {pop} 2 {funcParams} "TESTVAR" 16@ 22@ 0A8D: 22@ = read_memory 22@ size 4 virtual_protect 1 0AD0: show_formatted_text_lowpriority "Test Var %i" time 4000 22@ end end end // Other things end :carInfo hex 00 00 00 00 // veh ptr 00 00 00 00 // status end :carValue hex 00 end :buflicenseplate hex 00 end :positionRegister hex 00 00 00 00 00 00 00 00 end As for some reason the function of saving the date in the vehicle was not taking effect when I closed the garage, I had to create another script that saves the date in the vehicle all the time Here is the script: {$CLEO} {$USE CLEO+} 0AA2: 0@ = load_library "gsx.asi" // IF and SET 0AA4: 10@ = get_proc_address "pushDirectlyToSavedData" library 0@ // IF and SET 0000: :MAIN wait 0 29@ = 0 while get_any_car_no_save_recursive 29@ progress_to 29@ car_to 12@ if 056E: car 12@ defined then 0227: 28@ = car 12@ health //0AD0: show_formatted_text_lowpriority "Test Var %i" time 4000 28@ 0AC6: 25@ = label @carValue offset // 8 bytes 0A97: 16@ = vehicle 12@ struct 0A8C: write_memory 25@ size 4 value 1 virtual_protect 1 call_function {address} 10@ {numParams} 4 {pop} 4 {funcParams} 25@ 4 "TESTVAR" 16@ end end jump @MAIN :carValue hex 00 00 00 00 end Link to comment https://gtaforums.com/topic/925563-garage-save-extender/#findComment-1072446216 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now