mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
forward compat mode
This commit is contained in:
parent
7ef57bbf67
commit
91bff5fbb2
17 changed files with 263 additions and 98 deletions
|
@ -72,6 +72,8 @@ namespace geode {
|
|||
Done
|
||||
};
|
||||
|
||||
bool isForwardCompatMode();
|
||||
|
||||
// TODO: return void
|
||||
Result<> saveData();
|
||||
Result<> loadData();
|
||||
|
|
|
@ -47,73 +47,25 @@ DWORD WINAPI xinputGetDSoundAudioDeviceGuids(DWORD dwUserIndex, GUID* pDSoundRen
|
|||
#pragma comment(linker, "/export:XInputGetCapabilities=_xinputGetCapabilities@12")
|
||||
#pragma comment(linker, "/export:XInputGetDSoundAudioDeviceGuids=_xinputGetDSoundAudioDeviceGuids@12")
|
||||
|
||||
unsigned int getExeTimestamp() {
|
||||
HANDLE hMod = GetModuleHandleA(NULL);
|
||||
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hMod;
|
||||
|
||||
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) {
|
||||
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((uintptr_t)(hMod) + dosHeader->e_lfanew);
|
||||
|
||||
if (ntHeader->Signature == IMAGE_NT_SIGNATURE) {
|
||||
return ntHeader->FileHeader.TimeDateStamp;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL fileExists(char const* path) {
|
||||
DWORD attrib = GetFileAttributesA(path);
|
||||
|
||||
return (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY));
|
||||
}
|
||||
|
||||
// Table originally from this gist by absolute:
|
||||
// https://gist.github.com/absoIute/ebe5da42d118109a03632c9751d86e19
|
||||
|
||||
#define TIMESTAMP_FOR_1_900 1419173053
|
||||
#define TIMESTAMP_FOR_1_910 1419880840
|
||||
#define TIMESTAMP_FOR_1_920 1421745341
|
||||
#define TIMESTAMP_FOR_2_000 1440638199
|
||||
#define TIMESTAMP_FOR_2_001 1440643927
|
||||
#define TIMESTAMP_FOR_2_010 1443053232
|
||||
#define TIMESTAMP_FOR_2_011 1443077847
|
||||
#define TIMESTAMP_FOR_2_020 1443077847
|
||||
#define TIMESTAMP_FOR_2_100 1484612867
|
||||
#define TIMESTAMP_FOR_2_101 1484626658
|
||||
#define TIMESTAMP_FOR_2_102 1484737207
|
||||
#define TIMESTAMP_FOR_2_110 1510526914
|
||||
#define TIMESTAMP_FOR_2_111 1510538091
|
||||
#define TIMESTAMP_FOR_2_112 1510619253
|
||||
#define TIMESTAMP_FOR_2_113 1511220108
|
||||
#define TIMESTAMP_FOR_2_200 1702921605
|
||||
#define TIMESTAMP_FOR_2_201 1704582672
|
||||
#define TIMESTAMP_FOR_2_202 1704601266
|
||||
#define TIMESTAMP_FOR_2_203 1704948277
|
||||
|
||||
#define GEODE_WRAPPER_CONCAT(x, y) x##y
|
||||
#define GEODE_CONCAT(x, y) GEODE_WRAPPER_CONCAT(x, y)
|
||||
|
||||
// Hello future person. if this is erroring then you need to add
|
||||
// the exe timestamp for whatever you set GEODE_GD_VERSION to. hope that helps!
|
||||
#define TIMESTAMP GEODE_CONCAT(TIMESTAMP_FOR, GEODE_GD_VERSION_IDENTIFIER)
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID _) {
|
||||
if (reason != DLL_PROCESS_ATTACH)
|
||||
return TRUE;
|
||||
DisableThreadLibraryCalls(module);
|
||||
|
||||
if (fileExists("Geode.dll")) {
|
||||
unsigned int timestamp = getExeTimestamp();
|
||||
if (timestamp == TIMESTAMP) {
|
||||
// somehow, this works fine inside of dllmain :-)
|
||||
// yes, even on wine.
|
||||
LoadLibraryA("Geode.dll");
|
||||
} else {
|
||||
char buffer[128];
|
||||
sprintf_s(buffer, sizeof(buffer), "GD version mismatch, not loading Geode. (%" PRIu32 ")", timestamp);
|
||||
MessageBoxA(NULL, buffer, "Unable to load Geode!", MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
// somehow, this works fine inside of dllmain :-)
|
||||
// yes, even on wine.
|
||||
/* * * * * * * * * * * * * * * * * *\
|
||||
* The Shadows Shall Smite You 01 *
|
||||
* - ConfiG *
|
||||
\* * * * * * * * * * * * * * * * * */
|
||||
LoadLibraryA("Geode.dll");
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,16 @@
|
|||
using namespace geode::prelude;
|
||||
|
||||
struct MyGameToolbox : Modify<MyGameToolbox, GameToolbox> {
|
||||
static void preVisitWithClippingRect(CCNode* node, CCRect rect) {
|
||||
static void onModify(const auto& self) {
|
||||
if (!Loader::get()->isForwardCompatMode())
|
||||
return;
|
||||
log::warn("FixClippingRect disabled in forward compat");
|
||||
for (const auto& [_, hook] : self.m_hooks) {
|
||||
hook->setAutoEnable(false);
|
||||
}
|
||||
}
|
||||
|
||||
static void preVisitWithClippingRect(CCNode* node, CCRect rect) {
|
||||
if (node->isVisible()) {
|
||||
glEnable(0xc11);
|
||||
if (node->getParent()) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
#include <Geode/modify/LoadingLayer.hpp>
|
||||
#include <Geode/modify/CCLayer.hpp>
|
||||
#include <Geode/utils/cocos.hpp>
|
||||
#include <array>
|
||||
#include <fmt/format.h>
|
||||
|
@ -13,6 +14,15 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
|||
int m_geodeLoadStep = 0;
|
||||
int m_totalMods = 0;
|
||||
|
||||
static void onModify(const auto& self) {
|
||||
if (!Loader::get()->isForwardCompatMode())
|
||||
return;
|
||||
log::warn("Switching to fallback custom loading layer in forward compat");
|
||||
for (const auto& [_, hook] : self.m_hooks) {
|
||||
hook->setAutoEnable(false);
|
||||
}
|
||||
}
|
||||
|
||||
void updateLoadedModsLabel() {
|
||||
auto allMods = Loader::get()->getAllMods();
|
||||
auto count = std::count_if(allMods.begin(), allMods.end(), [&](auto& item) {
|
||||
|
@ -158,9 +168,9 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
|||
}
|
||||
return !m_fromRefresh;
|
||||
}
|
||||
|
||||
|
||||
// hook
|
||||
void loadAssets() {
|
||||
void loadAssets() {
|
||||
switch (m_fields->m_geodeLoadStep) {
|
||||
case 0:
|
||||
if (this->skipOnRefresh()) this->setupLoadingMods();
|
||||
|
@ -180,3 +190,38 @@ struct CustomLoadingLayer : Modify<CustomLoadingLayer, LoadingLayer> {
|
|||
this->updateLoadingBar();
|
||||
}
|
||||
};
|
||||
|
||||
struct FallbackCustomLoadingLayer : Modify<FallbackCustomLoadingLayer, CCLayer> {
|
||||
static void onModify(const auto& self) {
|
||||
if (Loader::get()->isForwardCompatMode())
|
||||
return;
|
||||
for (const auto& [_, hook] : self.m_hooks) {
|
||||
hook->setAutoEnable(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool init() {
|
||||
if (!CCLayer::init())
|
||||
return false;
|
||||
if (!typeinfo_cast<LoadingLayer*>(this))
|
||||
return true;
|
||||
|
||||
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
||||
|
||||
auto label = CCLabelBMFont::create(
|
||||
"Loading Geode without UI, see console for details.",
|
||||
"goldFont.fnt"
|
||||
);
|
||||
label->setPosition(winSize.width / 2, 30.f);
|
||||
label->setScale(.45f);
|
||||
label->setZOrder(99);
|
||||
label->setID("geode-small-label");
|
||||
this->addChild(label);
|
||||
|
||||
// TODO: verify loader resources on fallback?
|
||||
|
||||
Loader::get()->updateResources(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -49,6 +49,13 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
if (!self.setHookPriority("MenuLayer::init", geode::node_ids::GEODE_ID_PRIORITY)) {
|
||||
log::warn("Failed to set MenuLayer::init hook priority, node IDs may not work properly");
|
||||
}
|
||||
|
||||
if (!Loader::get()->isForwardCompatMode())
|
||||
return;
|
||||
log::warn("MenuLayer stuff disabled in forward compat");
|
||||
for (const auto& [_, hook] : self.m_hooks) {
|
||||
hook->setAutoEnable(false);
|
||||
}
|
||||
}
|
||||
|
||||
CCSprite* m_geodeButton;
|
||||
|
@ -63,7 +70,7 @@ struct CustomMenuLayer : Modify<CustomMenuLayer, MenuLayer> {
|
|||
auto winSize = CCDirector::sharedDirector()->getWinSize();
|
||||
|
||||
// add geode button
|
||||
|
||||
|
||||
m_fields->m_geodeButton = CircleButtonSprite::createWithSpriteFrameName(
|
||||
"geode-logo-outline-gold.png"_spr,
|
||||
1.0f,
|
||||
|
|
|
@ -29,9 +29,10 @@ static void __cdecl fixedErrorHandler(int code, char const* description) {
|
|||
}
|
||||
|
||||
$execute {
|
||||
(void)Mod::get()->patch(
|
||||
reinterpret_cast<void*>(geode::base::getCocos() + 0x19feec), toByteArray(&fixedErrorHandler)
|
||||
);
|
||||
// TODO: i'm pretty sure this patch only works on 2.113?
|
||||
//(void)Mod::get()->patch(
|
||||
// reinterpret_cast<void*>(geode::base::getCocos() + 0x19feec), toByteArray(&fixedErrorHandler)
|
||||
//);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,15 @@ using namespace geode::prelude;
|
|||
#include <Geode/modify/AchievementNotifier.hpp>
|
||||
|
||||
struct SceneSwitch : Modify<SceneSwitch, AchievementNotifier> {
|
||||
static void onModify(const auto& self) {
|
||||
if (!Loader::get()->isForwardCompatMode())
|
||||
return;
|
||||
log::warn("persist disabled in forward compat");
|
||||
for (const auto& [_, hook] : self.m_hooks) {
|
||||
hook->setAutoEnable(false);
|
||||
}
|
||||
}
|
||||
|
||||
void willSwitchToScene(CCScene* scene) {
|
||||
AchievementNotifier::willSwitchToScene(scene);
|
||||
SceneManager::get()->willSwitchToScene(scene);
|
||||
|
|
|
@ -5,6 +5,15 @@ using namespace geode::prelude;
|
|||
#include <Geode/modify/AppDelegate.hpp>
|
||||
|
||||
struct SaveLoader : Modify<SaveLoader, AppDelegate> {
|
||||
static void onModify(const auto& self) {
|
||||
if (!Loader::get()->isForwardCompatMode())
|
||||
return;
|
||||
log::warn("save disabled in forward compat");
|
||||
for (const auto& [_, hook] : self.m_hooks) {
|
||||
hook->setAutoEnable(false);
|
||||
}
|
||||
}
|
||||
|
||||
void trySaveGame(bool p0) {
|
||||
log::info("Saving mod data...");
|
||||
log::pushNest();
|
||||
|
|
|
@ -58,10 +58,32 @@ $execute {
|
|||
});
|
||||
}
|
||||
|
||||
void tryLogForwardCompat() {
|
||||
if (!LoaderImpl::get()->isForwardCompatMode()) return;
|
||||
log::warn("+-----------------------------------------------------------------------------------------------+");
|
||||
log::warn("| Geode is running in a newer version of GD than Geode targets. |");
|
||||
log::warn("| UI is going to be disabled, platform console is forced on and crashes can be more common. |");
|
||||
log::warn("| However, if your game crashes, it is probably caused by an outdated mod and not Geode itself. |");
|
||||
log::warn("+-----------------------------------------------------------------------------------------------+");
|
||||
}
|
||||
|
||||
int geodeEntry(void* platformData) {
|
||||
log::Logger::get()->setup();
|
||||
|
||||
log::info("Running {} {}", Mod::get()->getName(), Mod::get()->getVersion());
|
||||
std::string forwardCompatSuffix;
|
||||
if (LoaderImpl::get()->isForwardCompatMode())
|
||||
forwardCompatSuffix = " (forward compatibility mode)";
|
||||
|
||||
if (LoaderImpl::get()->getGameVersion().empty()) {
|
||||
log::info("Running {} {}{}", Mod::get()->getName(), Mod::get()->getVersion(),
|
||||
forwardCompatSuffix);
|
||||
}
|
||||
else {
|
||||
log::info("Running {} {} in Geometry Dash v{}{}", Mod::get()->getName(),
|
||||
Mod::get()->getVersion(), LoaderImpl::get()->getGameVersion(), forwardCompatSuffix);
|
||||
}
|
||||
|
||||
tryLogForwardCompat();
|
||||
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
|
@ -81,7 +103,8 @@ int geodeEntry(void* platformData) {
|
|||
}
|
||||
|
||||
// open console
|
||||
if (Mod::get()->getSettingValue<bool>("show-platform-console")) {
|
||||
if (LoaderImpl::get()->isForwardCompatMode() ||
|
||||
Mod::get()->getSettingValue<bool>("show-platform-console")) {
|
||||
log::debug("Opening console");
|
||||
Loader::get()->openPlatformConsole();
|
||||
}
|
||||
|
@ -119,5 +142,8 @@ int geodeEntry(void* platformData) {
|
|||
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
|
||||
log::info("Entry took {}s", static_cast<float>(time) / 1000.f);
|
||||
|
||||
// also log after entry so that users are more likely to notice
|
||||
tryLogForwardCompat();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,10 @@ Loader* Loader::get() {
|
|||
return g_geode;
|
||||
}
|
||||
|
||||
bool Loader::isForwardCompatMode() {
|
||||
return m_impl->isForwardCompatMode();
|
||||
}
|
||||
|
||||
void Loader::createDirectories() {
|
||||
return m_impl->createDirectories();
|
||||
}
|
||||
|
|
|
@ -37,6 +37,15 @@ Loader::Impl::~Impl() = default;
|
|||
|
||||
// Initialization
|
||||
|
||||
bool Loader::Impl::isForwardCompatMode() {
|
||||
if (!m_forwardCompatModeSet) {
|
||||
m_forwardCompatMode = !this->getGameVersion().empty() &&
|
||||
this->getGameVersion() != GEODE_STR(GEODE_GD_VERSION);
|
||||
m_forwardCompatModeSet = true;
|
||||
}
|
||||
return m_forwardCompatMode;
|
||||
}
|
||||
|
||||
void Loader::Impl::createDirectories() {
|
||||
#ifdef GEODE_IS_MACOS
|
||||
ghc::filesystem::create_directory(dirs::getSaveDir());
|
||||
|
|
|
@ -55,6 +55,10 @@ namespace geode {
|
|||
public:
|
||||
mutable std::mutex m_mutex;
|
||||
|
||||
bool m_forwardCompatModeSet = false;
|
||||
std::string m_gdVersion;
|
||||
bool m_forwardCompatMode = false;
|
||||
|
||||
std::vector<ghc::filesystem::path> m_modSearchDirectories;
|
||||
std::vector<LoadProblem> m_problems;
|
||||
std::unordered_map<std::string, Mod*> m_mods;
|
||||
|
@ -91,6 +95,9 @@ namespace geode {
|
|||
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> m_timerBegin;
|
||||
|
||||
std::string getGameVersion();
|
||||
bool isForwardCompatMode();
|
||||
|
||||
void provideNextMod(Mod* mod);
|
||||
Mod* takeNextMod();
|
||||
void releaseNextMod();
|
||||
|
|
|
@ -23,6 +23,13 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
std::string Loader::Impl::getGameVersion() {
|
||||
if (m_gdVersion.empty()) {
|
||||
// TODO: detect gd version
|
||||
}
|
||||
return m_gdVersion;
|
||||
}
|
||||
|
||||
void Loader::Impl::platformMessageBox(char const* title, std::string const& info) {
|
||||
cocos2d::CCMessageBox(info.c_str(), title);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,17 @@ using namespace geode::prelude;
|
|||
|
||||
static constexpr auto IPC_BUFFER_SIZE = 512;
|
||||
|
||||
#include "gdTimestampMap.hpp"
|
||||
std::string Loader::Impl::getGameVersion() {
|
||||
if (m_gdVersion.empty()) {
|
||||
auto dosHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(geode::base::get());
|
||||
auto ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(geode::base::get() + dosHeader->e_lfanew);
|
||||
auto timestamp = ntHeader->FileHeader.TimeDateStamp;
|
||||
m_gdVersion = timestampToVersion(timestamp);
|
||||
}
|
||||
return m_gdVersion;
|
||||
}
|
||||
|
||||
void Loader::Impl::platformMessageBox(char const* title, std::string const& info) {
|
||||
MessageBoxA(nullptr, info.c_str(), title, MB_ICONERROR);
|
||||
}
|
||||
|
|
70
loader/src/platform/windows/gdTimestampMap.hpp
Normal file
70
loader/src/platform/windows/gdTimestampMap.hpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include <map>
|
||||
|
||||
// Table originally from this gist by absolute:
|
||||
// https://gist.github.com/absoIute/ebe5da42d118109a03632c9751d86e19
|
||||
|
||||
namespace {
|
||||
// don't add versions here until Geode actually supports them,
|
||||
// this is used for toggling forward compat mode
|
||||
std::map<uint32_t, std::string>* s_gdTimestampMap = nullptr;
|
||||
std::map<std::string, uint32_t>* s_gdTimestampMapRev = nullptr;
|
||||
void tryInitializeTimestamps() {
|
||||
if (!s_gdTimestampMap) {
|
||||
s_gdTimestampMap = new std::map<uint32_t, std::string>{
|
||||
{ 1419173053, "1.900" },
|
||||
{ 1419880840, "1.910" },
|
||||
{ 1421745341, "1.920" },
|
||||
{ 1440638199, "2.000" },
|
||||
{ 1440643927, "2.001" },
|
||||
{ 1443053232, "2.010" },
|
||||
{ 1443077847, "2.011" },
|
||||
{ 1443077847, "2.020" },
|
||||
{ 1484612867, "2.100" },
|
||||
{ 1484626658, "2.101" },
|
||||
{ 1484737207, "2.102" },
|
||||
{ 1510526914, "2.110" },
|
||||
{ 1510538091, "2.111" },
|
||||
{ 1510619253, "2.112" },
|
||||
{ 1511220108, "2.113" },
|
||||
{ 1702921605, "2.200" },
|
||||
{ 1704582672, "2.201" },
|
||||
{ 1704601266, "2.202" },
|
||||
{ 1704948277, "2.203" }
|
||||
};
|
||||
}
|
||||
if (!s_gdTimestampMapRev) {
|
||||
s_gdTimestampMapRev = new std::map<std::string, uint32_t>{
|
||||
{ "1.900", 1419173053 },
|
||||
{ "1.910", 1419880840 },
|
||||
{ "1.920", 1421745341 },
|
||||
{ "2.000", 1440638199 },
|
||||
{ "2.001", 1440643927 },
|
||||
{ "2.010", 1443053232 },
|
||||
{ "2.011", 1443077847 },
|
||||
{ "2.020", 1443077847 },
|
||||
{ "2.100", 1484612867 },
|
||||
{ "2.101", 1484626658 },
|
||||
{ "2.102", 1484737207 },
|
||||
{ "2.110", 1510526914 },
|
||||
{ "2.111", 1510538091 },
|
||||
{ "2.112", 1510619253 },
|
||||
{ "2.113", 1511220108 },
|
||||
{ "2.200", 1702921605 },
|
||||
{ "2.201", 1704582672 },
|
||||
{ "2.202", 1704601266 },
|
||||
{ "2.203", 1704948277 }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string timestampToVersion(uint32_t timestamp) {
|
||||
tryInitializeTimestamps();
|
||||
return s_gdTimestampMap->contains(timestamp) ?
|
||||
s_gdTimestampMap->at(timestamp) :
|
||||
std::to_string(timestamp);
|
||||
}
|
||||
static uint32_t versionToTimestamp(const std::string& version) {
|
||||
tryInitializeTimestamps();
|
||||
return s_gdTimestampMapRev->contains(version) ? s_gdTimestampMapRev->at(version) : 0;
|
||||
}
|
|
@ -29,11 +29,28 @@ void updateGeode() {
|
|||
|
||||
void* mainTrampolineAddr;
|
||||
|
||||
#include "gdTimestampMap.hpp"
|
||||
unsigned int gdTimestamp = 0;
|
||||
|
||||
int WINAPI gdMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow) {
|
||||
// MessageBoxA(NULL, "Hello from gdMainHook!", "Hi", 0);
|
||||
|
||||
updateGeode();
|
||||
|
||||
if (versionToTimestamp(GEODE_STR(GEODE_GD_VERSION)) > gdTimestamp) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
"Unable to Load Geode!",
|
||||
fmt::format(
|
||||
"This version of Geode is made for Geometry Dash {} "
|
||||
"but you're trying to play with GD {}."
|
||||
"Please, update your game or install an older version of Geode.",
|
||||
GEODE_STR(GEODE_GD_VERSION),
|
||||
LoaderImpl::get()->getGameVersion()
|
||||
)
|
||||
);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int exitCode = geodeEntry(hInstance);
|
||||
if (exitCode != 0)
|
||||
return exitCode;
|
||||
|
@ -43,6 +60,10 @@ int WINAPI gdMainHook(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmd
|
|||
|
||||
std::string loadGeode() {
|
||||
auto process = GetCurrentProcess();
|
||||
auto dosHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(geode::base::get());
|
||||
auto ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(geode::base::get() + dosHeader->e_lfanew);
|
||||
|
||||
gdTimestamp = ntHeader->FileHeader.TimeDateStamp;
|
||||
|
||||
constexpr size_t trampolineSize = 12;
|
||||
mainTrampolineAddr = VirtualAlloc(
|
||||
|
@ -50,8 +71,6 @@ std::string loadGeode() {
|
|||
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE
|
||||
);
|
||||
|
||||
auto dosHeader = reinterpret_cast<IMAGE_DOS_HEADER*>(geode::base::get());
|
||||
auto ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(geode::base::get() + dosHeader->e_lfanew);
|
||||
auto entryAddr = geode::base::get() + ntHeader->OptionalHeader.AddressOfEntryPoint;
|
||||
// function that calls main
|
||||
auto preWinMainAddr = entryAddr + 5 + *reinterpret_cast<uintptr_t*>(entryAddr + 6) + 5;
|
||||
|
@ -126,37 +145,6 @@ void earlyError(std::string message) {
|
|||
LoaderImpl::get()->platformMessageBox("Unable to Load Geode!", message);
|
||||
}
|
||||
|
||||
DWORD WINAPI sus(void*) {
|
||||
ShellExecuteA(nullptr, nullptr, "https://media.tenor.com/cW1jA2hYdfcAAAAC/among-us-funny.gif", nullptr, nullptr, SW_SHOW);
|
||||
MessageBoxA(
|
||||
nullptr,
|
||||
"Red sus. Red suuuus. I\r\n"
|
||||
"said red, sus,\r\n"
|
||||
"hahahahahaha. Why\r\n"
|
||||
"arent you laughing? I\r\n"
|
||||
"just made a reference\r\n"
|
||||
"to the popular game\r\n"
|
||||
"\"Among Us\"! How can\r\n"
|
||||
"you not laugh at it?\r\n"
|
||||
"Emergency meeting!\r\n"
|
||||
"Guys, this here guy\r\n"
|
||||
"doesn't laugh at my\r\n"
|
||||
"funny Among Us\r\n"
|
||||
"memes! Let's beat him\r\n"
|
||||
"to death! Dead body\r\n"
|
||||
"reported! Skip! Skip!\r\n"
|
||||
"Vote blue! Blue was\r\n"
|
||||
"not an impostor.\r\n",
|
||||
"AMONG US ACTIVATED REAL !!!!!!!!!",
|
||||
MB_OK
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
extern "C" __declspec(dllexport) void fake() {
|
||||
for (int i = 0; i < 5; i++)
|
||||
CreateThread(nullptr, 0, sus, nullptr, 0, nullptr);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE module, DWORD reason, LPVOID) {
|
||||
if (reason != DLL_PROCESS_ATTACH)
|
||||
return TRUE;
|
||||
|
|
|
@ -388,6 +388,15 @@ void geode::cocos::reloadTextures(CreateLayerFunc returnTo) {
|
|||
}
|
||||
|
||||
struct LoadingFinished : Modify<LoadingFinished, LoadingLayer> {
|
||||
static void onModify(const auto& self) {
|
||||
if (!Loader::get()->isForwardCompatMode())
|
||||
return;
|
||||
log::warn("geode::cocos::reloadTextures disabled in forward compat");
|
||||
for (const auto& [_, hook] : self.m_hooks) {
|
||||
hook->setAutoEnable(false);
|
||||
}
|
||||
}
|
||||
|
||||
void loadAssets() {
|
||||
// loadFinished is inlined on Macchew OS :sob:
|
||||
|
||||
|
|
Loading…
Reference in a new issue