mirror of
https://github.com/geode-sdk/geode.git
synced 2025-04-16 06:55:04 -04:00
Macos support for Geode v2 (#437)
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:
parent
c2f626b937
commit
9869ddcdea
6 changed files with 53 additions and 112 deletions
loader
include/Geode/cocos/label_nodes
src
|
@ -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
|
||||
)
|
||||
|
||||
};
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue