DevourUnlocker/src/config.cpp
MiTHRAL 4af18a2f75
Some checks are pending
Build DevourUnlocker / windows-cross (push) Waiting to run
Build DevourUnlocker / linux (push) Waiting to run
Build DevourUnlocker / standalone (push) Waiting to run
v2.0.1: expand to all item types + fix pets + linux CI
- Config: add allPets (Crow/Pig/Goat/Rat/Spider/Cat/Pug), allPerks (29 inc Acceleration/Quartermaster etc), flashlights/emotes/outfits; unlockOutfits global
- Resolver: resolve HasPerk/HasPet/UpdateLocked* for Pets/Perks/Flashlights/Emotes/Outfits/Robes
- Patches: hook IsRobe/IsCharacter + HasPerk/HasOutfit + UpdateLockedPets/Perks/Flashlights/Emotes/Outfits/Robes bypass — fixes pets not unlocking
- GUI: 7 tabs (Robes/Chars/Perks/Pets/Flashlights/Emotes/Outfits), Unlock All covers all categories
- Standalone: --perks/--pets/--all now covers all categories, petOverrides etc, list shows 30 robes+9 chars+29 perks+7 pets+8 flashlights+12 emotes+8 outfits
- GUI standalone: 7 notebooks with per-category checkboxes
- BepInEx: add UpdateLocked* prefix patches + HasPerk/HasOutfit, GUI tabs for all
- CI: switch windows-latest to ubuntu-latest mingw cross (git.mithraic.cloud has only linux runner, windows jobs were stuck Waiting)
2026-08-21 21:15:58 -04:00

106 lines
4.1 KiB
C++

#include "config.hpp"
#include <fstream>
#include <filesystem>
#ifdef _WIN32
#include <Windows.h>
#endif
namespace devour {
static UnlockConfig g_config;
UnlockConfig& Config::get() { return g_config; }
std::string Config::defaultPath() {
#ifdef _WIN32
char buf[MAX_PATH]{};
if (GetModuleFileNameA(nullptr, buf, MAX_PATH)) {
std::filesystem::path exe(buf);
return (exe.parent_path() / "DevourUnlocker.json").string();
}
#endif
return "DevourUnlocker.json";
}
std::vector<std::string> Config::allRobes() {
return {
"StraightJacket","Patchwork","CherryBlossom","Eggs","Poison","Web",
"TownHard","TownNightmare","TownBooks","Horseshoes",
"SlaughterhouseHard","SlaughterhouseNightmare","SlaughterhousePigs","BarbedWires",
"Golden","ManorHard","ManorNightmare","ManorHeadsBuried","Feathers",
"CarnivalHard","CarnivalNightmare","CarnivalDollHeads","Tickets",
"Rose","Fire","Inmate","Electric","BlackWithGoldTrim","Hard","Nightmare"
};
}
std::vector<std::string> Config::allCharacters() {
return {"Molly","Nathan","Sam","Zara","Cultist","Kai","Anna","April","Frank"};
}
std::vector<std::string> Config::allPerks() {
return {
"Acceleration","Aftershock","Conservationist","Crawler","DuracellBunny","Evader",
"FastWorker","FieldMedic","FirstResponder","FullyCharged","Immune","Inspired",
"Keymaster","LongSighted","Patient","PowerfulInsight","Quartermaster","Regeneration",
"Repellent","Speedy","SpeedWalker","StayBack","SupplyRunner","Tamed","Teamwork",
"TeamLeader","Trapper","UnderPressure","CrawlerVent","ConservationistHard","PatientHard",
"RegenerationHard"
};
}
std::vector<std::string> Config::allPets() {
return {"Crow","Pig","Goat","Rat","Spider","Cat","Pug"};
}
std::vector<std::string> Config::allFlashlights() {
return {"Basic","UV","Battery","Gold","Carnival","Manor","Hospital","Infinity"};
}
std::vector<std::string> Config::allEmotes() {
return {"Wave","Dance","Sit","Point","Laugh","Cry","Angry","Cheer","Clap","Taunt","Shrug","Bow"};
}
std::vector<std::string> Config::allOutfits() {
return {"Default","Formal","Casual","Winter","Summer","Anniversary","Hard","Nightmare"};
}
bool Config::load(const std::string& path) {
std::ifstream f(path);
if (!f) return false;
std::string content((std::istreambuf_iterator<char>(f)), {});
// Minimal JSON parse — avoid nlohmann dep for portability
auto has = [&](const char* key, bool def) -> bool {
auto pos = content.find(std::string("\"") + key + "\"");
if (pos == std::string::npos) return def;
auto colon = content.find(':', pos);
if (colon == std::string::npos) return def;
auto v = content.substr(colon+1, 20);
if (v.find("true") != std::string::npos) return true;
if (v.find("false") != std::string::npos) return false;
return def;
};
g_config.unlockRobes = has("unlockRobes", true);
g_config.unlockCharacters = has("unlockCharacters", true);
g_config.unlockPerks = has("unlockPerks", true);
g_config.unlockFlashlights = has("unlockFlashlights", true);
g_config.unlockEmotes = has("unlockEmotes", true);
g_config.unlockPets = has("unlockPets", true);
g_config.unlockOutfits = has("unlockOutfits", true);
g_config.guiVisible = has("guiVisible", true);
return true;
}
bool Config::save(const std::string& path) {
std::ofstream f(path);
if (!f) return false;
auto& c = g_config;
f << "{\n";
f << " \"unlockRobes\": " << (c.unlockRobes?"true":"false") << ",\n";
f << " \"unlockCharacters\": " << (c.unlockCharacters?"true":"false") << ",\n";
f << " \"unlockPerks\": " << (c.unlockPerks?"true":"false") << ",\n";
f << " \"unlockFlashlights\": " << (c.unlockFlashlights?"true":"false") << ",\n";
f << " \"unlockEmotes\": " << (c.unlockEmotes?"true":"false") << ",\n";
f << " \"unlockPets\": " << (c.unlockPets?"true":"false") << ",\n";
f << " \"unlockOutfits\": " << (c.unlockOutfits?"true":"false") << ",\n";
f << " \"guiVisible\": " << (c.guiVisible?"true":"false") << "\n";
f << "}\n";
return true;
}
} // namespace devour