Skip to content

Commit

Permalink
fix: get loaded mods correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
BenMcAvoy committed Dec 31, 2024
1 parent 3d87b7c commit 02120ba
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 54 deletions.
6 changes: 4 additions & 2 deletions CarbonLauncher/include/gamemanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ namespace Carbon {
// Checks if a module is loaded in the game process
// @param moduleName The name of the module to check
// @return True if the module is loaded, false otherwise
bool IsModuleLoaded(const std::string& moduleName);
bool IsModuleLoaded(const std::string& moduleName) const;

// Gets all the loaded custom modules
// @return A vector of all the loaded custom modules (mods injected via CarbonLauncher)
std::vector<std::string> GetLoadedCustomModules();
int GetLoadedCustomModules();

bool ModulesInjected = false;

private:
// Checks every 1s if the game is running
Expand Down
14 changes: 11 additions & 3 deletions CarbonLauncher/src/discordmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,15 @@ void DiscordManager::Update() {
return;
}

int state = std::stoi(packet.data.value());
int state = 0;
try {
state = std::stoi(packet.data.value());
}
catch (std::invalid_argument& e) {
spdlog::error("Failed to parse state change packet: {}", e.what());
statePackets.pop();
return;
}

switch (state) {
case 1:
Expand All @@ -125,11 +133,11 @@ void DiscordManager::Update() {
case 2:
spdlog::trace("In a game!");

this->UpdateState(fmt::format("In a game! ({} mods loaded)", (int)C.gameManager.GetLoadedCustomModules().size()));
this->UpdateState(fmt::format("In a game! ({} mods loaded)", C.gameManager.GetLoadedCustomModules()));
break;
case 3:
spdlog::trace("In the main menu");
this->UpdateState(fmt::format("In the main menu with {} mods loaded", (int)C.gameManager.GetLoadedCustomModules().size()));
this->UpdateState(fmt::format("In the main menu with {} mods loaded", C.gameManager.GetLoadedCustomModules()));
break;
};

Expand Down
140 changes: 95 additions & 45 deletions CarbonLauncher/src/gamemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,29 +52,13 @@ GameManager::GameManager() {
this->gameStartedTime = std::chrono::system_clock::now();
}

auto hModules = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, entry.th32ProcessID);
if (hModules == INVALID_HANDLE_VALUE) {
continue;
}

MODULEENTRY32 module{};
module.dwSize = sizeof(module);
std::lock_guard<std::mutex> lock(this->gameStatusMutex);

if (!Module32First(hModules, &module)) {
CloseHandle(hModules);
continue;
if (found != this->gameRunning) {
spdlog::info("Game is {}", found ? "running" : "not running");
}

std::vector<MODULEENTRY32> modules;
do {
modules.push_back(module);
} while (Module32Next(hModules, &module));

CloseHandle(hModules);

std::lock_guard<std::mutex> lock(this->gameStatusMutex);
this->gameRunning = true;
this->modules = modules;
this->pid = entry.th32ProcessID;

if (!this->gameStartedTime.has_value()) {
Expand All @@ -99,8 +83,40 @@ GameManager::GameManager() {
this->moduleHandlerThread = std::thread([this]() {
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
bool hasInjectedAnything = false;
if (this->IsGameRunning()) {
if (!C.pipeManager.GetPacketsByType(PacketType::LOADED).empty()) {
// Get module list
auto hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (!hProcess) {
spdlog::error("Failed to open process with PID {}", pid);
continue;
}

MODULEENTRY32 moduleEntry{};
moduleEntry.dwSize = sizeof(moduleEntry);

auto hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid);
if (hModuleSnap == INVALID_HANDLE_VALUE) {
CloseHandle(hProcess);
continue;
}

if (!Module32First(hModuleSnap, &moduleEntry)) {
CloseHandle(hModuleSnap);
CloseHandle(hProcess);
continue;
}

do {
this->modules.emplace_back(moduleEntry);
} while (Module32Next(hModuleSnap, &moduleEntry));

CloseHandle(hModuleSnap);
CloseHandle(hProcess);

this->modules = modules;

spdlog::info("Game loaded, injecting modules");

std::string modulesDir = Utils::GetCurrentModuleDir() + "mods";
Expand All @@ -120,11 +136,16 @@ GameManager::GameManager() {

if (!found) {
this->InjectModule(module.path().string());
hasInjectedAnything = true;
}
else {
spdlog::warn("Module `{}` is already loaded", module.path().string());
}
}

if (hasInjectedAnything) {
this->ModulesInjected = true;
}
}
}
}
Expand Down Expand Up @@ -172,21 +193,31 @@ void GameManager::InjectModule(const std::string& modulePath) {
}

void GameManager::StartGame() {
std::thread([]() {
this->gameStartedTime = std::nullopt;
this->gameRunning = false;
this->pid = 0;
this->modules.clear();
this->ModulesInjected = false;

std::thread([&]() {
if (C.processTarget == "ScrapMechanic.exe") {
ShellExecute(NULL, L"open", L"steam://rungameid/387990", NULL, NULL, SW_SHOWNORMAL);
return;
}
else {
std::string exePath = Utils::GetCurrentModuleDir() + C.processTarget;
ShellExecute(NULL, L"open", std::wstring(exePath.begin(), exePath.end()).c_str(), NULL, NULL, SW_SHOWNORMAL);
}

std::string exePath = Utils::GetCurrentModuleDir() + C.processTarget;
ShellExecute(NULL, L"open", std::wstring(exePath.begin(), exePath.end()).c_str(), NULL, NULL, SW_SHOWNORMAL);
}).detach();
while (!this->IsGameRunning()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

this->gameStartedTime = std::chrono::system_clock::now();
this->gameStartedTime = std::chrono::system_clock::now();

while (!this->IsGameRunning()) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
std::this_thread::sleep_for(std::chrono::seconds(1));
spdlog::info("Game is running, injecting CarbonSupervisor.dll");
this->InjectModule(Utils::GetCurrentModuleDir() + "CarbonSupervisor.dll");
}).detach();
}

void GameManager::KillGame() {
Expand Down Expand Up @@ -217,33 +248,52 @@ void GameManager::KillGame() {
}
}

bool GameManager::IsModuleLoaded(const std::string& moduleName) {
for (auto& module : this->modules) {
if (std::wstring(module.szModule) == std::wstring(moduleName.begin(), moduleName.end())) {
bool GameManager::IsModuleLoaded(const std::string& moduleName) const {
std::vector<MODULEENTRY32> modules;
auto hProcesses = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, this->pid);
if (hProcesses == INVALID_HANDLE_VALUE) {
return false;
}

MODULEENTRY32 entry{ sizeof(entry) };

if (!Module32First(hProcesses, &entry)) {
CloseHandle(hProcesses);
return false;
}

do {
modules.emplace_back(entry);
} while (Module32Next(hProcesses, &entry));

CloseHandle(hProcesses);

for (auto& module : modules) {
std::wstring moduleNameW(module.szModule);
std::string moduleNameA(moduleNameW.begin(), moduleNameW.end());
if (moduleNameA == moduleName) {
return true;
}
}

return false;
}

std::vector<std::string> GameManager::GetLoadedCustomModules() {
std::lock_guard<std::mutex> lock(this->gameStatusMutex);
int GameManager::GetLoadedCustomModules() {
// Wait for injection to happen
while (!this->ModulesInjected) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

// We need to go through all repos and all their mods, incrementing module count
// if one of their files is found in the target process
std::vector<std::string> loadedModules;
int count = 0;

/* TODO: Implement this
for (auto& repo : C.repoManager.GetRepos()) {
for (auto& mod : repo.mods) {
for (auto& file : mod.files) {
if (this->IsModuleLoaded(file)) {
loadedModules.push_back(mod.name);
}
for (auto& file : std::filesystem::recursive_directory_iterator(Utils::GetCurrentModuleDir() + "mods")) {
if (file.is_regular_file() && file.path().extension() == ".dll") {
if (this->IsModuleLoaded(file.path().filename().string())) {
count++;
}
}
}*/
}

return loadedModules;
return count;
}
2 changes: 0 additions & 2 deletions CarbonLauncher/src/guimanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,6 @@ void _GUI() {
}
else {
C.gameManager.StartGame();
std::this_thread::sleep_for(std::chrono::seconds(1));
C.gameManager.InjectModule(Utils::GetCurrentModuleDir() + "CarbonSupervisor.dll");
}
}

Expand Down
2 changes: 1 addition & 1 deletion CarbonLauncher/src/pipemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ PipeManager::PipeManager() {
continue;
}

spdlog::trace("S-L : `{}` @ {}", !data.empty() ? data : "null", type);
spdlog::trace("G-L : `{}` @ {}", !data.empty() ? data : "null", type);

Packet parsedPacket;
parsedPacket.type = packetType;
Expand Down
2 changes: 1 addition & 1 deletion repos.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
},
{
"ghUser": "ScrappySM",
"ghRepo": "ModTemplate"
"ghRepo": "Network-Checksum-Disabler"
}
]
}

0 comments on commit 02120ba

Please sign in to comment.