Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/base
diff options
context:
space:
mode:
authorKae <80987908+Novaenia@users.noreply.github.com>2024-06-25 19:56:44 +1000
committerKae <80987908+Novaenia@users.noreply.github.com>2024-06-25 19:56:44 +1000
commit9edbe8cf2d50bd7c5e597120040160c1fa57b3db (patch)
treeb73f4f24daaf4fb9f54bbda6009579ec11c6668f /source/base
parent67c7257c3b7363f51ef27d8357798f799ad2c8b9 (diff)
Add .patchlist
#73
Diffstat (limited to 'source/base')
-rw-r--r--source/base/StarAssets.cpp52
1 files changed, 37 insertions, 15 deletions
diff --git a/source/base/StarAssets.cpp b/source/base/StarAssets.cpp
index 68e307a..9fbb66d 100644
--- a/source/base/StarAssets.cpp
+++ b/source/base/StarAssets.cpp
@@ -104,6 +104,7 @@ Maybe<RectU> FramesSpecification::getRect(String const& frame) const {
Assets::Assets(Settings settings, StringList assetSources) {
const char* AssetsPatchSuffix = ".patch";
+ const char* AssetsPatchListSuffix = ".patchlist";
const char* AssetsLuaPatchSuffix = ".patch.lua";
m_settings = std::move(settings);
@@ -204,6 +205,24 @@ Assets::Assets(Settings settings, StringList assetSources) {
auto targetPatchFile = filename.substr(0, filename.size() - strlen(AssetsLuaPatchSuffix));
if (auto p = m_files.ptr(targetPatchFile))
p->patchSources.append({filename, source});
+ } else if (filename.endsWith(AssetsPatchListSuffix, String::CaseInsensitive)) {
+ auto stream = source->read(filename);
+ size_t patchIndex = 0;
+ for (auto const& patchPair : inputUtf8Json(stream.begin(), stream.end(), JsonParseType::Top).iterateArray()) {
+ auto& patches = patchPair.getArray("patches");
+ for (auto& path : patchPair.getArray("paths")) {
+ if (auto p = m_files.ptr(path.toString())) {
+ for (size_t i = 0; i != patches.size(); ++i) {
+ auto& patch = patches[i];
+ if (patch.isType(Json::Type::String))
+ p->patchSources.append({patch.toString(), source});
+ else
+ p->patchSources.append({strf("{}:[{}].patches[{}]", filename, patchIndex, i), source});
+ }
+ }
+ }
+ patchIndex++;
+ }
} else {
for (int i = 0; i < 10; i++) {
if (filename.endsWith(AssetsPatchSuffix + toString(i), String::CaseInsensitive)) {
@@ -289,7 +308,7 @@ Assets::Assets(Settings settings, StringList assetSources) {
digest.push(assetPath);
digest.push(DataStreamBuffer::serialize(descriptor.source->open(descriptor.sourceName)->size()));
for (auto const& pair : descriptor.patchSources)
- digest.push(DataStreamBuffer::serialize(pair.second->open(pair.first)->size()));
+ digest.push(DataStreamBuffer::serialize(pair.second->open(AssetPath::removeSubPath(pair.first))->size()));
}
}
@@ -956,32 +975,35 @@ Json Assets::readJson(String const& path) const {
try {
Json result = inputUtf8Json(streamData.begin(), streamData.end(), JsonParseType::Top);
for (auto const& pair : m_files.get(path).patchSources) {
- auto& patchPath = pair.first;
+ auto patchAssetPath = AssetPath::split(pair.first);
+ auto& patchBasePath = patchAssetPath.basePath;
auto& patchSource = pair.second;
- auto patchStream = patchSource->read(patchPath);
- if (patchPath.endsWith(".lua")) {
+ auto patchStream = patchSource->read(patchBasePath);
+ if (patchBasePath.endsWith(".lua")) {
RecursiveMutexLocker luaLocker(m_luaMutex);
// Kae: i don't like that lock. perhaps have a LuaEngine and patch context cache per worker thread later on?
- LuaContextPtr& context = m_patchContexts[patchPath];
+ LuaContextPtr& context = m_patchContexts[patchBasePath];
if (!context) {
context = make_shared<LuaContext>(as<LuaEngine>(m_luaEngine.get())->createContext());
- context->load(patchStream, patchPath);
+ context->load(patchStream, patchBasePath);
}
auto newResult = context->invokePath<Json>("patch", result, path);
if (newResult)
result = std::move(newResult);
} else {
auto patchJson = inputUtf8Json(patchStream.begin(), patchStream.end(), JsonParseType::Top);
+ if (patchAssetPath.subPath)
+ patchJson = patchJson.query(*patchAssetPath.subPath);
if (patchJson.isType(Json::Type::Array)) {
- auto patchData = patchJson.toArray();
- try {
- result = checkPatchArray(patchPath, patchSource, result, patchData, {});
- } catch (JsonPatchTestFail const& e) {
- Logger::debug("Patch test failure from file {} in source: '{}' at '{}'. Caused by: {}", patchPath, patchSource->metadata().value("name", ""), m_assetSourcePaths.getLeft(patchSource), e.what());
- } catch (JsonPatchException const& e) {
- Logger::error("Could not apply patch from file {} in source: '{}' at '{}'. Caused by: {}", patchPath, patchSource->metadata().value("name", ""), m_assetSourcePaths.getLeft(patchSource), e.what());
- }
- } else if (patchJson.isType(Json::Type::Object)) {//Kae: Do a good ol' json merge instead if the .patch file is a Json object
+ auto patchData = patchJson.toArray();
+ try {
+ result = checkPatchArray(pair.first, patchSource, result, patchData, {});
+ } catch (JsonPatchTestFail const& e) {
+ Logger::debug("Patch test failure from file {} in source: '{}' at '{}'. Caused by: {}", pair.first, patchSource->metadata().value("name", ""), m_assetSourcePaths.getLeft(patchSource), e.what());
+ } catch (JsonPatchException const& e) {
+ Logger::error("Could not apply patch from file {} in source: '{}' at '{}'. Caused by: {}", pair.first, patchSource->metadata().value("name", ""), m_assetSourcePaths.getLeft(patchSource), e.what());
+ }
+ } else if (patchJson.isType(Json::Type::Object)) {
result = jsonMergeNulling(result, patchJson.toObject());
}
}