fix AddressGen hooking gd::base and causing Windows to not work at all +

fix GD bug with Open GL errors not showing properly
This commit is contained in:
HJfod 2022-07-31 22:50:49 +03:00
parent a149dcd6a2
commit 19c9f9ebde
7 changed files with 76 additions and 22 deletions

View file

@ -165,6 +165,7 @@ class cocos2d::CCEaseOut {
}
class cocos2d::CCEGLView {
CCEGLView();
static cocos2d::CCEGLView* sharedOpenGLView() = mac 0x295320;
virtual void swapBuffers() = mac 0x295510;
void updateWindow(int width, int height);
@ -641,7 +642,7 @@ class cocos2d::CCScheduler {
auto scheduleUpdateForTarget(cocos2d::CCObject*, int, bool) = mac 0x2438d0;
auto unscheduleAllForTarget(cocos2d::CCObject*) = mac 0x243e40;
auto unscheduleUpdateForTarget(cocos2d::CCObject const*) = mac 0x243c60;
virtual auto update(float delta) = mac 0x2446d0;
virtual void update(float delta) = mac 0x2446d0;
}
class cocos2d::CCSequence {

View file

@ -17,21 +17,28 @@ std::string generateAddressHeader(Root& root) {
for (auto& c : root.classes) {
for (auto& field : c.fields) {
if (codegen::getStatus(field) == BindStatus::Unbindable)
continue;
std::string address_str;
if (auto fn = field.get_as<FunctionBindField>()) {
address_str = fmt::format("base::get() + {}", codegen::platformNumber(fn->binds));
} else if (auto fn = field.get_as<OutOfLineField>()) {
auto fn = field.get_as<FunctionBindField>();
if (!fn) {
continue;
}
if (codegen::getStatus(field) == BindStatus::Binded) {
address_str = fmt::format("addresser::get{}Virtual((types::member{})(&{}::{}))",
str_if("Non", !fn->beginning.is_virtual),
field.field_id,
field.parent,
fn->beginning.name
);
} else {
} else if (codegen::getStatus(field) == BindStatus::NeedsBinding) {
address_str = fmt::format("base::get() + {}", codegen::platformNumber(fn->binds));
} else {
continue;
}

View file

@ -5,11 +5,11 @@
#pragma warning(disable: 4244) // narrowing conversion
#include <Windows.h>
#include <meta/cdecl.hpp>
#include <meta/function.hpp>
#include <meta/optcall.hpp>
#include <meta/membercall.hpp>
#include <meta/thiscall.hpp>
#include <Geode/meta/cdecl.hpp>
#include <Geode/meta/function.hpp>
#include <Geode/meta/optcall.hpp>
#include <Geode/meta/membercall.hpp>
#include <Geode/meta/thiscall.hpp>
#include <type_traits>
#include <typeinfo>
@ -26,6 +26,11 @@ namespace geode::base {
static uintptr_t base = reinterpret_cast<uintptr_t>(GetModuleHandle(0));
return base;
}
GEODE_NOINLINE inline uintptr_t getCocos() {
static uintptr_t base = reinterpret_cast<uintptr_t>(GetModuleHandleA("libcocos2d.dll"));
return base;
}
}

View file

@ -6,10 +6,11 @@ namespace geode {
using byte_array = std::vector<uint8_t>;
template <typename T>
byte_array to_byte_array(T& a) {
uint8_t* c_array = reinterpret_cast<uint8_t*>(&a);
return byte_array(c_array, c_array + sizeof(T));
byte_array to_byte_array(T const& a) {
byte_array out;
out.resize(sizeof(T));
std::memcpy(out.data(), &a, sizeof(T));
return out;
}
template<class T>

View file

@ -0,0 +1,40 @@
#include <Geode/Modify.hpp>
#ifdef GEODE_IS_WINDOWS
USE_GEODE_NAMESPACE();
using geode::core::meta::x86::Thiscall;
// for some reason RobTop uses MessageBoxW in his GLFW error handler.
// no one knows how this is possible (he passes char* to wchar_t*).
// so anyway, here's a fix for it
static auto CCEGLVIEW_CON_ADDR = reinterpret_cast<void*>(base::getCocos() + 0xc2860);
static void __cdecl fixedErrorHandler(int code, const char* description) {
Log::get() << Severity::Critical << "GLFW Error " << code << ": " << description;
MessageBoxA(
nullptr,
CCString::createWithFormat(
"GLFWError #%d: %s\nPlease contact the "
"Geode Development Team for more information.",
code, description
)->getCString(),
"OpenGL Error",
MB_ICONERROR
);
}
static CCEGLView* CCEGLView_CCEGLView(CCEGLView* self) {
// you will never have to make a manual hook with Geode again, they said
// it will be fun, they said
reinterpret_cast<CCEGLView*(__thiscall*)(CCEGLView*)>(CCEGLVIEW_CON_ADDR)(self);
static auto p = Mod::get()->patch(
reinterpret_cast<void*>(geode::base::getCocos() + 0x19feec),
to_byte_array(&fixedErrorHandler)
);
return self;
}
static auto _ = Interface::get()->addHook<&CCEGLView_CCEGLView, Thiscall>("CCEGLView::CCEGLView", CCEGLVIEW_CON_ADDR);
#endif

View file

@ -28,13 +28,13 @@ Result<Patch*> Mod::patch(void* address, byte_array data) {
delete p;
return Err<>("Unable to enable patch at " + std::to_string(p->getAddress()));
}
this->m_patches.push_back(p);
m_patches.push_back(p);
return Ok<Patch*>(p);
}
Result<> Mod::unpatch(Patch* patch) {
if (patch->restore()) {
vector_utils::erase<Patch*>(this->m_patches, patch);
vector_utils::erase<Patch*>(m_patches, patch);
delete patch;
return Ok<>();
}
@ -43,12 +43,12 @@ Result<> Mod::unpatch(Patch* patch) {
bool Patch::apply() {
return lilac::hook::write_memory(
this->m_address, this->m_patch.data(), this->m_patch.size()
m_address, m_patch.data(), m_patch.size()
);
}
bool Patch::restore() {
return lilac::hook::write_memory(
this->m_address, this->m_original.data(), this->m_original.size()
m_address, m_original.data(), m_original.size()
);
}

View file

@ -51,7 +51,6 @@ BOOL WINAPI DllMain(HINSTANCE lib, DWORD reason, LPVOID) {
#endif
int geodeEntry(void* platformData) {
// setup internals
@ -128,5 +127,6 @@ int geodeEntry(void* platformData) {
InternalMod::get()->log()
<< Severity::Debug
<< "Entry done.";
return 0;
}