diff --git a/cmake/gtav-classes.cmake b/cmake/gtav-classes.cmake index de8a6723..7ed10660 100644 --- a/cmake/gtav-classes.cmake +++ b/cmake/gtav-classes.cmake @@ -3,7 +3,7 @@ include(FetchContent) FetchContent_Declare( gtav_classes GIT_REPOSITORY https://github.com/Yimura/GTAV-Classes.git - GIT_TAG 09a586011a296cf8ce3ffb9c15db7ce474ea4363 + GIT_TAG ddd118410c5ede28e3a5978ebda93b83634d3293 GIT_PROGRESS TRUE CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/docs/lua/tables/script.md b/docs/lua/tables/script.md index e43b2697..a922cc0c 100644 --- a/docs/lua/tables/script.md +++ b/docs/lua/tables/script.md @@ -2,7 +2,7 @@ Table containing helper functions related to gta scripts. -## Functions (2) +## Functions (3) ### `register_looped(name, func)` @@ -75,4 +75,15 @@ end) script.run_in_fiber(func) ``` +### `execute_as_script(script_name, func)` + +- **Parameters:** + - `script_name` (string): target script thread. + - `func` (function): function that will be executed once in the script thread. + +**Example Usage:** +```lua +script.execute_as_script(script_name, func) +``` + diff --git a/src/backend/commands/player/kick/end_session_kick.cpp b/src/backend/commands/player/kick/end_session_kick.cpp index bd401c25..de269eff 100644 --- a/src/backend/commands/player/kick/end_session_kick.cpp +++ b/src/backend/commands/player/kick/end_session_kick.cpp @@ -21,7 +21,7 @@ namespace big return; if (!scripts::force_host("freemode"_J)) { - g_notification_service->push_error("END_KICK"_T.data(), "BACKEND_END_SESSION_KICK_FORCE_SCRIPT_HOST_FAILED"_T.data()); + g_notification_service.push_error("END_KICK"_T.data(), "BACKEND_END_SESSION_KICK_FORCE_SCRIPT_HOST_FAILED"_T.data()); return; } diff --git a/src/backend/commands/player/kick/host_kick.cpp b/src/backend/commands/player/kick/host_kick.cpp index 9330ef4d..281aecdd 100644 --- a/src/backend/commands/player/kick/host_kick.cpp +++ b/src/backend/commands/player/kick/host_kick.cpp @@ -18,7 +18,7 @@ namespace big return; if (!g_player_service->get_self()->is_host()) { - g_notification_service->push_error("HOST_KICK"_T.data(), "BACKEND_HOST_KICK_FAILED"_T.data()); + g_notification_service.push_error("HOST_KICK"_T.data(), "BACKEND_HOST_KICK_FAILED"_T.data()); return; } @@ -27,4 +27,4 @@ namespace big }; host_kick g_host_kick("hostkick", "HOST_KICK", "HOST_KICK_DESC", 0, false); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/kick/script_host_kick.cpp b/src/backend/commands/player/kick/script_host_kick.cpp index d66330e5..b6dbc96f 100644 --- a/src/backend/commands/player/kick/script_host_kick.cpp +++ b/src/backend/commands/player/kick/script_host_kick.cpp @@ -21,7 +21,7 @@ namespace big return; if (!scripts::force_host("freemode"_J)) { - g_notification_service->push_error("Kick", "Force script host failed!"); + g_notification_service.push_error("Kick", "Force script host failed!"); return; } diff --git a/src/backend/commands/player/toxic/turn_into_beast.cpp b/src/backend/commands/player/toxic/turn_into_beast.cpp index 1aa70b27..31bfcb7d 100644 --- a/src/backend/commands/player/toxic/turn_into_beast.cpp +++ b/src/backend/commands/player/toxic/turn_into_beast.cpp @@ -23,11 +23,11 @@ namespace big { if (!NETWORK::NETWORK_IS_PLAYER_A_PARTICIPANT_ON_SCRIPT(id, "am_launcher", -1)) { - g_notification_service->push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_CANNOT_START_AM_LAUNCHER"_T.data()); + g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_CANNOT_START_AM_LAUNCHER"_T.data()); return; } - g_notification_service->push("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_STARTING"_T.data()); + g_notification_service.push("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_STARTING"_T.data()); scripts::start_launcher_script(47); @@ -35,7 +35,7 @@ namespace big { if (i >= 1000) { - g_notification_service->push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED"_T.data()); + g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED"_T.data()); return; } @@ -48,7 +48,7 @@ namespace big if (!scripts::force_host("am_hunt_the_beast"_J)) { - g_notification_service->push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED_CONTROL"_T.data()); + g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED_CONTROL"_T.data()); return; } @@ -89,7 +89,7 @@ namespace big { if (i >= 7000) { - g_notification_service->push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED"_T.data()); + g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED"_T.data()); return; } @@ -100,7 +100,7 @@ namespace big if (!scripts::force_host("am_hunt_the_beast"_J)) { - g_notification_service->push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED_CONTROL"_T.data()); + g_notification_service.push_error("TURN_INTO_BEAST"_T.data(), "BACKEND_TURN_INTO_BEAST_FAILED_CONTROL"_T.data()); return; } diff --git a/src/backend/commands/player/vehicle/boost_vehicle.cpp b/src/backend/commands/player/vehicle/boost_vehicle.cpp index 9a6b0f43..685a669e 100644 --- a/src/backend/commands/player/vehicle/boost_vehicle.cpp +++ b/src/backend/commands/player/vehicle/boost_vehicle.cpp @@ -14,7 +14,7 @@ namespace big Ped ped = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()); if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -26,11 +26,11 @@ namespace big } else { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); } } } }; boost_vehicle g_boost_vehicle("boostveh", "BACKEND_BOOST_VEHICLE", "BACKEND_BOOST_VEHICLE_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/burst_tyres.cpp b/src/backend/commands/player/vehicle/burst_tyres.cpp index 338f6866..828af186 100644 --- a/src/backend/commands/player/vehicle/burst_tyres.cpp +++ b/src/backend/commands/player/vehicle/burst_tyres.cpp @@ -15,7 +15,7 @@ namespace big if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { diff --git a/src/backend/commands/player/vehicle/close_doors.cpp b/src/backend/commands/player/vehicle/close_doors.cpp index 0cdb2330..a793dfa9 100644 --- a/src/backend/commands/player/vehicle/close_doors.cpp +++ b/src/backend/commands/player/vehicle/close_doors.cpp @@ -14,7 +14,7 @@ namespace big if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -26,11 +26,11 @@ namespace big } else { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); } } } }; close_doors g_close_doors("closedoors", "BACKEND_CLOSE_VEHICLE_DOORS", "BACKEND_CLOSE_VEHICLE_DOORS_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/downgrade_vehicle.cpp b/src/backend/commands/player/vehicle/downgrade_vehicle.cpp index d3428636..34711f84 100644 --- a/src/backend/commands/player/vehicle/downgrade_vehicle.cpp +++ b/src/backend/commands/player/vehicle/downgrade_vehicle.cpp @@ -16,7 +16,7 @@ namespace big if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -34,4 +34,4 @@ namespace big }; downgrade_vehicle g_downgrade_vehicle("downgradeveh", "BACKEND_DOWNGRADE_VEHICLE", "BACKEND_DOWNGRADE_VEHICLE_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/flip_180.cpp b/src/backend/commands/player/vehicle/flip_180.cpp index e7cb7153..73002ed2 100644 --- a/src/backend/commands/player/vehicle/flip_180.cpp +++ b/src/backend/commands/player/vehicle/flip_180.cpp @@ -18,7 +18,7 @@ namespace big if (!PED::IS_PED_IN_ANY_VEHICLE(player_ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -41,4 +41,4 @@ namespace big }; flip_180 g_flip_180("flip180", "BACKEND_FLIP", "BACKEND_FLIP_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/flying_vehicle.cpp b/src/backend/commands/player/vehicle/flying_vehicle.cpp index ccb27b49..3e4d0c97 100644 --- a/src/backend/commands/player/vehicle/flying_vehicle.cpp +++ b/src/backend/commands/player/vehicle/flying_vehicle.cpp @@ -15,7 +15,7 @@ namespace big if (!PED::IS_PED_IN_ANY_VEHICLE(ent, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -30,4 +30,4 @@ namespace big }; flying_vehicle g_flying_vehicle("flyingveh", "BACKEND_FLYING_VEHICLE", "BACKEND_FLYING_VEHICLE_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/kill_engine.cpp b/src/backend/commands/player/vehicle/kill_engine.cpp index 83ef224c..97d6b18b 100644 --- a/src/backend/commands/player/vehicle/kill_engine.cpp +++ b/src/backend/commands/player/vehicle/kill_engine.cpp @@ -13,7 +13,7 @@ namespace big Ped ped = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()); if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -25,11 +25,11 @@ namespace big } else { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); } } } }; kill_engine g_kill_engine("killengine", "BACKEND_KILL_VEHICLE_ENGINE", "BACKEND_KILL_VEHICLE_ENGINE_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/lock_doors.cpp b/src/backend/commands/player/vehicle/lock_doors.cpp index 6d20ae6f..2962281e 100644 --- a/src/backend/commands/player/vehicle/lock_doors.cpp +++ b/src/backend/commands/player/vehicle/lock_doors.cpp @@ -14,7 +14,7 @@ namespace big Ped ped = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()); if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -27,4 +27,4 @@ namespace big }; lock_vehicle g_lock_vehicle("lockveh", "BACKEND_LOCK_VEHICLE", "BACKEND_LOCK_VEHICLE_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/open_doors.cpp b/src/backend/commands/player/vehicle/open_doors.cpp index 35525605..82cc3b29 100644 --- a/src/backend/commands/player/vehicle/open_doors.cpp +++ b/src/backend/commands/player/vehicle/open_doors.cpp @@ -14,7 +14,7 @@ namespace big Ped ped = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()); if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -29,11 +29,11 @@ namespace big } else { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); } } } }; open_doors g_open_doors("opendoors", "BACKEND_OPEN_VEHICLE_DOORS", "BACKEND_OPEN_VEHICLE_DOORS_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/remote_control_vehicle.cpp b/src/backend/commands/player/vehicle/remote_control_vehicle.cpp index 9e1f95a9..aeb027b6 100644 --- a/src/backend/commands/player/vehicle/remote_control_vehicle.cpp +++ b/src/backend/commands/player/vehicle/remote_control_vehicle.cpp @@ -15,9 +15,9 @@ namespace big if (veh == 0) { if (g.player.spectating) - g_notification_service->push_warning("REMOTE_CONTROL"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("REMOTE_CONTROL"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); else - g_notification_service->push_warning("REMOTE_CONTROL"_T.data(), std::format("{} {}", "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T, "BACKEND_REMOTE_CONTROL_VEHICLE_SPECTATE"_T).c_str()); + g_notification_service.push_warning("REMOTE_CONTROL"_T.data(), std::format("{} {}", "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T, "BACKEND_REMOTE_CONTROL_VEHICLE_SPECTATE"_T).c_str()); return; } @@ -27,4 +27,4 @@ namespace big }; remote_control_vehicle g_remote_control_vehicle("rcplayer", "BACKEND_REMOTE_CONTROL_VEHICLE", "BACKEND_REMOTE_CONTROL_VEHICLE_DESC", 0, false); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/special_ability.cpp b/src/backend/commands/player/vehicle/special_ability.cpp index cd824feb..0f980903 100644 --- a/src/backend/commands/player/vehicle/special_ability.cpp +++ b/src/backend/commands/player/vehicle/special_ability.cpp @@ -15,7 +15,7 @@ namespace big Ped ped = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()); if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -28,4 +28,4 @@ namespace big vehicle_special_ability<1> g_special_boost_vehicle("svehboost", "BACKEND_SPECIAL_ABILITY_BOOST", "BACKEND_SPECIAL_ABILITY_BOOST_DESC", 0); vehicle_special_ability<3> g_special_shunt_left("sshuntleft", "BACKEND_SPECIAL_ABILITY_LEFT", "BACKEND_SPECIAL_ABILITY_LEFT_DESC", 0); vehicle_special_ability<2> g_special_shunt_right("sshuntright", "BACKEND_SPECIAL_ABILITY_RIGHT", "BACKEND_SPECIAL_ABILITY_RIGHT_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/stop_vehicle.cpp b/src/backend/commands/player/vehicle/stop_vehicle.cpp index dd6bccc0..c74ba66b 100644 --- a/src/backend/commands/player/vehicle/stop_vehicle.cpp +++ b/src/backend/commands/player/vehicle/stop_vehicle.cpp @@ -13,7 +13,7 @@ namespace big Ped ped = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()); if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -25,11 +25,11 @@ namespace big } else { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_FAILED_TO_TAKE_CONTROL"_T.data()); } } } }; stop_vehicle g_stop_vehicle("stopveh", "BACKEND_STOP_VEHICLE", "BACKEND_STOP_VEHICLE_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/unlock_doors.cpp b/src/backend/commands/player/vehicle/unlock_doors.cpp index 9dfdacb7..87e12036 100644 --- a/src/backend/commands/player/vehicle/unlock_doors.cpp +++ b/src/backend/commands/player/vehicle/unlock_doors.cpp @@ -14,7 +14,7 @@ namespace big Ped ped = PLAYER::GET_PLAYER_PED_SCRIPT_INDEX(player->id()); if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("VEHICLE"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("VEHICLE"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -27,4 +27,4 @@ namespace big }; unlock_vehicle g_unlock_vehicle("unlockveh", "BACKEND_UNLOCK_DOORS", "BACKEND_UNLOCK_DOORS_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/player/vehicle/upgrade_vehicle.cpp b/src/backend/commands/player/vehicle/upgrade_vehicle.cpp index 1cb7accb..96fc1f23 100644 --- a/src/backend/commands/player/vehicle/upgrade_vehicle.cpp +++ b/src/backend/commands/player/vehicle/upgrade_vehicle.cpp @@ -17,7 +17,7 @@ namespace big if (!PED::IS_PED_IN_ANY_VEHICLE(ped, true)) { - g_notification_service->push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); + g_notification_service.push_warning("TOXIC"_T.data(), "ERROR_PLAYER_IS_NOT_IN_VEHICLE"_T.data()); } else { @@ -27,4 +27,4 @@ namespace big }; upgrade_vehicle g_upgrade_vehicle("upgradeveh", "MAX_VEHICLE", "BACKEND_UPGRADE_VEHICLE_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/session/wipe_session.cpp b/src/backend/commands/session/wipe_session.cpp index be66f76f..50a6dbd8 100644 --- a/src/backend/commands/session/wipe_session.cpp +++ b/src/backend/commands/session/wipe_session.cpp @@ -15,8 +15,8 @@ namespace big { player_mgr->RemovePlayer(plyr->get_net_game_player()); } - g_notification_service->push("EMPTY_SESSION"_T.data(), "BACKEND_WIPE_SESSION_COMPLETE"_T.data()); + g_notification_service.push("EMPTY_SESSION"_T.data(), "BACKEND_WIPE_SESSION_COMPLETE"_T.data()); } }; empty_session g_empty_session("emptysession", "EMPTY_SESSION", "BACKEND_WIPE_SESSION_DESC", 0); -} \ No newline at end of file +} diff --git a/src/backend/commands/spawn/spawn_vehicle.cpp b/src/backend/commands/spawn/spawn_vehicle.cpp index f7ec4755..3dba2f35 100644 --- a/src/backend/commands/spawn/spawn_vehicle.cpp +++ b/src/backend/commands/spawn/spawn_vehicle.cpp @@ -42,7 +42,7 @@ namespace big if (veh == 0) { - g_notification_service->push_error("GUI_TAB_SPAWN_VEHICLE"_T.data(), "UNABLE_TO_SPAWN_VEHICLE"_T.data()); + g_notification_service.push_error("GUI_TAB_SPAWN_VEHICLE"_T.data(), "UNABLE_TO_SPAWN_VEHICLE"_T.data()); } else { diff --git a/src/backend/context/chat_command_context.cpp b/src/backend/context/chat_command_context.cpp index 75c061b6..1c851685 100644 --- a/src/backend/context/chat_command_context.cpp +++ b/src/backend/context/chat_command_context.cpp @@ -2,7 +2,7 @@ #include "fiber_pool.hpp" #include "hooking/hooking.hpp" -#include "util/notify.hpp" +#include "util/chat.hpp" namespace big { @@ -26,18 +26,7 @@ namespace big void chat_command_context::report_output(const std::string& output) const { - g_fiber_pool->queue_job([this, output] { - char msg[265]{}; - msg[0] = g.session.chat_output_prefix; - msg[1] = ' '; - strncpy(msg + 2, output.c_str(), sizeof(msg) - 2); - - if (g_hooking->get_original()(*g_pointers->m_gta.m_send_chat_ptr, - g_player_service->get_self()->get_net_data(), - msg, - false)) - notify::draw_chat(msg, g_player_service->get_self()->get_name(), false); - }); + chat::send_message(output, this->get_sender(), true, true); } void chat_command_context::report_error(const std::string& error) const diff --git a/src/backend/context/default_command_context.cpp b/src/backend/context/default_command_context.cpp index 146973b8..c3535ec8 100644 --- a/src/backend/context/default_command_context.cpp +++ b/src/backend/context/default_command_context.cpp @@ -14,11 +14,11 @@ namespace big void default_command_context::report_output(const std::string& output) const { - g_notification_service->push("BACKEND_COMMAND"_T.data(), output); + g_notification_service.push("BACKEND_COMMAND"_T.data(), output); } void default_command_context::report_error(const std::string& error) const { - g_notification_service->push_error("BACKEND_COMMAND"_T.data(), error); + g_notification_service.push_error("BACKEND_COMMAND"_T.data(), error); } -} \ No newline at end of file +} diff --git a/src/backend/looped/self/persist_outfit.cpp b/src/backend/looped/self/persist_outfit.cpp index 69689832..5af1966e 100644 --- a/src/backend/looped/self/persist_outfit.cpp +++ b/src/backend/looped/self/persist_outfit.cpp @@ -1,11 +1,11 @@ #include "backend/looped/looped.hpp" +#include "core/scr_globals.hpp" #include "file_manager.hpp" +#include "gta/enums.hpp" #include "logger/logger.hpp" #include "natives.hpp" #include "pointers.hpp" #include "services/outfit/outfit_service.hpp" -#include "gta/enums.hpp" -#include "core/scr_globals.hpp" #include "services/tunables/tunables_service.hpp" namespace big @@ -15,13 +15,13 @@ namespace big int offset = 0; switch (model) { - case "mp_m_freemode_01"_J: break; - case "mp_f_freemode_01"_J: - { - offset = 1; - break; - } - default: return false; //For non-normal models + case "mp_m_freemode_01"_J: break; + case "mp_f_freemode_01"_J: + { + offset = 1; + break; + } + default: return false; //For non-normal models } return PED::GET_PED_DRAWABLE_VARIATION(self::ped, ComponentId::AUXILIARY) == 15 && PED::GET_PED_DRAWABLE_VARIATION(self::ped, ComponentId::TORSO) == 15 && PED::GET_PED_DRAWABLE_VARIATION(self::ped, ComponentId::LEGS) == (14 + offset); @@ -52,11 +52,28 @@ namespace big if (persisting_outfit != g.self.persist_outfit) { - persisting_outfit = g.self.persist_outfit; - folder saved_outfit_path = g_file_manager.get_project_folder("saved_outfits"); - std::ifstream i(saved_outfit_path.get_file(persisting_outfit).get_path()); - outfit.clear(); - i >> outfit; + persisting_outfit = g.self.persist_outfit; + folder saved_outfit_path = g_file_manager.get_project_folder("saved_outfits"); + const auto persist_outfit_file_path = saved_outfit_path.get_file(persisting_outfit).get_path(); + if (std::filesystem::exists(persist_outfit_file_path)) + { + std::ifstream i(persist_outfit_file_path); + if (i.is_open()) + { + outfit.clear(); + try + { + i >> outfit; + } + catch (const std::exception& e) + { + LOG(INFO) << e.what(); + + outfit = {}; + g.self.persist_outfit = ""; + } + } + } } if (outfit.contains("model") && outfit["model"].get() == model) diff --git a/src/backend/looped/self/super_hero_fly.cpp b/src/backend/looped/self/super_hero_fly.cpp index e832c28d..5ae2ed57 100644 --- a/src/backend/looped/self/super_hero_fly.cpp +++ b/src/backend/looped/self/super_hero_fly.cpp @@ -391,7 +391,7 @@ namespace big virtual void on_enable() override { - g_notification_service->push("SUPER_HERO_FLY"_T.data(), "SUPER_HERO_FLY_ENABLE_NOTIFICATION"_T.data()); + g_notification_service.push("SUPER_HERO_FLY"_T.data(), "SUPER_HERO_FLY_ENABLE_NOTIFICATION"_T.data()); } virtual void on_disable() override diff --git a/src/backend/looped/self/toggle_passive.cpp b/src/backend/looped/self/toggle_passive.cpp index a3a5c83d..84bbccc0 100644 --- a/src/backend/looped/self/toggle_passive.cpp +++ b/src/backend/looped/self/toggle_passive.cpp @@ -19,7 +19,7 @@ namespace big { on_disable(); g.self.passive = false; - g_notification_service->push_warning("PASSIVE"_T.data(), "BACKEND_LOOPED_SELF_TOGGLE_PASSIVE_DISABLED_PASSIVE_MODE_MESSAGE"_T.data()); + g_notification_service.push_warning("PASSIVE"_T.data(), "BACKEND_LOOPED_SELF_TOGGLE_PASSIVE_DISABLED_PASSIVE_MODE_MESSAGE"_T.data()); return; } *g_tunables_service->get_tunable(-29732167) = 0; // End Passive Time = 0s diff --git a/src/backend/looped/vehicle/auto_drive.cpp b/src/backend/looped/vehicle/auto_drive.cpp index 31c81feb..ad58eca8 100644 --- a/src/backend/looped/vehicle/auto_drive.cpp +++ b/src/backend/looped/vehicle/auto_drive.cpp @@ -29,7 +29,7 @@ namespace big { current_destination = AutoDriveDestination::STOPPED; changing_driving_styles = false; - g_notification_service->push_warning("AUTO_DRIVE"_T.data(), "PLAYER_INFO_NO_VEHICLE"_T.data()); + g_notification_service.push_warning("AUTO_DRIVE"_T.data(), "PLAYER_INFO_NO_VEHICLE"_T.data()); } else if (current_driving_flag != driving_style_flags[g.vehicle.auto_drive_style] || current_speed != g.vehicle.auto_drive_speed) { @@ -77,11 +77,11 @@ namespace big if (to_waypoint && !does_waypoint_exist) { - g_notification_service->push_warning("AUTO_DRIVE"_T.data(), "TELEPORT_NO_WAYPOINT_SET"_T.data()); + g_notification_service.push_warning("AUTO_DRIVE"_T.data(), "TELEPORT_NO_WAYPOINT_SET"_T.data()); } else { - g_notification_service->push_warning("AUTO_DRIVE"_T.data(), "BACKEND_LOOPED_VEHICLE_AUTO_DRIVE_STOPPED"_T.data()); + g_notification_service.push_warning("AUTO_DRIVE"_T.data(), "BACKEND_LOOPED_VEHICLE_AUTO_DRIVE_STOPPED"_T.data()); } started = false; diff --git a/src/backend/looped/vehicle/turn_signals.cpp b/src/backend/looped/vehicle/turn_signals.cpp index edd2f668..ec2914b3 100644 --- a/src/backend/looped/vehicle/turn_signals.cpp +++ b/src/backend/looped/vehicle/turn_signals.cpp @@ -125,7 +125,7 @@ namespace big virtual void on_enable() override { - g_notification_service->push("TURN_SIGNALS"_T.data(), "BACKEND_LOOPED_VEHICLE_TURN_SIGNALS_HELP"_T.data()); + g_notification_service.push("TURN_SIGNALS"_T.data(), "BACKEND_LOOPED_VEHICLE_TURN_SIGNALS_HELP"_T.data()); } virtual void on_tick() override diff --git a/src/backend/looped/weapons/cage_gun.cpp b/src/backend/looped/weapons/cage_gun.cpp index 9c9223c0..111d4efa 100644 --- a/src/backend/looped/weapons/cage_gun.cpp +++ b/src/backend/looped/weapons/cage_gun.cpp @@ -24,7 +24,7 @@ namespace big } else { - g_notification_service->push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); + g_notification_service.push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); } } } diff --git a/src/backend/looped/weapons/delete_gun.cpp b/src/backend/looped/weapons/delete_gun.cpp index 5b0ddade..8548595f 100644 --- a/src/backend/looped/weapons/delete_gun.cpp +++ b/src/backend/looped/weapons/delete_gun.cpp @@ -20,7 +20,7 @@ namespace big { if (ENTITY::IS_ENTITY_A_PED(entity) && PED::IS_PED_A_PLAYER(entity)) { - g_notification_service->push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_DELETE_GUN_PLAYER"_T.data()); + g_notification_service.push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_DELETE_GUN_PLAYER"_T.data()); } else { @@ -29,7 +29,7 @@ namespace big if (dist > 500) { - g_notification_service->push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_DELETE_GUN_TOO_FAR"_T.data()); + g_notification_service.push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_DELETE_GUN_TOO_FAR"_T.data()); } else { @@ -38,13 +38,13 @@ namespace big entity::delete_entity(entity); } else - g_notification_service->push_error("CUSTOM_WEAPONS"_T.data(), "TELEPORT_FAILED_TO_TAKE_CONTROL"_T.data()); + g_notification_service.push_error("CUSTOM_WEAPONS"_T.data(), "TELEPORT_FAILED_TO_TAKE_CONTROL"_T.data()); } } } else { - g_notification_service->push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); + g_notification_service.push_error("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); } } } diff --git a/src/backend/looped/weapons/gravity_gun.cpp b/src/backend/looped/weapons/gravity_gun.cpp index 4d228c2a..3d1b926b 100644 --- a/src/backend/looped/weapons/gravity_gun.cpp +++ b/src/backend/looped/weapons/gravity_gun.cpp @@ -65,7 +65,7 @@ namespace big { if (ENTITY::IS_ENTITY_A_PED(ent_to_add) && PED::IS_PED_A_PLAYER(ent_to_add)) { - g_notification_service->push_warning("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_GRAVITY_GUN_PLAYER"_T.data()); + g_notification_service.push_warning("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_GRAVITY_GUN_PLAYER"_T.data()); } else { @@ -79,7 +79,7 @@ namespace big if (temp_dist > 500) { - g_notification_service->push_warning("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_DELETE_GUN_TOO_FAR"_T.data()); + g_notification_service.push_warning("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_DELETE_GUN_TOO_FAR"_T.data()); } else { @@ -87,7 +87,7 @@ namespace big { TASK::SET_HIGH_FALL_TASK(ent_to_add, 0, 0, 0); - g_notification_service->push_warning("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_GRAVITY_GUN_SET"_T.data()); + g_notification_service.push_warning("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_GRAVITY_GUN_SET"_T.data()); } ents.push_back(ent_to_add); @@ -121,7 +121,7 @@ namespace big ents.clear(); - g_notification_service->push_success("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_GRAVITY_GUN_UNSET"_T.data()); + g_notification_service.push_success("CUSTOM_WEAPONS"_T.data(), "BACKEND_LOOPED_WEAPONS_GRAVITY_GUN_UNSET"_T.data()); } } } diff --git a/src/backend/looped/weapons/repair_gun.cpp b/src/backend/looped/weapons/repair_gun.cpp index d81068c0..0c10da64 100644 --- a/src/backend/looped/weapons/repair_gun.cpp +++ b/src/backend/looped/weapons/repair_gun.cpp @@ -24,15 +24,15 @@ namespace big } else { - g_notification_service->push_warning("BACKEND_LOOPED_WEAPONS_REPAIR_GUN"_T.data(), "VEHICLE_INVALID"_T.data()); + g_notification_service.push_warning("BACKEND_LOOPED_WEAPONS_REPAIR_GUN"_T.data(), "VEHICLE_INVALID"_T.data()); } } else { - g_notification_service->push_warning("BACKEND_LOOPED_WEAPONS_REPAIR_GUN"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); + g_notification_service.push_warning("BACKEND_LOOPED_WEAPONS_REPAIR_GUN"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); } } } } } -} \ No newline at end of file +} diff --git a/src/backend/looped/weapons/steal_vehicle_gun.cpp b/src/backend/looped/weapons/steal_vehicle_gun.cpp index 1493fe2b..6ba79c36 100644 --- a/src/backend/looped/weapons/steal_vehicle_gun.cpp +++ b/src/backend/looped/weapons/steal_vehicle_gun.cpp @@ -31,12 +31,12 @@ namespace big } else { - g_notification_service->push_warning("BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"_T.data(), "VEHICLE_INVALID"_T.data()); + g_notification_service.push_warning("BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"_T.data(), "VEHICLE_INVALID"_T.data()); } } else { - g_notification_service->push_warning("BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); + g_notification_service.push_warning("BACKEND_LOOPED_WEAPONS_STEAL_VEHICLE_GUN"_T.data(), "BACKEND_LOOPED_WEAPONS_CAGE_GUN_NO_ENTITY_FOUND"_T.data()); } } } diff --git a/src/backend/looped/world/nearby/auto_disarm.cpp b/src/backend/looped/world/nearby/auto_disarm.cpp index 249e929f..24040598 100644 --- a/src/backend/looped/world/nearby/auto_disarm.cpp +++ b/src/backend/looped/world/nearby/auto_disarm.cpp @@ -11,7 +11,7 @@ namespace big virtual void on_enable() override { - g_notification_service->push("Auto disarm", "Nearby hostile peds will be disarmed"); + g_notification_service.push("Auto disarm", "Nearby hostile peds will be disarmed"); } virtual void on_tick() override diff --git a/src/backend/reactions/interloper_reaction.cpp b/src/backend/reactions/interloper_reaction.cpp index 4546aee9..bb79a30e 100644 --- a/src/backend/reactions/interloper_reaction.cpp +++ b/src/backend/reactions/interloper_reaction.cpp @@ -5,7 +5,7 @@ #include "hooking/hooking.hpp" #include "pointers.hpp" #include "script.hpp" -#include "util/notify.hpp" +#include "util/chat.hpp" namespace big { @@ -36,23 +36,16 @@ namespace big if (announce_in_chat) { - g_fiber_pool->queue_job([attacker, victim, this] { - auto chat = std::format("{} {}", g.session.chat_output_prefix, g_translation_service.get_translation(m_announce_message)); - - if (g_hooking->get_original()(*g_pointers->m_gta.m_send_chat_ptr, - g_player_service->get_self()->get_net_data(), - chat.data(), - is_team_only)) - notify::draw_chat(chat.c_str(), g_player_service->get_self()->get_name(), is_team_only); - }); + auto msg = std::format("{} {}", g.session.chat_output_prefix, g_translation_service.get_translation(m_announce_message)); + chat::send_message(msg); } if (notify) { - g_notification_service->push_warning("PROTECTIONS"_T.data(), + g_notification_service.push_warning("PROTECTIONS"_T.data(), std::vformat(g_translation_service.get_translation(m_notify_message), std::make_format_args(attacker->get_name(), victim->get_name()))); } process_common(attacker); } -} \ No newline at end of file +} diff --git a/src/backend/reactions/reaction.cpp b/src/backend/reactions/reaction.cpp index bfd51844..08603cdf 100644 --- a/src/backend/reactions/reaction.cpp +++ b/src/backend/reactions/reaction.cpp @@ -6,7 +6,7 @@ #include "pointers.hpp" #include "script.hpp" #include "services/player_database/player_database_service.hpp" -#include "util/notify.hpp" +#include "util/chat.hpp" namespace big { @@ -62,20 +62,16 @@ namespace big if (announce_in_chat) { - g_fiber_pool->queue_job([player, this] { - auto chat = std::format("{} {}", g.session.chat_output_prefix, std::vformat(g_translation_service.get_translation(m_announce_message), std::make_format_args(player->get_name()))); + auto msg = std::format("{} {}", + g.session.chat_output_prefix, + std::vformat(g_translation_service.get_translation(m_announce_message), std::make_format_args(player->get_name()))); - if (g_hooking->get_original()(*g_pointers->m_gta.m_send_chat_ptr, - g_player_service->get_self()->get_net_data(), - chat.data(), - is_team_only)) - notify::draw_chat(chat.c_str(), g_player_service->get_self()->get_name(), is_team_only); - }); + chat::send_message(msg); } if (notify) { - g_notification_service->push_warning("PROTECTIONS"_T.data(), + g_notification_service.push_warning("PROTECTIONS"_T.data(), std::vformat(g_translation_service.get_translation(m_notify_message), std::make_format_args(player->get_name()))); } diff --git a/src/core/enums.hpp b/src/core/enums.hpp index 384b91aa..2f87ff3b 100644 --- a/src/core/enums.hpp +++ b/src/core/enums.hpp @@ -293,8 +293,7 @@ namespace big GOD = 1 << 8, EXPLOSION = 1 << 11, STEAM = 1 << 15, - DROWN = 1 << 16, - WATER = 1 << 24, + WATER = 1 << 16, }; enum ePedType : uint32_t { diff --git a/src/core/settings.hpp b/src/core/settings.hpp index 44f7f9f6..74723fd1 100644 --- a/src/core/settings.hpp +++ b/src/core/settings.hpp @@ -336,7 +336,6 @@ namespace big bool proof_melee = false; bool proof_explosion = false; bool proof_steam = false; - bool proof_drown = false; bool proof_water = false; uint32_t proof_mask = 0; bool mobile_radio = false; @@ -388,7 +387,7 @@ namespace big NLOHMANN_DEFINE_TYPE_INTRUSIVE(super_hero_fly, gradual, explosions, auto_land, charge, ptfx, fly_speed, initial_launch) } super_hero_fly{}; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(self, ipls, ptfx_effects, clean_player, force_wanted_level, passive, free_cam, invisibility, local_visibility, never_wanted, no_ragdoll, noclip, noclip_aim_speed_multiplier, noclip_speed_multiplier, off_radar, super_run, no_collision, unlimited_oxygen, no_water_collision, wanted_level, god_mode, part_water, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_drown, proof_water, proof_mask, mobile_radio, fast_respawn, auto_tp, super_jump, beast_jump, healthregen, healthregenrate, hud, superman, custom_weapon_stop, prompt_ambient_animations, persist_outfit, persist_outfits_mis, interaction_menu_freedom, super_hero_fly) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(self, ipls, ptfx_effects, clean_player, force_wanted_level, passive, free_cam, invisibility, local_visibility, never_wanted, no_ragdoll, noclip, noclip_aim_speed_multiplier, noclip_speed_multiplier, off_radar, super_run, no_collision, unlimited_oxygen, no_water_collision, wanted_level, god_mode, part_water, proof_bullet, proof_fire, proof_collision, proof_melee, proof_explosion, proof_steam, proof_water, proof_mask, mobile_radio, fast_respawn, auto_tp, super_jump, beast_jump, healthregen, healthregenrate, hud, superman, custom_weapon_stop, prompt_ambient_animations, persist_outfit, persist_outfits_mis, interaction_menu_freedom, super_hero_fly) } self{}; struct session diff --git a/src/function_types.hpp b/src/function_types.hpp index 234643a8..8dd3ef0d 100644 --- a/src/function_types.hpp +++ b/src/function_types.hpp @@ -210,4 +210,6 @@ namespace big::functions using get_ped_seat = CGetPedSeatReturnClass*(*)(PVOID seat_info, CPed* ped); using received_clone_remove = void (*)(CNetworkObjectMgr*, CNetGamePlayer*, CNetGamePlayer*, int16_t, uint32_t); + + using can_create_vehicle = bool (*)(); } diff --git a/src/gta/net_game_event.hpp b/src/gta/net_game_event.hpp index f7214075..8006f8ee 100644 --- a/src/gta/net_game_event.hpp +++ b/src/gta/net_game_event.hpp @@ -91,9 +91,9 @@ namespace rage { return big::g_pointers->m_gta.m_read_bitbuf_bool(this, boolean, 1); } - bool ReadPeerId(uint64_t* peer_id) + bool ReadRockstarId(int64_t* rockstar_id) { - return this->ReadQWord(peer_id, 0x40); + return this->ReadInt64(rockstar_id, sizeof(rockstar_id) * 8); } uint64_t ReadBits(size_t numBits) { @@ -207,6 +207,10 @@ namespace rage { return big::g_pointers->m_gta.m_write_bitbuf_int64(this, integer, bits); } + bool WriteRockstarId(int64_t rockstar_id) + { + return big::g_pointers->m_gta.m_write_bitbuf_int64(this, rockstar_id, sizeof(rockstar_id) * 8); + } bool ReadInt64(int64_t* integer, int bits) { uint32_t v8; diff --git a/src/gta_pointers.hpp b/src/gta_pointers.hpp index 050470e1..3531570f 100644 --- a/src/gta_pointers.hpp +++ b/src/gta_pointers.hpp @@ -365,6 +365,8 @@ namespace big functions::received_clone_remove m_received_clone_remove; CWeaponInfoManager* m_weapon_info_manager; + + functions::can_create_vehicle m_can_create_vehicle; }; #pragma pack(pop) static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned"); diff --git a/src/hooking/hooking.cpp b/src/hooking/hooking.cpp index d3537f1a..af3ce54a 100644 --- a/src/hooking/hooking.cpp +++ b/src/hooking/hooking.cpp @@ -140,6 +140,8 @@ namespace big detour_hook_helper::add("RCR", g_pointers->m_gta.m_received_clone_remove); + detour_hook_helper::add("CCV", g_pointers->m_gta.m_can_create_vehicle); + g_hooking = this; } diff --git a/src/hooking/hooking.hpp b/src/hooking/hooking.hpp index 9587f0ac..da9e5d8a 100644 --- a/src/hooking/hooking.hpp +++ b/src/hooking/hooking.hpp @@ -191,6 +191,8 @@ namespace big static bool sync_reader_serialize_vec3(void* _this, rage::fvector3* vec, float divisor, int size); static bool sync_reader_serialize_vec3_signed(void* _this, rage::fvector3* vec, float divisor, int size); static bool sync_reader_serialize_array(void* _this, void* array, int size); + + static bool can_create_vehicle(); }; class minhook_keepalive diff --git a/src/hooks/info/get_network_event_data.cpp b/src/hooks/info/get_network_event_data.cpp index e5a06c05..f4bd962e 100644 --- a/src/hooks/info/get_network_event_data.cpp +++ b/src/hooks/info/get_network_event_data.cpp @@ -64,11 +64,11 @@ namespace big g_fiber_pool->queue_job([] { session::join_session(gta_util::get_network()->m_last_joined_session.m_session_info); }); - g_notification_service->push_warning("KICKED"_T.data(), "You have been desync kicked. Rejoining previous session..."); + g_notification_service.push_warning("KICKED"_T.data(), "You have been desync kicked. Rejoining previous session..."); } else { - g_notification_service->push_warning("KICKED"_T.data(), "USER_DESYNC_KICKED"_T.data()); + g_notification_service.push_warning("KICKED"_T.data(), "USER_DESYNC_KICKED"_T.data()); } break; } diff --git a/src/hooks/misc/send_chat_message.cpp b/src/hooks/misc/send_chat_message.cpp index e184089d..40c3a845 100644 --- a/src/hooks/misc/send_chat_message.cpp +++ b/src/hooks/misc/send_chat_message.cpp @@ -5,36 +5,19 @@ #include "hooking/hooking.hpp" #include "packet.hpp" #include "services/players/player_service.hpp" -#include "util/spam.hpp" +#include "util/chat.hpp" namespace big { - inline void gamer_handle_serialize(rage::rlGamerHandle& hnd, rage::datBitBuffer& buf) - { - constexpr int PC_PLATFORM = 3; - buf.Write(PC_PLATFORM, 8); - buf.WriteInt64(*(int64_t*)&hnd.m_rockstar_id, 64); - buf.Write(hnd.unk_0009, 8); - } - bool hooks::send_chat_message(void* team_mgr, rage::rlGamerInfo* local_gamer_info, char* message, bool is_team) { if (g.session.chat_commands && message[0] == g.session.chat_command_prefix) command::process(std::string(message + 1), std::make_shared(g_player_service->get_self())); - packet msg{}; - msg.write_message(rage::eNetMessage::MsgTextMessage); - msg.m_buffer.WriteString(message ? message : "", 256); - gamer_handle_serialize(g_player_service->get_self()->get_net_data()->m_gamer_handle, msg.m_buffer); - msg.write(is_team, 1); + chat::send_message(message, nullptr, false, is_team); if (g.session.log_chat_messages) - spam::log_chat(message, g_player_service->get_self(), SpamReason::NOT_A_SPAMMER, is_team); - - if (*g_pointers->m_gta.m_is_session_started) - for (auto& player : g_player_service->players()) - if (player.second && player.second->is_valid()) - msg.send(player.second->get_net_game_player()->m_msg_id); + chat::log_chat(message, g_player_service->get_self(), SpamReason::NOT_A_SPAMMER, is_team); return true; } diff --git a/src/hooks/player_management/assign_physical_index.cpp b/src/hooks/player_management/assign_physical_index.cpp index 056a5eeb..68b59fde 100644 --- a/src/hooks/player_management/assign_physical_index.cpp +++ b/src/hooks/player_management/assign_physical_index.cpp @@ -41,7 +41,7 @@ namespace big if (g.notifications.player_leave.notify) { - g_notification_service->push("PLAYER_LEFT"_T.data(), + g_notification_service.push("PLAYER_LEFT"_T.data(), std::vformat("PLAYER_LEFT_INFO"_T, std::make_format_args(net_player_data->m_name, player->m_player_id, @@ -60,7 +60,7 @@ namespace big { if (admin_rids.contains(net_player_data->m_gamer_handle.m_rockstar_id)) { - g_notification_service->push_warning("POTENTIAL_ADMIN_FOUND"_T.data(), + g_notification_service.push_warning("POTENTIAL_ADMIN_FOUND"_T.data(), std::format("{} {}", net_player_data->m_name, "PLAYER_DETECTED_AS_ADMIN"_T)); LOG(WARNING) << net_player_data->m_name << " (" << net_player_data->m_gamer_handle.m_rockstar_id << ") has been detected as an admin"; @@ -82,7 +82,7 @@ namespace big if (g.notifications.player_join.notify) { - g_notification_service->push("PLAYER_JOINED"_T.data(), + g_notification_service.push("PLAYER_JOINED"_T.data(), std::vformat("PLAYER_JOINED_INFO"_T, std::make_format_args(net_player_data->m_name, player->m_player_id, @@ -109,7 +109,7 @@ namespace big if (strcmp(plyr->get_name(), entry->name.data())) { - g_notification_service->push("PLAYERS"_T.data(), + g_notification_service.push("PLAYERS"_T.data(), std::format("{} {}: {}", entry->name, "PLAYER_CHANGED_NAME"_T, plyr->get_name())); entry->name = plyr->get_name(); g_player_database_service->save(); @@ -133,14 +133,14 @@ namespace big { if ((plyr->is_friend() && g.session.allow_friends_into_locked_session) || plyr->is_trusted) { - g_notification_service->push_success("LOBBY_LOCK"_T.data(), + g_notification_service.push_success("LOBBY_LOCK"_T.data(), std::vformat("LOBBY_LOCK_ALLOWED"_T.data(), std::make_format_args(plyr->get_net_data()->m_name))); } else { dynamic_cast(command::get("multikick"_J))->call(plyr, {}); - g_notification_service->push_warning("LOBBY_LOCK"_T.data(), + g_notification_service.push_warning("LOBBY_LOCK"_T.data(), std::vformat("LOBBY_LOCK_DENIED"_T.data(), std::make_format_args(plyr->get_net_data()->m_name))); } } diff --git a/src/hooks/player_management/network_player_mgr.cpp b/src/hooks/player_management/network_player_mgr.cpp index f116efda..7551fda6 100644 --- a/src/hooks/player_management/network_player_mgr.cpp +++ b/src/hooks/player_management/network_player_mgr.cpp @@ -13,7 +13,7 @@ namespace big if (g.notifications.network_player_mgr_init.log) LOG(INFO) << "CNetworkPlayerMgr#init got called, we're probably entering a session."; if (g.notifications.network_player_mgr_init.notify) - g_notification_service->push("NETWORK_PLAYER_MGR"_T.data(), "NETWORK_PLAYER_MGR_INIT"_T.data()); + g_notification_service.push("NETWORK_PLAYER_MGR"_T.data(), "NETWORK_PLAYER_MGR_INIT"_T.data()); bool result = g_hooking->get_original()(_this, a2, a3, a4); @@ -32,7 +32,7 @@ namespace big if (g.notifications.network_player_mgr_shutdown.log) LOG(INFO) << "CNetworkPlayerMgr#shutdown got called, we're probably leaving our session."; if (g.notifications.network_player_mgr_shutdown.notify) - g_notification_service->push("NETWORK_PLAYER_MGR"_T.data(), "NETWORK_PLAYER_MGR_DESTROY"_T.data()); + g_notification_service.push("NETWORK_PLAYER_MGR"_T.data(), "NETWORK_PLAYER_MGR_DESTROY"_T.data()); g.session.trust_session = false; g_hooking->get_original()(_this); diff --git a/src/hooks/protections/allocate_memory_reliable.cpp b/src/hooks/protections/allocate_memory_reliable.cpp index 063f4ea9..1bd0b9a7 100644 --- a/src/hooks/protections/allocate_memory_reliable.cpp +++ b/src/hooks/protections/allocate_memory_reliable.cpp @@ -73,8 +73,8 @@ namespace big if (memory) return memory; - g_notification_service->push_error("Protections", "The network message allocator is out of memory"); // this never reaches here but why not + g_notification_service.push_error("Protections", "The network message allocator is out of memory"); // this never reaches here but why not return nullptr; } -} \ No newline at end of file +} diff --git a/src/hooks/protections/can_apply_data.cpp b/src/hooks/protections/can_apply_data.cpp index 36792bb8..96ebabb3 100644 --- a/src/hooks/protections/can_apply_data.cpp +++ b/src/hooks/protections/can_apply_data.cpp @@ -716,13 +716,9 @@ namespace big case sync_node_id("CPlayerExtendedGameStateNode"): LOG_FIELD(CPlayerExtendedGameStateNode, waypoint_x); LOG_FIELD(CPlayerExtendedGameStateNode, waypoint_y); - LOG_FIELD_B(CPlayerExtendedGameStateNode, unk1); - LOG_FIELD_B(CPlayerExtendedGameStateNode, unk2); - LOG_FIELD_B(CPlayerExtendedGameStateNode, unk3); - LOG_FIELD_B(CPlayerExtendedGameStateNode, unk4); - LOG_FIELD_B(CPlayerExtendedGameStateNode, unk5); - LOG_FIELD_B(CPlayerExtendedGameStateNode, has_waypoint_data); - LOG_FIELD_B(CPlayerExtendedGameStateNode, is_waypoint_set); + LOG_FIELD(CPlayerExtendedGameStateNode, waypoint_entity); + LOG_FIELD(CPlayerExtendedGameStateNode, has_active_waypoint); + LOG_FIELD(CPlayerExtendedGameStateNode, owns_waypoint); break; case sync_node_id("CPlayerGameStateDataNode"): LOG_FIELD(CPlayerGameStateDataNode, m_player_state); diff --git a/src/hooks/protections/handle_join_request.cpp b/src/hooks/protections/handle_join_request.cpp index ef51ec41..bbb8ab58 100644 --- a/src/hooks/protections/handle_join_request.cpp +++ b/src/hooks/protections/handle_join_request.cpp @@ -16,7 +16,7 @@ namespace big CMsgJoinResponse response{}; response.m_status_code = player->block_join_reason; g_pointers->m_gta.m_write_join_response_data(&response, ctx->m_join_response_data, 512, &ctx->m_join_response_size); - g_notification_service->push("BLOCK_JOIN"_T.data(), + g_notification_service.push("BLOCK_JOIN"_T.data(), std::vformat("BLOCK_JOIN_INFO"_T, std::make_format_args(player->name))); return false; } @@ -25,4 +25,4 @@ namespace big return g_hooking->get_original()(network, session, player_info, ctx, is_transition_session); } } -} \ No newline at end of file +} diff --git a/src/hooks/protections/receive_net_message.cpp b/src/hooks/protections/receive_net_message.cpp index 54b48911..67c71da4 100644 --- a/src/hooks/protections/receive_net_message.cpp +++ b/src/hooks/protections/receive_net_message.cpp @@ -10,7 +10,7 @@ #include "script/scriptIdBase.hpp" #include "services/players/player_service.hpp" #include "util/session.hpp" -#include "util/spam.hpp" +#include "util/chat.hpp" #include "gta/enums.hpp" #include @@ -19,12 +19,11 @@ inline void gamer_handle_deserialize(rage::rlGamerHandle& hnd, rage::datBitBuffer& buf) { - constexpr int PC_PLATFORM = 3; - if ((hnd.m_platform = buf.Read(8)) != PC_PLATFORM) + if ((hnd.m_platform = buf.Read(sizeof(hnd.m_platform) * 8)) != rage::rlPlatforms::PC) return; - buf.ReadInt64((int64_t*)&hnd.m_rockstar_id, 64); - hnd.unk_0009 = buf.Read(8); + buf.ReadRockstarId(&hnd.m_rockstar_id); + hnd.m_padding = buf.Read(sizeof(hnd.m_padding) * 8); } inline bool is_kick_instruction(rage::datBitBuffer& buffer) @@ -107,18 +106,21 @@ namespace big case rage::eNetMessage::MsgTextMessage2: { char message[256]; - buffer.ReadString(message, 256); + rage::rlGamerHandle handle{}; bool is_team; + buffer.ReadString(message, sizeof(message)); + gamer_handle_deserialize(handle, buffer); buffer.ReadBool(&is_team); if (player->is_spammer) return true; - if (auto spam_reason = spam::is_text_spam(message, player)) + if (auto spam_reason = chat::is_text_spam(message, player)) { if (g.session.log_chat_messages) - spam::log_chat(message, player, spam_reason, is_team); - g_notification_service->push("PROTECTIONS"_T.data(), + chat::log_chat(message, player, spam_reason, is_team); + g_notification_service.push("PROTECTIONS"_T.data(), + std::format("{} {}", player->get_name(), "IS_A_SPAMMER"_T.data())); player->is_spammer = true; if (g.session.kick_chat_spammers @@ -136,7 +138,7 @@ namespace big else { if (g.session.log_chat_messages) - spam::log_chat(message, player, SpamReason::NOT_A_SPAMMER, is_team); + chat::log_chat(message, player, SpamReason::NOT_A_SPAMMER, is_team); if (g.session.chat_commands && message[0] == g.session.chat_command_prefix) command::process(std::string(message + 1), std::make_shared(player)); @@ -145,16 +147,8 @@ namespace big if (msgType == rage::eNetMessage::MsgTextMessage && g_pointers->m_gta.m_chat_data && player->get_net_data()) { - rage::rlGamerHandle temp{}; - gamer_handle_deserialize(temp, buffer); - bool is_team = buffer.Read(1); - - g_pointers->m_gta.m_handle_chat_message(*g_pointers->m_gta.m_chat_data, - nullptr, - &player->get_net_data()->m_gamer_handle, - message, - is_team); - return true; + buffer.Seek(0); + return g_hooking->get_original()(netConnectionManager, a2, frame); // Call original function since we can't seem to handle it } } break; @@ -166,7 +160,7 @@ namespace big if (player->m_host_migration_rate_limit.exceeded_last_process()) { session::add_infraction(player, Infraction::TRIED_KICK_PLAYER); - g_notification_service->push_error("PROTECTIONS"_T.data(), + g_notification_service.push_error("PROTECTIONS"_T.data(), std::vformat("OOM_KICK"_T, std::make_format_args(player->get_name()))); } return true; @@ -209,7 +203,7 @@ namespace big if (reason == KickReason::VOTED_OUT) { - g_notification_service->push_warning("PROTECTIONS"_T.data(), "YOU_HAVE_BEEN_KICKED"_T.data()); + g_notification_service.push_warning("PROTECTIONS"_T.data(), "YOU_HAVE_BEEN_KICKED"_T.data()); return true; } @@ -225,7 +219,7 @@ namespace big if (player->m_radio_request_rate_limit.exceeded_last_process()) { session::add_infraction(player, Infraction::TRIED_KICK_PLAYER); - g_notification_service->push_error("PROTECTIONS"_T.data(), + g_notification_service.push_error("PROTECTIONS"_T.data(), std::vformat("OOM_KICK"_T, std::make_format_args(player->get_name()))); player->block_radio_requests = true; } diff --git a/src/hooks/protections/receive_pickup.cpp b/src/hooks/protections/receive_pickup.cpp index 9bf80f16..000c4737 100644 --- a/src/hooks/protections/receive_pickup.cpp +++ b/src/hooks/protections/receive_pickup.cpp @@ -6,10 +6,10 @@ namespace big { if (g.protections.receive_pickup) { - g_notification_service->push_error("PROTECTIONS"_T.data(), "Blocked pickup"); + g_notification_service.push_error("PROTECTIONS"_T.data(), "Blocked pickup"); return false; } return g_hooking->get_original()(object, unk, ped); } -} \ No newline at end of file +} diff --git a/src/hooks/protections/received_event.cpp b/src/hooks/protections/received_event.cpp index 9f3c2d6f..2e63ac01 100644 --- a/src/hooks/protections/received_event.cpp +++ b/src/hooks/protections/received_event.cpp @@ -355,7 +355,7 @@ namespace big && player->m_player_info->m_ped && player->m_player_info->m_ped->m_net_object && ownerNetId != player->m_player_info->m_ped->m_net_object->m_object_id && !offset_object) { - g_notification_service->push_error("WARNING"_T.data(), + g_notification_service.push_error("WARNING"_T.data(), std::vformat("BLAMED_FOR_EXPLOSION"_T, std::make_format_args(player->get_name(), reinterpret_cast(entity)->m_player_info->m_net_player_data.m_name))); @@ -615,7 +615,7 @@ namespace big if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id) { weapon_item weapon = g_gta_data_service->weapon_by_hash(hash); - g_notification_service->push_warning("PROTECTIONS"_T.data(), + g_notification_service.push_warning("PROTECTIONS"_T.data(), std::format("{} {} {}.", source_player->get_name(), "REMOVE_WEAPON_ATTEMPT_MESSAGE"_T, weapon.m_display_name)); g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); return; @@ -632,7 +632,7 @@ namespace big if (g_local_player && g_local_player->m_net_object && g_local_player->m_net_object->m_object_id == net_id) { weapon_item weapon = g_gta_data_service->weapon_by_hash(hash); - g_notification_service->push_warning("PROTECTIONS"_T.data(), + g_notification_service.push_warning("PROTECTIONS"_T.data(), std::format("{} {} {}.", source_player->get_name(), "GIVE_WEAPON_ATTEMPT_MESSAGE"_T, weapon.m_display_name)); g_pointers->m_gta.m_send_event_ack(event_manager, source_player, target_player, event_index, event_handled_bitset); return; diff --git a/src/hooks/protections/script_event_handler.cpp b/src/hooks/protections/script_event_handler.cpp index b9d252f2..91b0e609 100644 --- a/src/hooks/protections/script_event_handler.cpp +++ b/src/hooks/protections/script_event_handler.cpp @@ -20,7 +20,7 @@ namespace big LOG(WARNING) << "BLOCKED_SCRIPT_EVENT From: " << player_name << " Event Type: " << protection_type; if (should_notify) - g_notification_service->push_warning("Script Event Protection", + g_notification_service.push_warning("Script Event Protection", std::format("From: {}\nEvent Type: {}", player_name.data(), protection_type.data())); } diff --git a/src/hooks/protections/send_non_physical_player_data.cpp b/src/hooks/protections/send_non_physical_player_data.cpp index c54a9912..aabf422e 100644 --- a/src/hooks/protections/send_non_physical_player_data.cpp +++ b/src/hooks/protections/send_non_physical_player_data.cpp @@ -16,7 +16,7 @@ namespace big if (plyr && plyr->block_join && *g_pointers->m_gta.m_is_session_started) { data->m_bubble_id = 10; - g_notification_service->push("BLOCK_JOIN"_T.data(), std::vformat("BLOCK_JOIN_PREVENT_PLAYER_JOIN"_T, std::make_format_args(plyr->get_name()))); + g_notification_service.push("BLOCK_JOIN"_T.data(), std::vformat("BLOCK_JOIN_PREVENT_PLAYER_JOIN"_T, std::make_format_args(plyr->get_name()))); } bool result = g_hooking->get_original()(player, message, flags, a4, a5); @@ -25,4 +25,4 @@ namespace big return result; } -} \ No newline at end of file +} diff --git a/src/hooks/script/can_create_vehicle.cpp b/src/hooks/script/can_create_vehicle.cpp new file mode 100644 index 00000000..95c07c94 --- /dev/null +++ b/src/hooks/script/can_create_vehicle.cpp @@ -0,0 +1,10 @@ +#include "hooking/hooking.hpp" +#include "gta/pools.hpp" + +namespace big +{ + bool hooks::can_create_vehicle() + { + return (**g_pointers->m_gta.m_vehicle_pool)->m_item_count < (**g_pointers->m_gta.m_vehicle_pool)->m_size; + } +} diff --git a/src/hooks/script/gta_thread_kill.cpp b/src/hooks/script/gta_thread_kill.cpp index c5deaaa3..f5cd8f20 100644 --- a/src/hooks/script/gta_thread_kill.cpp +++ b/src/hooks/script/gta_thread_kill.cpp @@ -11,7 +11,7 @@ namespace big LOG(INFO) << "Script Thread '" << thread->m_name << "' terminated (" << thread->m_exit_message << ")."; if (g.notifications.gta_thread_kill.notify) - g_notification_service->push("Script Thread Termination", + g_notification_service.push("Script Thread Termination", std::format("Script Thread '{}' terminated.", thread->m_name)); if (thread == g.m_hunt_the_beast_thread) diff --git a/src/hooks/script/gta_thread_start.cpp b/src/hooks/script/gta_thread_start.cpp index db7da41a..60a294b6 100644 --- a/src/hooks/script/gta_thread_start.cpp +++ b/src/hooks/script/gta_thread_start.cpp @@ -12,7 +12,7 @@ namespace big if (g.notifications.gta_thread_kill.log) LOG(INFO) << "Script Thread '" << name << "' started."; if (g.notifications.gta_thread_kill.notify) - g_notification_service->push("Script Thread Startup", std::format("Script Thread '{}' started.", name)); + g_notification_service.push("Script Thread Startup", std::format("Script Thread '{}' started.", name)); } return new_thread; diff --git a/src/logger/logger.cpp b/src/logger/logger.cpp index b30652e9..e478d5be 100644 --- a/src/logger/logger.cpp +++ b/src/logger/logger.cpp @@ -22,7 +22,6 @@ namespace big m_console_logger = &logger::format_console_simple; } - toggle_external_console(attach_console); create_backup(); m_file_out.open(m_file.get_path(), std::ios_base::out | std::ios_base::trunc); @@ -33,6 +32,8 @@ namespace big Logger::AddSink([this](LogMessagePtr msg) { format_file(std::move(msg)); }); + + toggle_external_console(attach_console); } void logger::destroy() @@ -44,6 +45,19 @@ namespace big void logger::toggle_external_console(bool toggle) { + if (m_is_console_open == toggle) + { + return; + } + m_is_console_open = toggle; + + m_console_out.close(); + if (m_did_console_exist) + SetConsoleMode(m_console_handle, m_original_console_mode); + + if (!m_did_console_exist) + FreeConsole(); + if (toggle) { if (m_did_console_exist = ::AttachConsole(GetCurrentProcessId()); !m_did_console_exist) @@ -60,23 +74,12 @@ namespace big // terminal like behaviour enable full color support console_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING | DISABLE_NEWLINE_AUTO_RETURN; - // prevent clicking in terminal from suspending our main thread - console_mode &= ~(ENABLE_QUICK_EDIT_MODE); SetConsoleMode(m_console_handle, console_mode); } m_console_out.open("CONOUT$", std::ios_base::out | std::ios_base::app); - - return; } - - m_console_out.close(); - if (m_did_console_exist) - SetConsoleMode(m_console_handle, m_original_console_mode); - - if (!m_did_console_exist) - FreeConsole(); } void logger::create_backup() @@ -119,6 +122,11 @@ namespace big void logger::format_console(const LogMessagePtr msg) { + if (!m_is_console_open) + { + return; + } + const auto color = get_color(msg->Level()); const auto timestamp = std::format("{0:%H:%M:%S}", msg->Timestamp()); @@ -133,6 +141,11 @@ namespace big void logger::format_console_simple(const LogMessagePtr msg) { + if (!m_is_console_open) + { + return; + } + const auto color = get_color(msg->Level()); const auto timestamp = std::format("{0:%H:%M:%S}", msg->Timestamp()); diff --git a/src/logger/logger.hpp b/src/logger/logger.hpp index 647ae01b..b1e46a76 100644 --- a/src/logger/logger.hpp +++ b/src/logger/logger.hpp @@ -28,6 +28,7 @@ namespace big private: bool m_attach_console = true; bool m_did_console_exist = false; + bool m_is_console_open = false; void (logger::*m_console_logger)(const LogMessagePtr msg) = &logger::format_console; @@ -59,4 +60,4 @@ namespace big }; inline logger g_log{}; -} \ No newline at end of file +} diff --git a/src/lua/bindings/gui.cpp b/src/lua/bindings/gui.cpp index a55b2a4e..4aa3f270 100644 --- a/src/lua/bindings/gui.cpp +++ b/src/lua/bindings/gui.cpp @@ -251,7 +251,7 @@ namespace lua::gui // Shows a message to the user with the given title and message. static void show_message(const std::string& title, const std::string& message) { - big::g_notification_service->push(title, message); + big::g_notification_service.push(title, message); } // Lua API: Function @@ -262,7 +262,7 @@ namespace lua::gui // Shows a warning to the user with the given title and message. static void show_warning(const std::string& title, const std::string& message) { - big::g_notification_service->push_warning(title, message); + big::g_notification_service.push_warning(title, message); } // Lua API: Function @@ -273,7 +273,7 @@ namespace lua::gui // Shows an error to the user with the given title and message. static void show_error(const std::string& title, const std::string& message) { - big::g_notification_service->push_error(title, message); + big::g_notification_service.push_error(title, message); } // Lua API: Function @@ -373,4 +373,4 @@ namespace lua::gui tab_ut["add_input_string"] = &tab::add_input_string; tab_ut["add_imgui"] = &tab::add_imgui; } -} \ No newline at end of file +} diff --git a/src/lua/bindings/network.cpp b/src/lua/bindings/network.cpp index 880daf00..3d784f99 100644 --- a/src/lua/bindings/network.cpp +++ b/src/lua/bindings/network.cpp @@ -5,6 +5,7 @@ #include "pointers.hpp" #include "services/player_database/player_database_service.hpp" #include "util/notify.hpp" +#include "util/chat.hpp" #include "util/scripts.hpp" #include "util/session.hpp" #include "util/system.hpp" @@ -183,13 +184,22 @@ namespace lua::network // Sends a message to the in game chat. static void send_chat_message(const std::string& msg, bool team_only) { - big::g_fiber_pool->queue_job([msg, team_only] { - if (big::g_hooking->get_original()(*big::g_pointers->m_gta.m_send_chat_ptr, - big::g_player_service->get_self()->get_net_data(), - (char*)msg.c_str(), - team_only)) - big::notify::draw_chat((char*)msg.data(), big::g_player_service->get_self()->get_name(), team_only); - }); + big::chat::send_message(msg, nullptr, true, team_only); + } + + // Lua API: Function + // Table: network + // Name: send_chat_message_to_player + // Param: player_idx: integer: Index of the player. + // Param: msg: string: Message to be sent. + // Sends a chat message to the specified player. Other players would not be able to see the message + static void send_chat_message_to_player(int player_idx, const std::string& msg) + { + if (auto player = big::g_player_service->get_by_id(player_idx)) + { + big::chat::send_message(msg, player); + + } } void bind(sol::state& state) @@ -229,5 +239,6 @@ namespace lua::network ns["get_flagged_modder_reason"] = get_flagged_modder_reason; ns["force_script_host"] = force_script_host; ns["send_chat_message"] = send_chat_message; + ns["send_chat_message_to_player"] = send_chat_message_to_player; } } \ No newline at end of file diff --git a/src/lua/bindings/script.cpp b/src/lua/bindings/script.cpp index ecc01e78..a47108d7 100644 --- a/src/lua/bindings/script.cpp +++ b/src/lua/bindings/script.cpp @@ -3,6 +3,7 @@ #include "lua/lua_manager.hpp" #include "script_mgr.hpp" +#include "gta_util.hpp" namespace lua::script { @@ -151,15 +152,26 @@ namespace lua::script module->m_registered_scripts.push_back(std::move(lua_script)); } + // Lua API: function + // Table: script + // Name: execute_as_script + // Param: script_name: string: target script thread. + // Param: func: function: function that will be executed once in the script thread. + static void execute_as_script(const std::string& script_name, sol::protected_function func) + { + big::gta_util::execute_as_script(rage::joaat(script_name), func); + } + void bind(sol::state& state) { auto ns = state["script"].get_or_create(); ns["register_looped"] = register_looped; ns["run_in_fiber"] = run_in_fiber; + ns["execute_as_script"] = execute_as_script; auto usertype = state.new_usertype("script_util"); usertype["yield"] = sol::yielding(&script_util::yield); usertype["sleep"] = sol::yielding(&script_util::sleep); } -} \ No newline at end of file +} diff --git a/src/main.cpp b/src/main.cpp index 6873f2ef..84fb819a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -152,9 +152,8 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) g_file_manager.init(base_dir); g.init(g_file_manager.get_project_file("./settings.json")); - LOG(INFO) << "Settings Loaded."; - g_log.initialize("YimMenu", g_file_manager.get_project_file("./cout.log"), g.debug.external_console); + LOG(INFO) << "Settings Loaded and logger initialized."; LOG(INFO) << "Yim's Menu Initializing"; LOGF(INFO, "Git Info\n\tBranch:\t{}\n\tHash:\t{}\n\tDate:\t{}", version::GIT_BRANCH, version::GIT_SHA1, version::GIT_DATE); @@ -211,7 +210,6 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) auto context_menu_service_instance = std::make_unique(); auto custom_text_service_instance = std::make_unique(); auto mobile_service_instance = std::make_unique(); - auto notification_service_instance = std::make_unique(); auto pickup_service_instance = std::make_unique(); auto player_service_instance = std::make_unique(); auto gta_data_service_instance = std::make_unique(); @@ -229,6 +227,9 @@ BOOL APIENTRY DllMain(HMODULE hmod, DWORD reason, PVOID) auto xml_maps_service_instance = std::make_unique(); LOG(INFO) << "Registered service instances..."; + g_notification_service.initialise(); + LOG(INFO) << "Finished initialising services."; + g_script_mgr.add_script(std::make_unique