mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-14 19:15:05 -05:00
Merge branch 'main' into 1.4.0-dev
This commit is contained in:
commit
d5027ca6ab
15 changed files with 226 additions and 105 deletions
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
|
@ -2,6 +2,7 @@ name: Build Binaries
|
|||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- '**' # every branch
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -72,3 +72,6 @@ test-docs.bat
|
|||
|
||||
# Ignore krita files too because we don't want our project files shaking my head
|
||||
**/*.kra
|
||||
|
||||
# Ignore clangd cache
|
||||
.cache
|
||||
|
|
|
@ -3018,6 +3018,9 @@ class GameLevelManager : cocos2d::CCNode {
|
|||
void storeUserName(int userID, int accountID, gd::string str) = mac 0x2B9020, win 0xa1a70;
|
||||
gd::string userNameForUserID(int id) = mac 0x2B91D0, win 0xa1c20;
|
||||
void updateUserScore() = mac 0x2CB6A0, win 0xada60;
|
||||
void uploadAccountComment(gd::string text) = win 0xb3250;
|
||||
void uploadLevelComment(int levelID, gd::string text, int unk) = win 0xb31c0;
|
||||
void uploadComment(gd::string text, CommentType type, int levelID, int unk) = win 0xb32e0;
|
||||
void downloadLevel(int id, bool downloadData) = win 0xaa730;
|
||||
bool hasDownloadedLevel(int id) = win 0xab830;
|
||||
GJGameLevel* getSavedLevel(int id) = win 0xa2ee0;
|
||||
|
@ -3489,6 +3492,13 @@ class GameObject : CCSpritePlus {
|
|||
void loadGroupsFromString(gd::string str) = mac 0x33b380, win 0xebcb0;
|
||||
static GameObject* objectFromString(gd::string, bool) = mac 0x33b720, win 0xebe50;
|
||||
void playShineEffect() = mac 0x2fa9d0, win 0xeab20;
|
||||
bool canRotateFree() {
|
||||
return (
|
||||
m_objectType != GameObjectType::Solid &&
|
||||
m_objectType != GameObjectType::Breakable &&
|
||||
m_objectType != GameObjectType::Slope
|
||||
);
|
||||
}
|
||||
//void quickUpdatePosition() = mac 0x335790;
|
||||
// inlined on windows
|
||||
void quickUpdatePosition() {
|
||||
|
@ -4247,7 +4257,7 @@ class LevelInfoLayer : cocos2d::CCLayer, LevelDownloadDelegate, LevelUpdateDeleg
|
|||
void downloadLevel() = win 0x177d90, mac 0x161b90;
|
||||
void onPlay(cocos2d::CCObject* sender) = mac 0x161840, win 0x179730;
|
||||
void onBack(cocos2d::CCObject* sender) = mac 0x163810, win 0x17C110;
|
||||
void onDelete(cocos2d::CCObject* sender) = mac 0x162f30, win 0x17A2B0;
|
||||
void onDelete(cocos2d::CCObject* sender) = mac 0x162f30, win 0x17a1b0;
|
||||
|
||||
virtual void levelDownloadFinished(GJGameLevel*) = mac 0x164C00, win 0x1790C0;
|
||||
virtual void levelUpdateFinished(GJGameLevel*, UpdateResponse) = mac 0x164E60, win 0x1792B0;
|
||||
|
@ -5795,6 +5805,13 @@ class SetupTouchTogglePopup : FLAlertLayer {
|
|||
void updateTargetID() = mac 0x159480;
|
||||
}
|
||||
|
||||
[[link(android)]]
|
||||
class ShareCommentLayer : FLAlertLayer, TextInputDelegate, UploadActionDelegate, UploadPopupDelegate {
|
||||
static ShareCommentLayer* create(gd::string, int, CommentType, int) = win 0x24bac0;
|
||||
bool init(gd::string, int, CommentType, int) = win 0x24bb90;
|
||||
void onShare(CCObject*) = win 0x24c760;
|
||||
}
|
||||
|
||||
[[link(android)]]
|
||||
class SimplePlayer : cocos2d::CCSprite {
|
||||
SimplePlayer() {}
|
||||
|
|
|
@ -51,6 +51,10 @@ elseif (GEODE_TARGET_PLATFORM STREQUAL "MacOS")
|
|||
${GEODE_LOADER_PATH}/include/link/libfmod.dylib
|
||||
)
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} INTERFACE
|
||||
-DCommentType=CommentTypeDummy
|
||||
)
|
||||
|
||||
set(GEODE_PLATFORM_BINARY "Geode.dylib")
|
||||
|
||||
elseif (GEODE_TARGET_PLATFORM STREQUAL "Win32")
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "DefaultInclude.hpp"
|
||||
|
||||
// thanks pie
|
||||
enum class SearchType {
|
||||
Search = 0,
|
||||
|
@ -54,6 +56,7 @@ enum class GameObjectType {
|
|||
MiniSizePortal = 18,
|
||||
UfoPortal = 19,
|
||||
Modifier = 20,
|
||||
Breakable = 21,
|
||||
SecretCoin = 22,
|
||||
DualPortal = 23,
|
||||
SoloPortal = 24,
|
||||
|
@ -109,6 +112,16 @@ enum class CommentError {
|
|||
enum class BackupAccountError {
|
||||
};
|
||||
|
||||
// Thanks cocoa!
|
||||
#ifdef GEODE_IS_MACOS
|
||||
#undef CommentType
|
||||
#endif
|
||||
|
||||
enum class CommentType {
|
||||
Level = 0,
|
||||
Account = 1,
|
||||
};
|
||||
|
||||
enum class BoomListType {
|
||||
Default = 0x0,
|
||||
User = 0x2,
|
||||
|
|
|
@ -64,6 +64,7 @@ namespace geode {
|
|||
|
||||
public:
|
||||
// TODO: do we want to expose all of these functions?
|
||||
|
||||
static Loader* get();
|
||||
|
||||
enum class LoadingState : uint8_t {
|
||||
|
@ -77,6 +78,7 @@ namespace geode {
|
|||
Done
|
||||
};
|
||||
|
||||
// TODO: return void
|
||||
Result<> saveData();
|
||||
Result<> loadData();
|
||||
|
||||
|
|
|
@ -6,14 +6,18 @@ using namespace geode::prelude;
|
|||
|
||||
struct SaveLoader : Modify<SaveLoader, AppDelegate> {
|
||||
void trySaveGame() {
|
||||
log::info("Saving...");
|
||||
log::info("Saving mod data...");
|
||||
log::pushNest();
|
||||
|
||||
auto r = Loader::get()->saveData();
|
||||
if (!r) {
|
||||
log::info("{}", r.unwrapErr());
|
||||
}
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
log::info("Saved");
|
||||
(void)Loader::get()->saveData();
|
||||
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
|
||||
log::info("Took {}s", static_cast<float>(time) / 1000.f);
|
||||
|
||||
log::popNest();
|
||||
|
||||
return AppDelegate::trySaveGame();
|
||||
}
|
||||
|
|
|
@ -58,8 +58,17 @@ $execute {
|
|||
}
|
||||
|
||||
int geodeEntry(void* platformData) {
|
||||
log::Logger::setup();
|
||||
|
||||
log::info("Entry");
|
||||
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
// set up internal mod, settings and data
|
||||
log::info("Setting up internal mod");
|
||||
log::pushNest();
|
||||
auto internalSetupRes = LoaderImpl::get()->setupInternalMod();
|
||||
log::popNest();
|
||||
if (!internalSetupRes) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
"Unable to Load Geode!",
|
||||
|
@ -72,16 +81,20 @@ int geodeEntry(void* platformData) {
|
|||
|
||||
// open console
|
||||
if (Mod::get()->getSettingValue<bool>("show-platform-console")) {
|
||||
log::debug("Opening console");
|
||||
Loader::get()->openPlatformConsole();
|
||||
}
|
||||
|
||||
// set up loader, load mods, etc.
|
||||
log::info("Setting up loader");
|
||||
log::pushNest();
|
||||
auto setupRes = LoaderImpl::get()->setup();
|
||||
log::popNest();
|
||||
if (!setupRes) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
"Unable to Load Geode!",
|
||||
"There was an unknown fatal error setting up "
|
||||
"the loader and Geode can not be loaded. "
|
||||
"the loader and Geode can not be loaded. "
|
||||
"(" + setupRes.unwrapErr() + ")"
|
||||
);
|
||||
LoaderImpl::get()->forceReset();
|
||||
|
@ -94,10 +107,16 @@ int geodeEntry(void* platformData) {
|
|||
|
||||
// download and install new loader update in the background
|
||||
if (Mod::get()->getSettingValue<bool>("auto-check-updates")) {
|
||||
log::info("Starting loader update check");
|
||||
LoaderImpl::get()->checkForLoaderUpdates();
|
||||
}
|
||||
else {
|
||||
log::info("Skipped loader update check");
|
||||
}
|
||||
|
||||
log::debug("Entry done.");
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
auto time = std::chrono::duration_cast<std::chrono::milliseconds>(end - begin).count();
|
||||
log::info("Entry took {}s", static_cast<float>(time) / 1000.f);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -44,28 +44,35 @@ tulip::hook::HookMetadata Hook::Impl::getHookMetadata() const {
|
|||
}
|
||||
|
||||
Result<> Hook::Impl::enable() {
|
||||
if (!m_enabled) {
|
||||
if (!LoaderImpl::get()->hasHandler(m_address)) {
|
||||
GEODE_UNWRAP(LoaderImpl::get()->createHandler(m_address, m_handlerMetadata));
|
||||
}
|
||||
GEODE_UNWRAP_INTO(auto handler, LoaderImpl::get()->getHandler(m_address));
|
||||
if (m_enabled)
|
||||
return Ok();
|
||||
|
||||
m_handle = tulip::hook::createHook(handler, m_detour, m_hookMetadata);
|
||||
log::debug("Enabling hook at function {} with address {}", m_displayName, m_address);
|
||||
m_enabled = true;
|
||||
if (!LoaderImpl::get()->hasHandler(m_address)) {
|
||||
GEODE_UNWRAP(LoaderImpl::get()->createHandler(m_address, m_handlerMetadata));
|
||||
}
|
||||
GEODE_UNWRAP_INTO(auto handler, LoaderImpl::get()->getHandler(m_address));
|
||||
|
||||
m_handle = tulip::hook::createHook(handler, m_detour, m_hookMetadata);
|
||||
if (m_owner)
|
||||
log::debug("Enabled {} hook at {} for {}", m_displayName, m_address, m_owner->getID());
|
||||
else
|
||||
log::debug("Enabled {} hook at {}", m_displayName, m_address);
|
||||
|
||||
m_enabled = true;
|
||||
return Ok();
|
||||
}
|
||||
|
||||
Result<> Hook::Impl::disable() {
|
||||
if (m_enabled) {
|
||||
GEODE_UNWRAP_INTO(auto handler, LoaderImpl::get()->getHandler(m_address));
|
||||
if (!m_enabled)
|
||||
return Ok();
|
||||
|
||||
tulip::hook::removeHook(handler, m_handle);
|
||||
GEODE_UNWRAP_INTO(auto handler, LoaderImpl::get()->getHandler(m_address));
|
||||
|
||||
log::debug("Disabling hook at function {}", m_displayName);
|
||||
m_enabled = false;
|
||||
}
|
||||
tulip::hook::removeHook(handler, m_handle);
|
||||
|
||||
log::debug("Disabled {} hook", m_displayName);
|
||||
|
||||
m_enabled = false;
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
@ -101,4 +108,4 @@ bool Hook::Impl::getAutoEnable() const {
|
|||
|
||||
void Hook::Impl::setAutoEnable(bool autoEnable) {
|
||||
m_autoEnable = autoEnable;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -403,6 +403,8 @@ void Index::Impl::checkForUpdates() {
|
|||
|
||||
void Index::Impl::updateFromLocalTree() {
|
||||
log::debug("Updating local index cache");
|
||||
log::pushNest();
|
||||
|
||||
IndexUpdateEvent(UpdateProgress(100, "Updating local cache")).post();
|
||||
// delete old items
|
||||
m_items.clear();
|
||||
|
@ -442,6 +444,8 @@ void Index::Impl::updateFromLocalTree() {
|
|||
// mark source as finished
|
||||
m_isUpToDate = true;
|
||||
IndexUpdateEvent(UpdateFinished()).post();
|
||||
|
||||
log::popNest();
|
||||
}
|
||||
|
||||
void Index::update(bool force) {
|
||||
|
|
|
@ -58,33 +58,30 @@ Result<> Loader::Impl::setup() {
|
|||
return Ok();
|
||||
}
|
||||
|
||||
log::Logger::setup();
|
||||
|
||||
if (crashlog::setupPlatformHandler()) {
|
||||
log::debug("Set up platform crash logger");
|
||||
}
|
||||
else {
|
||||
log::debug("Unable to set up platform crash logger");
|
||||
log::debug("Setting up crash handler");
|
||||
log::pushNest();
|
||||
if (!crashlog::setupPlatformHandler()) {
|
||||
log::debug("Failed to set up crash handler");
|
||||
}
|
||||
log::popNest();
|
||||
|
||||
log::debug("Setting up Loader...");
|
||||
|
||||
log::debug("Set up internal mod representation");
|
||||
log::debug("Loading hooks... ");
|
||||
|
||||
log::debug("Loading hooks");
|
||||
log::pushNest();
|
||||
if (!this->loadHooks()) {
|
||||
return Err("There were errors loading some hooks, see console for details");
|
||||
}
|
||||
log::popNest();
|
||||
|
||||
log::debug("Loaded hooks");
|
||||
|
||||
log::debug("Setting up IPC...");
|
||||
|
||||
log::debug("Setting up IPC");
|
||||
log::pushNest();
|
||||
this->setupIPC();
|
||||
log::popNest();
|
||||
|
||||
log::debug("Setting up directories");
|
||||
log::pushNest();
|
||||
this->createDirectories();
|
||||
|
||||
this->addSearchPaths();
|
||||
log::popNest();
|
||||
|
||||
this->refreshModGraph();
|
||||
|
||||
|
@ -104,14 +101,14 @@ void Loader::Impl::updateResources() {
|
|||
|
||||
void Loader::Impl::updateResources(bool forceReload) {
|
||||
log::debug("Adding resources");
|
||||
|
||||
// add mods' spritesheets
|
||||
log::pushNest();
|
||||
for (auto const& [_, mod] : m_mods) {
|
||||
if (forceReload || !ModImpl::getImpl(mod)->m_resourcesLoaded) {
|
||||
this->updateModResources(mod);
|
||||
ModImpl::getImpl(mod)->m_resourcesLoaded = true;
|
||||
}
|
||||
if (!forceReload && ModImpl::getImpl(mod)->m_resourcesLoaded)
|
||||
continue;
|
||||
this->updateModResources(mod);
|
||||
ModImpl::getImpl(mod)->m_resourcesLoaded = true;
|
||||
}
|
||||
log::popNest();
|
||||
}
|
||||
|
||||
std::vector<Mod*> Loader::Impl::getAllMods() {
|
||||
|
@ -161,25 +158,27 @@ bool Loader::Impl::isModVersionSupported(VersionInfo const& version) {
|
|||
// Data saving
|
||||
|
||||
Result<> Loader::Impl::saveData() {
|
||||
// save mods' data
|
||||
for (auto& [id, mod] : m_mods) {
|
||||
log::debug("{}", mod->getID());
|
||||
log::pushNest();
|
||||
auto r = mod->saveData();
|
||||
if (!r) {
|
||||
log::warn("Unable to save data for mod \"{}\": {}", mod->getID(), r.unwrapErr());
|
||||
}
|
||||
log::popNest();
|
||||
}
|
||||
// save loader data
|
||||
GEODE_UNWRAP(Mod::get()->saveData());
|
||||
|
||||
return Ok();
|
||||
}
|
||||
|
||||
Result<> Loader::Impl::loadData() {
|
||||
for (auto& [_, mod] : m_mods) {
|
||||
log::debug("{}", mod->getID());
|
||||
log::pushNest();
|
||||
auto r = mod->loadData();
|
||||
if (!r) {
|
||||
log::warn("Unable to load data for mod \"{}\": {}", mod->getID(), r.unwrapErr());
|
||||
}
|
||||
log::popNest();
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
@ -222,9 +221,9 @@ void Loader::Impl::updateModResources(Mod* mod) {
|
|||
if (mod->getMetadata().getSpritesheets().empty())
|
||||
return;
|
||||
|
||||
log::debug("Adding resources for {}", mod->getID());
|
||||
log::debug("{}", mod->getID());
|
||||
log::pushNest();
|
||||
|
||||
// add spritesheets
|
||||
for (auto const& sheet : mod->getMetadata().getSpritesheets()) {
|
||||
log::debug("Adding sheet {}", sheet);
|
||||
auto png = sheet + ".png";
|
||||
|
@ -243,6 +242,8 @@ void Loader::Impl::updateModResources(Mod* mod) {
|
|||
CCSpriteFrameCache::get()->addSpriteFramesWithFile(plist.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
log::popNest();
|
||||
}
|
||||
|
||||
// Dependencies and refreshing
|
||||
|
@ -432,6 +433,9 @@ void Loader::Impl::loadModGraph(Mod* node, bool early) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (node->getID() == "absolllute.megahack")
|
||||
log::debug("megahack creepypasta");
|
||||
|
||||
for (auto const& dep : node->m_impl->m_dependants) {
|
||||
m_modsToLoad.push_front(dep);
|
||||
}
|
||||
|
@ -564,17 +568,17 @@ void Loader::Impl::findProblems() {
|
|||
}
|
||||
|
||||
void Loader::Impl::refreshModGraph() {
|
||||
log::info("Refreshing mod graph...");
|
||||
log::info("Refreshing mod graph");
|
||||
log::pushNest();
|
||||
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (m_isSetup) {
|
||||
log::error("Cannot refresh mod graph after startup");
|
||||
log::popNest();
|
||||
return;
|
||||
}
|
||||
|
||||
auto begin = std::chrono::high_resolution_clock::now();
|
||||
|
||||
m_problems.clear();
|
||||
|
||||
m_loadingState = LoadingState::Queue;
|
||||
|
@ -707,23 +711,22 @@ bool Loader::Impl::isReadyToHook() const {
|
|||
return m_readyToHook;
|
||||
}
|
||||
|
||||
void Loader::Impl::addInternalHook(Hook* hook, Mod* mod) {
|
||||
m_internalHooks.emplace_back(hook, mod);
|
||||
void Loader::Impl::addUninitializedHook(Hook* hook, Mod* mod) {
|
||||
m_uninitializedHooks.emplace_back(hook, mod);
|
||||
}
|
||||
|
||||
bool Loader::Impl::loadHooks() {
|
||||
m_readyToHook = true;
|
||||
auto thereWereErrors = false;
|
||||
for (auto const& hook : m_internalHooks) {
|
||||
bool hadErrors = false;
|
||||
for (auto const& hook : m_uninitializedHooks) {
|
||||
auto res = hook.second->addHook(hook.first);
|
||||
if (!res) {
|
||||
log::internalLog(Severity::Error, hook.second, "{}", res.unwrapErr());
|
||||
thereWereErrors = true;
|
||||
hadErrors = true;
|
||||
}
|
||||
}
|
||||
// free up memory
|
||||
m_internalHooks.clear();
|
||||
return !thereWereErrors;
|
||||
m_uninitializedHooks.clear();
|
||||
return !hadErrors;
|
||||
}
|
||||
|
||||
void Loader::Impl::queueInMainThread(ScheduledFunction func) {
|
||||
|
@ -1103,21 +1106,16 @@ void Loader::Impl::provideNextMod(Mod* mod) {
|
|||
}
|
||||
|
||||
Mod* Loader::Impl::takeNextMod() {
|
||||
if (!m_nextMod) {
|
||||
m_nextMod = this->createInternalMod();
|
||||
log::debug("Created internal mod {}", m_nextMod->getName());
|
||||
}
|
||||
auto ret = m_nextMod;
|
||||
return ret;
|
||||
if (!m_nextMod)
|
||||
m_nextMod = this->getInternalMod();
|
||||
return m_nextMod;
|
||||
}
|
||||
|
||||
void Loader::Impl::releaseNextMod() {
|
||||
m_nextMod = nullptr;
|
||||
|
||||
m_nextModLock.unlock();
|
||||
}
|
||||
|
||||
|
||||
Result<> Loader::Impl::createHandler(void* address, tulip::hook::HandlerMetadata const& metadata) {
|
||||
if (m_handlerHandles.count(address)) {
|
||||
return Err("Handler already exists at address");
|
||||
|
|
|
@ -71,7 +71,8 @@ namespace geode {
|
|||
|
||||
std::vector<utils::MiniFunction<void(void)>> m_gdThreadQueue;
|
||||
mutable std::mutex m_gdThreadMutex;
|
||||
std::vector<std::pair<Hook*, Mod*>> m_internalHooks;
|
||||
bool m_platformConsoleOpen = false;
|
||||
std::vector<std::pair<Hook*, Mod*>> m_uninitializedHooks;
|
||||
bool m_readyToHook = false;
|
||||
|
||||
bool m_platformConsoleOpen = false;
|
||||
|
@ -183,9 +184,9 @@ namespace geode {
|
|||
bool isNewUpdateDownloaded() const;
|
||||
|
||||
bool isReadyToHook() const;
|
||||
void addInternalHook(Hook* hook, Mod* mod);
|
||||
void addUninitializedHook(Hook* hook, Mod* mod);
|
||||
|
||||
Mod* createInternalMod();
|
||||
Mod* getInternalMod();
|
||||
Result<> setupInternalMod();
|
||||
|
||||
bool userTriedToLoadDLLs() const;
|
||||
|
|
|
@ -113,6 +113,36 @@ std::string Log::toString(bool logTime, uint32_t nestLevel) const {
|
|||
res += fmt::format("{:%H:%M:%S}", m_time);
|
||||
}
|
||||
|
||||
switch (m_severity.m_value) {
|
||||
case Severity::Debug:
|
||||
res += " DBG";
|
||||
break;
|
||||
case Severity::Info:
|
||||
res += " INF";
|
||||
break;
|
||||
case Severity::Notice:
|
||||
res += " NTC";
|
||||
break;
|
||||
case Severity::Warning:
|
||||
res += " WRN";
|
||||
break;
|
||||
case Severity::Error:
|
||||
res += " ERR";
|
||||
break;
|
||||
case Severity::Critical:
|
||||
res += " CRT";
|
||||
break;
|
||||
case Severity::Alert:
|
||||
res += " ALR";
|
||||
break;
|
||||
case Severity::Emergency:
|
||||
res += " FAT";
|
||||
break;
|
||||
default:
|
||||
res += " UNK";
|
||||
break;
|
||||
}
|
||||
|
||||
res += fmt::format(" [{}]: ", m_sender ? m_sender->getName() : "Geode?");
|
||||
|
||||
for (uint32_t i = 0; i < nestLevel; i++) {
|
||||
|
|
|
@ -226,7 +226,7 @@ Result<> Mod::Impl::saveData() {
|
|||
log::debug("Check covered");
|
||||
for (auto& [key, value] : m_savedSettingsData.as_object()) {
|
||||
log::debug("Check if {} is saved", key);
|
||||
if (!coveredSettings.count(key)) {
|
||||
if (!coveredSettings.contains(key)) {
|
||||
json[key] = value;
|
||||
}
|
||||
}
|
||||
|
@ -485,18 +485,21 @@ Result<> Mod::Impl::disableHook(Hook* hook) {
|
|||
}
|
||||
|
||||
Result<Hook*> Mod::Impl::addHook(Hook* hook) {
|
||||
m_hooks.push_back(hook);
|
||||
if (LoaderImpl::get()->isReadyToHook()) {
|
||||
if (this->isEnabled() && hook->getAutoEnable()) {
|
||||
auto res = this->enableHook(hook);
|
||||
if (!res) {
|
||||
delete hook;
|
||||
return Err("Can't create hook: "+ res.unwrapErr());
|
||||
}
|
||||
}
|
||||
if (!ranges::contains(m_hooks, [&](auto const& h) { return h == hook; }))
|
||||
m_hooks.push_back(hook);
|
||||
|
||||
if (!LoaderImpl::get()->isReadyToHook()) {
|
||||
LoaderImpl::get()->addUninitializedHook(hook, m_self);
|
||||
return Ok(hook);
|
||||
}
|
||||
else {
|
||||
LoaderImpl::get()->addInternalHook(hook, m_self);
|
||||
|
||||
if (!this->isEnabled() || !hook->getAutoEnable())
|
||||
return Ok(hook);
|
||||
|
||||
auto res = this->enableHook(hook);
|
||||
if (!res) {
|
||||
delete hook;
|
||||
return Err("Can't create hook: " + res.unwrapErr());
|
||||
}
|
||||
|
||||
return Ok(hook);
|
||||
|
@ -683,9 +686,10 @@ static Result<ModMetadata> getModImplInfo() {
|
|||
return Ok(info);
|
||||
}
|
||||
|
||||
Mod* Loader::Impl::createInternalMod() {
|
||||
Mod* Loader::Impl::getInternalMod() {
|
||||
auto& mod = Mod::sharedMod<>;
|
||||
if (mod) return mod;
|
||||
if (mod)
|
||||
return mod;
|
||||
auto infoRes = getModImplInfo();
|
||||
if (!infoRes) {
|
||||
LoaderImpl::get()->platformMessageBox(
|
||||
|
@ -702,6 +706,7 @@ Mod* Loader::Impl::createInternalMod() {
|
|||
}
|
||||
mod->m_impl->m_enabled = true;
|
||||
m_mods.insert({ mod->getID(), mod });
|
||||
log::debug("Created internal mod {}", mod->getName());
|
||||
return mod;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,24 +20,37 @@ void Loader::Impl::platformMessageBox(char const* title, std::string const& info
|
|||
bool hasAnsiColorSupport = false;
|
||||
|
||||
void Loader::Impl::logConsoleMessageWithSeverity(std::string const& msg, Severity severity) {
|
||||
if (m_platformConsoleOpen) {
|
||||
if (hasAnsiColorSupport) {
|
||||
int color = 0;
|
||||
switch (severity) {
|
||||
case Severity::Debug: color = 243; break;
|
||||
case Severity::Info: color = 33; break;
|
||||
case Severity::Warning: color = 229; break;
|
||||
case Severity::Error: color = 9; break;
|
||||
default: color = 7; break;
|
||||
}
|
||||
auto const colorStr = fmt::format("\x1b[38;5;{}m", color);
|
||||
auto const newMsg = fmt::format("{}{}\x1b[0m{}", colorStr, msg.substr(0, 8), msg.substr(8));
|
||||
if (!m_platformConsoleOpen)
|
||||
return;
|
||||
|
||||
std::cout << newMsg << "\n" << std::flush;
|
||||
} else {
|
||||
std::cout << msg << "\n" << std::flush;
|
||||
}
|
||||
if (!hasAnsiColorSupport) {
|
||||
std::cout << msg << "\n" << std::flush;
|
||||
return;
|
||||
}
|
||||
|
||||
int color = 0;
|
||||
switch (severity) {
|
||||
case Severity::Debug:
|
||||
color = 243;
|
||||
break;
|
||||
case Severity::Info:
|
||||
color = 33;
|
||||
break;
|
||||
case Severity::Warning:
|
||||
color = 229;
|
||||
break;
|
||||
case Severity::Error:
|
||||
color = 9;
|
||||
break;
|
||||
default:
|
||||
color = 7;
|
||||
break;
|
||||
}
|
||||
auto const colorStr = fmt::format("\x1b[38;5;{}m", color);
|
||||
auto const newMsg = fmt::format("{}{}\x1b[0m{}", colorStr, msg.substr(0, 12),
|
||||
msg.substr(12));
|
||||
|
||||
std::cout << newMsg << "\n" << std::flush;
|
||||
}
|
||||
|
||||
void Loader::Impl::openPlatformConsole() {
|
||||
|
|
Loading…
Reference in a new issue