### Complete RED4ext Plugin Example Source: https://context7.com/wopss/red4ext/llms.txt A comprehensive example demonstrating the full plugin lifecycle, including initialization, logging, game state handling, and cleanup. It shows how to register game state callbacks and attach hooks. ```cpp #include // Global state static RED4ext::PluginHandle g_handle = nullptr; static const RED4ext::Sdk* g_sdk = nullptr; // Hook state using SomeGameFunc_t = int (*)(void*, int); static SomeGameFunc_t Original_SomeGameFunc = nullptr; int Hook_SomeGameFunc(void* self, int value) { g_sdk->logger->DebugF(g_handle, "SomeGameFunc called with value: %d", value); return Original_SomeGameFunc(self, value); } bool OnGameRunning(RED4ext::CGameApplication* aApp) { g_sdk->logger->Info(g_handle, "Game world is now active!"); return true; } RED4EXT_C_EXPORT uint32_t RED4EXT_CALL Supports() { return RED4EXT_API_VERSION_LATEST; } RED4EXT_C_EXPORT void RED4EXT_CALL Query(RED4ext::PluginInfo* aInfo) { aInfo->name = L"Complete Example Plugin"; aInfo->author = L"Modder"; aInfo->version = RED4EXT_SEMVER(1, 0, 0); aInfo->runtime = RED4EXT_RUNTIME_INDEPENDENT; aInfo->sdk = RED4EXT_SDK_LATEST; } RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::PluginHandle aHandle, RED4ext::EMainReason aReason, const RED4ext::Sdk* aSdk) { switch (aReason) { case RED4ext::EMainReason::Load: { g_handle = aHandle; g_sdk = aSdk; g_sdk->logger->Info(g_handle, "Plugin loading..."); // Register game state callback RED4ext::GameState state; state.OnEnter = &OnGameRunning; state.OnUpdate = nullptr; state.OnExit = nullptr; g_sdk->gameStates->Add(g_handle, RED4ext::EGameStateType::Running, &state); // Attach hooks (example address - would come from reverse engineering) // void* target = GetGameFunctionAddress(); // g_sdk->hooking->Attach(g_handle, target, // reinterpret_cast(&Hook_SomeGameFunc), // reinterpret_cast(&Original_SomeGameFunc)); // Register scripts g_sdk->scripts->Add(g_handle, L"red4ext\\plugins\\CompleteExample\\scripts"); g_sdk->logger->Info(g_handle, "Plugin loaded successfully!"); return true; } case RED4ext::EMainReason::Unload: { g_sdk->logger->Info(g_handle, "Plugin unloading..."); // Hooks are automatically detached by RED4ext on unload // But you can manually detach if needed: // if (Original_SomeGameFunc) // { // g_sdk->hooking->Detach(g_handle, targetAddress); // Original_SomeGameFunc = nullptr; // } g_sdk->logger->Info(g_handle, "Plugin unloaded!"); g_handle = nullptr; g_sdk = nullptr; return true; } } return false; } ``` -------------------------------- ### RED4ext Configuration File Example Source: https://context7.com/wopss/red4ext/llms.txt Example TOML configuration file for RED4ext, illustrating settings for developer options, logging levels, and plugin management. ```toml # red4ext/config.toml - RED4ext configuration file ``` -------------------------------- ### Configure Red4ext Installation Rules Source: https://github.com/wopss/red4ext/blob/master/CMakeLists.txt Sets installation directories for x64 binaries and the main red4ext directory. This configuration is applied only if CMake install rules are not skipped. ```cmake if(NOT CMAKE_SKIP_INSTALL_RULES) set(RED4EXT_INSTALL_X64_DIR bin/x64) set(RED4EXT_INSTALL_BIN_DIR red4ext) install( TARGETS RED4ext.Loader RUNTIME DESTINATION "${RED4EXT_INSTALL_X64_DIR}" ) install( FILES $ DESTINATION "${RED4EXT_INSTALL_X64_DIR}" ) install( TARGETS RED4ext.Dll RUNTIME DESTINATION "${RED4EXT_INSTALL_BIN_DIR}" ) install( FILES $ DESTINATION "${RED4EXT_INSTALL_BIN_DIR}" ) install( FILES "${PROJECT_SOURCE_DIR}/LICENSE.md" DESTINATION "${RED4EXT_INSTALL_BIN_DIR}" RENAME LICENSE.txt ) install( FILES "${PROJECT_SOURCE_DIR}/THIRD_PARTY_LICENSES.md" DESTINATION "${RED4EXT_INSTALL_BIN_DIR}" RENAME THIRD_PARTY_LICENSES.txt ) endif() ``` -------------------------------- ### RED4ext Logger API Examples Source: https://context7.com/wopss/red4ext/llms.txt Demonstrates how to use the SDK's logging system for various severity levels, including formatted ANSI and wide character messages. Initialize logging with plugin handle and SDK. ```cpp #include static RED4ext::PluginHandle g_handle; static const RED4ext::Sdk* g_sdk; void InitializeLogging(RED4ext::PluginHandle handle, const RED4ext::Sdk* sdk) { g_handle = handle; g_sdk = sdk; } void LoggingExamples() { auto logger = g_sdk->logger; // Simple messages (ANSI) logger->Trace(g_handle, "Trace level message"); logger->Debug(g_handle, "Debug level message"); logger->Info(g_handle, "Info level message"); logger->Warn(g_handle, "Warning level message"); logger->Error(g_handle, "Error level message"); logger->Critical(g_handle, "Critical level message"); // Formatted messages (ANSI) - printf-style logger->InfoF(g_handle, "Player health: %d, armor: %d", 100, 50); logger->WarnF(g_handle, "Memory usage: %.2f MB", 1024.5); logger->ErrorF(g_handle, "Failed to load file: %s (error: %d)", "config.json", 404); // Wide character messages logger->InfoW(g_handle, L"Wide string message"); logger->DebugW(g_handle, L"配置已加载"); // Unicode support // Formatted wide character messages logger->InfoWF(g_handle, L"Player name: %ls, level: %d", L"V", 50); logger->ErrorWF(g_handle, L"Failed to process: %ls", L"任务文件.quest"); } ``` -------------------------------- ### RED4ext Configuration Example Source: https://context7.com/wopss/red4ext/llms.txt This TOML configuration file sets up RED4ext's behavior, including developer console, debugger attachment, logging levels, and plugin management. ```toml version = 0 [dev] hasConsole = false waitForDebugger = false [logging] level = "info" flushOn = "info" maxFiles = 5 maxFileSize = 10 [plugins] isEnabled = true ignored = ["BrokenPlugin", "DeprecatedMod"] ``` -------------------------------- ### RED4ext Installation Output Structure Source: https://context7.com/wopss/red4ext/llms.txt This outlines the directory structure after a successful RED4ext installation, detailing the locations of the loader, main library, license, and plugin directory. ```text # Installation output structure: # bin/x64/winmm.dll - Loader (proxy DLL) # red4ext/RED4ext.dll - Main library # red4ext/LICENSE.txt - License file # red4ext/plugins/ - Plugin directory (place your .dll plugins here) ``` -------------------------------- ### Build RED4ext from Source on Windows Source: https://context7.com/wopss/red4ext/llms.txt Compile RED4ext from source using Visual Studio and CMake on Windows. Ensure prerequisites like Visual Studio and CMake are installed. ```bash # Prerequisites: # - Windows 10/11 # - Visual Studio 2022 Community Edition (or newer) # - CMake 3.26 or newer # Clone the repository git clone https://github.com/WopsS/RED4ext.git cd RED4ext # Initialize submodules (dependencies) git submodule update --init --recursive # Create build directory and generate solution mkdir build cd build cmake .. # Open solution in Visual Studio start RED4ext.sln # Or build from command line cmake --build . --config Release ``` -------------------------------- ### Initialize Git Submodules Source: https://github.com/wopss/red4ext/blob/master/BUILDING.md Run this command in the repository root to download all necessary dependencies. ```bash git submodule update --init --recursive ``` -------------------------------- ### Configure Build with CMake Source: https://github.com/wopss/red4ext/blob/master/BUILDING.md Navigate to the build directory and execute CMake to configure the build environment. Requires CMake 3.23 or newer. ```bash cmake .. ``` -------------------------------- ### Register Game State Callbacks Source: https://context7.com/wopss/red4ext/llms.txt Shows how to register callbacks for different game states (BaseInitialization, Initialization, Running, Shutdown) using OnEnter, OnUpdate, and OnExit handlers. Callbacks should return true to allow state processing to continue. ```cpp #include static RED4ext::PluginHandle g_handle; static const RED4ext::Sdk* g_sdk; // Callback when entering the Running state (game fully loaded) bool OnRunningStateEnter(RED4ext::CGameApplication* aApp) { g_sdk->logger->Info(g_handle, "Game entered Running state - world is loaded"); // Safe to access game systems here // Initialize mod features that depend on game world return true; // Return true to continue state processing } // Called every frame while in Running state bool OnRunningStateUpdate(RED4ext::CGameApplication* aApp) { // Perform per-frame logic here // Be careful with performance - this runs every frame return true; } // Callback when exiting the Running state (leaving game world) bool OnRunningStateExit(RED4ext::CGameApplication* aApp) { g_sdk->logger->Info(g_handle, "Game exiting Running state - cleanup"); // Cleanup resources before world unloads return true; } bool RegisterGameStates() { auto gameStates = g_sdk->gameStates; // Create a game state structure with callbacks RED4ext::GameState runningState; runningState.OnEnter = &OnRunningStateEnter; runningState.OnUpdate = &OnRunningStateUpdate; runningState.OnExit = &OnRunningStateExit; // Register for the Running state bool success = gameStates->Add( g_handle, RED4ext::EGameStateType::Running, &runningState ); if (success) { g_sdk->logger->Info(g_handle, "Game state callbacks registered"); } // Available states: // RED4ext::EGameStateType::BaseInitialization - Early engine init // RED4ext::EGameStateType::Initialization - Game systems init // RED4ext::EGameStateType::Running - Game world active // RED4ext::EGameStateType::Shutdown - Game closing return success; } ``` -------------------------------- ### RED4ext Plugin Entry Points Source: https://context7.com/wopss/red4ext/llms.txt Defines the required `Supports` and `Query` functions, and the optional `Main` function for plugin lifecycle management. Ensure to include necessary headers and export functions correctly. ```cpp #include // Required: Returns the API version your plugin supports RED4EXT_C_EXPORT uint32_t RED4EXT_CALL Supports() { return RED4EXT_API_VERSION_LATEST; } // Required: Provides plugin metadata to RED4ext RED4EXT_C_EXPORT void RED4EXT_CALL Query(RED4ext::PluginInfo* aInfo) { aInfo->name = L"My Plugin"; aInfo->author = L"Your Name"; aInfo->version = RED4EXT_SEMVER(1, 0, 0); // Set to RED4EXT_RUNTIME_INDEPENDENT for all game versions // Or specify a specific game version for compatibility aInfo->runtime = RED4EXT_RUNTIME_INDEPENDENT; aInfo->sdk = RED4EXT_SDK_LATEST; } // Optional: Called when plugin is loaded/unloaded RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::PluginHandle aHandle, RED4ext::EMainReason aReason, const RED4ext::Sdk* aSdk) { switch (aReason) { case RED4ext::EMainReason::Load: // Initialize your plugin here // Store aHandle and aSdk for later use return true; case RED4ext::EMainReason::Unload: // Cleanup resources return true; } return false; } ``` -------------------------------- ### Configure RED4ext Plugin Output Directory Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Appends the 'plugins' directory to the output directory for the RED4ext.Playground target. ```cmake red4ext_target_append_output_directory( RED4ext.Playground plugins ) ``` -------------------------------- ### Configure RED4ext Resource RC File Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Configures the resource compilation for the RED4ext.Playground target with a description. ```cmake red4ext_configure_resource_rc( RED4ext.Playground "A playground plugin for ${PROJECT_NAME}." ) ``` -------------------------------- ### Target Precompile Headers Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Configures precompiled headers for the RED4ext.Playground target, using 'stdafx.hpp'. ```cmake target_precompile_headers( RED4ext.Playground PRIVATE stdafx.hpp ) ``` -------------------------------- ### Configure RED4ext Loader Library Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Defines the RED4ext.Loader as a SHARED library and sets its output name to 'winmm'. This is typically used for building dynamic link libraries. ```cmake add_library(RED4ext.Loader SHARED) set_target_properties( RED4ext.Loader PROPERTIES OUTPUT_NAME winmm ) ``` -------------------------------- ### Register Custom Scripts for Compilation Source: https://context7.com/wopss/red4ext/llms.txt Use this function to add a directory containing .reds files for compilation by the game's scripting system. The path is relative to the game's root directory. Also registers custom reference types for script compilation. ```cpp #include static RED4ext::PluginHandle g_handle; static const RED4ext::Sdk* g_sdk; bool RegisterScripts() { auto scripts = g_sdk->scripts; // Add a directory containing .reds files for compilation // Path is relative to the game's root directory bool success = scripts->Add( g_handle, L"red4ext\\plugins\\MyPlugin\\scripts" ); if (success) { g_sdk->logger->Info(g_handle, "Script directory registered for compilation"); } else { g_sdk->logger->Error(g_handle, "Failed to register script directory"); } // Register custom reference types for script compilation // NeverRef types are never passed by reference scripts->RegisterNeverRefType("MyCustomValueType"); // MixedRef types can be passed by value or reference scripts->RegisterMixedRefType("MyFlexibleType"); return success; } // Example Redscript file (MyPlugin/scripts/MyFeature.reds): /* // Custom scripting that gets compiled with the game public class MyCustomFeature { public static func Initialize() { LogChannel(n"MyPlugin", "Custom feature initialized!"); } public static func DoSomething(player: ref) { // Interact with game objects via scripts let health = player.GetHealthPercentage(); LogChannel(n"MyPlugin", "Player health: " + ToString(health)); } } // Add to game event @wrapMethod(PlayerPuppet) protected cb func OnGameAttached() -> Bool { let result = wrappedMethod(); MyCustomFeature.Initialize(); return result; } */ ``` -------------------------------- ### Add RED4ext Playground Library Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Defines the RED4ext.Playground library as a SHARED library. ```cmake add_library(RED4ext.Playground SHARED) ``` -------------------------------- ### Target Link Libraries Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Links the RED4ext.Playground target against the fmt::fmt and RED4ext::SDK libraries. ```cmake target_link_libraries( RED4ext.Playground PRIVATE fmt::fmt RED4ext::SDK ) ``` -------------------------------- ### Target Include Directories Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Adds the current source directory to the include directories for the RED4ext.Playground target. ```cmake target_include_directories( RED4ext.Playground PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" ) ``` -------------------------------- ### Link Libraries for RED4ext Loader Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Links the 'fmt::fmt' and 'WIL::WIL' libraries as private dependencies for the RED4ext.Loader target. These are likely external libraries required for the loader's functionality. ```cmake target_link_libraries( RED4ext.Loader PRIVATE fmt::fmt WIL::WIL ) ``` -------------------------------- ### Set Precompiled Headers Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Configures 'stdafx.hpp' as a private precompiled header for the RED4ext.Loader target. Precompiled headers can significantly speed up compilation times. ```cmake target_precompile_headers( RED4ext.Loader PRIVATE stdafx.hpp ) ``` -------------------------------- ### Set Include Directories Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Specifies that the current source directory should be included as a private include directory for the RED4ext.Loader target. This allows the library to find its own header files. ```cmake target_include_directories( RED4ext.Loader PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" ) ``` -------------------------------- ### Glob Recursively Find RED4ext Files Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Finds all .hpp and .cpp files recursively within the project directory and stores them in RED4EXT_FILES. ```cmake file( GLOB_RECURSE RED4EXT_FILES *.hpp *.cpp ) ``` -------------------------------- ### Set Source Files for Target Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Adds all found header, source, and definition files, along with the generated resource compilation file, as private sources for the RED4ext.Loader target. This ensures all necessary files are compiled as part of the library. ```cmake target_sources( RED4ext.Loader PRIVATE ${RED4EXT_FILES} ${RED4EXT_RC_FILE} ) ``` -------------------------------- ### Target Sources Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Specifies the source files for the RED4ext.Playground target, including found files and generated resources. ```cmake target_sources( RED4ext.Playground PRIVATE ${RED4EXT_FILES} ${RED4EXT_RC_FILE} ) ``` -------------------------------- ### Configure Resource RC File Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Uses the custom CMake function 'red4ext_configure_resource_rc' to configure the resource compilation for the RED4ext.Loader. This function likely handles the creation and processing of resource files (.rc) necessary for the library. ```cmake red4ext_configure_resource_rc( RED4ext.Loader "The loader for ${PROJECT_NAME}." ) ``` -------------------------------- ### Attach and Detach Game Hooks Source: https://context7.com/wopss/red4ext/llms.txt Demonstrates how to attach a hook to a game function using Microsoft Detours and how to detach it. Ensure the target address is correct and the detour function signature matches the original. ```cpp #include static RED4ext::PluginHandle g_handle; static const RED4ext::Sdk* g_sdk; // Type definition for the function we want to hook using PlayerTakeDamage_t = void (*)(void* player, float damage, void* source); static PlayerTakeDamage_t Original_PlayerTakeDamage = nullptr; // Our detour function - must match the original signature void Hook_PlayerTakeDamage(void* player, float damage, void* source) { // Modify damage before calling original (e.g., god mode) if (damage > 0) { g_sdk->logger->InfoF(g_handle, "Player taking %.2f damage, reducing by 50%%", damage); damage *= 0.5f; // Reduce damage by 50% } // Call the original function Original_PlayerTakeDamage(player, damage, source); } bool AttachHooks() { auto hooking = g_sdk->hooking; // Get the address of the function to hook (from reverse engineering) void* targetAddress = reinterpret_cast(0x140123456); // Example address // Attach the hook bool success = hooking->Attach( g_handle, targetAddress, // Target function reinterpret_cast(&Hook_PlayerTakeDamage), // Our detour reinterpret_cast(&Original_PlayerTakeDamage) // Store original ); if (success) { g_sdk->logger->Info(g_handle, "Hook attached successfully"); } else { g_sdk->logger->Error(g_handle, "Failed to attach hook"); } return success; } bool DetachHooks() { auto hooking = g_sdk->hooking; void* targetAddress = reinterpret_cast(0x140123456); // Detach the hook - restores original function bool success = hooking->Detach(g_handle, targetAddress); if (success) { g_sdk->logger->Info(g_handle, "Hook detached successfully"); Original_PlayerTakeDamage = nullptr; } return success; } ``` -------------------------------- ### Source Grouping for Build Artifacts Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Groups generated resource (.rc) and version files under the binary directory. ```cmake source_group( TREE "${CMAKE_CURRENT_BINARY_DIR}" FILES ${RED4EXT_RC_FILE} ${RED4EXT_VERSION_FILE} ) ``` -------------------------------- ### Glob Recursively Find Source Files Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Finds all header (.hpp) and source (.cpp) files, as well as module definition (.def) files recursively within the current source directory and stores them in the RED4EXT_FILES variable. This is a common way to automatically include all source files in a build. ```cmake file( GLOB_RECURSE RED4EXT_FILES *.hpp *.cpp *.def ) ``` -------------------------------- ### Source Grouping for CMake Source: https://github.com/wopss/red4ext/blob/master/src/loader/CMakeLists.txt Organizes source files within the CMake build system. It creates groups for 'cmake_pch.*' files and then groups all found RED4EXT_FILES under a 'TREE' structure based on the source directory. It also groups the generated RC file under the binary directory. ```cmake source_group(CMake REGULAR_EXPRESSION cmake_pch.*) source_group( TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${RED4EXT_FILES} ) source_group( TREE "${CMAKE_CURRENT_BINARY_DIR}" FILES ${RED4EXT_RC_FILE} ) ``` -------------------------------- ### Source Grouping by Tree Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Groups source files found recursively within the project tree. ```cmake source_group( TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${RED4EXT_FILES} ) ``` -------------------------------- ### Source Grouping for CMake PCH Source: https://github.com/wopss/red4ext/blob/master/src/playground/CMakeLists.txt Groups files matching 'cmake_pch.*' under a 'CMake' source group. ```cmake source_group(CMake REGULAR_EXPRESSION cmake_pch.*) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.