now uses MinHook on Windows (😨)

This commit is contained in:
HJfod 2022-09-01 11:02:14 +03:00
parent 8d7a46f6ab
commit e6aee53f45
9 changed files with 126 additions and 94 deletions

3
.gitignore vendored
View file

@ -43,3 +43,6 @@ build
bin
loader/src/internal/about.hpp
fods-catgirl-hideout.txt

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "loader/md4c"]
path = loader/md4c
url = https://github.com/mity/md4c
[submodule "loader/minhook"]
path = loader/minhook
url = https://github.com/TsudaKageyu/minhook

View file

@ -134,13 +134,17 @@ if (APPLE)
endif()
elseif (WIN32)
add_subdirectory(launcher/windows)
target_include_directories(${PROJECT_NAME} PRIVATE dobby/include)
target_link_directories(${PROJECT_NAME} PRIVATE dobby)
target_link_libraries(${PROJECT_NAME} dobby)
set(DOBBY_GENERATE_SHARED OFF CACHE BOOL "Build dobby shared library" FORCE)
# set(DOBBY_DEBUG ON CACHE BOOL "Build dobby shared library" FORCE)
add_subdirectory(dobby)
add_subdirectory(minhook)
target_link_libraries(${PROJECT_NAME} minhook)
# target_include_directories(${PROJECT_NAME} PRIVATE dobby/include)
# target_link_directories(${PROJECT_NAME} PRIVATE dobby)
# target_link_libraries(${PROJECT_NAME} dobby)
# set(DOBBY_GENERATE_SHARED OFF CACHE BOOL "Build dobby shared library" FORCE)
# # set(DOBBY_DEBUG ON CACHE BOOL "Build dobby shared library" FORCE)
# add_subdirectory(dobby)
target_link_libraries(${PROJECT_NAME} dbghelp)
endif()

View file

@ -133,6 +133,11 @@ namespace geode {
*/
ghc::filesystem::path getGeodeSaveDirectory() const;
/**
* Check if a mod's version is within the supported range
*/
bool supportedModVersion(VersionInfo const& version);
/**
* Whether mod specified with ID is enabled
* @param id The ID of the mod

1
loader/minhook Submodule

@ -0,0 +1 @@
Subproject commit 4a455528f61b5a375b1f9d44e7d296d47f18bb18

View file

@ -147,7 +147,8 @@ bool geode::core::hook::initialize() {
#else
#include <dobby.h>
// #include <dobby.h>
#include <MinHook.h>
namespace geode::core::impl {
namespace {
@ -162,8 +163,14 @@ namespace geode::core::impl {
}
void addJump(void* at, void* to) {
DobbyDestroy(at);
DobbyHook(at, to, &trampolines()[at]);
// DobbyDestroy(at);
// DobbyHook(at, to, &trampolines()[at]);
static auto _ = MH_Initialize();
MH_RemoveHook(at);
MH_CreateHook(at, to, &trampolines()[at]);
MH_EnableHook(at);
}
}

View file

@ -1,6 +1,7 @@
#include "Index.hpp"
#include <thread>
#include <Geode/utils/json.hpp>
#include <Geode/utils/json_check.hpp>
#include "fetch.hpp"
#define GITHUB_DONT_RATE_LIMIT_ME_PLS 0
@ -72,6 +73,18 @@ static Result<> unzipTo(
return Ok();
}
static PlatformID platformFromString(std::string const& str) {
switch (hash(string_utils::trim(string_utils::toLower(str)).c_str())) {
default:
case hash("unknown"): return PlatformID::Unknown;
case hash("windows"): return PlatformID::Windows;
case hash("macos"): return PlatformID::MacOS;
case hash("ios"): return PlatformID::iOS;
case hash("android"): return PlatformID::Android;
case hash("linux"): return PlatformID::Linux;
}
}
Index* Index::get() {
static auto ret = new Index();
@ -281,18 +294,6 @@ void Index::updateIndex(IndexUpdateCallback callback, bool force) {
std::thread(&Index::updateIndexThread, this, force).detach();
}
PlatformID platformFromString(std::string const& str) {
switch (hash(string_utils::trim(string_utils::toLower(str)).c_str())) {
default:
case hash("unknown"): return PlatformID::Unknown;
case hash("windows"): return PlatformID::Windows;
case hash("macos"): return PlatformID::MacOS;
case hash("ios"): return PlatformID::iOS;
case hash("android"): return PlatformID::Android;
case hash("linux"): return PlatformID::Linux;
}
}
void Index::addIndexItemFromFolder(ghc::filesystem::path const& dir) {
if (ghc::filesystem::exists(dir / "index.json")) {
@ -329,79 +330,83 @@ void Index::addIndexItemFromFolder(ghc::filesystem::path const& dir) {
item.m_path = dir;
item.m_info = info.value();
if (json.contains("download") && json["download"].is_object()) {
auto download = json["download"];
std::set<PlatformID> unsetPlatforms = {
PlatformID::Windows,
PlatformID::MacOS,
PlatformID::iOS,
PlatformID::Android,
PlatformID::Linux,
};
for (auto& key : std::initializer_list<std::string> {
"windows",
"macos",
"android",
"ios",
"*",
}) {
if (download.contains(key)) {
auto platformDownload = download[key];
if (!platformDownload.is_object()) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< " is not an object, skipping";
return;
}
if (
!platformDownload.contains("url") ||
!platformDownload["url"].is_string()
) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< ".url is not a string, skipping";
return;
}
if (
!platformDownload.contains("name") ||
!platformDownload["name"].is_string()
) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< ".name is not a string, skipping";
return;
}
if (
!platformDownload.contains("hash") ||
!platformDownload["hash"].is_string()
) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< ".hash is not a string, skipping";
return;
}
IndexItem::Download down;
down.m_url = platformDownload["url"];
down.m_filename = platformDownload["name"];
down.m_hash = platformDownload["hash"];
if (key == "*") {
for (auto& platform : unsetPlatforms) {
item.m_download[platform] = down;
}
} else {
auto id = platformFromString(key);
item.m_download[id] = down;
unsetPlatforms.erase(id);
if (
!json.contains("download") ||
!json["download"].is_object()
) {
Log::get() << Severity::Warning
<< "[index.json].download is not an object, "
"skipping";
}
auto download = json["download"];
std::set<PlatformID> unsetPlatforms = {
PlatformID::Windows,
PlatformID::MacOS,
PlatformID::iOS,
PlatformID::Android,
PlatformID::Linux,
};
for (auto& key : std::initializer_list<std::string> {
"windows",
"macos",
"android",
"ios",
"*",
}) {
if (download.contains(key)) {
auto platformDownload = download[key];
if (!platformDownload.is_object()) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< " is not an object, skipping";
return;
}
if (
!platformDownload.contains("url") ||
!platformDownload["url"].is_string()
) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< ".url is not a string, skipping";
return;
}
if (
!platformDownload.contains("name") ||
!platformDownload["name"].is_string()
) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< ".name is not a string, skipping";
return;
}
if (
!platformDownload.contains("hash") ||
!platformDownload["hash"].is_string()
) {
Log::get() << Severity::Warning
<< "[index.json].download."
<< key
<< ".hash is not a string, skipping";
return;
}
IndexItem::Download down;
down.m_url = platformDownload["url"];
down.m_filename = platformDownload["name"];
down.m_hash = platformDownload["hash"];
if (key == "*") {
for (auto& platform : unsetPlatforms) {
item.m_download[platform] = down;
}
} else {
auto id = platformFromString(key);
item.m_download[id] = down;
unsetPlatforms.erase(id);
}
}
} else {
Log::get() << Severity::Warning
<< "[index.json] is missing \"download\", adding anyway";
}
m_items.push_back(item);

View file

@ -430,3 +430,9 @@ size_t Loader::getFieldIndexForClass(size_t hash) {
static std::unordered_map<size_t, size_t> nextIndex;
return nextIndex[hash]++;
}
bool Loader::supportedModVersion(VersionInfo const& version) {
return
version >= s_supportedVersionMin &&
version <= s_supportedVersionMax;
}

View file

@ -498,9 +498,7 @@ std::string sanitizeDetailsData(unsigned char* start, unsigned char* end) {
return string_utils::replace(std::string(start, end), "\r", "");
}
Result<ModInfo> ModInfo::createFromSchemaV010(
nlohmann::json const& rawJson
) {
Result<ModInfo> ModInfo::createFromSchemaV010(nlohmann::json const& rawJson) {
ModInfo info;
auto json = rawJson;