diff --git a/src/core/settings.hpp b/src/core/settings.hpp index 02eaf121..184a1abf 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -212,10 +212,9 @@ namespace big reaction request_control_event{"Request Control Event", "Blocked Request Control Event from %s", "%s tried to mess with my vehicle!"}; reaction report{"Report", "Blocked Report from %s", "%s tried to report me!"}; - interloper_reaction breakup_others{"Breakup Kicks On Other Players", "%s is trying to breakup kick %s!", "%s is trying to breakup kick %s!", true, true}; // blockable only when host but we have no way to specify that atm reaction gamer_instruction_kick{"Gamer Instruction Kick", "Blocked Gamer Instruction Kick from %s", "%s tried to kick me out!"}; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(reactions, bounty, ceo_money, ceo_kick, clear_wanted_level, crash, end_session_kick, fake_deposit, force_mission, force_teleport, gta_banner, kick_from_interior, mc_teleport, network_bail, personal_vehicle_destroyed, remote_off_radar, rotate_cam, send_to_cutscene, send_to_location, sound_spam, spectate_notification, give_collectible, transaction_error, tse_freeze, tse_sender_mismatch, vehicle_kick, teleport_to_warehouse, trigger_business_raid, start_activity, start_script, null_function_kick, destroy_personal_vehicle, clear_ped_tasks, turn_into_beast, remote_wanted_level, remote_wanted_level_others, remote_ragdoll, kick_vote, report_cash_spawn, modder_detection, request_control_event, report, breakup_others, gamer_instruction_kick) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(reactions, bounty, ceo_money, ceo_kick, clear_wanted_level, crash, end_session_kick, fake_deposit, force_mission, force_teleport, gta_banner, kick_from_interior, mc_teleport, network_bail, personal_vehicle_destroyed, remote_off_radar, rotate_cam, send_to_cutscene, send_to_location, sound_spam, spectate_notification, give_collectible, transaction_error, tse_freeze, tse_sender_mismatch, vehicle_kick, teleport_to_warehouse, trigger_business_raid, start_activity, start_script, null_function_kick, destroy_personal_vehicle, clear_ped_tasks, turn_into_beast, remote_wanted_level, remote_wanted_level_others, remote_ragdoll, kick_vote, report_cash_spawn, modder_detection, request_control_event, report, gamer_instruction_kick) } reactions{}; struct player @@ -772,7 +771,7 @@ namespace big bool show_infinite_mag = false; bool show_aimbot = false; bool show_triggerbot = false; - bool show_invisibility = false; + bool show_invisibility = false; NLOHMANN_DEFINE_TYPE_INTRUSIVE(ingame_overlay_indicators, show_player_godmode, show_off_radar, show_vehicle_godmode, show_never_wanted, show_always_full_ammo, show_infinite_ammo, show_infinite_mag, show_aimbot, show_triggerbot, show_invisibility) } ingame_overlay_indicators{}; diff --git a/src/function_types.hpp b/src/function_types.hpp index 85841d6d..4eb902a0 100644 --- a/src/function_types.hpp +++ b/src/function_types.hpp @@ -89,9 +89,11 @@ namespace big::functions using fidevice_get_device = rage::fiDevice* (*)(const char* path, bool allow_root); using fipackfile_ctor = rage::fiPackfile* (*)(rage::fiPackfile* this_); + using fipackfile_dtor = rage::fiPackfile* (*)(rage::fiPackfile* this_); using fipackfile_open_archive = bool (*)(rage::fiPackfile* this_, const char* archive, bool b_true, int type, intptr_t very_false); - using fipackfile_mount = bool (*)(rage::fiPackfile* this_, const char* mount_point); - using fipackfile_unmount = bool (*)(const char* mount_point); + using fipackfile_mount = bool (*)(rage::fiPackfile* this_, const char* mount_point); + using fipackfile_unmount = bool (*)(const char* mount_point); + using fipackfile_close_archive = void (*)(rage::fiDevice* this_); using get_gamer_online_state = bool (*)(int profile_index, rage::rlGamerHandle* handles, std::uint32_t count, int* online_state, rage::rlTaskStatus* status); using start_get_session_by_gamer_handle = bool (*)(int profile_index, rage::rlGamerHandle* handles, int count, rage::rlSessionByGamerTaskResult* result, int unk, bool* success, rage::rlTaskStatus* state); diff --git a/src/gta/fidevice.cpp b/src/gta/fidevice.cpp index 1b1297ec..9969a116 100644 --- a/src/gta/fidevice.cpp +++ b/src/gta/fidevice.cpp @@ -13,12 +13,9 @@ namespace rage { } - fiDeviceImplemented::~fiDeviceImplemented() - { - } - - fiDevice::~fiDevice() + void fiDeviceImplemented::Destroy() { + LOG(FATAL) << "pure fiDevice call (" __FUNCTION__ ")"; } uint64_t fiDeviceImplemented::Open(const char* fileName, bool) @@ -256,6 +253,11 @@ namespace rage big::g_pointers->m_gta.m_fipackfile_ctor(this); } + fiPackfile::~fiPackfile() + { + big::g_pointers->m_gta.m_fipackfile_dtor(this); + } + bool fiPackfile::OpenPackfile(const char* archive, bool b_true, int type, intptr_t very_false) { return big::g_pointers->m_gta.m_fipackfile_open_archive(this, archive, b_true, type, very_false); @@ -266,6 +268,11 @@ namespace rage return big::g_hooking->get_original()(this, mount_point); } + void fiPackfile::ClosePackfile() + { + big::g_pointers->m_gta.m_fipackfile_close_archive(this); + } + void fiDevice::Unmount(const char* rootPath) { big::g_pointers->m_gta.m_fipackfile_unmount(rootPath); diff --git a/src/gta/fidevice.hpp b/src/gta/fidevice.hpp index a57a3562..9bbfcb06 100644 --- a/src/gta/fidevice.hpp +++ b/src/gta/fidevice.hpp @@ -33,102 +33,57 @@ namespace rage } static bool MountGlobal(const char* mountPoint, fiDevice* device, bool allowRoot); - static void Unmount(const char* rootPath); - static void Unmount(fiDevice const& device); public: - virtual ~fiDevice() = 0; - - virtual uint64_t Open(const char* fileName, bool readOnly) = 0; - - virtual uint64_t OpenBulk(const char* fileName, uint64_t* ptr) = 0; - - virtual uint64_t OpenBulkWrap(const char* fileName, uint64_t* ptr, void*) = 0; - - virtual uint64_t CreateLocal(const char* fileName) = 0; - - virtual uint64_t Create(const char* fileName) = 0; - - virtual uint32_t Read(uint64_t handle, void* buffer, uint32_t toRead) = 0; - + virtual void Destroy() = 0; + virtual uint64_t Open(const char* fileName, bool readOnly) = 0; + virtual uint64_t OpenBulk(const char* fileName, uint64_t* ptr) = 0; + virtual uint64_t OpenBulkWrap(const char* fileName, uint64_t* ptr, void*) = 0; + virtual uint64_t CreateLocal(const char* fileName) = 0; + virtual uint64_t Create(const char* fileName) = 0; + virtual uint32_t Read(uint64_t handle, void* buffer, uint32_t toRead) = 0; virtual uint32_t ReadBulk(uint64_t handle, uint64_t ptr, void* buffer, uint32_t toRead) = 0; - - virtual uint32_t WriteBulk(uint64_t, int, int, int, int) = 0; - - virtual uint32_t Write(uint64_t, void*, int) = 0; - - virtual uint32_t Seek(uint64_t handle, int32_t distance, uint32_t method) = 0; - - virtual uint64_t SeekLong(uint64_t handle, int64_t distance, uint32_t method) = 0; - - virtual int32_t Close(uint64_t handle) = 0; - - virtual int32_t CloseBulk(uint64_t handle) = 0; - - virtual int GetFileLength(uint64_t handle) = 0; - - virtual uint64_t GetFileLengthUInt64(uint64_t handle) = 0; - - // dummy! - virtual int m_40(int) = 0; - - virtual bool RemoveFile(const char* file) = 0; - virtual int RenameFile(const char* from, const char* to) = 0; - virtual int CreateDirectory(const char* dir) = 0; - - virtual int RemoveDirectory(const char* dir) = 0; - - virtual void m_xx() = 0; - - virtual uint64_t GetFileLengthLong(const char* fileName) = 0; - - virtual uint64_t GetFileTime(const char* file) = 0; - virtual bool SetFileTime(const char* file, FILETIME fileTime) = 0; - - virtual uint64_t FindFirst(const char* path, fiFindData* findData) = 0; - virtual bool FindNext(uint64_t handle, fiFindData* findData) = 0; - virtual int FindClose(uint64_t handle) = 0; - - virtual rage::fiDevice* GetUnkDevice() = 0; - - virtual void* m_xy(void*, int, void*) = 0; - - virtual bool Truncate(uint64_t handle) = 0; - - virtual uint32_t GetFileAttributes(const char* path) = 0; - - virtual bool m_xz() = 0; - - virtual bool SetFileAttributes(const char* file, uint32_t FileAttributes) = 0; - - virtual int m_yx() = 0; - - // read even if read() returns less than length - virtual bool ReadFull(uint64_t handle, void* buffer, uint32_t length) = 0; - - virtual bool WriteFull(uint64_t handle, void* buffer, uint32_t length) = 0; - - virtual int32_t GetResourceVersion(const char* fileName, ResourceFlags* flags) = 0; - - virtual int32_t m_yy() = 0; - - virtual int32_t m_yz(void*) = 0; - - virtual int32_t m_zx(void*) = 0;// return 0x40000000 - - virtual bool IsCollection() = 0; - - virtual bool m_addedIn1290() = 0; - - virtual fiDevice* GetCollection() = 0;// return this - - virtual bool m_ax() = 0; - - virtual int32_t GetCollectionId() = 0; - - virtual const char* GetName() = 0; + virtual uint32_t WriteBulk(uint64_t, int, int, int, int) = 0; + virtual uint32_t Write(uint64_t, void*, int) = 0; + virtual uint32_t Seek(uint64_t handle, int32_t distance, uint32_t method) = 0; + virtual uint64_t SeekLong(uint64_t handle, int64_t distance, uint32_t method) = 0; + virtual int32_t Close(uint64_t handle) = 0; + virtual int32_t CloseBulk(uint64_t handle) = 0; + virtual int GetFileLength(uint64_t handle) = 0; + virtual uint64_t GetFileLengthUInt64(uint64_t handle) = 0; + virtual int m_40(int) = 0; + virtual bool RemoveFile(const char* file) = 0; + virtual int RenameFile(const char* from, const char* to) = 0; + virtual int CreateDirectory(const char* dir) = 0; + virtual int RemoveDirectory(const char* dir) = 0; + virtual void m_xx() = 0; + virtual uint64_t GetFileLengthLong(const char* fileName) = 0; + virtual uint64_t GetFileTime(const char* file) = 0; + virtual bool SetFileTime(const char* file, FILETIME fileTime) = 0; + virtual uint64_t FindFirst(const char* path, fiFindData* findData) = 0; + virtual bool FindNext(uint64_t handle, fiFindData* findData) = 0; + virtual int FindClose(uint64_t handle) = 0; + virtual rage::fiDevice* GetUnkDevice() = 0; + virtual void* m_xy(void*, int, void*) = 0; + virtual bool Truncate(uint64_t handle) = 0; + virtual uint32_t GetFileAttributes(const char* path) = 0; + virtual bool m_xz() = 0; + virtual bool SetFileAttributes(const char* file, uint32_t FileAttributes) = 0; + virtual int m_yx() = 0; + virtual bool ReadFull(uint64_t handle, void* buffer, uint32_t length) = 0; + virtual bool WriteFull(uint64_t handle, void* buffer, uint32_t length) = 0; + virtual int32_t GetResourceVersion(const char* fileName, ResourceFlags* flags) = 0; + virtual int32_t m_yy() = 0; + virtual int32_t m_yz(void*) = 0; + virtual int32_t m_zx(void*) = 0; + virtual bool IsCollection() = 0; + virtual bool m_addedIn1290() = 0; + virtual fiDevice* GetCollection() = 0; + virtual bool m_ax() = 0; + virtual int32_t GetCollectionId() = 0; + virtual const char* GetName() = 0; }; class fiDeviceImplemented : public fiDevice @@ -137,144 +92,64 @@ namespace rage fiDeviceImplemented(); public: - virtual ~fiDeviceImplemented(); - + virtual void Destroy(); virtual uint64_t Open(const char* fileName, bool readOnly); - virtual uint64_t OpenBulk(const char* fileName, uint64_t* ptr); - virtual uint64_t OpenBulkWrap(const char* fileName, uint64_t* ptr, void* a3); - virtual uint64_t CreateLocal(const char* fileName); - virtual uint64_t Create(const char* fileName); - virtual uint32_t Read(uint64_t handle, void* buffer, uint32_t toRead); - virtual uint32_t ReadBulk(uint64_t handle, uint64_t ptr, void* buffer, uint32_t toRead); - virtual uint32_t WriteBulk(uint64_t, int, int, int, int); - virtual uint32_t Write(uint64_t, void*, int); - virtual uint32_t Seek(uint64_t handle, int32_t distance, uint32_t method); - virtual uint64_t SeekLong(uint64_t handle, int64_t distance, uint32_t method); - virtual int32_t Close(uint64_t handle); - virtual int32_t CloseBulk(uint64_t handle); - virtual int GetFileLength(uint64_t handle); - virtual uint64_t GetFileLengthUInt64(uint64_t handle); - - // dummy! virtual int m_40(int); - virtual bool RemoveFile(const char* file); virtual int RenameFile(const char* from, const char* to); virtual int CreateDirectory(const char* dir); - virtual int RemoveDirectory(const char* dir); - virtual void m_xx(); - virtual uint64_t GetFileLengthLong(const char* fileName); - virtual uint64_t GetFileTime(const char* file); virtual bool SetFileTime(const char* file, FILETIME fileTime); - virtual uint64_t FindFirst(const char* path, fiFindData* findData); virtual bool FindNext(uint64_t handle, fiFindData* findData); virtual int FindClose(uint64_t handle); - virtual rage::fiDevice* GetUnkDevice(); - virtual void* m_xy(void* a1, int a2, void* a3); - virtual bool Truncate(uint64_t handle); - virtual uint32_t GetFileAttributes(const char* path); - virtual bool m_xz(); - virtual bool SetFileAttributes(const char* file, uint32_t FileAttributes); - virtual int m_yx(); - // read even if read() returns less than length virtual bool ReadFull(uint64_t handle, void* buffer, uint32_t length); - virtual bool WriteFull(uint64_t handle, void* buffer, uint32_t length); - virtual int32_t GetResourceVersion(const char* fileName, ResourceFlags* version); - virtual int32_t m_yy(); - virtual int32_t m_yz(void*); - - virtual int32_t m_zx(void*);// return 0x40000000 - + virtual int32_t m_zx(void*); // return 0x40000000 virtual bool IsCollection(); - virtual bool m_addedIn1290(); - - virtual fiDevice* GetCollection();// return this - + virtual fiDevice* GetCollection(); // return this virtual bool m_ax(); - virtual int32_t GetCollectionId(); - virtual const char* GetName(); }; - class fiDeviceRelative : public fiDeviceImplemented - { - private: - char m_pad[272]; - - public: - fiDeviceRelative(); - - // any RAGE path can be used; including root-relative paths - void SetPath(const char* relativeTo, rage::fiDevice* baseDevice, bool allowRoot); - - // compatibility wrapper for NY code - inline void SetPath(const char* relativeTo, bool allowRoot) - { - SetPath(relativeTo, nullptr, allowRoot); - } - - // mounts the device in the device stack - void Mount(const char* mountPoint); - }; - - class fiEncryptingDevice : public fiDeviceImplemented - { - private: - void* m_keyState; - void* m_0010; - char m_buffer[4096]; - bool m_1018; - alignas(int) char m_pad[64];// unsure - - private: - void* AllocKeyState(const uint8_t* key); - - public: - fiEncryptingDevice(const std::array& key); - - void FreeKeyState(); - }; - class fiPackfile : public fiDeviceImplemented { private: - char m_pad[368 + (0x650 - 0x590)]; + char m_pad[368 + (0x650 - 0x590)]{}; public: fiPackfile(); + ~fiPackfile(); // any RAGE path can be used; including root-relative paths bool OpenPackfile(const char* archive, bool bTrue, int type, intptr_t veryFalse); diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index 67b4ab44..732d81f9 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -148,10 +148,12 @@ namespace big functions::fidevice_get_device m_fidevice_get_device{}; functions::fipackfile_ctor m_fipackfile_ctor{}; + functions::fipackfile_dtor m_fipackfile_dtor{}; rage::fiPackfile** m_fipackfile_instances{}; functions::fipackfile_open_archive m_fipackfile_open_archive{}; functions::fipackfile_mount m_fipackfile_mount{}; functions::fipackfile_unmount m_fipackfile_unmount{}; + functions::fipackfile_close_archive m_fipackfile_close_archive{}; PVOID m_invalid_mods_crash_detour{}; PVOID m_invalid_decal_crash{}; diff --git a/src/hooks/misc/fipackfile_mount.cpp b/src/hooks/misc/fipackfile_mount.cpp index 230235d7..77d70030 100644 --- a/src/hooks/misc/fipackfile_mount.cpp +++ b/src/hooks/misc/fipackfile_mount.cpp @@ -17,9 +17,13 @@ namespace big if (g_gta_data_service->state() == eGtaDataUpdateState::ON_INIT_UPDATE_START) { yim_fipackfile rpf_wrapper = yim_fipackfile(this_, mount_point); - std::for_each(yim_fipackfile::m_wrapper_call_back.begin(), yim_fipackfile::m_wrapper_call_back.end(), [&rpf_wrapper](std::function cb) { - cb(rpf_wrapper); - }); + const auto files = rpf_wrapper.get_file_paths(); + for (const auto& file : files) + { + std::for_each(yim_fipackfile::m_wrapper_call_back.begin(), yim_fipackfile::m_wrapper_call_back.end(), [&rpf_wrapper, file](std::function cb) { + cb(rpf_wrapper, file); + }); + } if (!stricmp(this_->GetName(), "BgScript.rpf")) { diff --git a/src/hooks/protections/receive_net_message.cpp b/src/hooks/protections/receive_net_message.cpp index 57c67cb6..13ee9106 100644 --- a/src/hooks/protections/receive_net_message.cpp +++ b/src/hooks/protections/receive_net_message.cpp @@ -166,71 +166,16 @@ namespace big } break; } - case rage::eNetMessage::MsgRemoveGamersFromSessionCmd: - { - player_ptr pl; - uint64_t session_id; - buffer.ReadQWord(&session_id, 64); - uint32_t count; - buffer.ReadDword(&count, 6); - for (std::uint32_t i = 0; i < count; i++) - { - uint64_t peer_id; - buffer.ReadQWord(&peer_id, 64); - for (std::uint32_t i = 0; i < gta_util::get_network()->m_game_session_ptr->m_peer_count; i++) - { - if (gta_util::get_network()->m_game_session_ptr->m_peers[i]->m_peer_data.m_peer_id_2 == peer_id) - { - pl = g_player_service->get_by_host_token( - gta_util::get_network()->m_game_session_ptr->m_peers[i]->m_peer_data.m_host_token); - break; - } - } - } - - if (player && pl && player->id() != pl->id() && count == 1 && frame->m_msg_id == -1) - { - if (g_player_service->get_self()->is_host()) - { - g.reactions.breakup_others.process(player, pl); - session::add_infraction(player, Infraction::BREAKUP_KICK_DETECTED); - - if (g.reactions.breakup_others.block) - return true; - - if (g.reactions.breakup_others.karma) - dynamic_cast(command::get(RAGE_JOAAT("breakup")))->call(player, {}); - } - else - { - g.reactions.breakup_others.process(player, pl); - session::add_infraction(player, Infraction::BREAKUP_KICK_DETECTED); - - if (g.reactions.breakup_others.karma) - dynamic_cast(command::get(RAGE_JOAAT("breakup")))->call(player, {}); - ; - } - } - - break; - } case rage::eNetMessage::MsgNetComplaint: { uint64_t host_token{}; buffer.ReadQWord(&host_token, 64); - - std::vector players; - - uint32_t num_of_tokens{}; - buffer.ReadDword(&num_of_tokens, 32); - if (player && host_token != player->get_net_data()->m_host_token && !player->exposed_desync_protection) { session::add_infraction(player, Infraction::DESYNC_PROTECTION); player->exposed_desync_protection = true; } - - return true; // block desync kicks as host + return true; } case rage::eNetMessage::MsgRequestObjectIds: { diff --git a/src/pointers.cpp b/src/pointers.cpp index 000c2796..1c538310 100644 --- a/src/pointers.cpp +++ b/src/pointers.cpp @@ -535,31 +535,25 @@ namespace big g_pointers->m_gta.m_fipackfile_instances = ptr.add(26).rip().as(); } }, - // fiPackfile open archive + // fiPackfile dtor { - "FPFOA", - "48 8D 68 98 48 81 EC 40 01 00 00 41 8B F9", + "FPFD", + "48 89 5C 24 08 57 48 83 EC 20 48 8D 05 ? ? ? ? 33 FF 48 8B D9 48 89 01 40 88", [](memory::handle ptr) { - g_pointers->m_gta.m_fipackfile_open_archive = ptr.sub(0x18).as(); + g_pointers->m_gta.m_fipackfile_dtor = ptr.as(); } }, - // fiPackfile mount + // fiPackfile stuff { - "FPFM", - "84 C0 74 1D 48 85 DB 74 0F 48", - [](memory::handle ptr) - { - g_pointers->m_gta.m_fipackfile_mount = ptr.sub(0x1E).as(); - } - }, - // fiPackfile unmount - { - "FPFUM", - "E8 ? ? ? ? 84 C0 74 37 80 3D", + "FPU&FPCA&FPOA&FPM", + "E8 ? ? ? ? 48 8D 0D ? ? ? ? E8 ? ? ? ? 8A 05 ? ? ? ? 48 8D 0D", [](memory::handle ptr) { g_pointers->m_gta.m_fipackfile_unmount = ptr.add(1).rip().as(); + g_pointers->m_gta.m_fipackfile_close_archive = ptr.add(0xD).rip().as(); + g_pointers->m_gta.m_fipackfile_open_archive = ptr.add(0x34).rip().as(); + g_pointers->m_gta.m_fipackfile_mount = ptr.add(0x47).rip().as(); } }, // Invalid Mods Crash Detour diff --git a/src/services/gta_data/gta_data_service.cpp b/src/services/gta_data/gta_data_service.cpp index 9d453805..b8289d9d 100644 --- a/src/services/gta_data/gta_data_service.cpp +++ b/src/services/gta_data/gta_data_service.cpp @@ -30,9 +30,9 @@ namespace big } gta_data_service::gta_data_service() : - m_peds_cache(g_file_manager->get_project_file("./cache/peds.bin"), 4), - m_vehicles_cache(g_file_manager->get_project_file("./cache/vehicles.bin"), 3), - m_weapons_cache(g_file_manager->get_project_file("./cache/weapons.bin"), 4), + m_peds_cache(g_file_manager->get_project_file("./cache/peds.bin"), 5), + m_vehicles_cache(g_file_manager->get_project_file("./cache/vehicles.bin"), 4), + m_weapons_cache(g_file_manager->get_project_file("./cache/weapons.bin"), 5), m_update_state(eGtaDataUpdateState::IDLE) { if (!is_cache_up_to_date()) @@ -264,178 +264,170 @@ namespace big LOG(INFO) << "Rebuilding cache started..."; - yim_fipackfile::add_wrapper_call_back([&](yim_fipackfile& rpf_wrapper) { - const auto files = rpf_wrapper.get_file_paths(); - for (const auto& file : files) + yim_fipackfile::add_wrapper_call_back([&](yim_fipackfile& rpf_wrapper, std::filesystem::path path) -> void { + if (path.filename() == "setup2.xml") { - if (file.filename() == "setup2.xml") + std::string dlc_name; + rpf_wrapper.read_xml_file(path, [&dlc_name](pugi::xml_document& doc) { + const auto item = doc.select_node("/SSetupData/nameHash"); + dlc_name = item.node().text().as_string(); + }); + + if (dlc_name == "mpG9EC") { - std::string dlc_name; - rpf_wrapper.read_xml_file(file, [&dlc_name](pugi::xml_document& doc) { - const auto item = doc.select_node("/SSetupData/nameHash"); - dlc_name = item.node().text().as_string(); - }); - - if (dlc_name == "mpG9EC") - { - LOG(VERBOSE) << "Bad DLC, skipping..."; - - return std::size_t(0); - } - } - else if (file.filename() == "vehicles.meta") - { - rpf_wrapper.read_xml_file(file, [&exists, &vehicles, &mapped_vehicles](pugi::xml_document& doc) { - const auto& items = doc.select_nodes("/CVehicleModelInfo__InitDataList/InitDatas/Item"); - for (const auto& item_node : items) - { - const auto item = item_node.node(); - - const auto name = item.child("modelName").text().as_string(); - const auto hash = rage::joaat(name); - - if (exists(mapped_vehicles, hash)) - continue; - mapped_vehicles.emplace_back(hash); - - auto veh = vehicle_item{}; - std::strncpy(veh.m_name, name, sizeof(veh.m_name)); - - const auto manufacturer_display = item.child("vehicleMakeName").text().as_string(); - std::strncpy(veh.m_display_manufacturer, manufacturer_display, sizeof(veh.m_display_manufacturer)); - - const auto game_name = item.child("gameName").text().as_string(); - std::strncpy(veh.m_display_name, game_name, sizeof(veh.m_display_name)); - - const auto vehicle_class = item.child("vehicleClass").text().as_string(); - constexpr auto enum_prefix_len = 3; - if (std::strlen(vehicle_class) > enum_prefix_len) - std::strncpy(veh.m_vehicle_class, vehicle_class + enum_prefix_len, sizeof(veh.m_vehicle_class)); - - veh.m_hash = hash; - - vehicles.emplace_back(std::move(veh)); - } - }); - } - else if (const auto file_str = file.string(); file_str.find("weapon") != std::string::npos && file.extension() == ".meta") - { - rpf_wrapper.read_xml_file(file, [&exists, &weapons, &mapped_weapons](pugi::xml_document& doc) { - const auto& items = doc.select_nodes("/CWeaponInfoBlob/Infos/Item/Infos/Item[@type='CWeaponInfo']"); - for (const auto& item_node : items) - { - const auto item = item_node.node(); - const auto name = item.child("Name").text().as_string(); - const auto hash = rage::joaat(name); - - if (hash == RAGE_JOAAT("WEAPON_BIRD_CRAP")) - continue; - - if (exists(mapped_weapons, hash)) - continue; - mapped_weapons.emplace_back(hash); - - const auto human_name_hash = item.child("HumanNameHash").text().as_string(); - if (std::strcmp(human_name_hash, "WT_INVALID") == 0 || std::strcmp(human_name_hash, "WT_VEHMINE") == 0) - continue; - - auto weapon = weapon_item{}; - - std::strncpy(weapon.m_name, name, sizeof(weapon.m_name)); - - std::strncpy(weapon.m_display_name, human_name_hash, sizeof(weapon.m_display_name)); - - auto weapon_flags = std::string(item.child("WeaponFlags").text().as_string()); - - bool is_gun = false; - bool is_rechargable = false; - - const char* category = ""; - - std::size_t pos; - while ((pos = weapon_flags.find(' ')) != std::string::npos) - { - const auto flag = weapon_flags.substr(0, pos); - if (flag == "Thrown") - { - weapon.m_throwable = true; - } - else if (flag == "Gun") - { - is_gun = true; - } - else if (flag == "DisplayRechargeTimeHUD") - { - is_rechargable = true; - } - else if (flag == "Vehicle" || flag == "HiddenFromWeaponWheel" || flag == "NotAWeapon") - { - goto skip; - } - - weapon_flags.erase(0, pos + 1); - } - - category = item.child("Group").text().as_string(); - - if (std::strlen(category) == 0 || std::strcmp(category, "GROUP_DIGISCANNER") == 0) - continue; - - if (std::strlen(category) > 6) - { - std::strncpy(weapon.m_weapon_type, category + 6, sizeof(weapon.m_weapon_type)); - } - - if (is_gun || !std::strcmp(weapon.m_weapon_type, "MELEE") || !std::strcmp(weapon.m_weapon_type, "UNARMED")) - { - const std::string reward_prefix = "REWARD_"; - weapon.m_reward_hash = rage::joaat(reward_prefix + name); - - if (is_gun && !is_rechargable) - { - std::string weapon_id = name + 7; - weapon.m_reward_ammo_hash = rage::joaat(reward_prefix + "AMMO_" + weapon_id); - } - } - - weapon.m_hash = hash; - - weapons.emplace_back(std::move(weapon)); - skip: - continue; - } - }); - } - else if (file.filename() == "peds.meta") - { - rpf_wrapper.read_xml_file(file, [&exists, &peds, &mapped_peds](pugi::xml_document& doc) { - parse_ped(peds, mapped_peds, doc); - }); - } - else if (std::string str = rpf_wrapper.get_name(); (str.find("componentpeds") != std::string::npos || str.find("streamedpeds") != std::string::npos || str.find("mppatches") != std::string::npos || str.find("cutspeds") != std::string::npos) && file.extension() == ".yft") - { - const auto name = file.stem().string(); - const auto hash = rage::joaat(name); - - if (is_crash_ped(hash)) - continue; - - if (std::find(mapped_peds.begin(), mapped_peds.end(), hash) != mapped_peds.end()) - continue; - - mapped_peds.emplace_back(hash); - - auto ped = ped_item{}; - - std::strncpy(ped.m_name, name.c_str(), sizeof(ped.m_name)); - - ped.m_hash = hash; - - peds.emplace_back(std::move(ped)); + LOG(VERBOSE) << "Bad DLC, skipping..."; } } + else if (path.filename() == "vehicles.meta") + { + rpf_wrapper.read_xml_file(path, [&exists, &vehicles, &mapped_vehicles](pugi::xml_document& doc) { + const auto& items = doc.select_nodes("/CVehicleModelInfo__InitDataList/InitDatas/Item"); + for (const auto& item_node : items) + { + const auto item = item_node.node(); - return files.size(); + const auto name = item.child("modelName").text().as_string(); + const auto hash = rage::joaat(name); + + if (exists(mapped_vehicles, hash)) + continue; + mapped_vehicles.emplace_back(hash); + + auto veh = vehicle_item{}; + std::strncpy(veh.m_name, name, sizeof(veh.m_name)); + + const auto manufacturer_display = item.child("vehicleMakeName").text().as_string(); + std::strncpy(veh.m_display_manufacturer, manufacturer_display, sizeof(veh.m_display_manufacturer)); + + const auto game_name = item.child("gameName").text().as_string(); + std::strncpy(veh.m_display_name, game_name, sizeof(veh.m_display_name)); + + const auto vehicle_class = item.child("vehicleClass").text().as_string(); + constexpr auto enum_prefix_len = 3; + if (std::strlen(vehicle_class) > enum_prefix_len) + std::strncpy(veh.m_vehicle_class, vehicle_class + enum_prefix_len, sizeof(veh.m_vehicle_class)); + + veh.m_hash = hash; + + vehicles.emplace_back(std::move(veh)); + } + }); + } + else if (const auto file_str = path.string(); file_str.find("weapon") != std::string::npos && path.extension() == ".meta") + { + rpf_wrapper.read_xml_file(path, [&exists, &weapons, &mapped_weapons](pugi::xml_document& doc) { + const auto& items = doc.select_nodes("/CWeaponInfoBlob/Infos/Item/Infos/Item[@type='CWeaponInfo']"); + for (const auto& item_node : items) + { + const auto item = item_node.node(); + const auto name = item.child("Name").text().as_string(); + const auto hash = rage::joaat(name); + + if (hash == RAGE_JOAAT("WEAPON_BIRD_CRAP")) + continue; + + if (exists(mapped_weapons, hash)) + continue; + mapped_weapons.emplace_back(hash); + + const auto human_name_hash = item.child("HumanNameHash").text().as_string(); + if (std::strcmp(human_name_hash, "WT_INVALID") == 0 || std::strcmp(human_name_hash, "WT_VEHMINE") == 0) + continue; + + auto weapon = weapon_item{}; + + std::strncpy(weapon.m_name, name, sizeof(weapon.m_name)); + + std::strncpy(weapon.m_display_name, human_name_hash, sizeof(weapon.m_display_name)); + + auto weapon_flags = std::string(item.child("WeaponFlags").text().as_string()); + + bool is_gun = false; + bool is_rechargable = false; + + const char* category = ""; + + std::size_t pos; + while ((pos = weapon_flags.find(' ')) != std::string::npos) + { + const auto flag = weapon_flags.substr(0, pos); + if (flag == "Thrown") + { + weapon.m_throwable = true; + } + else if (flag == "Gun") + { + is_gun = true; + } + else if (flag == "DisplayRechargeTimeHUD") + { + is_rechargable = true; + } + else if (flag == "Vehicle" || flag == "HiddenFromWeaponWheel" || flag == "NotAWeapon") + { + goto skip; + } + + weapon_flags.erase(0, pos + 1); + } + + category = item.child("Group").text().as_string(); + + if (std::strlen(category) == 0 || std::strcmp(category, "GROUP_DIGISCANNER") == 0) + continue; + + if (std::strlen(category) > 6) + { + std::strncpy(weapon.m_weapon_type, category + 6, sizeof(weapon.m_weapon_type)); + } + + if (is_gun || !std::strcmp(weapon.m_weapon_type, "MELEE") || !std::strcmp(weapon.m_weapon_type, "UNARMED")) + { + const std::string reward_prefix = "REWARD_"; + weapon.m_reward_hash = rage::joaat(reward_prefix + name); + + if (is_gun && !is_rechargable) + { + std::string weapon_id = name + 7; + weapon.m_reward_ammo_hash = rage::joaat(reward_prefix + "AMMO_" + weapon_id); + } + } + + weapon.m_hash = hash; + + weapons.emplace_back(std::move(weapon)); + skip: + continue; + } + }); + } + else if (path.filename() == "peds.meta") + { + rpf_wrapper.read_xml_file(path, [&exists, &peds, &mapped_peds](pugi::xml_document& doc) { + parse_ped(peds, mapped_peds, doc); + }); + } + else if (std::string str = rpf_wrapper.get_name(); (str.find("componentpeds") != std::string::npos || str.find("streamedpeds") != std::string::npos || str.find("mppatches") != std::string::npos || str.find("cutspeds") != std::string::npos) && path.extension() == ".yft") + { + const auto name = path.stem().string(); + const auto hash = rage::joaat(name); + + if (is_crash_ped(hash)) + return; + + if (std::find(mapped_peds.begin(), mapped_peds.end(), hash) != mapped_peds.end()) + return; + + mapped_peds.emplace_back(hash); + + auto ped = ped_item{}; + + std::strncpy(ped.m_name, name.c_str(), sizeof(ped.m_name)); + + ped.m_hash = hash; + + peds.emplace_back(std::move(ped)); + } }); if (state() == eGtaDataUpdateState::UPDATING) diff --git a/src/services/gta_data/yim_fipackfile.cpp b/src/services/gta_data/yim_fipackfile.cpp index 60f32595..ded1b8c5 100644 --- a/src/services/gta_data/yim_fipackfile.cpp +++ b/src/services/gta_data/yim_fipackfile.cpp @@ -8,30 +8,67 @@ namespace big { yim_fipackfile::yim_fipackfile(rage::fiPackfile* rpf, const std::string& mount_name) { - this->rpf = rpf; + this->rpf = rpf; this->mount_name = mount_name; } - void yim_fipackfile::add_wrapper_call_back(std::function cb) + void yim_fipackfile::add_wrapper_call_back(std::function cb) { m_wrapper_call_back.push_back(cb); } - void yim_fipackfile::for_each_fipackfile() + void yim_fipackfile::traverse_rpf_file(const std::string& path, int depth) { - for (int i = 1; i < 3672; i++) // fipackfile ctor start with 1 + std::string mount_path = std::format("temp{}:/", depth); + + rage::fiPackfile packfile; + packfile.OpenPackfile(path.c_str(), true, 0, 0); + packfile.Mount(mount_path.c_str()); + + yim_fipackfile rpf_wrapper = yim_fipackfile(&packfile, mount_path); + + const auto files = rpf_wrapper.get_file_paths(); + for (const auto& file : files) { - auto* rpf = g_pointers->m_gta.m_fipackfile_instances[i]; - - if (rpf) + if (file.extension() == ".rpf") { - yim_fipackfile rpf_wrapper = yim_fipackfile(rpf); + if (auto handle = ((rage::fiDevice*)&packfile)->Open(file.string().c_str(), true)) + { + uint32_t encryption_type{}; + ((rage::fiDevice*)&packfile)->Seek(handle, 12, 0); + ((rage::fiDevice*)&packfile)->Read(handle, &encryption_type, 4); + ((rage::fiDevice*)&packfile)->Close(handle); - std::for_each(yim_fipackfile::m_wrapper_call_back.begin(), yim_fipackfile::m_wrapper_call_back.end(), [&rpf_wrapper](std::function cb) { - cb(rpf_wrapper); + if (encryption_type == 0xFFFFFF9) + continue; // skip AES encrypted RPFs + + traverse_rpf_file(file.string(), depth + 1); + } + } + else + { + std::for_each(yim_fipackfile::m_wrapper_call_back.begin(), yim_fipackfile::m_wrapper_call_back.end(), [&rpf_wrapper, file](std::function cb) { + cb(rpf_wrapper, file); }); } } + + packfile.Unmount(mount_path.c_str()); + packfile.ClosePackfile(); + } + + void yim_fipackfile::for_each_fipackfile() + { + for (auto& entry : std::filesystem::recursive_directory_iterator(std::filesystem::current_path())) + { + auto rel_path = std::filesystem::relative(entry.path()); + + if (rel_path.string().contains("mods")) + continue; + + if (rel_path.extension() == ".rpf") + traverse_rpf_file(rel_path.string()); + } } std::vector yim_fipackfile::get_file_paths(std::string parent) @@ -50,7 +87,7 @@ namespace big { std::string fn; - if (parent == "/") + if (parent == mount_name) fn = std::string(parent.c_str()) + std::string(findData.fileName); else fn = std::string(parent.c_str()) + std::string("/") + std::string(findData.fileName); diff --git a/src/services/gta_data/yim_fipackfile.hpp b/src/services/gta_data/yim_fipackfile.hpp index 67eeb7e5..2586cee0 100644 --- a/src/services/gta_data/yim_fipackfile.hpp +++ b/src/services/gta_data/yim_fipackfile.hpp @@ -13,10 +13,11 @@ namespace big public: explicit yim_fipackfile(rage::fiPackfile* rpf, const std::string& mount_name = "/"); - static inline std::vector> m_wrapper_call_back; + static inline std::vector> m_wrapper_call_back; - static void add_wrapper_call_back(std::function cb); + static void add_wrapper_call_back(std::function cb); + static void traverse_rpf_file(const std::string& path, int depth = 0); static void for_each_fipackfile(); std::vector get_file_paths(std::string parent = {}); diff --git a/src/views/settings/view_reaction_settings.cpp b/src/views/settings/view_reaction_settings.cpp index 0e79d15a..84bc07b8 100644 --- a/src/views/settings/view_reaction_settings.cpp +++ b/src/views/settings/view_reaction_settings.cpp @@ -100,7 +100,6 @@ namespace big draw_reaction(g.reactions.request_control_event); ImGui::Separator(); draw_reaction(g.reactions.gamer_instruction_kick); - draw_interloper_reaction(g.reactions.breakup_others); components::title("SETTINGS_NOTIFICATIONS"_T); components::sub_title("SETTINGS_NOTIFY_GTA_THREADS"_T);