2018-11-17 15:36:28 +00:00
|
|
|
// Copyright 2018 Dolphin Emulator Project
|
2021-07-05 01:22:19 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2018-11-17 15:36:28 +00:00
|
|
|
|
|
|
|
#include "UICommon/ResourcePack/Manager.h"
|
|
|
|
|
|
|
|
#include "Common/CommonTypes.h"
|
|
|
|
#include "Common/FileSearch.h"
|
|
|
|
#include "Common/FileUtil.h"
|
|
|
|
#include "Common/IniFile.h"
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
2019-06-08 00:20:09 +00:00
|
|
|
namespace ResourcePack
|
|
|
|
{
|
2018-11-17 15:36:28 +00:00
|
|
|
namespace
|
|
|
|
{
|
2019-06-08 00:20:09 +00:00
|
|
|
std::vector<ResourcePack> packs;
|
2018-11-17 15:36:28 +00:00
|
|
|
std::string packs_path;
|
|
|
|
|
2023-04-13 13:38:09 +00:00
|
|
|
Common::IniFile GetPackConfig()
|
2018-11-17 15:36:28 +00:00
|
|
|
{
|
|
|
|
packs_path = File::GetUserPath(D_RESOURCEPACK_IDX) + "/Packs.ini";
|
|
|
|
|
2023-04-13 13:38:09 +00:00
|
|
|
Common::IniFile file;
|
2018-11-17 15:36:28 +00:00
|
|
|
file.Load(packs_path);
|
|
|
|
|
|
|
|
return file;
|
|
|
|
}
|
2019-06-08 00:20:09 +00:00
|
|
|
} // Anonymous namespace
|
2018-11-17 15:36:28 +00:00
|
|
|
|
|
|
|
bool Init()
|
|
|
|
{
|
|
|
|
packs.clear();
|
2022-03-18 05:47:01 +00:00
|
|
|
const std::vector<std::string> pack_list =
|
|
|
|
Common::DoFileSearch({File::GetUserPath(D_RESOURCEPACK_IDX)}, {".zip"});
|
2018-11-17 15:36:28 +00:00
|
|
|
|
2023-04-13 13:38:09 +00:00
|
|
|
Common::IniFile file = GetPackConfig();
|
2018-11-17 15:36:28 +00:00
|
|
|
|
|
|
|
auto* order = file.GetOrCreateSection("Order");
|
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
struct OrderHelper
|
|
|
|
{
|
|
|
|
size_t pack_list_index;
|
|
|
|
std::string manifest_id;
|
|
|
|
};
|
2018-11-17 15:36:28 +00:00
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
std::vector<OrderHelper> pack_list_order;
|
|
|
|
pack_list_order.reserve(pack_list.size());
|
|
|
|
for (size_t i = 0; i < pack_list.size(); ++i)
|
|
|
|
{
|
|
|
|
const ResourcePack pack(pack_list[i]);
|
|
|
|
std::string manifest_id = pack.IsValid() ? pack.GetManifest()->GetID() : pack_list[i];
|
|
|
|
pack_list_order.emplace_back(OrderHelper{i, std::move(manifest_id)});
|
|
|
|
}
|
2018-11-17 15:36:28 +00:00
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
std::sort(
|
|
|
|
pack_list_order.begin(), pack_list_order.end(),
|
|
|
|
[](const OrderHelper& a, const OrderHelper& b) { return a.manifest_id < b.manifest_id; });
|
2018-11-17 15:36:28 +00:00
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
bool error = false;
|
|
|
|
for (size_t i = 0; i < pack_list_order.size(); ++i)
|
2018-11-17 15:36:28 +00:00
|
|
|
{
|
2022-03-18 05:47:01 +00:00
|
|
|
const auto& path = pack_list[pack_list_order[i].pack_list_index];
|
2018-11-17 15:36:28 +00:00
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
const ResourcePack* const pack = Add(path);
|
|
|
|
if (pack == nullptr)
|
2019-01-02 21:47:18 +00:00
|
|
|
{
|
|
|
|
error = true;
|
|
|
|
continue;
|
|
|
|
}
|
2018-11-17 15:36:28 +00:00
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
order->Set(pack->GetManifest()->GetID(), static_cast<u64>(i));
|
2018-11-17 15:36:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
file.Save(packs_path);
|
|
|
|
|
|
|
|
return !error;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<ResourcePack>& GetPacks()
|
|
|
|
{
|
|
|
|
return packs;
|
|
|
|
}
|
|
|
|
|
2023-06-16 14:19:38 +00:00
|
|
|
std::vector<ResourcePack*> GetLowerPriorityPacks(const ResourcePack& pack)
|
2018-11-17 15:36:28 +00:00
|
|
|
{
|
|
|
|
std::vector<ResourcePack*> list;
|
2019-09-14 20:48:48 +00:00
|
|
|
for (auto it = std::find(packs.begin(), packs.end(), pack) + 1; it != packs.end(); ++it)
|
2018-11-17 15:36:28 +00:00
|
|
|
{
|
|
|
|
auto& entry = *it;
|
|
|
|
if (!IsInstalled(pack))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
list.push_back(&entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2023-06-16 14:19:38 +00:00
|
|
|
std::vector<ResourcePack*> GetHigherPriorityPacks(const ResourcePack& pack)
|
2018-11-17 15:36:28 +00:00
|
|
|
{
|
|
|
|
std::vector<ResourcePack*> list;
|
|
|
|
auto end = std::find(packs.begin(), packs.end(), pack);
|
|
|
|
|
2019-09-14 20:48:48 +00:00
|
|
|
for (auto it = packs.begin(); it != end; ++it)
|
2018-11-17 15:36:28 +00:00
|
|
|
{
|
|
|
|
auto& entry = *it;
|
|
|
|
if (!IsInstalled(entry))
|
|
|
|
continue;
|
|
|
|
list.push_back(&entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
return list;
|
|
|
|
}
|
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
ResourcePack* Add(const std::string& path, int offset)
|
2018-11-17 15:36:28 +00:00
|
|
|
{
|
|
|
|
if (offset == -1)
|
|
|
|
offset = static_cast<int>(packs.size());
|
|
|
|
|
|
|
|
ResourcePack pack(path);
|
|
|
|
|
2019-01-02 21:47:18 +00:00
|
|
|
if (!pack.IsValid())
|
2022-03-18 05:47:01 +00:00
|
|
|
return nullptr;
|
2019-01-02 21:47:18 +00:00
|
|
|
|
2023-04-13 13:38:09 +00:00
|
|
|
Common::IniFile file = GetPackConfig();
|
2018-11-17 15:36:28 +00:00
|
|
|
|
|
|
|
auto* order = file.GetOrCreateSection("Order");
|
|
|
|
|
|
|
|
order->Set(pack.GetManifest()->GetID(), offset);
|
|
|
|
|
|
|
|
for (int i = offset; i < static_cast<int>(packs.size()); i++)
|
|
|
|
order->Set(packs[i].GetManifest()->GetID(), i + 1);
|
|
|
|
|
|
|
|
file.Save(packs_path);
|
|
|
|
|
2022-03-18 05:47:01 +00:00
|
|
|
auto it = packs.insert(packs.begin() + offset, std::move(pack));
|
|
|
|
return &*it;
|
2018-11-17 15:36:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Remove(ResourcePack& pack)
|
|
|
|
{
|
|
|
|
const auto result = pack.Uninstall(File::GetUserPath(D_USER_IDX));
|
|
|
|
|
|
|
|
if (!result)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
auto pack_iterator = std::find(packs.begin(), packs.end(), pack);
|
|
|
|
|
|
|
|
if (pack_iterator == packs.end())
|
|
|
|
return false;
|
|
|
|
|
2023-04-13 13:38:09 +00:00
|
|
|
Common::IniFile file = GetPackConfig();
|
2018-11-17 15:36:28 +00:00
|
|
|
|
|
|
|
auto* order = file.GetOrCreateSection("Order");
|
|
|
|
|
|
|
|
order->Delete(pack.GetManifest()->GetID());
|
|
|
|
|
|
|
|
int offset = pack_iterator - packs.begin();
|
|
|
|
|
|
|
|
for (int i = offset + 1; i < static_cast<int>(packs.size()); i++)
|
|
|
|
order->Set(packs[i].GetManifest()->GetID(), i - 1);
|
|
|
|
|
|
|
|
file.Save(packs_path);
|
|
|
|
|
|
|
|
packs.erase(pack_iterator);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetInstalled(const ResourcePack& pack, bool installed)
|
|
|
|
{
|
2023-04-13 13:38:09 +00:00
|
|
|
Common::IniFile file = GetPackConfig();
|
2018-11-17 15:36:28 +00:00
|
|
|
|
|
|
|
auto* install = file.GetOrCreateSection("Installed");
|
|
|
|
|
|
|
|
if (installed)
|
|
|
|
install->Set(pack.GetManifest()->GetID(), installed);
|
|
|
|
else
|
|
|
|
install->Delete(pack.GetManifest()->GetID());
|
|
|
|
|
|
|
|
file.Save(packs_path);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsInstalled(const ResourcePack& pack)
|
|
|
|
{
|
2023-04-13 13:38:09 +00:00
|
|
|
Common::IniFile file = GetPackConfig();
|
2018-11-17 15:36:28 +00:00
|
|
|
|
|
|
|
auto* install = file.GetOrCreateSection("Installed");
|
|
|
|
|
|
|
|
bool installed;
|
|
|
|
|
|
|
|
install->Get(pack.GetManifest()->GetID(), &installed, false);
|
|
|
|
|
|
|
|
return installed;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace ResourcePack
|