├── README.md ├── example ├── .gitignore ├── CMakeLists.txt ├── generate.bat ├── include │ ├── examples │ │ ├── ExampleBlipEventHandler.hpp │ │ ├── ExampleCheckpointEventHandler.hpp │ │ ├── ExampleColshapeEventHandler.hpp │ │ ├── ExampleConnectionEventHandler.hpp │ │ ├── ExampleEntityEventHandler.hpp │ │ ├── ExampleLocalEventEventHandler.hpp │ │ ├── ExamplePlayerEventHandler.hpp │ │ ├── ExampleServerEventHandler.hpp │ │ ├── ExampleTickEventHandler.hpp │ │ └── ExampleVehicleEventHandler.hpp │ └── rage_log.hpp └── src │ └── main.cpp ├── handlers ├── IBlipHandler.hpp ├── ICheckpointHandler.hpp ├── IColshapeHandler.hpp ├── IConnectionHandler.hpp ├── IEntityHandler.hpp ├── ILocalEventHandler.hpp ├── IPlayerHandler.hpp ├── IServerHandler.hpp ├── ITickHandler.hpp └── IVehicleHandler.hpp ├── objects ├── IBlip.hpp ├── ICheckpoint.hpp ├── IColshape.hpp ├── IDummyEntity.hpp ├── IEntity.hpp ├── IMarker.hpp ├── IObject.hpp ├── IPickup.hpp ├── IPlayer.hpp ├── ITextLabel.hpp └── IVehicle.hpp ├── rage_sdk.hpp └── types.hpp /README.md: -------------------------------------------------------------------------------- 1 | # RAGE Multiplayer C++ SDK - 1.1 2 | Repository containing updated version of [RAGE:MP C++ SDK](https://github.com/ragemultiplayer/ragemp-cppsdk) for version 1.1. 3 | **NOTE:** *not finished yet.* 4 | 5 | ## Contributing 6 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 7 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | build/ -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8) 2 | 3 | project(ragemp-cppsdk) 4 | 5 | set(PROJECT_NAME ragemp-cppsdk) 6 | 7 | set(CMAKE_CXX_STANDARD 17) 8 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 9 | 10 | file(GLOB_RECURSE PROJECT_SOURCE_FILES "src/*.h" "src/*.hpp" "src/*.cpp" "include/*.h" "include/*.hpp" "include/*.cpp") 11 | 12 | macro(GroupSources curdir groupindex) 13 | file(GLOB children RELATIVE ${curdir} ${curdir}/*) 14 | 15 | foreach(child ${children}) 16 | if(IS_DIRECTORY ${curdir}/${child}) 17 | GroupSources(${curdir}/${child} ${groupindex}/${child}) 18 | else() 19 | 20 | string(REPLACE "/" "\\" groupname ${groupindex}) 21 | 22 | source_group(${groupname} FILES ${curdir}/${child}) 23 | endif() 24 | endforeach() 25 | endmacro() 26 | 27 | GroupSources(${PROJECT_SOURCE_DIR}/src "Source Files") 28 | GroupSources(${PROJECT_SOURCE_DIR}/include "Include Files") 29 | 30 | include_directories( 31 | ${PROJECT_SOURCE_DIR}/src 32 | ${PROJECT_SOURCE_DIR}/include 33 | ../ 34 | ) 35 | 36 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 37 | target_compile_options(${PROJECT_NAME} PRIVATE 38 | -Wno-deprecated-declarations 39 | -Wno-switch-enum 40 | -Wno-unused-command-line-argument 41 | -Wno-macro-redefined 42 | -Wno-inconsistent-missing-override 43 | -Wno-deprecated-declarations 44 | -Wno-return-type 45 | -Wno-switch-enum 46 | -Wno-switch 47 | -Wno-parentheses 48 | -Wno-unused-private-field 49 | -Wno-unused-variable 50 | -Wno-format 51 | -Wno-reorder 52 | -Wno-delete-non-virtual-dtor 53 | -Wno-microsoft-cast 54 | -Wno-unused-function 55 | -Wno-unused-lambda-capture 56 | -Wno-missing-braces 57 | -Wno-unused-local-typedef 58 | -Wno-tautological-constant-out-of-range-compare 59 | -Wno-delete-incomplete 60 | -Wno-c++11-narrowing 61 | -Wno-comment 62 | ) 63 | 64 | target_compile_options(${PROJECT_NAME} PRIVATE 65 | -fms-compatibility 66 | -fms-extensions 67 | /EHsc 68 | /FORCE 69 | ) 70 | set_target_properties(${PROJECT_NAME} PROPERTIES 71 | COTIRE_ENABLE_PRECOMPILED_HEADER FALSE 72 | COTIRE_ADD_UNITY_BUILD FALSE 73 | ) 74 | endif() 75 | 76 | add_library( 77 | ${PROJECT_NAME} SHARED 78 | ${PROJECT_SOURCE_FILES} 79 | ) -------------------------------------------------------------------------------- /example/generate.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | if not exist build mkdir build 3 | cd build 4 | cmake -G "Visual Studio 16" -A x64 .. 5 | cd ../ -------------------------------------------------------------------------------- /example/include/examples/ExampleBlipEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleBlipEventHandler : public rage::IEventHandler, 4 | public rage::IBlipHandler { 5 | public: 6 | virtual rage::IBlipHandler* GetBlipHandler() override { return this; } 7 | 8 | virtual void on_player_create_waypoint(rage::IPlayer* entity_ptr, const rage::vec3_t& waypoint_position) override { 9 | rage::Log::Debug("IBlipHandler", ">>", "Create Waypoint"); 10 | } 11 | 12 | virtual void on_player_reach_waypoint(rage::IPlayer* entity_ptr) override { 13 | rage::Log::Debug("IBlipHandler", ">>", "Reach"); 14 | } 15 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleCheckpointEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleCheckpointEventHandler : public rage::IEventHandler, 4 | public rage::ICheckpointHandler { 5 | public: 6 | virtual rage::ICheckpointHandler* GetCheckpointHandler() override { return this; } 7 | 8 | virtual void on_player_enter_checkpoint(rage::IPlayer* entity_ptr, rage::ICheckpoint* checkpoint_ptr) override { 9 | rage::Log::Debug("ICheckpointHandler", ">>", "Enter", checkpoint_ptr); 10 | } 11 | 12 | virtual void on_player_exit_checkpoint(rage::IPlayer* entity_ptr, rage::ICheckpoint* checkpoint_ptr) override { 13 | rage::Log::Debug("ICheckpointHandler", ">>", "Exit", checkpoint_ptr); 14 | } 15 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleColshapeEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleColshapeEventHandler : public rage::IEventHandler, 4 | public rage::IColshapeHandler { 5 | public: 6 | virtual rage::IColshapeHandler* GetColshapeHandler() override { return this; } 7 | 8 | virtual void on_player_enter_colshape(rage::IPlayer* entity_ptr, rage::IColshape* colshape_ptr) override { 9 | rage::Log::Debug("IColshapeHandler", ">>", "Enter", colshape_ptr); 10 | } 11 | 12 | virtual void on_player_exit_colshape(rage::IPlayer* entity_ptr, rage::IColshape* colshape_ptr) override { 13 | rage::Log::Debug("IColshapeHandler", ">>", "Exit", colshape_ptr); 14 | } 15 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleConnectionEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class ExampleConnectionEventHandler : public rage::IEventHandler, 5 | public rage::IConnectionHandler { 6 | public: 7 | virtual rage::IConnectionHandler* GetConnectionHandler() override { return this; } 8 | 9 | virtual void on_incoming_connection(const char* ip, const std::string& serial, const char* rgsc_name, unsigned long rgsc_id, rage::game_type_t game_type) override { 10 | rage::Log::Debug(">>>>>>>>>>>>>>>>>", "IConnectionHandler - Connection Start", ">>>>>>>>>>>>>>>>>"); 11 | rage::Log::Debug("IP:", ip); 12 | rage::Log::Debug("Serial:", serial); 13 | rage::Log::Debug("RGSC-Name:", rgsc_name); 14 | rage::Log::Debug("RGSC-ID:", rgsc_id); 15 | rage::Log::Debug("Game-Type:", (int)game_type); 16 | rage::Log::Debug(">>>>>>>>>>>>>>>>>", "IConnectionHandler - Connection End", ">>>>>>>>>>>>>>>>>"); 17 | } 18 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleEntityEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleEntityEventHandler : public rage::IEventHandler, 4 | public rage::IEntityHandler { 5 | public: 6 | virtual rage::IEntityHandler* GetEntityHandler() override { return this; } 7 | 8 | virtual void on_entity_created(rage::IEntity *entity_ptr) override { 9 | rage::Log::Debug("IEntityHandler", ">>", "Created", (int)entity_ptr->get_id(), (int)entity_ptr->get_entity_type()); 10 | } 11 | 12 | virtual void on_entity_destroyed(rage::IEntity* entity_ptr) override { 13 | rage::Log::Debug("IEntityHandler", ">>", "Destroyed"); 14 | } 15 | 16 | virtual void on_entity_model_change(rage::IEntity* entity_ptr, uint32_t new_model) override { 17 | rage::Log::Debug("IEntityHandler", ">>", "Model-Change", new_model); 18 | } 19 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleLocalEventEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleLocalEventEventHandler : public rage::IEventHandler, 4 | public rage::ILocalEventHandler { 5 | public: 6 | virtual rage::ILocalEventHandler* GetLocalEventHandler() override { return this; } 7 | 8 | virtual void on_local_event(uint64_t event_name_hash, const rage::args_t& args, __int64* return_value) override { 9 | rage::Log::Debug("ILocalEventHandler", ">>", event_name_hash, args.Length(), return_value); 10 | } 11 | }; -------------------------------------------------------------------------------- /example/include/examples/ExamplePlayerEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExamplePlayerEventHandler : public rage::IEventHandler, 4 | public rage::IPlayerHandler { 5 | public: 6 | virtual rage::IPlayerHandler* GetPlayerHandler() override { return this; } 7 | 8 | virtual void on_player_connect(rage::IPlayer* player) override { 9 | rage::Log::Debug("IPlayerHandler", ">>", "Connect"); 10 | } 11 | 12 | virtual void on_player_ready(rage::IPlayer* player) override { 13 | rage::Log::Debug("IPlayerHandler", ">>", "Ready", player->get_id()); 14 | } 15 | 16 | virtual void on_player_disconnect(rage::IPlayer* player, unsigned __int8 disconnect_type, __int64 reason) override { 17 | // disconnect_type -> broken? 18 | 19 | rage::Log::Debug("IPlayerHandler", ">>", "Disconnect", (int)disconnect_type, reason); 20 | } 21 | 22 | virtual void on_player_command(rage::IPlayer* player, const std::u16string& command) override { 23 | std::string string_command(command.begin(), command.end()); 24 | 25 | if (string_command.find("kick") != std::string::npos) { 26 | player->kick_silent(); 27 | } 28 | 29 | rage::Log::Debug("IPlayerHandler", ">>", "Command", string_command); 30 | } 31 | 32 | virtual void on_player_chat(rage::IPlayer* player, const std::u16string& message) override { 33 | std::string string_message(message.begin(), message.end()); 34 | 35 | rage::Log::Debug("IPlayerHandler", ">>", "Chat", string_message); 36 | } 37 | 38 | virtual void on_player_death(rage::IPlayer* player, uint32_t death_reason, rage::IPlayer* killer_ptr) override { 39 | rage::Log::Debug("IPlayerHandler", ">>", "Death", death_reason, killer_ptr); 40 | } 41 | 42 | virtual void on_player_spawn(rage::IPlayer* player) override { 43 | rage::Log::Debug("IPlayerHandler", ">>", "Spawn"); 44 | } 45 | 46 | virtual void on_player_damage(rage::IPlayer* player, float health_loss, float armor_loss) override { 47 | rage::Log::Debug("IPlayerHandler", ">>", "Damage", health_loss, armor_loss); 48 | } 49 | 50 | virtual void on_player_weapon_switch(rage::IPlayer* player, uint32_t old_weapon, uint32_t new_weapon) override { 51 | rage::Log::Debug("IPlayerHandler", ">>", "WeaponSwitch", old_weapon, new_weapon); 52 | } 53 | 54 | virtual void on_player_remote_event(rage::IPlayer* player, uint64_t event_name_hash, const rage::args_t& args) override { 55 | rage::Log::Debug("IPlayerHandler", ">>", "RemoteEvent", event_name_hash, args.Length()); 56 | } 57 | 58 | virtual void on_player_start_enter_vehicle(rage::IPlayer* player, rage::IVehicle* vehicle_ptr, unsigned __int8 seat_id) override { } 59 | 60 | virtual void on_player_enter_vehicle(rage::IPlayer* player, rage::IVehicle* vehicle_ptr, unsigned __int8 seat_id) override { 61 | rage::Log::Debug("IPlayerHandler", ">>", "EnterVehicle", vehicle_ptr, (int)seat_id); 62 | } 63 | 64 | virtual void on_player_start_exit_vehicle(rage::IPlayer* player) override { } 65 | 66 | virtual void on_player_exit_vehicle(rage::IPlayer* player) override { 67 | rage::Log::Debug("IPlayerHandler", ">>", "ExitVehicle"); 68 | } 69 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleServerEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleServerEventHandler : public rage::IEventHandler, 4 | public rage::IServerHandler { 5 | public: 6 | virtual rage::IServerHandler* GetServerHandler() override { return this; } 7 | 8 | virtual void Unload() override { 9 | rage::Log::Debug("IServerHandler", ">>", "Unload"); 10 | Sleep(2000); 11 | } 12 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleTickEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleTickEventHandler : public rage::IEventHandler, 4 | public rage::ITickHandler { 5 | public: 6 | virtual rage::ITickHandler* GetTickHandler() override { return this; } 7 | 8 | virtual void Tick() override { 9 | DWORD64 current_tick = GetTickCount64(); 10 | 11 | static DWORD64 current_tick_timeout = 0x0; 12 | static DWORD64 latest_tick_timeout = 0x0; 13 | 14 | if ((current_tick_timeout - latest_tick_timeout) > 60000) { 15 | rage::Log::Debug("ITickHandler", ">>", "Tick (60000)"); 16 | 17 | latest_tick_timeout = current_tick_timeout; 18 | } 19 | current_tick_timeout = current_tick; 20 | } 21 | }; -------------------------------------------------------------------------------- /example/include/examples/ExampleVehicleEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ExampleVehicleEventHandler : public rage::IEventHandler, 4 | public rage::IVehicleHandler { 5 | public: 6 | virtual rage::IVehicleHandler* GetVehicleHandler() override { return this; } 7 | 8 | virtual void on_vehicle_death(rage::IVehicle* vehicle_ptr) override { 9 | rage::Log::Debug("IVehicleHandler", ">>", "Death"); 10 | } 11 | 12 | virtual void on_vehicle_siren_toggle(rage::IVehicle* vehicle_ptr, bool state) override { 13 | rage::Log::Debug("IVehicleHandler", ">>", "Siren", state); 14 | } 15 | 16 | virtual void on_vehicle_horn_toggle(rage::IVehicle* vehicle_ptr, bool state) override { 17 | rage::Log::Debug("IVehicleHandler", ">>", "Horen", state); 18 | } 19 | 20 | virtual void on_trailer_attached(rage::IVehicle* vehicle_ptr, rage::IVehicle* trailer_ptr) override { 21 | rage::Log::Debug("IVehicleHandler", ">>", "Trailer attached"); 22 | } 23 | 24 | virtual void on_vehicle_damage(rage::IVehicle* vehicle_ptr, float body_health_loss, float engine_health_loss) override { 25 | rage::Log::Debug("IVehicleHandler", ">>", "Damage", body_health_loss, engine_health_loss); 26 | } 27 | }; -------------------------------------------------------------------------------- /example/include/rage_log.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace rage 12 | { 13 | class Log : protected std::ostream 14 | { 15 | public: 16 | enum Color 17 | { 18 | RESET, 19 | BLACK, LBLACK, 20 | RED, LRED, 21 | GREEN, LGREEN, 22 | BLUE, LBLUE, 23 | YELLOW, LYELLOW, 24 | MAGENTA, LMAGENTA, 25 | CYAN, LCYAN, 26 | WHITE, LWHITE 27 | }; 28 | 29 | using StdStreamManip = std::ostream& (*)(std::ostream&); 30 | using LogManip = Log & (*)(Log&); 31 | 32 | Log& Write(const std::string& val) 33 | { 34 | for (auto& s : streams) 35 | s->Put(val); 36 | 37 | return *this; 38 | } 39 | 40 | template 41 | Log& Put(const T& val) 42 | { 43 | std::cout << val; 44 | return *this; 45 | } 46 | 47 | Log& Put(bool val) 48 | { 49 | return Put(val ? "true" : "false"); 50 | } 51 | 52 | Log& Put(LogManip val) 53 | { 54 | return val(*this); 55 | } 56 | 57 | Log& Put(StdStreamManip val) 58 | { 59 | std::cout << val; 60 | return *this; 61 | } 62 | 63 | template 64 | Log& Put(LogManip val, const Args&... args) 65 | { 66 | return Put(val).Put(args...); 67 | } 68 | 69 | template 70 | Log& Put(const T& val, const Args&... args) 71 | { 72 | return Put(val).Put(" ").Put(args...); 73 | } 74 | 75 | Log& PutTime() 76 | { 77 | const time_t t = time(nullptr); 78 | tm tt; 79 | 80 | localtime_s(&tt, &t); 81 | 82 | std::cout << std::put_time(&tt, "[%H:%M:%S]") << std::flush; 83 | return *this; 84 | } 85 | 86 | Log& PutColor(Color col) 87 | { 88 | *this << std::flush; 89 | 90 | for (auto& s : streams) 91 | s->PutColor(col); 92 | 93 | return *this; 94 | } 95 | 96 | template Log& operator<<(const T& val) { return Put(val); } 97 | Log& operator<<(StdStreamManip val) { return Put(val); } 98 | Log& operator<<(LogManip val) { return Put(val); } 99 | 100 | // Manipulators 101 | static Log& Reset(Log& log) { return log.PutColor(RESET); } 102 | static Log& Black(Log& log) { return log.PutColor(BLACK); } 103 | static Log& LBlack(Log& log) { return log.PutColor(LBLACK); } 104 | static Log& Red(Log& log) { return log.PutColor(RED); } 105 | static Log& LRed(Log& log) { return log.PutColor(LRED); } 106 | static Log& Green(Log& log) { return log.PutColor(GREEN); } 107 | static Log& LGreen(Log& log) { return log.PutColor(LGREEN); } 108 | static Log& Blue(Log& log) { return log.PutColor(BLUE); } 109 | static Log& LBlue(Log& log) { return log.PutColor(LBLUE); } 110 | static Log& Yellow(Log& log) { return log.PutColor(YELLOW); } 111 | static Log& LYellow(Log& log) { return log.PutColor(LYELLOW); } 112 | static Log& Magenta(Log& log) { return log.PutColor(MAGENTA); } 113 | static Log& LMagenta(Log& log) { return log.PutColor(LMAGENTA); } 114 | static Log& Cyan(Log& log) { return log.PutColor(CYAN); } 115 | static Log& LCyan(Log& log) { return log.PutColor(LCYAN); } 116 | static Log& White(Log& log) { return log.PutColor(WHITE); } 117 | static Log& LWhite(Log& log) { return log.PutColor(LWHITE); } 118 | static Log& Endl(Log& log) { return log.Put(std::endl).Put(std::dec).PutColor(WHITE); } 119 | static Log& Time(Log& log) { return log.PutTime(); } 120 | 121 | struct Log_Base 122 | { 123 | virtual Log& Begin() const = 0; 124 | template Log& operator()(const Args&... args) const { return Begin().Put(args...).Put(Endl); } 125 | template Log& operator<<(const T& val) const { return Begin().Put(val); } 126 | }; 127 | 128 | static constexpr struct Log_Raw : public Log_Base { 129 | Log& Begin() const override { return Instance(); } 130 | } Raw{}; 131 | 132 | static constexpr struct Log_Done : public Log_Base { 133 | Log& Begin() const override { return Instance().Put(Green, " - [DONE]", Reset); } 134 | } Done{}; 135 | 136 | static constexpr struct Log_Debug : public Log_Base { 137 | Log& Begin() const override { return Instance().Put(Cyan, " - [DEBUG]", Reset); } 138 | } Debug{}; 139 | 140 | static constexpr struct Log_Error : public Log_Base { 141 | Log& Begin() const override { return Instance().Put(Red, " - [ERROR]", Reset); } 142 | } Error{}; 143 | 144 | static constexpr struct Log_Info : public Log_Base { 145 | private: 146 | Log& Begin() const override { return Instance().Put(Yellow, " - [INFO]", Reset); } 147 | } Info{}; 148 | 149 | static Log& Instance() noexcept 150 | { 151 | static Log s; 152 | return s; 153 | } 154 | 155 | class Stream 156 | { 157 | public: 158 | virtual Stream& Put(const std::string& val) = 0; 159 | virtual Stream& PutColor(Color color) = 0; 160 | }; 161 | 162 | void AddOut(Stream* stream) { streams.emplace_back(stream); } 163 | 164 | static void Push(Stream* stream) { Instance().AddOut(stream); } 165 | 166 | class ConsoleStream : public Stream 167 | { 168 | public: 169 | Stream& Put(const std::string& val) override 170 | { 171 | std::cout << val; 172 | 173 | return *this; 174 | } 175 | 176 | Stream& PutColor(Color val) override 177 | { 178 | switch (val) 179 | { 180 | case RESET: 181 | std::cout << "\033[0m"; 182 | break; 183 | case BLACK: 184 | std::cout << "\033[30m"; 185 | break; 186 | case LBLACK: 187 | std::cout << "\033[90m"; 188 | break; 189 | case RED: 190 | std::cout << "\033[31m"; 191 | break; 192 | case LRED: 193 | std::cout << "\033[91m"; 194 | break; 195 | case GREEN: 196 | std::cout << "\033[32m"; 197 | break; 198 | case LGREEN: 199 | std::cout << "\033[92m"; 200 | break; 201 | case BLUE: 202 | std::cout << "\033[34m"; 203 | break; 204 | case LBLUE: 205 | std::cout << "\033[94m"; 206 | break; 207 | case YELLOW: 208 | std::cout << "\033[33m"; 209 | break; 210 | case LYELLOW: 211 | std::cout << "\033[93m"; 212 | break; 213 | case MAGENTA: 214 | std::cout << "\033[35m"; 215 | break; 216 | case LMAGENTA: 217 | std::cout << "\033[95m"; 218 | break; 219 | case CYAN: 220 | std::cout << "\033[36m"; 221 | break; 222 | case LCYAN: 223 | std::cout << "\033[96m"; 224 | break; 225 | case WHITE: 226 | std::cout << "\033[37m"; 227 | break; 228 | case LWHITE: 229 | std::cout << "\033[97m"; 230 | break; 231 | } 232 | 233 | return *this; 234 | } 235 | 236 | }; 237 | 238 | private: 239 | class Buffer : public std::streambuf 240 | { 241 | static const std::size_t BUF_SIZE = 1024; 242 | 243 | char buf[BUF_SIZE]; 244 | 245 | public: 246 | using Traits = std::char_traits; 247 | 248 | Buffer() { setp(buf, buf + BUF_SIZE); } 249 | 250 | protected: 251 | virtual Traits::int_type overflow(Traits::int_type c = Traits::eof()) override 252 | { 253 | put(pbase(), pptr()); 254 | if (c != Traits::eof()) { 255 | char c2 = c; 256 | put(&c2, &c2 + 1); 257 | } 258 | setp(buf, buf + BUF_SIZE); 259 | 260 | return c; 261 | } 262 | 263 | virtual int sync() override 264 | { 265 | put(pbase(), pptr()); 266 | setp(buf, buf + BUF_SIZE); 267 | return 0; 268 | } 269 | 270 | private: 271 | void put(const char* begin, const char* end) { Log::Instance().Write(std::string(begin, end)); } 272 | }; 273 | 274 | Log() :std::ostream(&buf) { }; 275 | Log(const Log&) = delete; 276 | Log& operator=(const Log&) = delete; 277 | 278 | Buffer buf; 279 | std::vector> streams; 280 | }; 281 | } 282 | -------------------------------------------------------------------------------- /example/src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "rage_sdk.hpp" 5 | #include "rage_log.hpp" 6 | 7 | #include "examples/ExampleEntityEventHandler.hpp" 8 | #include "examples/ExamplePlayerEventHandler.hpp" 9 | #include "examples/ExampleVehicleEventHandler.hpp" 10 | #include "examples/ExampleColshapeEventHandler.hpp" 11 | #include "examples/ExampleCheckpointEventHandler.hpp" 12 | #include "examples/ExampleBlipEventHandler.hpp" 13 | #include "examples/ExampleTickEventHandler.hpp" 14 | #include "examples/ExampleLocalEventEventHandler.hpp" 15 | #include "examples/ExampleConnectionEventHandler.hpp" 16 | #include "examples/ExampleServerEventHandler.hpp" 17 | 18 | EXTERN uint32_t GetPluginVersion() 19 | { 20 | return rage::IMultiplayer::SDK_VERSION; 21 | } 22 | 23 | EXTERN const char* GetPluginName() 24 | { 25 | return "rage:MP SDK"; 26 | } 27 | 28 | EXTERN bool InitializePlugin(rage::IMultiplayer* _mp) 29 | { 30 | rage::IMultiplayer::SetInstance(_mp); 31 | rage::Log::Push(new rage::Log::ConsoleStream); 32 | 33 | rage::Log::Done("Initialized plugin.", ">>", GetPluginName()); 34 | 35 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleEntityEventHandler); 36 | rage::IMultiplayer::Instance().SetEventHandler(new ExamplePlayerEventHandler); 37 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleVehicleEventHandler); 38 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleColshapeEventHandler); 39 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleCheckpointEventHandler); 40 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleBlipEventHandler); 41 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleTickEventHandler); 42 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleLocalEventEventHandler); 43 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleConnectionEventHandler); 44 | rage::IMultiplayer::Instance().SetEventHandler(new ExampleServerEventHandler); 45 | 46 | return true; 47 | } -------------------------------------------------------------------------------- /handlers/IBlipHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A808F8 ; class rage::IBlipHandler 7 | .rdata:0000000141A808F8 18 AC E6 41 01 00 00 00 dq offset ??_R4EventHandler@bridge@@6B@_5 ; const bridge::EventHandler::`RTTI Complete Object Locator' 8 | .rdata:0000000141A80900 ; const bridge::EventHandler::`vftable' 9 | .rdata:0000000141A80900 C0 02 01 40 01 00 00 00 ??_7EventHandler@bridge@@6B@_5 dq offset on_player_create_waypoint 10 | .rdata:0000000141A80900 ; DATA XREF: sub_14120D250+6B 11 | .rdata:0000000141A80908 C0 02 01 40 01 00 00 00 dq offset on_player_reach_waypoint 12 | */ 13 | 14 | class IBlipHandler 15 | { 16 | public: 17 | // NOT WORKING - NOT SYNCED 18 | virtual void on_player_create_waypoint(rage::IPlayer* entity_ptr, const rage::vec3_t& waypoint_position) = 0; 19 | virtual void on_player_reach_waypoint(rage::IPlayer* entity_ptr) = 0; 20 | }; 21 | } -------------------------------------------------------------------------------- /handlers/ICheckpointHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A808E0 ; class rage::ICheckpointHandler 7 | .rdata:0000000141A808E0 F0 AB E6 41 01 00 00 00 dq offset ??_R4EventHandler@bridge@@6B@_4 ; const bridge::EventHandler::`RTTI Complete Object Locator' 8 | .rdata:0000000141A808E8 ; const bridge::EventHandler::`vftable' 9 | .rdata:0000000141A808E8 F0 37 21 41 01 00 00 00 ??_7EventHandler@bridge@@6B@_4 dq offset on_player_enter_checkpoint 10 | .rdata:0000000141A808E8 ; DATA XREF: sub_14120D250+60 11 | .rdata:0000000141A808F0 F0 38 21 41 01 00 00 00 dq offset on_player_exit_checkpoint 12 | */ 13 | 14 | class ICheckpointHandler 15 | { 16 | public: 17 | virtual void on_player_enter_checkpoint(rage::IPlayer* entity_ptr, rage::ICheckpoint* checkpoint_ptr) = 0; 18 | virtual void on_player_exit_checkpoint(rage::IPlayer* entity_ptr, rage::ICheckpoint* checkpoint_ptr) = 0; 19 | }; 20 | } -------------------------------------------------------------------------------- /handlers/IColshapeHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A808C8 ; class rage::IColshapeHandler 7 | .rdata:0000000141A808C8 C8 AB E6 41 01 00 00 00 dq offset ??_R4EventHandler@bridge@@6B@_3 ; const bridge::EventHandler::`RTTI Complete Object Locator' 8 | .rdata:0000000141A808D0 ; const bridge::EventHandler::`vftable' 9 | .rdata:0000000141A808D0 40 38 21 41 01 00 00 00 ??_7EventHandler@bridge@@6B@_3 dq offset EnterColshape 10 | .rdata:0000000141A808D0 ; DATA XREF: sub_14120D250+55 11 | .rdata:0000000141A808D8 40 39 21 41 01 00 00 00 dq offset ExitColshape 12 | */ 13 | 14 | class IColshapeHandler 15 | { 16 | public: 17 | virtual void on_player_enter_colshape(rage::IPlayer* entity_ptr, rage::IColshape* colshape_ptr) = 0; 18 | virtual void on_player_exit_colshape(rage::IPlayer* entity_ptr, rage::IColshape* colshape_ptr) = 0; 19 | }; 20 | } -------------------------------------------------------------------------------- /handlers/IConnectionHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A80940 ; class rage::IConnectionHandler 7 | .rdata:0000000141A80940 B8 AC E6 41 01 00 00 00 dq offset ??_R4EventHandler@bridge@@6B@_9 ; const bridge::EventHandler::`RTTI Complete Object Locator' 8 | .rdata:0000000141A80948 ; const bridge::EventHandler::`vftable' 9 | .rdata:0000000141A80948 C0 35 21 41 01 00 00 00 ??_7EventHandler@bridge@@6B@_9 dq offset on_incoming_connection 10 | */ 11 | 12 | class IConnectionHandler 13 | { 14 | public: 15 | virtual void on_incoming_connection(const char* ip, const std::string& serial, const char* rgsc_name, unsigned long rgsc_id, rage::game_type_t game_type) = 0; 16 | }; 17 | } -------------------------------------------------------------------------------- /handlers/IEntityHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A807F8 C0 34 21 41 01 00 00 00 ??_7EventHandler@bridge@@6B@_0 dq offset on_entity_created 7 | .rdata:0000000141A807F8 ; DATA XREF: sub_14120D250+2E 8 | .rdata:0000000141A80800 10 35 21 41 01 00 00 00 dq offset on_entity_destroyed 9 | .rdata:0000000141A80808 60 35 21 41 01 00 00 00 dq offset on_entity_model_change 10 | */ 11 | 12 | class IEntityHandler 13 | { 14 | public: 15 | virtual void on_entity_created(rage::IEntity* entity_ptr) = 0; 16 | virtual void on_entity_destroyed(rage::IEntity* entity_ptr) = 0; 17 | virtual void on_entity_model_change(rage::IEntity* entity_ptr, uint32_t new_model) = 0; 18 | }; 19 | } -------------------------------------------------------------------------------- /handlers/ILocalEventHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A80930 ; class rage::ILocalEventHandler 7 | .rdata:0000000141A80930 90 AC E6 41 01 00 00 00 dq offset ??_R4EventHandler@bridge@@6B@_8 ; const bridge::EventHandler::`RTTI Complete Object Locator' 8 | .rdata:0000000141A80938 ; const bridge::EventHandler::`vftable' 9 | .rdata:0000000141A80938 30 36 21 41 01 00 00 00 ??_7EventHandler@bridge@@6B@_8 dq offset on_local_event 10 | */ 11 | 12 | class ILocalEventHandler 13 | { 14 | public: 15 | // not tested 16 | virtual void on_local_event(uint64_t event_name_hash, const rage::args_t& args, __int64* return_value) = 0; 17 | }; 18 | } -------------------------------------------------------------------------------- /handlers/IPlayerHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A80818 C0 02 01 40 01 00 00 00 ??_7EventHandler@@6B@_1 dq offset PlayerConnect 7 | .rdata:0000000141A80820 30 3A 21 41 01 00 00 00 dq offset PlayerReady_0 8 | .rdata:0000000141A80828 E0 39 21 41 01 00 00 00 dq offset PlayerQuit 9 | .rdata:0000000141A80830 E0 36 21 41 01 00 00 00 dq offset Command 10 | .rdata:0000000141A80838 90 36 21 41 01 00 00 00 dq offset Chat 11 | .rdata:0000000141A80840 80 37 21 41 01 00 00 00 dq offset Death 12 | .rdata:0000000141A80848 E0 3A 21 41 01 00 00 00 dq offset Spawn 13 | .rdata:0000000141A80850 30 37 21 41 01 00 00 00 dq offset Damage 14 | .rdata:0000000141A80858 C0 3B 21 41 01 00 00 00 dq offset WeaponSwitch 15 | .rdata:0000000141A80860 60 3A 21 41 01 00 00 00 dq offset RemoteEvent_0 16 | .rdata:0000000141A80868 C0 02 01 40 01 00 00 00 dq offset uv_cond_destroy 17 | .rdata:0000000141A80870 C0 02 01 40 01 00 00 00 dq offset uv_cond_destroy 18 | .rdata:0000000141A80878 10 3B 21 41 01 00 00 00 dq offset StartEnterVeh 19 | .rdata:0000000141A80880 90 38 21 41 01 00 00 00 dq offset EnterVeh 20 | .rdata:0000000141A80888 70 3B 21 41 01 00 00 00 dq offset StartExit 21 | .rdata:0000000141A80890 90 39 21 41 01 00 00 00 dq offset Exit 22 | */ 23 | 24 | class IPlayerHandler 25 | { 26 | public: 27 | virtual void on_player_connect(rage::IPlayer* player) = 0; 28 | virtual void on_player_ready(rage::IPlayer* player) = 0; 29 | virtual void on_player_disconnect(rage::IPlayer* player, unsigned __int8 disconnect_type, __int64 reason) = 0; 30 | 31 | virtual void on_player_command(rage::IPlayer* player, const std::u16string& command) = 0; 32 | virtual void on_player_chat(rage::IPlayer* player, const std::u16string& message) = 0; 33 | 34 | virtual void on_player_death(rage::IPlayer* player, uint32_t death_reason, rage::IPlayer* killer) = 0; 35 | virtual void on_player_spawn(rage::IPlayer* player) = 0; 36 | 37 | virtual void on_player_damage(rage::IPlayer* player, float health_loss, float armor_loss) = 0; 38 | virtual void on_player_weapon_switch(rage::IPlayer* player, uint32_t old_weapon, uint32_t new_weapon) = 0; 39 | 40 | virtual void on_player_remote_event(rage::IPlayer* player, uint64_t event_name_hash, const rage::args_t& args) = 0; 41 | 42 | virtual void padding_01(rage::IPlayer* player) { } 43 | virtual void padding_02(rage::IPlayer* player) { } 44 | 45 | virtual void on_player_start_enter_vehicle(rage::IPlayer* player, rage::IVehicle* vehicle_ptr, unsigned __int8 seat_id) = 0; 46 | virtual void on_player_enter_vehicle(rage::IPlayer* player, rage::IVehicle* vehicle_ptr, unsigned __int8 seat_id) = 0; 47 | 48 | virtual void on_player_start_exit_vehicle(rage::IPlayer* player) = 0; 49 | virtual void on_player_exit_vehicle(rage::IPlayer* player) = 0; 50 | }; 51 | } -------------------------------------------------------------------------------- /handlers/IServerHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .text:0000000141213D90 sub_141213D90 proc near ; DATA XREF: .rdata:const EventHandler::IServerHandler` 7 | .text:0000000141213D90 48 FF 25 69 8B 3A 01 jmp cs:qword_1425BC900 8 | .text:0000000141213D90 sub_141213D90 endp 9 | .text:0000000141213D90 10 | */ 11 | 12 | class IServerHandler 13 | { 14 | public: 15 | virtual void Unload() = 0; 16 | }; 17 | } -------------------------------------------------------------------------------- /handlers/ITickHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | class ITickHandler 6 | { 7 | public: 8 | virtual void Tick() = 0; 9 | }; 10 | } -------------------------------------------------------------------------------- /handlers/IVehicleHandler.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | /* 6 | .rdata:0000000141A808A0 50 3E 21 41 01 00 00 00 ??_7EventHandler@bridge@@6B@_2 dq offset OnVehicleDeath 7 | .rdata:0000000141A808A0 ; DATA XREF: sub_14120D250+4A 8 | .rdata:0000000141A808A8 00 3F 21 41 01 00 00 00 dq offset OnSirenToggle 9 | .rdata:0000000141A808B0 C0 3E 21 41 01 00 00 00 dq offset OnVehicleHorn 10 | .rdata:0000000141A808B8 A0 3D 21 41 01 00 00 00 dq offset OnTrailerAttach 11 | .rdata:0000000141A808C0 00 3E 21 41 01 00 00 00 dq offset OnVehicleDamage 12 | */ 13 | 14 | class IVehicleHandler 15 | { 16 | public: 17 | virtual void on_vehicle_death(rage::IVehicle* vehicle_ptr) = 0; 18 | virtual void on_vehicle_siren_toggle(rage::IVehicle* vehicle_ptr, bool state) = 0; 19 | virtual void on_vehicle_horn_toggle(rage::IVehicle* vehicle_ptr, bool state) = 0; 20 | virtual void on_trailer_attached(rage::IVehicle* vehicle_ptr, rage::IVehicle* trailer_ptr) = 0; 21 | virtual void on_vehicle_damage(rage::IVehicle* vehicle_ptr, float body_health_loss, float engine_health_loss) = 0; 22 | }; 23 | } -------------------------------------------------------------------------------- /objects/IBlip.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IBlip : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/ICheckpoint.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class ICheckpoint : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/IColshape.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IColshape : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/IDummyEntity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IDummyEntity : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/IEntity.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IEntity { 5 | public: 6 | virtual uint16_t get_id() = 0; // 0x38 7 | virtual entity_type_t get_entity_type() = 0; // 0xB 8 | 9 | virtual void v8_internal_compiler_LoadElimination() = 0; // ???? 10 | 11 | virtual void destroy() = 0; 12 | 13 | virtual uint32_t get_dimension() = 0; // 0x3A 14 | virtual void set_dimension(uint32_t dimension) = 0; 15 | 16 | //virtual void v8_internal_OptimizedCompilationInfo_InlinedFunctionHolder_inlined_functions() = 0; 17 | virtual const vec3_t& get_position() = 0; // 0x64 18 | virtual void set_position(const vec3_t& position) = 0; 19 | 20 | virtual const vec3_t& get_rotation() = 0; 21 | virtual void set_rotation(const vec3_t& rotation) = 0; 22 | 23 | virtual uint32_t get_model() = 0; // 0x3E 24 | virtual void set_model(uint32_t model_hash) = 0; 25 | 26 | virtual const vec3_t& get_velocity() = 0; // could be velocity, or something different idk 27 | 28 | virtual uint8_t get_alpha() = 0; 29 | virtual void set_alpha(uint8_t alpha) = 0; 30 | 31 | private: 32 | virtual void padding_01() = 0; 33 | virtual void padding_02() = 0; 34 | virtual void padding_03() = 0; // get_shared_data 35 | virtual void padding_04() = 0; 36 | virtual void padding_05() = 0; 37 | virtual void padding_06() = 0; // returns 0 or 1 - might be a "has" function 38 | }; 39 | } -------------------------------------------------------------------------------- /objects/IMarker.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IMarker : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/IObject.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IObject : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/IPickup.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IPickup : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/IPlayer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IPlayer : public rage::IEntity { 5 | public: 6 | virtual void kick(const char* reason = nullptr) = 0; 7 | virtual void kick_silent(const char* reason = nullptr) = 0; 8 | virtual void ban(const char* reason = nullptr) = 0; 9 | 10 | /* 11 | * When I tried this with the local player, my game crashed. 12 | */ 13 | virtual void do_something_with_player(rage::IPlayer* player) = 0; 14 | 15 | }; 16 | } -------------------------------------------------------------------------------- /objects/ITextLabel.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class ITextLabel : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /objects/IVehicle.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | namespace rage { 4 | class IVehicle : public rage::IEntity { 5 | public: 6 | 7 | }; 8 | } -------------------------------------------------------------------------------- /rage_sdk.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include "types.hpp" 15 | 16 | #include "objects/IEntity.hpp" 17 | #include "objects/IPlayer.hpp" 18 | #include "objects/IVehicle.hpp" 19 | #include "objects/IObject.hpp" 20 | #include "objects/IPickup.hpp" 21 | #include "objects/IBlip.hpp" 22 | #include "objects/ICheckpoint.hpp" 23 | #include "objects/IMarker.hpp" 24 | #include "objects/IColshape.hpp" 25 | #include "objects/ITextLabel.hpp" 26 | #include "objects/IDummyEntity.hpp" 27 | 28 | #include "handlers/IEntityHandler.hpp" 29 | #include "handlers/IPlayerHandler.hpp" 30 | #include "handlers/IVehicleHandler.hpp" 31 | #include "handlers/IColshapeHandler.hpp" 32 | #include "handlers/ICheckpointHandler.hpp" 33 | #include "handlers/IBlipHandler.hpp" 34 | #include "handlers/ITickHandler.hpp" 35 | #include "handlers/ILocalEventHandler.hpp" 36 | #include "handlers/IConnectionHandler.hpp" 37 | #include "handlers/IServerHandler.hpp" 38 | 39 | #ifdef _WIN32 40 | #define EXTERN extern "C" __declspec(dllexport) 41 | #else 42 | #define EXTERN extern "C" 43 | #endif 44 | 45 | namespace rage 46 | { 47 | //rage::IEntityHandler, rage::IPlayerHandler, rage::IVehicleHandler, rage::IColshapeHandler, rage::ICheckpointHandler, rage::IBlipHandler, 48 | // rage::ITickHandler, rage::IServerHandler, rage::ILocalEventHandler, rage::IConnectionHandler, rage::IRpcHandler; 49 | class IEventHandler 50 | { 51 | public: 52 | virtual IEntityHandler* GetEntityHandler() { return nullptr; } // 0x0 53 | virtual IPlayerHandler* GetPlayerHandler() { return nullptr; } // 0x8 54 | virtual IVehicleHandler* GetVehicleHandler() { return nullptr; } // 0x10 55 | virtual IColshapeHandler* GetColshapeHandler() { return nullptr; } // 0x18 56 | virtual ICheckpointHandler* GetCheckpointHandler() { return nullptr; } // 0x20 57 | virtual IBlipHandler* GetBlipHandler() { return nullptr; } // 0x28 58 | virtual __int64* padding_01() { return nullptr; } // 0x30 59 | virtual ITickHandler* GetTickHandler() { return nullptr; } // 0x38 60 | virtual ILocalEventHandler* GetLocalEventHandler() { return nullptr; } // 0x40 61 | virtual IConnectionHandler* GetConnectionHandler() { return nullptr; } // 0x48 62 | virtual __int64* GetDebugHandler() { return nullptr; } // 0x50 <- cant find class for it 63 | virtual IServerHandler* GetServerHandler() { return nullptr; } // 0x58 64 | 65 | virtual __int64 GetRPCHandler() { return 2; } // 0x60 66 | }; 67 | 68 | class IMultiplayer 69 | { 70 | public: 71 | static constexpr uint32_t SDK_VERSION = 6; 72 | 73 | virtual void SetEventHandler(IEventHandler* event_handler) = 0; 74 | 75 | static IMultiplayer& Instance() 76 | { 77 | return *_instance(); 78 | } 79 | static void SetInstance(IMultiplayer* server) { _instance() = server; } 80 | 81 | protected: 82 | virtual ~IMultiplayer() = default; 83 | 84 | private: 85 | static IMultiplayer*& _instance() 86 | { 87 | static IMultiplayer* instance = nullptr; 88 | return instance; 89 | } 90 | }; 91 | } -------------------------------------------------------------------------------- /types.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace rage { 5 | enum class game_type_t : uint8_t { 6 | rgsc, 7 | steam, 8 | egs 9 | }; 10 | 11 | struct vec3_t { 12 | float x, y, z; 13 | }; 14 | 15 | enum class entity_type_t : uint8_t 16 | { 17 | PLAYER, 18 | VEHICLE, 19 | OBJECT, 20 | PICKUP, 21 | BLIP, 22 | CHECKPOINT, 23 | MARKER, 24 | COLSHAPE, 25 | TEXTLABEL, 26 | DUMMYENTITY 27 | }; 28 | 29 | #pragma pack(push, 1) 30 | struct arg_t 31 | { 32 | public: 33 | enum class val_t : uint8_t 34 | { 35 | Int, 36 | Float, 37 | String, 38 | Boolean, 39 | Vector3, 40 | Object, 41 | Null, 42 | 43 | Entity 44 | }; 45 | 46 | arg_t() : type(val_t::Null), v{} { } 47 | arg_t(bool b) : type(val_t::Boolean), v{ b } { } 48 | arg_t(int i) : type(val_t::Int), v{ i } { } 49 | arg_t(float f) : type(val_t::Float), v{ f } { } 50 | arg_t(const std::string& str) : type(val_t::String), v{ new char[str.length() + 1] } { memcpy(v.str, str.c_str(), str.length()); v.str[str.length()] = 0; } 51 | arg_t(entity_type_t entityType, uint16_t id, __int64* entity) : type(val_t::Entity), v{ entityType, id, entity } { } 52 | arg_t(const arg_t& r) : type(val_t::Null) { *this = r; } 53 | 54 | void SetNull() { DeleteString(); type = val_t::Null; } 55 | void SetBoolean(bool b) { DeleteString(); type = val_t::Boolean; v.b = b; } 56 | void SetInteger(int i) { DeleteString(); type = val_t::Int; v.i = i; } 57 | void SetFloat(float f) { DeleteString(); type = val_t::Float; v.f = f; } 58 | void SetString(const std::string& str) { DeleteString(); type = val_t::String; v.str = new char[str.length() + 1]; memcpy(v.str, str.c_str(), str.length()); v.str[str.length()] = 0; } 59 | void SetJson(const std::string& str) { DeleteString(); type = val_t::Object; v.str = new char[str.length() + 1]; memcpy(v.str, str.c_str(), str.length()); v.str[str.length()] = 0; } 60 | void SetEntity(entity_type_t entityType, uint16_t id, __int64* entity) { DeleteString(); type = val_t::Entity; v.entity = { entityType, id, entity }; } 61 | void SetVector3(const vec3_t& vec) { DeleteString(); type = val_t::Vector3; v.vector = vec; } 62 | 63 | val_t GetType() const { return type; } 64 | bool IsNull() const { return type == val_t::Null; } 65 | bool IsBoolean() const { return type == val_t::Boolean; } 66 | bool IsInt() const { return type == val_t::Int; } 67 | bool IsFloat() const { return type == val_t::Float; } 68 | bool IsString() const { return type == val_t::String; } 69 | bool IsEntity() const { return type == val_t::Entity; } 70 | 71 | bool Boolean() const { return (type == val_t::Boolean) ? v.b : false; } 72 | int Int() const { return (type == val_t::Int) ? v.i : 0; } 73 | float Float() const { return (type == val_t::Float) ? v.f : 0.0f; } 74 | const char* String() const { return (type == val_t::String && v.str) ? v.str : ""; } 75 | const char* Object() const { return (type == val_t::Object && v.str) ? v.str : ""; } 76 | const vec3_t& Vector3() const { if (type == val_t::Vector3) { return v.vector; } else { static vec3_t ret; return ret; } } 77 | 78 | __int64* Entity() const { return (type == val_t::Entity) ? v.entity.ptr : nullptr; } 79 | uint16_t EntityId() const { return (type == val_t::Entity) ? v.entity.id : 0xFFFF; } 80 | entity_type_t EntityType() const { return (type == val_t::Entity) ? v.entity.type : static_cast(-1); } 81 | 82 | arg_t& operator=(const arg_t& r) { DeleteString(); if (r.GetType() != val_t::String) { this->v.entity = r.v.entity; type = r.GetType(); } else { this->SetString(r.String()); } return *this; } 83 | arg_t& operator=(arg_t&& r) { DeleteString(); this->v.str = r.v.str; type = r.GetType(); r.type = val_t::Null; r.v.str = nullptr; return *this; } 84 | 85 | ~arg_t() { DeleteString(); } 86 | 87 | private: 88 | bool OwnsAString() { return (type == val_t::Object || type == val_t::String); } 89 | void DeleteString() { if (this->OwnsAString() && v.str) { delete[] v.str; v.str = nullptr; } } 90 | 91 | union _Value 92 | { 93 | bool b; 94 | int i; 95 | float f; 96 | char* str; 97 | 98 | vec3_t vector; 99 | 100 | struct _EntityData 101 | { 102 | entity_type_t type; 103 | uint16_t id; 104 | 105 | __int64* ptr; 106 | } entity; 107 | 108 | _Value() { memset(this, 0, sizeof(_Value)); } 109 | _Value(bool _b) : b{ _b } { } 110 | _Value(int _i) : i{ _i } { } 111 | _Value(float _f) : f{ _f } { } 112 | _Value(char* _str) : str{ _str } { } 113 | _Value(const vec3_t& _vec) : vector{ _vec } { } 114 | _Value(entity_type_t entityType, uint16_t id, __int64* ptr) : entity{ entityType, id, ptr } { } 115 | } v; 116 | 117 | val_t type; 118 | }; 119 | #pragma pack(pop) 120 | 121 | struct args_t 122 | { 123 | public: 124 | args_t(arg_t* data, size_t len) 125 | : m_data(data), m_len(len) { } 126 | 127 | size_t Length() const { return this->m_len; } 128 | const arg_t& operator[](size_t id) const { if (id >= this->m_len) { static arg_t ar{}; return ar; } return this->m_data[id]; } 129 | 130 | auto begin() const { return m_data; } 131 | auto end() const { return &m_data[this->m_len]; } 132 | 133 | private: 134 | size_t m_len; 135 | arg_t* m_data; 136 | }; 137 | } --------------------------------------------------------------------------------