Skip to content

Commit

Permalink
Add working inject panel
Browse files Browse the repository at this point in the history
  • Loading branch information
TTENSHII committed Nov 12, 2023
1 parent d82a679 commit 43398b3
Show file tree
Hide file tree
Showing 16 changed files with 452 additions and 28 deletions.
5 changes: 5 additions & 0 deletions src/GUI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,9 @@ target_sources(
${CMAKE_CURRENT_SOURCE_DIR}/WindowManager.cpp
${CMAKE_CURRENT_SOURCE_DIR}/DirectX11.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Imgui.cpp
${CMAKE_CURRENT_SOURCE_DIR}/InjectPanel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/EjectPanel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SideBar.cpp
${CMAKE_CURRENT_SOURCE_DIR}/SettingsPanel.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ConfigPanel.cpp
)
10 changes: 10 additions & 0 deletions src/GUI/ConfigPanel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "imgui.h"
#include "Imgui.hpp"

namespace Xash::GUI
{
void Imgui::DrawConfigPanel()
{
ImGui::Text("--------CONFIG--------");
}
}
39 changes: 39 additions & 0 deletions src/GUI/EjectPanel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#include "imgui.h"
#include "Imgui.hpp"
#include "System.hpp"
#include "ModsManager.hpp"

namespace Xash::GUI
{
void Imgui::DrawEjectPanel()
{
Injector::ModsManager &modsManager = Injector::ModsManager::getInstance();
auto &loadedMods = modsManager.getLoadedMods();

if (loadedMods.empty())
{
ImGui::Text("No mod loaded");
return;
}

char unloadMethodNameBuffer[256] = {0};
strcpy_s(unloadMethodNameBuffer, mModInfos.modUnloadMethod.c_str());
ImGui::InputText("Unload method", unloadMethodNameBuffer, sizeof(unloadMethodNameBuffer));
mModInfos.modUnloadMethod = unloadMethodNameBuffer;

for (auto &loadedMod : loadedMods)
{
ImGui::Text("--------------------");
ImGui::Text("Mod name: %s", loadedMod.first.modClass.c_str());
ImGui::Text("Mod Namespace: %s", loadedMod.first.modNamespace.c_str());
ImGui::Text("Mod Path: %s", loadedMod.first.modPath.c_str());
ImGui::Text("Targeted process: %s", loadedMod.first.targetedProcessName.c_str());
if (ImGui::Button("Eject"))
{
Injector::ModInfos modInfos = loadedMod.first;
modInfos.modUnloadMethod = mModInfos.modUnloadMethod;
modsManager.UnLoadMod(modInfos);
}
}
}
}
51 changes: 43 additions & 8 deletions src/GUI/Imgui.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <algorithm>
#include <stdexcept>
#include "imgui.h"
#include <unordered_map>
#include <functional>
#include "System.hpp"
#include "Imgui.hpp"
#include "imgui_impl_win32.h"
#include "imgui_impl_dx11.h"
Expand All @@ -10,6 +13,7 @@ namespace Xash::GUI
{
ImGui::CreateContext();
ImGui::StyleColorsDark();
GetProcessesNames();
}

void Imgui::InitWin32AndDX11(
Expand Down Expand Up @@ -46,15 +50,46 @@ namespace Xash::GUI
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();

ImGui::SetNextWindowSize(ImGui::GetIO().DisplaySize);
ImGui::SetNextWindowPos(ImVec2(0, 0));
DrawSideBar();
MaximizeMainWindow();
ImGui::Begin(
"Main Window", nullptr,
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize
| ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar
"Xash", nullptr, ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar
);
ImGui::Text("Xash Injector");

DrawPanels();
ImGui::End();
}

void Imgui::DrawPanels()
{
static const std::unordered_map<ActivePanel, std::function<void()>> mPanelsDrawers = {
{ActivePanel::INJECT, std::bind(&Imgui::DrawInjectPanel, this)},
{ActivePanel::EJECT, std::bind(&Imgui::DrawEjectPanel, this)},
{ActivePanel::CONFIG, std::bind(&Imgui::DrawConfigPanel, this)},
{ActivePanel::SETTINGS, std::bind(&Imgui::DrawSettingsPanel, this)}
};

auto it = mPanelsDrawers.find(mActivePanel);
if (it != mPanelsDrawers.end())
{
it->second();
}
}

void Imgui::MaximizeMainWindow()
{
ImGui::SetNextWindowSize(
ImVec2(ImGui::GetIO().DisplaySize.x, ImGui::GetIO().DisplaySize.y)
);
ImGui::SetNextWindowPos(mainWindowPos);
}

void Imgui::GetProcessesNames()
{
mProcessesNames = Xash::System::GetRunningProcessesNames();
std::sort(mProcessesNames.begin(), mProcessesNames.end());
mProcessesNames.erase(
std::unique(mProcessesNames.begin(), mProcessesNames.end()),
mProcessesNames.end()
);
}
} // namespace Xash::GUI
49 changes: 45 additions & 4 deletions src/GUI/Imgui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,61 @@
#include <windows.h>
#include <wrl/client.h>
#include <d3d11.h>
#include <vector>
#include <string>
#include "ModInfos.hpp"
#include "imgui.h"

namespace Xash::GUI
{
class Imgui
{
static constexpr ImVec2 mainWindowPos = ImVec2(120, 0);

public:
Imgui();
~Imgui();

void InitWin32AndDX11(
const HWND &window, Microsoft::WRL::ComPtr<ID3D11Device> device,
Microsoft::WRL::ComPtr<ID3D11DeviceContext> deviceContext
);
void InitWin32AndDX11(
const HWND &window, Microsoft::WRL::ComPtr<ID3D11Device> device,
Microsoft::WRL::ComPtr<ID3D11DeviceContext> deviceContext
);
void Draw();
void Render();

private:
enum class ActivePanel : uint8_t
{
INJECT,
EJECT,
CONFIG,
SETTINGS
};

void DrawSideBar();
void DrawPanels();
void MaximizeMainWindow();

// INJECT
void DrawInjectPanel();
void DrawProcessesBox();
void DrawDllBox();
void DrawInjectInputs();
void DrawInjectButton();
void GetProcessesNames();

// EJECT
void DrawEjectPanel();

// CONFIG
void DrawConfigPanel();

// SETTINGS
void DrawSettingsPanel();

Injector::ModInfos mModInfos;
std::size_t mSelectedProcessIndex = 0;
std::vector<std::string> mProcessesNames;
ActivePanel mActivePanel = ActivePanel::INJECT;
};
} // namespace Xash::GUI
96 changes: 96 additions & 0 deletions src/GUI/InjectPanel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#include "imgui.h"
#include "Imgui.hpp"
#include "System.hpp"
#include "ModsManager.hpp"

namespace Xash::GUI
{

void Imgui::DrawInjectButton()
{
if (ImGui::Button("Inject"))
{
Xash::Injector::ModsManager &modsManager = Xash::Injector::ModsManager::getInstance();
mModInfos.targetedProcessName = mProcessesNames[mSelectedProcessIndex];
modsManager.LoadMod(mModInfos);
}
}

void Imgui::DrawProcessesBox()
{
if (ImGui::BeginCombo("##combo", mProcessesNames[mSelectedProcessIndex].c_str()))
{
for (int i = 0; i < mProcessesNames.size(); i++)
{
bool isSelected = (mSelectedProcessIndex == i);
if (ImGui::Selectable(mProcessesNames[i].c_str(), isSelected))
{
mSelectedProcessIndex = i;
}
if (isSelected)
{
ImGui::SetItemDefaultFocus();
}
}
ImGui::EndCombo();
}
}

void Imgui::DrawDllBox()
{
static std::string selectedFile = "Select mod DLL";

if (ImGui::Selectable(selectedFile.c_str()))
{
OPENFILENAME ofn;
TCHAR filePath[MAX_PATH] = {0};
TCHAR currentDir[MAX_PATH] = {0};
GetCurrentDirectory(MAX_PATH, currentDir);

ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = NULL;
ofn.lpstrFilter = "DLL\0*.dll\0";
ofn.lpstrFile = filePath;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrTitle = "Select DLL";
ofn.Flags = OFN_FILEMUSTEXIST;

if (GetOpenFileName(&ofn))
{
SetCurrentDirectory(currentDir);
selectedFile = ofn.lpstrFile;
mModInfos.modPath = selectedFile;
}
}
}

void Imgui::DrawInjectInputs()
{
char namespaceBuffer[256] = {0};
char classNameBuffer[256] = {0};
char loadMethodNameBuffer[256] = {0};

strcpy_s(namespaceBuffer, mModInfos.modNamespace.c_str());
strcpy_s(classNameBuffer, mModInfos.modClass.c_str());
strcpy_s(loadMethodNameBuffer, mModInfos.modInitMethod.c_str());

ImGui::InputText("Namespace", namespaceBuffer, IM_ARRAYSIZE(namespaceBuffer));
ImGui::InputText("Class", classNameBuffer, IM_ARRAYSIZE(classNameBuffer));
ImGui::InputText(
"Load Method", loadMethodNameBuffer, IM_ARRAYSIZE(loadMethodNameBuffer)
);

mModInfos.modNamespace = namespaceBuffer;
mModInfos.modClass = classNameBuffer;
mModInfos.modInitMethod = loadMethodNameBuffer;
}

void Imgui::DrawInjectPanel()
{
DrawProcessesBox();
DrawDllBox();
DrawInjectInputs();
DrawInjectButton();
}
} // namespace Xash::GUI
10 changes: 10 additions & 0 deletions src/GUI/SettingsPanel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "imgui.h"
#include "Imgui.hpp"

namespace Xash::GUI
{
void Imgui::DrawSettingsPanel()
{
ImGui::Text("--------SETTINGS--------");
}
}
58 changes: 58 additions & 0 deletions src/GUI/SideBar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include <unordered_map>
#include "Imgui.hpp"
#include "imgui.h"

static void addSideBarStyle()
{
ImVec4 transparent = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
ImVec4 hoverColor = ImVec4(0.7f, 0.7f, 0.7f, 1.0f);
ImVec4 selectedColor = ImVec4(0.4f, 0.4f, 0.4f, 1.0f);

ImGui::PushStyleColor(ImGuiCol_Button, transparent);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered, hoverColor);
ImGui::PushStyleColor(ImGuiCol_ButtonActive, selectedColor);

ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 5.0f);
ImGui::PushStyleVar(ImGuiStyleVar_ButtonTextAlign, ImVec2(0.0f, 0.5f));
}

static void removeSideBarStyle()
{
ImGui::PopStyleColor(3);
ImGui::PopStyleVar(2);
}

static void createSideBarWindow()
{
ImGui::Begin("##sidebar", nullptr,
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoTitleBar);
ImGui::SetWindowSize(ImVec2(120, ImGui::GetIO().DisplaySize.y));
ImGui::SetWindowPos(ImVec2(0, 0));
}

void Xash::GUI::Imgui::DrawSideBar()
{
static std::unordered_map<ActivePanel, std::string> panelNames = {
{ ActivePanel::INJECT, "Inject" },
{ ActivePanel::EJECT, "Loaded Dll" },
{ ActivePanel::CONFIG, "Config" },
{ ActivePanel::SETTINGS, "Settings" }
};

createSideBarWindow();
addSideBarStyle();

for (auto &panel : panelNames)
{
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 20);
ImGui::SetCursorPosX(10);

if (ImGui::Button(panel.second.c_str(), ImVec2(200, 25)))
{
mActivePanel = panel.first;
}
}

removeSideBarStyle();
ImGui::End();
}
1 change: 1 addition & 0 deletions src/injector/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ target_sources(
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/MonoModule.cpp
${CMAKE_CURRENT_SOURCE_DIR}/Assembly.cpp
${CMAKE_CURRENT_SOURCE_DIR}/ModsManager.cpp
)
26 changes: 26 additions & 0 deletions src/injector/ModInfos.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <string>

namespace Xash::Injector
{
struct ModInfos
{
std::string modPath;
std::string modNamespace;
std::string modClass;
std::string modInitMethod;
std::string modUnloadMethod;
std::string targetedProcessName;

bool operator==(const ModInfos &other) const
{
if (modPath != other.modPath ||
modNamespace != other.modNamespace ||
modClass != other.modClass) {
return false;
}
return true;
}
};
} // namespace Xash::Injector
Loading

0 comments on commit 43398b3

Please sign in to comment.