Skip to content

Commit 28b203f

Browse files
committed
xd
1 parent 832993b commit 28b203f

2 files changed

Lines changed: 118 additions & 21 deletions

File tree

mod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"mac": "2.2081",
88
"ios": "2.2081"
99
},
10-
"version": "v1.0.0-beta.3",
10+
"version": "v1.0.0-beta.4",
1111
"id": "lil2kki.main-levels-config",
1212
"name": "Main Levels Config",
1313
"developers": [ "lil2kki" ],

src/main.cpp

Lines changed: 117 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,107 @@ std::string escENC(std::string str) {
1717
return matjson::Value(str).dump().c_str();
1818
}
1919

20+
namespace FileCache {
21+
struct FileResult {
22+
std::string content;
23+
std::string error;
24+
std::filesystem::file_time_type time;
25+
bool ok = false;
26+
};
27+
28+
struct IniResult {
29+
CSimpleIni ini;
30+
SI_Error err = SI_OK;
31+
std::string errorStr;
32+
std::filesystem::file_time_type time;
33+
bool ok = false;
34+
};
35+
36+
inline std::unordered_map<std::string, FileResult> fileCache;
37+
inline std::unordered_map<std::string, IniResult> iniCache;
38+
inline std::recursive_mutex mtx;
39+
40+
inline std::filesystem::file_time_type getWriteTime(const std::string& path) {
41+
std::error_code ec;
42+
return std::filesystem::last_write_time(path, ec);
43+
}
44+
45+
inline FileResult& getText(const std::string& path) {
46+
std::lock_guard lock(mtx);
47+
48+
auto now = getWriteTime(path);
49+
auto it = fileCache.find(path);
50+
51+
if (it != fileCache.end() && it->second.time == now) {
52+
return it->second;
53+
}
54+
55+
auto& res = fileCache[path];
56+
57+
res.time = now;
58+
res.ok = false;
59+
res.error.clear();
60+
res.content.clear();
61+
62+
auto read = file::readString(path.c_str());
63+
if (read.err()) {
64+
res.error = read.err().value();
65+
}
66+
else {
67+
res.ok = true;
68+
res.content = read.unwrap();
69+
}
70+
71+
return res;
72+
}
73+
74+
inline IniResult& getIni(const std::string& path) {
75+
std::lock_guard lock(mtx);
76+
77+
auto now = getWriteTime(path);
78+
auto it = iniCache.find(path);
79+
80+
if (it != iniCache.end() && it->second.time == now) {
81+
return it->second;
82+
}
83+
84+
auto& res = iniCache[path];
85+
86+
res.time = now;
87+
res.ok = false;
88+
res.errorStr.clear();
89+
res.ini.Reset();
90+
91+
auto& file = getText(path);
92+
93+
if (!file.ok) {
94+
res.ok = false;
95+
res.errorStr = file.error;
96+
}
97+
else {
98+
res.err = res.ini.LoadData(file.content);
99+
100+
if (res.err < 0) {
101+
if (res.err == SI_FAIL) res.errorStr = "Generic failure";
102+
else if (res.err == SI_NOMEM) res.errorStr = "Out of memory";
103+
else if (res.err == SI_FILE) res.errorStr = std::string("File error\n") + strerror(errno);
104+
else res.errorStr = "Unknown error";
105+
}
106+
else {
107+
res.ok = true;
108+
}
109+
}
110+
111+
return res;
112+
}
113+
114+
inline void invalidate(const std::string& path) {
115+
std::lock_guard lock(mtx);
116+
fileCache.erase(path);
117+
iniCache.erase(path);
118+
}
119+
}
120+
20121
$execute{
21122
for (auto path : {
22123
string::pathToString(Mod::get()->getConfigDir()),
@@ -43,23 +144,22 @@ class $modify(MLE_LocalLevelManager, LocalLevelManager) {
43144
}
44145

45146
auto path = CCFileUtils::get()->fullPathForFilename(filename.c_str(), !"why");
46-
auto read = file::readString(path.c_str());
47-
if (auto err = read.err()) {
48-
//yea
49-
log::error("{}.readString: {}", __FUNCTION__, err);
147+
auto& res = FileCache::getText(path);
148+
if (!res.ok) {
149+
log::error("{}.readString: {}", __FUNCTION__, res.error);
50150
//whyyy the fuuuuck i done that
51151
std::string errlevel = R"(kS38,1_110_2_110_3_112_6_1000_7_1_15_0_18_0_8_1|1_0_2_0_3_0_6_1001_7_1_15_0_18_0_8_1|1_0_2_102_3_255_11_255_12_255_13_255_4_-1_6_1009_7_1_15_1_18_0_8_1|1_255_2_255_3_255_6_1002_5_1_7_1_15_0_18_0_8_1|1_40_2_125_3_255_11_255_12_255_13_255_4_-1_6_1013_7_1_15_1_18_0_8_1|1_40_2_125_3_255_11_255_12_255_13_255_4_-1_6_1014_7_1_15_1_18_0_8_1|1_255_2_255_3_255_6_1004_7_1_15_0_18_0_8_1|1_255_2_255_3_255_6_1003_7_1_15_0_18_0_8_1|1_125_2_255_3_0_11_255_12_255_13_255_4_-1_6_1005_5_1_7_1_15_1_18_0_8_1|1_0_2_255_3_255_11_255_12_255_13_255_4_-1_6_1006_5_1_7_1_15_1_18_0_8_1|,kA13,0,kA15,0,kA16,0,kA14,,kA6,0,kA7,0,kA25,0,kA17,0,kA18,0,kS39,0,kA2,1,kA3,0,kA8,0,kA4,0,kA9,0,kA10,0,kA22,1,kA23,0,kA24,0,kA27,0,kA40,0,kA48,0,kA41,0,kA42,0,kA28,0,kA29,0,kA31,0,kA32,0,kA36,0,kA43,0,kA44,0,kA45,0,kA46,0,kA47,0,kA33,0,kA34,0,kA35,0,kA37,0,kA38,0,kA39,0,kA19,0,kA26,0,kA20,0,kA21,0,kA11,0;
52152
1,2925,2,-45,3,135,155,1,36,1,111,1,112,1,113,20,114,1;
53153
1,1934,2,-45,3,105,155,1,13,1,36,1,406,1,421,1,422,0.5,10,0.5;
54154
1,914,2,495,3,135,155,2,128,0.5,129,0.5,31,YXNk;
55155
1,2899,2,-45,3,165,155,1,36,1,532,1;)";
56156
errlevel = string::replace(errlevel, "YXNk", ZipUtils::base64URLEncode(
57-
"Failed to load " + filename + "!\n" + err.value_or("unk err")
157+
"Failed to load " + filename + "!\n" + res.error
58158
).c_str());
59159
return errlevel;
60160
}
61161

62-
return read.unwrapOr(LocalLevelManager::getMainLevelString(id));
162+
return res.content;
63163
};
64164
};
65165

@@ -93,8 +193,8 @@ class $modify(MLE_LevelTools, LevelTools) {
93193

94194
auto path = CCFileUtils::get()->fullPathForFilename(filename.c_str(), !"why");
95195

96-
CSimpleIni Ini;
97-
auto sierr = Ini.LoadFile(path.c_str());
196+
auto& iniRes = FileCache::getIni(path);
197+
auto& Ini = iniRes.ini;
98198

99199
//m_levelID
100200
if (!(Ini.KeyExists("GJGameLevel", "m_levelID"))) Ini.SetLongValue(
@@ -165,16 +265,13 @@ class $modify(MLE_LevelTools, LevelTools) {
165265
);
166266
else level->m_capacityString = escDEC(Ini.GetValue("GJGameLevel", "m_capacityString")).c_str();
167267

168-
if (sierr < 0) {
169-
auto err = std::string();
170-
if (sierr == SI_FAIL) err = "Generic failure";
171-
if (sierr == SI_NOMEM) err = "Out of memory";
172-
if (sierr == SI_FILE) err = "File error\n" + std::string(strerror(errno));
173-
level->m_levelName = "[INI ERROR]: " + err;
174-
level->m_difficulty = GJDifficulty::Harder;
268+
if (!iniRes.ok) {
269+
level->m_levelName = "[INI ERROR]: " + iniRes.errorStr;
270+
level->m_difficulty = GJDifficulty::Harder;
175271
}
176272

177273
Ini.SaveFile(path.c_str());
274+
FileCache::invalidate(path);
178275

179276
return level;
180277
};
@@ -280,14 +377,14 @@ class $modify(BoomScrollLayerLevelSelectExt, BoomScrollLayer) {
280377
).err()) log::error("{}.writeString: {}", __FUNCTION__, err);
281378
}
282379
auto path = CCFileUtils::get()->fullPathForFilename(file, !"why");
283-
auto read = file::readString(path.c_str());
380+
auto read = FileCache::getText(path);
284381

285-
if (read.err()) {
286-
log::error("{}.readString: {}", __FUNCTION__, read.err().value());
382+
if (!read.ok) {
383+
log::error("{}.readString: {}", __FUNCTION__, read.error);
287384
if (layer) queueInMainThread( // hi Node IDs
288385
[file, read, layer = Ref(layer)] {
289386
auto label = CCLabelBMFont::create(
290-
fmt::format("Error reading {}:\n{}", file, read.err().value()).c_str(),
387+
fmt::format("Error reading {}!\n{}", file, read.error).c_str(),
291388
"bigFont.fnt"
292389
);
293390
label->setID("err-label"_spr);
@@ -302,7 +399,7 @@ class $modify(BoomScrollLayerLevelSelectExt, BoomScrollLayer) {
302399

303400
unk3->removeAllObjects();
304401

305-
for (auto id : parseListingIDs(read.unwrapOr(""))) unk3->addObject(
402+
for (auto id : parseListingIDs(read.content)) unk3->addObject(
306403
GameLevelManager::get()->getMainLevel(id, 0)
307404
);
308405

0 commit comments

Comments
 (0)