feat: add very early mod.toml packwiz support
Also use it as a on-disk format for storing mod metadata. This will be used later on to make better mod managment.
This commit is contained in:
parent
dca4ea5cea
commit
b30b88716e
@ -331,6 +331,8 @@ set(MINECRAFT_SOURCES
|
|||||||
minecraft/mod/ModFolderLoadTask.cpp
|
minecraft/mod/ModFolderLoadTask.cpp
|
||||||
minecraft/mod/LocalModParseTask.h
|
minecraft/mod/LocalModParseTask.h
|
||||||
minecraft/mod/LocalModParseTask.cpp
|
minecraft/mod/LocalModParseTask.cpp
|
||||||
|
minecraft/mod/LocalModUpdateTask.h
|
||||||
|
minecraft/mod/LocalModUpdateTask.cpp
|
||||||
minecraft/mod/ResourcePackFolderModel.h
|
minecraft/mod/ResourcePackFolderModel.h
|
||||||
minecraft/mod/ResourcePackFolderModel.cpp
|
minecraft/mod/ResourcePackFolderModel.cpp
|
||||||
minecraft/mod/TexturePackFolderModel.h
|
minecraft/mod/TexturePackFolderModel.h
|
||||||
@ -543,6 +545,11 @@ set(MODPACKSCH_SOURCES
|
|||||||
modplatform/modpacksch/FTBPackManifest.cpp
|
modplatform/modpacksch/FTBPackManifest.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(PACKWIZ_SOURCES
|
||||||
|
modplatform/packwiz/Packwiz.h
|
||||||
|
modplatform/packwiz/Packwiz.cpp
|
||||||
|
)
|
||||||
|
|
||||||
set(TECHNIC_SOURCES
|
set(TECHNIC_SOURCES
|
||||||
modplatform/technic/SingleZipPackInstallTask.h
|
modplatform/technic/SingleZipPackInstallTask.h
|
||||||
modplatform/technic/SingleZipPackInstallTask.cpp
|
modplatform/technic/SingleZipPackInstallTask.cpp
|
||||||
@ -596,6 +603,7 @@ set(LOGIC_SOURCES
|
|||||||
${FLAME_SOURCES}
|
${FLAME_SOURCES}
|
||||||
${MODRINTH_SOURCES}
|
${MODRINTH_SOURCES}
|
||||||
${MODPACKSCH_SOURCES}
|
${MODPACKSCH_SOURCES}
|
||||||
|
${PACKWIZ_SOURCES}
|
||||||
${TECHNIC_SOURCES}
|
${TECHNIC_SOURCES}
|
||||||
${ATLAUNCHER_SOURCES}
|
${ATLAUNCHER_SOURCES}
|
||||||
)
|
)
|
||||||
|
32
launcher/minecraft/mod/LocalModUpdateTask.cpp
Normal file
32
launcher/minecraft/mod/LocalModUpdateTask.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "LocalModUpdateTask.h"
|
||||||
|
|
||||||
|
#include <toml.h>
|
||||||
|
|
||||||
|
#include "FileSystem.h"
|
||||||
|
#include "modplatform/packwiz/Packwiz.h"
|
||||||
|
|
||||||
|
LocalModUpdateTask::LocalModUpdateTask(QDir mods_dir, ModPlatform::IndexedPack& mod, ModPlatform::IndexedVersion& mod_version)
|
||||||
|
: m_mod(mod), m_mod_version(mod_version)
|
||||||
|
{
|
||||||
|
// Ensure a '.index' folder exists in the mods folder, and create it if it does not
|
||||||
|
m_index_dir = { QString("%1/.index").arg(mods_dir.absolutePath()) };
|
||||||
|
if (!FS::ensureFolderPathExists(m_index_dir.path())) {
|
||||||
|
emitFailed(QString("Unable to create index for mod %1!").arg(m_mod.name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LocalModUpdateTask::executeTask()
|
||||||
|
{
|
||||||
|
setStatus(tr("Updating index for mod:\n%1").arg(m_mod.name));
|
||||||
|
|
||||||
|
auto pw_mod = Packwiz::createModFormat(m_index_dir, m_mod, m_mod_version);
|
||||||
|
Packwiz::updateModIndex(m_index_dir, pw_mod);
|
||||||
|
|
||||||
|
emitSucceeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LocalModUpdateTask::abort()
|
||||||
|
{
|
||||||
|
emitAborted();
|
||||||
|
return true;
|
||||||
|
}
|
26
launcher/minecraft/mod/LocalModUpdateTask.h
Normal file
26
launcher/minecraft/mod/LocalModUpdateTask.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include "tasks/Task.h"
|
||||||
|
#include "modplatform/ModIndex.h"
|
||||||
|
|
||||||
|
class LocalModUpdateTask : public Task {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
using Ptr = shared_qobject_ptr<LocalModUpdateTask>;
|
||||||
|
|
||||||
|
explicit LocalModUpdateTask(QDir mods_dir, ModPlatform::IndexedPack& mod, ModPlatform::IndexedVersion& mod_version);
|
||||||
|
|
||||||
|
bool canAbort() const override { return true; }
|
||||||
|
bool abort() override;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
//! Entry point for tasks.
|
||||||
|
void executeTask() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDir m_index_dir;
|
||||||
|
ModPlatform::IndexedPack& m_mod;
|
||||||
|
ModPlatform::IndexedVersion& m_mod_version;
|
||||||
|
};
|
@ -8,6 +8,35 @@
|
|||||||
|
|
||||||
namespace ModPlatform {
|
namespace ModPlatform {
|
||||||
|
|
||||||
|
enum class Provider{
|
||||||
|
MODRINTH,
|
||||||
|
FLAME
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProviderCapabilities {
|
||||||
|
public:
|
||||||
|
static QString hashType(Provider p)
|
||||||
|
{
|
||||||
|
switch(p){
|
||||||
|
case Provider::MODRINTH:
|
||||||
|
return "sha256";
|
||||||
|
case Provider::FLAME:
|
||||||
|
return "murmur2";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
static QString providerName(Provider p)
|
||||||
|
{
|
||||||
|
switch(p){
|
||||||
|
case Provider::MODRINTH:
|
||||||
|
return "modrinth";
|
||||||
|
case Provider::FLAME:
|
||||||
|
return "curseforge";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct ModpackAuthor {
|
struct ModpackAuthor {
|
||||||
QString name;
|
QString name;
|
||||||
QString url;
|
QString url;
|
||||||
@ -26,6 +55,7 @@ struct IndexedVersion {
|
|||||||
|
|
||||||
struct IndexedPack {
|
struct IndexedPack {
|
||||||
QVariant addonId;
|
QVariant addonId;
|
||||||
|
Provider provider;
|
||||||
QString name;
|
QString name;
|
||||||
QString description;
|
QString description;
|
||||||
QList<ModpackAuthor> authors;
|
QList<ModpackAuthor> authors;
|
||||||
@ -40,3 +70,4 @@ struct IndexedPack {
|
|||||||
} // namespace ModPlatform
|
} // namespace ModPlatform
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(ModPlatform::IndexedPack)
|
Q_DECLARE_METATYPE(ModPlatform::IndexedPack)
|
||||||
|
Q_DECLARE_METATYPE(ModPlatform::Provider)
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
void FlameMod::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||||
{
|
{
|
||||||
pack.addonId = Json::requireInteger(obj, "id");
|
pack.addonId = Json::requireInteger(obj, "id");
|
||||||
|
pack.provider = ModPlatform::Provider::FLAME;
|
||||||
pack.name = Json::requireString(obj, "name");
|
pack.name = Json::requireString(obj, "name");
|
||||||
pack.websiteUrl = Json::ensureString(Json::ensureObject(obj, "links"), "websiteUrl", "");
|
pack.websiteUrl = Json::ensureString(Json::ensureObject(obj, "links"), "websiteUrl", "");
|
||||||
pack.description = Json::ensureString(obj, "summary", "");
|
pack.description = Json::ensureString(obj, "summary", "");
|
||||||
|
@ -28,6 +28,7 @@ static ModrinthAPI api;
|
|||||||
void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
void Modrinth::loadIndexedPack(ModPlatform::IndexedPack& pack, QJsonObject& obj)
|
||||||
{
|
{
|
||||||
pack.addonId = Json::requireString(obj, "project_id");
|
pack.addonId = Json::requireString(obj, "project_id");
|
||||||
|
pack.provider = ModPlatform::Provider::MODRINTH;
|
||||||
pack.name = Json::requireString(obj, "title");
|
pack.name = Json::requireString(obj, "title");
|
||||||
|
|
||||||
QString slug = Json::ensureString(obj, "slug", "");
|
QString slug = Json::ensureString(obj, "slug", "");
|
||||||
|
60
launcher/modplatform/packwiz/Packwiz.cpp
Normal file
60
launcher/modplatform/packwiz/Packwiz.cpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#include "Packwiz.h"
|
||||||
|
|
||||||
|
#include "modplatform/ModIndex.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
auto Packwiz::createModFormat(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> Mod
|
||||||
|
{
|
||||||
|
Mod mod;
|
||||||
|
|
||||||
|
mod.name = mod_pack.name;
|
||||||
|
mod.filename = mod_version.fileName;
|
||||||
|
|
||||||
|
mod.url = mod_version.downloadUrl;
|
||||||
|
mod.hash_format = ModPlatform::ProviderCapabilities::hashType(mod_pack.provider);
|
||||||
|
mod.hash = ""; // FIXME
|
||||||
|
|
||||||
|
mod.provider = mod_pack.provider;
|
||||||
|
mod.file_id = mod_pack.addonId;
|
||||||
|
mod.project_id = mod_version.fileId;
|
||||||
|
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Packwiz::updateModIndex(QDir& index_dir, Mod& mod)
|
||||||
|
{
|
||||||
|
// Ensure the corresponding mod's info exists, and create it if not
|
||||||
|
auto index_file_name = QString("%1.toml").arg(mod.name);
|
||||||
|
QFile index_file(index_dir.absoluteFilePath(index_file_name));
|
||||||
|
|
||||||
|
// There's already data on there!
|
||||||
|
if (index_file.exists()) { index_file.remove(); }
|
||||||
|
|
||||||
|
if (!index_file.open(QIODevice::ReadWrite)) {
|
||||||
|
qCritical() << "Could not open file " << index_file_name << "!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put TOML data into the file
|
||||||
|
QTextStream in_stream(&index_file);
|
||||||
|
auto addToStream = [&in_stream](QString&& key, QString value) { in_stream << QString("%1 = \"%2\"\n").arg(key, value); };
|
||||||
|
|
||||||
|
{
|
||||||
|
addToStream("name", mod.name);
|
||||||
|
addToStream("filename", mod.filename);
|
||||||
|
addToStream("side", mod.side);
|
||||||
|
|
||||||
|
in_stream << QString("\n[download]\n");
|
||||||
|
addToStream("url", mod.url.toString());
|
||||||
|
addToStream("hash-format", mod.hash_format);
|
||||||
|
addToStream("hash", mod.hash);
|
||||||
|
|
||||||
|
in_stream << QString("\n[update]\n");
|
||||||
|
in_stream << QString("[update.%1]\n").arg(ModPlatform::ProviderCapabilities::providerName(mod.provider));
|
||||||
|
addToStream("file-id", mod.file_id.toString());
|
||||||
|
addToStream("project-id", mod.project_id.toString());
|
||||||
|
}
|
||||||
|
}
|
43
launcher/modplatform/packwiz/Packwiz.h
Normal file
43
launcher/modplatform/packwiz/Packwiz.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
namespace ModPlatform {
|
||||||
|
enum class Provider;
|
||||||
|
class IndexedPack;
|
||||||
|
class IndexedVersion;
|
||||||
|
} // namespace ModPlatform
|
||||||
|
|
||||||
|
class QDir;
|
||||||
|
|
||||||
|
class Packwiz {
|
||||||
|
public:
|
||||||
|
struct Mod {
|
||||||
|
QString name;
|
||||||
|
QString filename;
|
||||||
|
// FIXME: make side an enum
|
||||||
|
QString side = "both";
|
||||||
|
|
||||||
|
// [download]
|
||||||
|
QUrl url;
|
||||||
|
// FIXME: make hash-format an enum
|
||||||
|
QString hash_format;
|
||||||
|
QString hash;
|
||||||
|
|
||||||
|
// [update]
|
||||||
|
ModPlatform::Provider provider;
|
||||||
|
QVariant file_id;
|
||||||
|
QVariant project_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Generates the object representing the information in a mod.toml file via its common representation in the launcher */
|
||||||
|
static auto createModFormat(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> Mod;
|
||||||
|
|
||||||
|
/* Updates the mod index for the provided mod.
|
||||||
|
* This creates a new index if one does not exist already
|
||||||
|
* TODO: Ask the user if they want to override, and delete the old mod's files, or keep the old one.
|
||||||
|
* */
|
||||||
|
static void updateModIndex(QDir& index_dir, Mod& mod);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user