Macos support for Geode v2 ()

updates loader refactor stuff and other things

---------

Co-authored-by: matcool <26722564+matcool@users.noreply.github.com>
Co-authored-by: dankmeme01 <42031238+dankmeme01@users.noreply.github.com>
This commit is contained in:
alk 2024-01-21 20:08:06 +03:00 committed by GitHub
parent c2f626b937
commit 9869ddcdea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 53 additions and 112 deletions
loader
include/Geode/cocos/label_nodes
src

View file

@ -123,7 +123,7 @@ public://@public
gd::string m_sAtlasName;
//! values for kerning
tCCKerningHashElement *m_pKerningDictionary;
// Character Set defines the letters that actually exist in the font
std::set<unsigned int> *m_pCharacterSet;
public:
@ -144,10 +144,10 @@ public:
/** initializes a BitmapFontConfiguration with a FNT file */
bool initWithFNTfile(const char *FNTfile);
inline const char* getAtlasName(){ return m_sAtlasName.c_str(); }
inline void setAtlasName(const char* atlasName) { m_sAtlasName = atlasName; }
inline std::set<unsigned int>* getCharacterSet() const { return m_pCharacterSet; }
private:
std::set<unsigned int>* parseConfigFile(const char *controlFile);
@ -212,7 +212,7 @@ public:
/** creates a bitmap font atlas with an initial string and the FNT file */
static CCLabelBMFont * create(const char *str, const char *fntFile, float width, CCTextAlignment alignment, CCPoint imageOffset);
static CCLabelBMFont * create(const char *str, const char *fntFile, float width, CCTextAlignment alignment);
static CCLabelBMFont * create(const char *str, const char *fntFile, float width);
@ -243,8 +243,8 @@ public:
virtual void setScale(float scale);
virtual void setScaleX(float scaleX);
virtual void setScaleY(float scaleY);
// CCRGBAProtocol
// CCRGBAProtocol
virtual bool isOpacityModifyRGB();
virtual void setOpacityModifyRGB(bool isOpacityModifyRGB); virtual GLubyte getOpacity();
virtual GLubyte getDisplayedOpacity();
@ -288,33 +288,33 @@ private:
int kerningAmountForFirst(unsigned short first, unsigned short second);
float getLetterPosXLeft( CCSprite* characterSprite, float, bool);
float getLetterPosXRight( CCSprite* characterSprite, float, bool);
protected:
virtual void setString(unsigned short *newString, bool needUpdateLabel);
// string to render
unsigned short* m_sString;
// name of fntFile
gd::string m_sFntFile;
// initial string without line breaks
unsigned short* m_sInitialString;
gd::string m_sInitialStringUTF8;
// alignment of all lines
CCTextAlignment m_pAlignment;
// max width until a line break is added
float m_fWidth;
CCBMFontConfiguration *m_pConfiguration;
bool m_bLineBreakWithoutSpaces;
// offset of the texture atlas
CCPoint m_tImageOffset;
// reused char
CCSprite *m_pReusedChar;
// texture RGBA
GLubyte m_cDisplayedOpacity;
GLubyte m_cRealOpacity;
@ -329,6 +329,7 @@ protected:
bool m_bIsBatched;
CCArray* m_pTargetArray;
CCTexture2D* m_pSomeTexture;
void* m_pUnknown; // 2.2 addition, might be positioned somewhere else
)
};

View file

@ -9,9 +9,8 @@ $execute {
// layers, which fail on user layers due to typeinfo not matching
#if defined(GEODE_IS_MACOS)
(void)Mod::get()->patch(
reinterpret_cast<void*>(base::get() + 0x603948), toByteArray(&cast::typeinfoCastInternal)
);
void* dynamicCastAddr = reinterpret_cast<void*>(base::get() + 0x7a7c9f);
(void) Mod::get()->hook(dynamicCastAddr, &cast::typeinfoCastInternal, "__dynamic_cast");
#elif defined(GEODE_IS_ANDROID)
void* handle = dlopen("libcocos2dcpp.so", RTLD_LAZY | RTLD_NOLOAD);
void* dynamicCastAddr = dlsym(handle, "__dynamic_cast");

View file

@ -2,6 +2,8 @@
#include <Geode/loader/Log.hpp>
#include <iostream>
#include <loader/LoaderImpl.hpp>
#include <loader/console.hpp>
#include <loader/IPC.hpp>
#include <loader/ModImpl.hpp>
#import <Foundation/Foundation.h>
#include <sys/stat.h>
@ -15,7 +17,10 @@ struct MacConsoleData {
int logFd;
};
void Loader::Impl::platformMessageBox(char const* title, std::string const& info) {
bool s_isOpen = false;
MacConsoleData s_platformData;
void console::messageBox(char const* title, std::string const& info, Severity) {
CFStringRef cfTitle = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8);
CFStringRef cfMessage = CFStringCreateWithCString(NULL, info.c_str(), kCFStringEncodingUTF8);
@ -24,8 +29,8 @@ void Loader::Impl::platformMessageBox(char const* title, std::string const& info
);
}
void Loader::Impl::logConsoleMessageWithSeverity(std::string const& msg, Severity severity) {
if (m_platformConsoleOpen) {
void console::log(std::string const& msg, Severity severity) {
if (s_isOpen) {
int colorcode = 0;
switch (severity) {
case Severity::Debug: colorcode = 36; break;
@ -40,8 +45,9 @@ void Loader::Impl::logConsoleMessageWithSeverity(std::string const& msg, Severit
}
}
void Loader::Impl::openPlatformConsole() {
if (m_platformConsoleOpen) return;
void console::open() {
if (s_isOpen) return;
std::string outFile = "/tmp/command_output_XXXXXX";
int outFd = mkstemp(&outFile[0]);
@ -71,32 +77,28 @@ void Loader::Impl::openPlatformConsole() {
task.arguments = @[[NSString stringWithUTF8String:script.c_str()]];
[task launch];
m_platformData = new MacConsoleData {
s_platformData = MacConsoleData {
outFile,
script,
outFd
};
}
m_platformConsoleOpen = true;
s_isOpen = true;
for (auto const& log : log::Logger::get()->list()) {
this->logConsoleMessageWithSeverity(log.toString(true), log.getSeverity());
console::log(log.toString(true), log.getSeverity());
}
}
void Loader::Impl::closePlatformConsole() {
if (m_platformData) {
auto consoleData = reinterpret_cast<MacConsoleData*>(m_platformData);
close(consoleData->logFd);
unlink(consoleData->logFile.c_str());
unlink(consoleData->scriptFile.c_str());
delete consoleData;
m_platformData = nullptr;
void console::close() {
if (s_isOpen) {
::close(s_platformData.logFd);
unlink(s_platformData.logFile.c_str());
unlink(s_platformData.scriptFile.c_str());
}
m_platformConsoleOpen = false;
s_isOpen = false;
}
CFDataRef msgPortCallback(CFMessagePortRef port, SInt32 messageID, CFDataRef data, void* info) {
@ -104,11 +106,11 @@ CFDataRef msgPortCallback(CFMessagePortRef port, SInt32 messageID, CFDataRef dat
std::string cdata(reinterpret_cast<char const*>(CFDataGetBytePtr(data)), CFDataGetLength(data));
std::string reply = LoaderImpl::get()->processRawIPC(port, cdata).dump();
std::string reply = geode::ipc::processRaw(port, cdata).dump();
return CFDataCreate(NULL, (UInt8 const*)reply.data(), reply.size());
}
void Loader::Impl::setupIPC() {
void geode::ipc::setup() {
std::thread([]() {
CFStringRef portName = CFStringCreateWithCString(NULL, IPC_PORT_NAME, kCFStringEncodingUTF8);
@ -140,3 +142,6 @@ void Loader::Impl::addNativeBinariesPath(ghc::filesystem::path const& path) {
log::warn("LoaderImpl::addNativeBinariesPath not implement on this platform, not adding path {}", path.string());
}
std::string Loader::Impl::getGameVersion() {
return "2.200"; // TODO implement
}

View file

@ -29,15 +29,3 @@ Result<> Mod::Impl::loadPlatformBinary() {
std::string err = (char const*)dlerror();
return Err("Unable to load the DYLIB: dlerror returned (" + err + ")");
}
Result<> Mod::Impl::unloadPlatformBinary() {
auto dylib = m_platformInfo->m_dylib;
delete m_platformInfo;
m_platformInfo = nullptr;
if (dlclose(dylib) == 0) {
return Ok();
}
else {
return Err("Unable to free library");
}
}

View file

@ -1,57 +0,0 @@
#include <Geode/c++stl/gdstdlib.hpp>
namespace gd {
namespace {
static inline auto emptyInternalString() {
return reinterpret_cast<_internal_string*>(
*reinterpret_cast<uintptr_t*>(geode::base::get() + 0x6030d0) + sizeof(_internal_string)
);
}
}
string::string() : m_data(nullptr) {
m_data = emptyInternalString();
}
string::string(char const* ok) : m_data(nullptr) {
reinterpret_cast<void (*)(string*, char const*)>(geode::base::get() + 0x489fc0)(this, ok);
}
string::string(string const& ok) : m_data(nullptr) {
if (*(string**)(&ok) == nullptr) return;
reinterpret_cast<void (*)(string*, string const&)>(geode::base::get() + 0x489fcc)(this, ok);
}
string& string::operator=(char const* ok) {
auto ret = reinterpret_cast<string* (*)(string*, char const*, size_t)>(
geode::base::get() + 0x489f96
)(this, ok, strlen(ok));
return *ret;
}
string& string::operator=(string const& ok) {
auto ret = reinterpret_cast<string* (*)(string*, string const&)>(
geode::base::get() + 0x489f9c
)(this, ok);
return *ret;
}
string::~string() {
if (m_data == nullptr) return;
if (m_data == emptyInternalString()) return;
if (m_data[-1].m_refcount-- <= 0) {
void* al;
reinterpret_cast<void (*)(_internal_string*, void*)>(geode::base::get() + 0x489f78)(
&m_data[-1], al
);
}
}
bool string::operator<(string const& other) const {
return std::string(*this) < std::string(other);
}
bool string::operator==(string const& other) const {
return std::string(*this) == std::string(other);
}
}

View file

@ -12,9 +12,13 @@
#include "../../loader/LoaderImpl.hpp"
#include <thread>
#include <variant>
#include <loader/updater.hpp>
using namespace geode::prelude;
// address of applicationDidFinishLaunching:
constexpr static uintptr_t ENTRY_ADDRESS = 0xb030;
std::length_error::~length_error() _NOEXCEPT {} // do not ask...
// camila has an old ass macos and this function turned
@ -84,6 +88,7 @@ void updateFiles() {
}
$execute {
using namespace geode::updater;
new EventListener(+[](LoaderUpdateEvent* event) {
if (std::holds_alternative<UpdateFinished>(event->status)) {
updateFiles();
@ -118,30 +123,30 @@ void applicationDidFinishLaunchingHook(void* self, SEL sel, NSNotification* noti
0x41, 0x57
};
auto res = tulip::hook::writeMemory((void*)(base::get() + 0x69a0), patchBytes.data(), 6);
auto res = tulip::hook::writeMemory((void*)(base::get() + ENTRY_ADDRESS), patchBytes.data(), 6);
if (!res)
return;
int exitCode = geodeEntry(nullptr);
if (exitCode != 0)
return;
return reinterpret_cast<void(*)(void*, SEL, NSNotification*)>(geode::base::get() + 0x69a0)(self, sel, notification);
return reinterpret_cast<void(*)(void*, SEL, NSNotification*)>(geode::base::get() + ENTRY_ADDRESS)(self, sel, notification);
}
bool loadGeode() {
auto detourAddr = reinterpret_cast<uintptr_t>(&applicationDidFinishLaunchingHook) - geode::base::get() - 0x69a5;
auto detourAddr = reinterpret_cast<uintptr_t>(&applicationDidFinishLaunchingHook) - geode::base::get() - ENTRY_ADDRESS - 5;
auto detourAddrPtr = reinterpret_cast<uint8_t*>(&detourAddr);
std::array<uint8_t, 5> patchBytes = {
0xe9, detourAddrPtr[0], detourAddrPtr[1], detourAddrPtr[2], detourAddrPtr[3]
};
auto res = tulip::hook::writeMemory((void*)(base::get() + 0x69a0), patchBytes.data(), 5);
auto res = tulip::hook::writeMemory((void*)(base::get() + ENTRY_ADDRESS), patchBytes.data(), 5);
if (!res)
return false;
return true;
}