mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
Compare commits
11 commits
46f70cf4a5
...
28e0993d1e
Author | SHA1 | Date | |
---|---|---|---|
|
28e0993d1e | ||
|
71f56ef49e | ||
|
1af10eea7f | ||
|
37fb2a3ddf | ||
|
290e0e0a34 | ||
|
a4f8295784 | ||
|
9bebb9819c | ||
|
6765bbbc75 | ||
|
6dbe289a7a | ||
|
4a40835f71 | ||
|
74d0924bcb |
6 changed files with 147 additions and 5 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -137,7 +137,6 @@ jobs:
|
||||||
build-mac:
|
build-mac:
|
||||||
name: Build macOS
|
name: Build macOS
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
if: false
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
SCCACHE_CACHE_MULTIARCH: 1
|
SCCACHE_CACHE_MULTIARCH: 1
|
||||||
|
|
25
CHANGELOG.md
25
CHANGELOG.md
|
@ -1,5 +1,30 @@
|
||||||
# Geode Changelog
|
# Geode Changelog
|
||||||
|
|
||||||
|
## v4.0.0-alpha.1
|
||||||
|
* Support for the 2.2074 update
|
||||||
|
* Developers, see [this page for a migration guide](https://docs.geode-sdk.org/tutorials/migrate-v4)
|
||||||
|
* Major API breaks:
|
||||||
|
* Remove everything previously marked deprecated
|
||||||
|
* `utils::MiniFunction` removed
|
||||||
|
* Rewritten `geode::Result` class
|
||||||
|
* Rewritten matjson library
|
||||||
|
* Settings V2 completely removed, use V3 now
|
||||||
|
* `JsonChecker` removed
|
||||||
|
* Add new system for ordered hook priority (673317d, 6db3084)
|
||||||
|
* See docs: LINK HERE!!
|
||||||
|
* C++20 coroutine support for `geode::Task`, [see docs](https://docs.geode-sdk.org/tutorials/tasks#coroutines) (e61b2c0, ab196b9)
|
||||||
|
* Add `Task::chain`, [see docs](https://docs.geode-sdk.org/tutorials/tasks#chaining-tasks) (3248831)
|
||||||
|
* Single page local mods list (efb1fbf)
|
||||||
|
* Split mod problems into load and outdated (12e8bbb, 09fa872, df2528c)
|
||||||
|
* This means mods made for outdated gd or geode versions no longer count as actual errors, resulting in less clutter in the ui
|
||||||
|
* Fix safe mode popup on windows showing up when not supposed to (038788b)
|
||||||
|
* WebRequest::ignoreContentLength (#1126)
|
||||||
|
* Lots of smaller fixes to the geode ui (c9afa75, f5f3365, 2d66279, 02845d9, 9b95301, 6d13f78, 123b3ab, 0b2fc66, f96ea5e, cad670f)
|
||||||
|
* Fix CCArrayExt::pop_back() return type (#1130)
|
||||||
|
* Add missing spanish translations to installer (#1145)
|
||||||
|
* Add hashtag symbol to CommonFilter::Any (#1131)
|
||||||
|
* Disable forward compat on android (c9e97af)
|
||||||
|
|
||||||
## v3.9.0
|
## v3.9.0
|
||||||
* Many changes to the settings ui (#1108)
|
* Many changes to the settings ui (#1108)
|
||||||
* Fuzzy search is now more reasonable
|
* Fuzzy search is now more reasonable
|
||||||
|
|
|
@ -164,7 +164,27 @@ function(setup_geode_mod proname)
|
||||||
set(HAS_HEADERS Off)
|
set(HAS_HEADERS Off)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (HAS_HEADERS AND WIN32)
|
if (GEODE_BUNDLE_PDB AND WIN32 AND (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
|
||||||
|
if (HAS_HEADERS)
|
||||||
|
add_custom_target(${proname}_PACKAGE ALL
|
||||||
|
DEPENDS ${proname} ${CMAKE_CURRENT_SOURCE_DIR}/mod.json
|
||||||
|
COMMAND ${GEODE_CLI} package new ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
--binary $<TARGET_FILE:${proname}> $<TARGET_LINKER_FILE:${proname}> $<TARGET_PDB_FILE:${proname}>
|
||||||
|
--output ${CMAKE_CURRENT_BINARY_DIR}/${MOD_ID}.geode
|
||||||
|
${INSTALL_ARG} ${PDB_ARG}
|
||||||
|
VERBATIM USES_TERMINAL
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_custom_target(${proname}_PACKAGE ALL
|
||||||
|
DEPENDS ${proname} ${CMAKE_CURRENT_SOURCE_DIR}/mod.json
|
||||||
|
COMMAND ${GEODE_CLI} package new ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
--binary $<TARGET_FILE:${proname}> $<TARGET_PDB_FILE:${proname}>
|
||||||
|
--output ${CMAKE_CURRENT_BINARY_DIR}/${MOD_ID}.geode
|
||||||
|
${INSTALL_ARG} ${PDB_ARG}
|
||||||
|
VERBATIM USES_TERMINAL
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
elseif (HAS_HEADERS AND WIN32)
|
||||||
# this adds the .lib file on windows, which is needed for linking with the headers
|
# this adds the .lib file on windows, which is needed for linking with the headers
|
||||||
add_custom_target(${proname}_PACKAGE ALL
|
add_custom_target(${proname}_PACKAGE ALL
|
||||||
DEPENDS ${proname} ${CMAKE_CURRENT_SOURCE_DIR}/mod.json
|
DEPENDS ${proname} ${CMAKE_CURRENT_SOURCE_DIR}/mod.json
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
struct XINPUT_STATE;
|
struct XINPUT_STATE;
|
||||||
struct XINPUT_CAPABILITIES;
|
struct XINPUT_CAPABILITIES;
|
||||||
|
struct XINPUT_VIBRATION;
|
||||||
|
|
||||||
constexpr static auto MAX_PATH_CHARS = 32768u;
|
constexpr static auto MAX_PATH_CHARS = 32768u;
|
||||||
|
|
||||||
|
@ -41,6 +42,17 @@ extern "C" DWORD XInputGetState(DWORD dwUserIndex, XINPUT_STATE *pState) {
|
||||||
return ERROR_DEVICE_NOT_CONNECTED;
|
return ERROR_DEVICE_NOT_CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma comment(linker, "/export:XInputSetState,@3")
|
||||||
|
extern "C" DWORD XInputSetState(DWORD dwUserIndex, XINPUT_VIBRATION* pVibration) {
|
||||||
|
static auto fp = getFP("XInputSetState");
|
||||||
|
if (fp) {
|
||||||
|
using FPType = decltype(&XInputSetState);
|
||||||
|
return reinterpret_cast<FPType>(fp)(dwUserIndex, pVibration);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ERROR_DEVICE_NOT_CONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma comment(linker, "/export:XInputGetCapabilities,@4")
|
#pragma comment(linker, "/export:XInputGetCapabilities,@4")
|
||||||
extern "C" DWORD XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES *pCapabilities) {
|
extern "C" DWORD XInputGetCapabilities(DWORD dwUserIndex, DWORD dwFlags, XINPUT_CAPABILITIES *pCapabilities) {
|
||||||
static auto fp = getFP("XInputGetCapabilities");
|
static auto fp = getFP("XInputGetCapabilities");
|
||||||
|
|
|
@ -8,11 +8,15 @@ $execute {
|
||||||
// this is needed because the transitions in cocos uses dynamic cast to check
|
// this is needed because the transitions in cocos uses dynamic cast to check
|
||||||
// layers, which fail on user layers due to typeinfo not matching
|
// layers, which fail on user layers due to typeinfo not matching
|
||||||
|
|
||||||
|
#if defined(GEODE_IS_MAC) && GEODE_COMP_GD_VERSION != 22074
|
||||||
|
#error "Unsupported version for macOS dynamic cast fix, please update the addresses"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(GEODE_IS_INTEL_MAC)
|
#if defined(GEODE_IS_INTEL_MAC)
|
||||||
void* dynamicCastAddr = reinterpret_cast<void*>(base::get() + 0x7dd5e7);
|
void* dynamicCastAddr = reinterpret_cast<void*>(base::get() + 0x7ba1d8);
|
||||||
(void) Mod::get()->hook(dynamicCastAddr, &cast::typeinfoCastInternal, "__dynamic_cast");
|
(void) Mod::get()->hook(dynamicCastAddr, &cast::typeinfoCastInternal, "__dynamic_cast");
|
||||||
#elif defined(GEODE_IS_ARM_MAC)
|
#elif defined(GEODE_IS_ARM_MAC)
|
||||||
void* dynamicCastAddr = reinterpret_cast<void*>(base::get() + 0x6dfb10);
|
void* dynamicCastAddr = reinterpret_cast<void*>(base::get() + 0x6c8bcc);
|
||||||
(void)Mod::get()->hook(dynamicCastAddr, &cast::typeinfoCastInternal, "__dynamic_cast");
|
(void)Mod::get()->hook(dynamicCastAddr, &cast::typeinfoCastInternal, "__dynamic_cast");
|
||||||
#elif defined(GEODE_IS_ANDROID)
|
#elif defined(GEODE_IS_ANDROID)
|
||||||
void* handle = dlopen("libcocos2dcpp.so", RTLD_LAZY | RTLD_NOLOAD);
|
void* handle = dlopen("libcocos2dcpp.so", RTLD_LAZY | RTLD_NOLOAD);
|
||||||
|
|
|
@ -161,13 +161,95 @@ void Loader::Impl::addNativeBinariesPath(std::filesystem::path const& path) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gameVersionIsAmbiguous(std::string gameVersion) {
|
||||||
|
return gameVersion == "2.207";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<std::uint8_t, 16> getBinaryUUID() {
|
||||||
|
auto imageCount = _dyld_image_count();
|
||||||
|
|
||||||
|
auto binaryHeader = _dyld_get_image_header(0);
|
||||||
|
for (auto i = 0u; i < imageCount; i++) {
|
||||||
|
auto headerCandidate = _dyld_get_image_header(i);
|
||||||
|
if (headerCandidate->filetype == MH_EXECUTE) {
|
||||||
|
auto imageName = _dyld_get_image_name(i);
|
||||||
|
|
||||||
|
binaryHeader = headerCandidate;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto commandCount = binaryHeader->ncmds;
|
||||||
|
auto commandSize = binaryHeader->sizeofcmds;
|
||||||
|
|
||||||
|
// for whatever reason _dyld_get_image_header returns a 32bit mach header, not a 64bit one
|
||||||
|
// that's okay but we do have to account for that issue here
|
||||||
|
auto commands = reinterpret_cast<const std::uint8_t*>(binaryHeader) + sizeof(struct mach_header_64);
|
||||||
|
|
||||||
|
for (auto i = 0u; i < commandCount; i++) {
|
||||||
|
auto cCommand = reinterpret_cast<const struct load_command*>(commands);
|
||||||
|
if (cCommand->cmd == LC_UUID) {
|
||||||
|
auto uuidCommand = reinterpret_cast<const struct uuid_command*>(commands);
|
||||||
|
return std::to_array(uuidCommand->uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
commands += cCommand->cmdsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& uuidToVersionMap() {
|
||||||
|
// we only need to define versions that are ambiguous
|
||||||
|
// so for now, 2.207
|
||||||
|
// you can get these hashes from otool, just look for the LC_UUID load command!
|
||||||
|
static std::unordered_map<std::string, std::string> uuidToVersionName{
|
||||||
|
#if defined(GEODE_IS_ARM_MAC)
|
||||||
|
{"27044C8B-76BD-303C-A035-5314AF1D9E6E", "2.2074"},
|
||||||
|
#elif defined(GEODE_IS_INTEL_MAC)
|
||||||
|
{"DB5CADC0-E533-3123-8A63-5A434FE391ED", "2.2074"}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
return uuidToVersionName;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Loader::Impl::getGameVersion() {
|
std::string Loader::Impl::getGameVersion() {
|
||||||
NSBundle* mainBundle = [NSBundle mainBundle];
|
NSBundle* mainBundle = [NSBundle mainBundle];
|
||||||
NSDictionary* infoDictionary = [mainBundle infoDictionary];
|
NSDictionary* infoDictionary = [mainBundle infoDictionary];
|
||||||
|
|
||||||
NSString *version = infoDictionary[@"CFBundleShortVersionString"];
|
NSString *version = infoDictionary[@"CFBundleShortVersionString"];
|
||||||
|
|
||||||
return std::string([version UTF8String]);
|
auto versionStr = std::string([version UTF8String]);
|
||||||
|
|
||||||
|
if (gameVersionIsAmbiguous(versionStr)) {
|
||||||
|
static std::string manualVersionStr = []() -> std::string {
|
||||||
|
auto uuid = getBinaryUUID();
|
||||||
|
if (uuid.empty()) {
|
||||||
|
// i wonder if this might cause issues
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
auto uuidStr = fmt::format("{:02X}{:02X}{:02X}{:02X}-{:02X}{:02X}-{:02X}{:02X}-{:02X}{:02X}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}",
|
||||||
|
uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
|
||||||
|
uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]
|
||||||
|
);
|
||||||
|
|
||||||
|
auto& versionMap = uuidToVersionMap();
|
||||||
|
auto versionElem = versionMap.find(uuidStr);
|
||||||
|
if (versionElem != versionMap.end()) {
|
||||||
|
return versionElem->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the uuid as a fallback
|
||||||
|
// in this situation, geode (and any mods) won't load, so it's not really a big deal
|
||||||
|
return uuidStr;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return manualVersionStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return versionStr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
Loading…
Reference in a new issue