Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion SharpPluginLoader.Core/IO/Key.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ namespace SharpPluginLoader.Core.IO
/// <summary>
/// The buttons on a keyboard.
/// </summary>
public enum Key
public enum Key : int
{
MaxNameLength = 12, // For parsing purposes.
// -------
Escape = 1,
D1 = 2,
D2 = 3,
Expand Down
65 changes: 44 additions & 21 deletions SharpPluginLoader.Core/Rendering/Renderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,21 +199,18 @@ internal static unsafe void ResolveCustomFonts()
}

[UnmanagedCallersOnly]
internal static nint Initialize(Size viewportSize, Size windowSize, byte d3d12, nint menuKey)
internal static unsafe nint Initialize(Size viewportSize, Size windowSize, byte d3d12, LoaderGuiConfig* config)
{
IsDirectX12 = d3d12 != 0;

if (menuKey != 0)
string keyStr = new string(config->MenuKey);
if (Enum.TryParse<Key>(keyStr, out var key))
{
var keyStr = MemoryUtil.ReadString(menuKey);
if (Enum.TryParse<Key>(keyStr, out var key))
{
_menuKey = key;
}
else
{
Log.Warn($"Invalid menu key: {keyStr}, falling back to {DefaultMenuKey}");
}
_menuKey = key;
}
else
{
Log.Warn($"Invalid menu key: {keyStr}, falling back to {DefaultMenuKey}");
}

_viewportSize = new Vector2(viewportSize.Width, viewportSize.Height);
Expand Down Expand Up @@ -241,6 +238,13 @@ Initializing Renderer with
// Currently causes a freeze when dragging a window outside of the main window.
// Most likely the WndProc doesn't process events anymore which causes windows to think it's frozen.
// io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
if (config->KeyboardNavigation)
{
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard;
}

io.FontGlobalScale = config->FontScale;
_baseAlpha = config->WindowTransparency;

SetupImGuiStyle();

Expand Down Expand Up @@ -387,7 +391,7 @@ internal static unsafe nint ImGuiRender()
io.DisplaySize = _viewportSize;

if (_showMenu)
ImGui.GetStyle().Alpha = anyFocused ? 1.0f : 0.5f;
ImGui.GetStyle().Alpha = anyFocused ? _baseAlpha : Math.Max(_baseAlpha - 0.5f, 0.25f);

ImGui.NewFrame();
if (_showMenu)
Expand All @@ -398,6 +402,13 @@ internal static unsafe nint ImGuiRender()
{
if (ImGui.BeginMenu("Options"))
{
ImGui.Checkbox("Draw Primitives as Wireframe",
ref MemoryUtil.AsRef(_renderingOptionPointers.DrawPrimitivesAsWireframe));

ImGui.SliderFloat("Line Thickness",
ref MemoryUtil.AsRef(_renderingOptionPointers.LineThickness),
1.0f, 10.0f);

bool keyboardNav = (io.ConfigFlags & ImGuiConfigFlags.NavEnableKeyboard) != 0;
if (ImGui.Checkbox("Keyboard Navigation", ref keyboardNav))
{
Expand All @@ -411,14 +422,16 @@ internal static unsafe nint ImGuiRender()
}
}

ImGui.Checkbox("Draw Primitives as Wireframe",
ref MemoryUtil.AsRef(_renderingOptionPointers.DrawPrimitivesAsWireframe));

ImGui.SliderFloat("Line Thickness",
ref MemoryUtil.AsRef(_renderingOptionPointers.LineThickness),
1.0f, 10.0f);
ImGui.SliderFloat("Font Scale",
ref io.FontGlobalScale,
0.5f, 2.0f, null, ImGuiSliderFlags.NoRoundToFormat);

ImGui.SliderFloat("Font Scale", ref io.FontGlobalScale, 0.5f, 2.0f);
if (ImGui.SliderFloat("Window Transparency",
ref _baseAlpha,
0.25f, 1.0f, null, ImGuiSliderFlags.NoRoundToFormat))
{
ImGui.GetStyle().DisabledAlpha = _baseAlpha;
}

ImGui.EndMenu();
}
Expand Down Expand Up @@ -485,8 +498,8 @@ private static void SetupImGuiStyle()
{
var style = ImGui.GetStyle();

style.Alpha = 1.0f;
style.DisabledAlpha = 1.0f;
style.Alpha = _baseAlpha;
style.DisabledAlpha = _baseAlpha;
style.WindowPadding = new Vector2(12.0f, 12.0f);
style.WindowRounding = 2.0f;
style.WindowBorderSize = 1.0f;
Expand Down Expand Up @@ -607,6 +620,7 @@ private static nint GetCursorPositionHook(nint app, out Point pos)
private static Vector2 _windowSize;
private static Vector2 _mousePos;
private static Vector2 _mousePosScalingFactor;
private static float _baseAlpha = 1.0f;
private static bool _fontsSubmitted = false;

private static NativeArray<CustomFontNative> CustomFonts;
Expand Down Expand Up @@ -646,4 +660,13 @@ internal unsafe struct CustomFontNative
public ushort* GlyphRanges;
public ImFont* Font;
}

[StructLayout(LayoutKind.Sequential)]
public unsafe struct LoaderGuiConfig
{
public fixed sbyte MenuKey[(int)Key.MaxNameLength + 1];
public bool KeyboardNavigation;
public float FontScale;
public float WindowTransparency;
}
}
2 changes: 1 addition & 1 deletion mhw-cs-plugin-loader/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,4 @@ static constexpr const char* SPL_DEFAULT_CHUNK_PATH = "nativePC/plugins/CSharp/L

// The path of the address repository cache file
static constexpr const char* SPL_ADDRESS_REPOSITORY_CACHE_PATH = "nativePC/plugins/CSharp/Loader/NativeAddressCache.json";
}
}
6 changes: 3 additions & 3 deletions mhw-cs-plugin-loader/D3DModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void D3DModule::initialize(CoreClr* coreclr) {
L"SharpPluginLoader.Core.Rendering.Renderer",
L"ImGuiRender"
);
m_core_initialize_imgui = coreclr->get_method<ImGuiContext*(MtSize, MtSize, bool, const char*)>(
m_core_initialize_imgui = coreclr->get_method<ImGuiContext*(MtSize, MtSize, bool, const preloader::LoaderGuiConfig*)>(
config::SPL_CORE_ASSEMBLY_NAME,
L"SharpPluginLoader.Core.Rendering.Renderer",
L"Initialize"
Expand Down Expand Up @@ -493,7 +493,7 @@ void D3DModule::d3d12_initialize_imgui(IDXGISwapChain* swap_chain) {
};

const auto& config = preloader::LoaderConfig::get();
const auto context = m_core_initialize_imgui(viewport_size, window_size, true, config.get_menu_key().c_str());
const auto context = m_core_initialize_imgui(viewport_size, window_size, true, config.get_gui_config());

igSetCurrentContext(context);

Expand Down Expand Up @@ -626,7 +626,7 @@ void D3DModule::d3d11_initialize_imgui(IDXGISwapChain* swap_chain) {
};

const auto& config = preloader::LoaderConfig::get();
const auto context = m_core_initialize_imgui(viewport_size, window_size, false, config.get_menu_key().c_str());
const auto context = m_core_initialize_imgui(viewport_size, window_size, false, config.get_gui_config());
igSetCurrentContext(context);

imgui_load_fonts();
Expand Down
3 changes: 2 additions & 1 deletion mhw-cs-plugin-loader/D3DModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "NativeModule.h"
#include "TextureManager.h"
#include "PrimitiveRenderingModule.h"
#include "LoaderConfig.h"

#include <d3d11.h>
#include <d3d12.h>
Expand Down Expand Up @@ -121,7 +122,7 @@ class D3DModule final : public NativeModule {
HWND m_temp_window = nullptr;
WNDCLASSEX* m_temp_window_class = nullptr;

ImGuiContext*(*m_core_initialize_imgui)(MtSize viewport_size, MtSize window_size, bool d3d12, const char* menu_key) = nullptr;
ImGuiContext*(*m_core_initialize_imgui)(MtSize viewport_size, MtSize window_size, bool d3d12, const preloader::LoaderGuiConfig* config) = nullptr;
ImDrawData*(*m_core_imgui_render)() = nullptr;
void(*m_core_render)() = nullptr;
int(*m_core_get_custom_fonts)(CustomFont** out_fonts) = nullptr;
Expand Down
56 changes: 25 additions & 31 deletions mhw-cs-plugin-loader/LoaderConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,20 @@ namespace preloader
using json = nlohmann::ordered_json;

void to_json(json& j, const ConfigFile& c) {
j = json{
j = json {
{"logfile", c.LogFile},
{"logcmd", c.LogCmd},
{"logLevel", c.LogLevel},
{"outputEveryPath", c.OutputEveryPath},
{"enablePluginLoader", c.EnablePluginLoader},
{"SPL", {
{"PreloadDlls", c.PreloadDlls},
{"ImGuiRenderingEnabled", c.ImGuiRenderingEnabled},
{"PrimitiveRenderingEnabled", c.PrimitiveRenderingEnabled},
{"MenuKey", c.MenuKey},
{"MenuKey", c.Gui.MenuKey},
{"KeyboardNavigation", c.Gui.KeyboardNavigation},
{"FontScale", c.Gui.FontScale},
{"WindowTransparency", c.Gui.WindowTransparency},
}}
};
}
Expand All @@ -30,54 +34,44 @@ namespace preloader
j.at("logLevel").get_to(c.LogLevel);
j.at("outputEveryPath").get_to(c.OutputEveryPath);
j.at("enablePluginLoader").get_to(c.EnablePluginLoader);

if (j.contains("SPL")) {
const json& spl = j.at("SPL");
spl.at("ImGuiRenderingEnabled").get_to(c.ImGuiRenderingEnabled);
spl.at("PrimitiveRenderingEnabled").get_to(c.PrimitiveRenderingEnabled);
c.MenuKey = spl.value("MenuKey", "F9");
}
else {
c.ImGuiRenderingEnabled = true;
c.PrimitiveRenderingEnabled = true;
if (spl.contains("PreloadDlls"))
{
spl.at("PreloadDlls").get_to(c.PreloadDlls);
}
c.ImGuiRenderingEnabled = spl.value("ImGuiRenderingEnabled", true);
c.PrimitiveRenderingEnabled = spl.value("PrimitiveRenderingEnabled", true);
std::string keyStr = spl.value("MenuKey", "F9");
if (keyStr.length() <= sizeof(c.Gui.MenuKey) - 1) {
std::memcpy(c.Gui.MenuKey, keyStr.c_str(), keyStr.length() + 1);
}
c.Gui.KeyboardNavigation = spl.value("KeyboardNavigation", false);
c.Gui.FontScale = spl.value("FontScale", 1.0f);
c.Gui.WindowTransparency = spl.value("WindowTransparency", 1.0f);
}
}

LoaderConfig& LoaderConfig::get()
{
LoaderConfig& LoaderConfig::get() {
static LoaderConfig instance;
return instance;
}

LoaderConfig::LoaderConfig()
{
// Attempt to load file from disk
if (std::filesystem::exists(config::SPL_LOADER_CONFIG_FILE))
{
LoaderConfig::LoaderConfig() {
// Attempt to load file from disk.
if (std::filesystem::exists(config::SPL_LOADER_CONFIG_FILE)) {
std::ifstream file(config::SPL_LOADER_CONFIG_FILE);
json data = json::parse(file);
this->config = data.get<ConfigFile>();
file.close();
}
else
{
// No existing config, create a default and save to disk.
this->config = ConfigFile
{
.LogFile = true,
.LogCmd = true,
.LogLevel = "INFO",
.OutputEveryPath = false,
.EnablePluginLoader = true,
};
}

// Make sure any new options are added to the config file
// Make sure any new options are added to the config file.
std::ofstream outfile(config::SPL_LOADER_CONFIG_FILE);
if (outfile.is_open()) {
json data = this->config;
outfile << std::setw(4) << data << "\n";
outfile.close();
}
}
} // namespace preloader
} // namespace preloader
21 changes: 15 additions & 6 deletions mhw-cs-plugin-loader/LoaderConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,24 @@

namespace preloader
{
struct LoaderGuiConfig {
char MenuKey[13] = { "F9" };
bool KeyboardNavigation = false;
float FontScale = 1.0f;
float WindowTransparency = 1.0f;
};

struct ConfigFile {
bool LogFile = true;
bool LogCmd = false;
std::string LogLevel = "ERROR";
bool LogFile = false;
bool LogCmd = true;
std::string LogLevel = "INFO";
Comment on lines -7 to +16

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert this

bool OutputEveryPath = false;
bool EnablePluginLoader = true;
struct {
std::vector<std::string> PreloadDlls = { "dinput8.dll", "dxgi.dll" };
bool ImGuiRenderingEnabled = true;
bool PrimitiveRenderingEnabled = true;
std::string MenuKey = "F9";
LoaderGuiConfig Gui;
};
};
void to_json(nlohmann::json& j, const ConfigFile& c);
Expand All @@ -35,9 +43,10 @@ namespace preloader
inline bool get_log_cmd() const { return this->config.LogCmd; }
inline std::string get_log_level() const { return this->config.LogLevel; }
inline bool get_output_every_path() const { return this->config.OutputEveryPath; }
inline std::vector<std::string>& get_preload_dlls() { return this->config.PreloadDlls; }
inline bool get_enable_plugin_loader() const { return this->config.EnablePluginLoader; }
inline bool get_imgui_rendering_enabled() const { return this->config.ImGuiRenderingEnabled; }
inline bool get_primitive_rendering_enabled() const { return this->config.PrimitiveRenderingEnabled; }
inline std::string get_menu_key() const { return this->config.MenuKey; }
inline const LoaderGuiConfig* get_gui_config() const { return &this->config.Gui; }
};
} // namespace preloader
} // namespace preloader
14 changes: 7 additions & 7 deletions mhw-cs-plugin-loader/NativePluginFramework.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ void NativePluginFramework::trigger_on_mh_main_ctor() {
m_managed_functions.TriggerOnMhMainCtor();
}

void NativePluginFramework::run_compatibility_checks() {
// We intentionally force Stracker's Loader to be loaded early so any (native) plugins that
// rely on injecting code via relative calls will be able to find available memory for their hooks.
constexpr auto DINPUT8_PATH = "dinput8.dll";

if (std::filesystem::exists(DINPUT8_PATH)) {
(void)LoadLibraryA(DINPUT8_PATH);
// We intentionally force Stracker's Loader to be loaded early so any (native) plugins that
// rely on injecting code via relative calls will be able to find available memory for their hooks.
void NativePluginFramework::preload_dlls(std::vector<std::string>& dlls) {
for (const auto& dll : dlls) {
if (std::filesystem::exists(dll)) {
(void)LoadLibraryA(dll.c_str());
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion mhw-cs-plugin-loader/NativePluginFramework.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class NativePluginFramework {
void trigger_on_win_main();
void trigger_on_mh_main_ctor();

static void run_compatibility_checks();
static void preload_dlls(std::vector<std::string>& dlls);
static uintptr_t get_repository_address(const char* name);
static const char* get_game_revision();

Expand Down
3 changes: 2 additions & 1 deletion mhw-cs-plugin-loader/Preloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ void hooked_get_system_time_as_file_time(LPFILETIME lpSystemTimeAsFileTime) {
}
dlog::debug("[Preloader] Resolved address for sMhMain::ctor: 0x{:X}", mhmain_ctor_address);

NativePluginFramework::run_compatibility_checks();
auto& loader_config = preloader::LoaderConfig::get();
NativePluginFramework::preload_dlls(loader_config.get_preload_dlls());

// Hook the functions.
g_scrt_common_main_hook = safetyhook::create_inline(
Expand Down
3 changes: 1 addition & 2 deletions mhw-cs-plugin-loader/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
// Only load the the mod loader DLL if winmm.dll/ucrtbase.dll has been loaded into the correct process.
if (wil::GetModuleFileNameW<std::wstring>().contains(L"MonsterHunterWorld.exe")) {
auto& loader_config = preloader::LoaderConfig::get();
if (loader_config.get_enable_plugin_loader())
{
if (loader_config.get_enable_plugin_loader()) {
initialize_preloader();
}
}
Expand Down
Loading