refactor: move general info from Mod to Resource
This allows us to create other resources that are not Mods, but can still share a significant portion of code. Signed-off-by: flow <flowlnlnln@gmail.com>
This commit is contained in:
parent
2d63c86022
commit
3225f514f6
@ -318,6 +318,8 @@ set(MINECRAFT_SOURCES
|
|||||||
minecraft/mod/ModDetails.h
|
minecraft/mod/ModDetails.h
|
||||||
minecraft/mod/ModFolderModel.h
|
minecraft/mod/ModFolderModel.h
|
||||||
minecraft/mod/ModFolderModel.cpp
|
minecraft/mod/ModFolderModel.cpp
|
||||||
|
minecraft/mod/Resource.h
|
||||||
|
minecraft/mod/Resource.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
|
||||||
|
@ -148,7 +148,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
|||||||
// do not merge disabled mods.
|
// do not merge disabled mods.
|
||||||
if (!mod->enabled())
|
if (!mod->enabled())
|
||||||
continue;
|
continue;
|
||||||
if (mod->type() == Mod::MOD_ZIPFILE)
|
if (mod->type() == ResourceType::ZIPFILE)
|
||||||
{
|
{
|
||||||
if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles))
|
if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles))
|
||||||
{
|
{
|
||||||
@ -158,7 +158,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mod->type() == Mod::MOD_SINGLEFILE)
|
else if (mod->type() == ResourceType::SINGLEFILE)
|
||||||
{
|
{
|
||||||
// FIXME: buggy - does not work with addedFiles
|
// FIXME: buggy - does not work with addedFiles
|
||||||
auto filename = mod->fileinfo();
|
auto filename = mod->fileinfo();
|
||||||
@ -171,7 +171,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
|||||||
}
|
}
|
||||||
addedFiles.insert(filename.fileName());
|
addedFiles.insert(filename.fileName());
|
||||||
}
|
}
|
||||||
else if (mod->type() == Mod::MOD_FOLDER)
|
else if (mod->type() == ResourceType::FOLDER)
|
||||||
{
|
{
|
||||||
// untested, but seems to be unused / not possible to reach
|
// untested, but seems to be unused / not possible to reach
|
||||||
// FIXME: buggy - does not work with addedFiles
|
// FIXME: buggy - does not work with addedFiles
|
||||||
|
@ -714,7 +714,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
|||||||
});
|
});
|
||||||
for(auto mod: modList)
|
for(auto mod: modList)
|
||||||
{
|
{
|
||||||
if(mod->type() == Mod::MOD_FOLDER)
|
if(mod->type() == ResourceType::FOLDER)
|
||||||
{
|
{
|
||||||
out << u8" [🖿] " + mod->fileinfo().completeBaseName() + " (folder)";
|
out << u8" [🖿] " + mod->fileinfo().completeBaseName() + " (folder)";
|
||||||
continue;
|
continue;
|
||||||
|
@ -36,13 +36,10 @@
|
|||||||
|
|
||||||
#include "Mod.h"
|
#include "Mod.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
|
||||||
#include <FileSystem.h>
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
#include "Application.h"
|
|
||||||
#include "MetadataHandler.h"
|
#include "MetadataHandler.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -51,75 +48,27 @@ ModDetails invalidDetails;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mod::Mod(const QFileInfo& file)
|
Mod::Mod(const QFileInfo& file) : Resource(file)
|
||||||
{
|
{
|
||||||
repath(file);
|
m_enabled = (file.suffix() != "disabled");
|
||||||
m_changedDateTime = file.lastModified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata)
|
Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata)
|
||||||
: m_file(mods_dir.absoluteFilePath(metadata.filename))
|
: Mod(mods_dir.absoluteFilePath(metadata.filename))
|
||||||
, m_internal_id(metadata.filename)
|
|
||||||
, m_name(metadata.name)
|
|
||||||
{
|
{
|
||||||
if (m_file.isDir()) {
|
m_name = metadata.name;
|
||||||
m_type = MOD_FOLDER;
|
|
||||||
} else {
|
|
||||||
if (metadata.filename.endsWith(".zip") || metadata.filename.endsWith(".jar"))
|
|
||||||
m_type = MOD_ZIPFILE;
|
|
||||||
else if (metadata.filename.endsWith(".litemod"))
|
|
||||||
m_type = MOD_LITEMOD;
|
|
||||||
else
|
|
||||||
m_type = MOD_SINGLEFILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_enabled = true;
|
|
||||||
m_changedDateTime = m_file.lastModified();
|
|
||||||
|
|
||||||
m_temp_metadata = std::make_shared<Metadata::ModStruct>(std::move(metadata));
|
m_temp_metadata = std::make_shared<Metadata::ModStruct>(std::move(metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mod::repath(const QFileInfo& file)
|
|
||||||
{
|
|
||||||
m_file = file;
|
|
||||||
QString name_base = file.fileName();
|
|
||||||
|
|
||||||
m_type = Mod::MOD_UNKNOWN;
|
|
||||||
|
|
||||||
m_internal_id = name_base;
|
|
||||||
|
|
||||||
if (m_file.isDir()) {
|
|
||||||
m_type = MOD_FOLDER;
|
|
||||||
m_name = name_base;
|
|
||||||
} else if (m_file.isFile()) {
|
|
||||||
if (name_base.endsWith(".disabled")) {
|
|
||||||
m_enabled = false;
|
|
||||||
name_base.chop(9);
|
|
||||||
} else {
|
|
||||||
m_enabled = true;
|
|
||||||
}
|
|
||||||
if (name_base.endsWith(".zip") || name_base.endsWith(".jar")) {
|
|
||||||
m_type = MOD_ZIPFILE;
|
|
||||||
name_base.chop(4);
|
|
||||||
} else if (name_base.endsWith(".litemod")) {
|
|
||||||
m_type = MOD_LITEMOD;
|
|
||||||
name_base.chop(8);
|
|
||||||
} else {
|
|
||||||
m_type = MOD_SINGLEFILE;
|
|
||||||
}
|
|
||||||
m_name = name_base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Mod::enable(bool value) -> bool
|
auto Mod::enable(bool value) -> bool
|
||||||
{
|
{
|
||||||
if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
|
if (m_type == ResourceType::UNKNOWN || m_type == ResourceType::FOLDER)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_enabled == value)
|
if (m_enabled == value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
QString path = m_file.absoluteFilePath();
|
QString path = m_file_info.absoluteFilePath();
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
if (value) {
|
if (value) {
|
||||||
if (!path.endsWith(".disabled"))
|
if (!path.endsWith(".disabled"))
|
||||||
@ -136,7 +85,7 @@ auto Mod::enable(bool value) -> bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (status() == ModStatus::NoMetadata)
|
if (status() == ModStatus::NoMetadata)
|
||||||
repath(QFileInfo(path));
|
setFile(QFileInfo(path));
|
||||||
|
|
||||||
m_enabled = value;
|
m_enabled = value;
|
||||||
return true;
|
return true;
|
||||||
@ -175,8 +124,7 @@ auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_type = MOD_UNKNOWN;
|
return Resource::destroy();
|
||||||
return FS::deletePath(m_file.filePath());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Mod::details() const -> const ModDetails&
|
auto Mod::details() const -> const ModDetails&
|
||||||
@ -239,8 +187,8 @@ auto Mod::metadata() const -> const std::shared_ptr<Metadata::ModStruct>
|
|||||||
|
|
||||||
void Mod::finishResolvingWithDetails(std::shared_ptr<ModDetails> details)
|
void Mod::finishResolvingWithDetails(std::shared_ptr<ModDetails> details)
|
||||||
{
|
{
|
||||||
m_resolving = false;
|
m_is_resolving = false;
|
||||||
m_resolved = true;
|
m_is_resolved = true;
|
||||||
m_localDetails = details;
|
m_localDetails = details;
|
||||||
|
|
||||||
setStatus(m_temp_status);
|
setStatus(m_temp_status);
|
||||||
|
@ -39,38 +39,23 @@
|
|||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
|
||||||
#include "QObjectPtr.h"
|
#include "Resource.h"
|
||||||
#include "ModDetails.h"
|
#include "ModDetails.h"
|
||||||
|
|
||||||
class Mod : public QObject
|
class Mod : public Resource
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
enum ModType
|
|
||||||
{
|
|
||||||
MOD_UNKNOWN, //!< Indicates an unspecified mod type.
|
|
||||||
MOD_ZIPFILE, //!< The mod is a zip file containing the mod's class files.
|
|
||||||
MOD_SINGLEFILE, //!< The mod is a single file (not a zip file).
|
|
||||||
MOD_FOLDER, //!< The mod is in a folder on the filesystem.
|
|
||||||
MOD_LITEMOD, //!< The mod is a litemod
|
|
||||||
};
|
|
||||||
|
|
||||||
using Ptr = shared_qobject_ptr<Mod>;
|
using Ptr = shared_qobject_ptr<Mod>;
|
||||||
|
|
||||||
Mod() = default;
|
Mod() = default;
|
||||||
Mod(const QFileInfo &file);
|
Mod(const QFileInfo &file);
|
||||||
explicit Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata);
|
explicit Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata);
|
||||||
|
|
||||||
auto fileinfo() const -> QFileInfo { return m_file; }
|
|
||||||
auto dateTimeChanged() const -> QDateTime { return m_changedDateTime; }
|
|
||||||
auto internal_id() const -> QString { return m_internal_id; }
|
|
||||||
auto type() const -> ModType { return m_type; }
|
|
||||||
auto enabled() const -> bool { return m_enabled; }
|
auto enabled() const -> bool { return m_enabled; }
|
||||||
|
|
||||||
auto valid() const -> bool { return m_type != MOD_UNKNOWN; }
|
|
||||||
|
|
||||||
auto details() const -> const ModDetails&;
|
auto details() const -> const ModDetails&;
|
||||||
auto name() const -> QString;
|
auto name() const -> QString override;
|
||||||
auto version() const -> QString;
|
auto version() const -> QString;
|
||||||
auto homeurl() const -> QString;
|
auto homeurl() const -> QString;
|
||||||
auto description() const -> QString;
|
auto description() const -> QString;
|
||||||
@ -85,31 +70,12 @@ public:
|
|||||||
|
|
||||||
auto enable(bool value) -> bool;
|
auto enable(bool value) -> bool;
|
||||||
|
|
||||||
// delete all the files of this mod
|
// Delete all the files of this mod
|
||||||
auto destroy(QDir& index_dir, bool preserve_metadata = false) -> bool;
|
auto destroy(QDir& index_dir, bool preserve_metadata = false) -> bool;
|
||||||
|
|
||||||
// change the mod's filesystem path (used by mod lists for *MAGIC* purposes)
|
|
||||||
void repath(const QFileInfo &file);
|
|
||||||
|
|
||||||
auto shouldResolve() const -> bool { return !m_resolving && !m_resolved; }
|
|
||||||
auto isResolving() const -> bool { return m_resolving; }
|
|
||||||
auto resolutionTicket() const -> int { return m_resolutionTicket; }
|
|
||||||
|
|
||||||
void setResolving(bool resolving, int resolutionTicket) {
|
|
||||||
m_resolving = resolving;
|
|
||||||
m_resolutionTicket = resolutionTicket;
|
|
||||||
}
|
|
||||||
void finishResolvingWithDetails(std::shared_ptr<ModDetails> details);
|
void finishResolvingWithDetails(std::shared_ptr<ModDetails> details);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QFileInfo m_file;
|
|
||||||
QDateTime m_changedDateTime;
|
|
||||||
|
|
||||||
QString m_internal_id;
|
|
||||||
/* Name as reported via the file name */
|
|
||||||
QString m_name;
|
|
||||||
ModType m_type = MOD_UNKNOWN;
|
|
||||||
|
|
||||||
/* If the mod has metadata, this will be filled in the constructor, and passed to
|
/* If the mod has metadata, this will be filled in the constructor, and passed to
|
||||||
* the ModDetails when calling finishResolvingWithDetails */
|
* the ModDetails when calling finishResolvingWithDetails */
|
||||||
std::shared_ptr<Metadata::ModStruct> m_temp_metadata;
|
std::shared_ptr<Metadata::ModStruct> m_temp_metadata;
|
||||||
@ -120,7 +86,4 @@ protected:
|
|||||||
std::shared_ptr<ModDetails> m_localDetails;
|
std::shared_ptr<ModDetails> m_localDetails;
|
||||||
|
|
||||||
bool m_enabled = true;
|
bool m_enabled = true;
|
||||||
bool m_resolving = false;
|
|
||||||
bool m_resolved = false;
|
|
||||||
int m_resolutionTicket = 0;
|
|
||||||
};
|
};
|
||||||
|
53
launcher/minecraft/mod/Resource.cpp
Normal file
53
launcher/minecraft/mod/Resource.cpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#include "Resource.h"
|
||||||
|
|
||||||
|
#include "FileSystem.h"
|
||||||
|
|
||||||
|
Resource::Resource(QObject* parent) : QObject(parent) {}
|
||||||
|
|
||||||
|
Resource::Resource(QFileInfo file_info) : QObject()
|
||||||
|
{
|
||||||
|
setFile(file_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resource::setFile(QFileInfo file_info)
|
||||||
|
{
|
||||||
|
m_file_info = file_info;
|
||||||
|
parseFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Resource::parseFile()
|
||||||
|
{
|
||||||
|
QString file_name{ m_file_info.fileName() };
|
||||||
|
|
||||||
|
m_type = ResourceType::UNKNOWN;
|
||||||
|
|
||||||
|
m_internal_id = file_name;
|
||||||
|
|
||||||
|
if (m_file_info.isDir()) {
|
||||||
|
m_type = ResourceType::FOLDER;
|
||||||
|
m_name = file_name;
|
||||||
|
} else if (m_file_info.isFile()) {
|
||||||
|
if (file_name.endsWith(".disabled"))
|
||||||
|
file_name.chop(9);
|
||||||
|
|
||||||
|
if (file_name.endsWith(".zip") || file_name.endsWith(".jar")) {
|
||||||
|
m_type = ResourceType::ZIPFILE;
|
||||||
|
file_name.chop(4);
|
||||||
|
} else if (file_name.endsWith(".litemod")) {
|
||||||
|
m_type = ResourceType::LITEMOD;
|
||||||
|
file_name.chop(8);
|
||||||
|
} else {
|
||||||
|
m_type = ResourceType::SINGLEFILE;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_name = file_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_changed_date_time = m_file_info.lastModified();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Resource::destroy()
|
||||||
|
{
|
||||||
|
m_type = ResourceType::UNKNOWN;
|
||||||
|
return FS::deletePath(m_file_info.filePath());
|
||||||
|
}
|
74
launcher/minecraft/mod/Resource.h
Normal file
74
launcher/minecraft/mod/Resource.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include "QObjectPtr.h"
|
||||||
|
|
||||||
|
enum class ResourceType {
|
||||||
|
UNKNOWN, //!< Indicates an unspecified resource type.
|
||||||
|
ZIPFILE, //!< The resource is a zip file containing the resource's class files.
|
||||||
|
SINGLEFILE, //!< The resource is a single file (not a zip file).
|
||||||
|
FOLDER, //!< The resource is in a folder on the filesystem.
|
||||||
|
LITEMOD, //!< The resource is a litemod
|
||||||
|
};
|
||||||
|
|
||||||
|
/** General class for managed resources. It mirrors a file in disk, with some more info
|
||||||
|
* for display and house-keeping purposes.
|
||||||
|
*
|
||||||
|
* Subclass it to add additional data / behavior, such as Mods or Resource packs.
|
||||||
|
*/
|
||||||
|
class Resource : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_DISABLE_COPY(Resource)
|
||||||
|
public:
|
||||||
|
using Ptr = shared_qobject_ptr<Resource>;
|
||||||
|
|
||||||
|
Resource(QObject* parent = nullptr);
|
||||||
|
Resource(QFileInfo file_info);
|
||||||
|
~Resource() override = default;
|
||||||
|
|
||||||
|
void setFile(QFileInfo file_info);
|
||||||
|
void parseFile();
|
||||||
|
|
||||||
|
[[nodiscard]] auto fileinfo() const -> QFileInfo { return m_file_info; }
|
||||||
|
[[nodiscard]] auto dateTimeChanged() const -> QDateTime { return m_changed_date_time; }
|
||||||
|
[[nodiscard]] auto internal_id() const -> QString { return m_internal_id; }
|
||||||
|
[[nodiscard]] auto type() const -> ResourceType { return m_type; }
|
||||||
|
|
||||||
|
[[nodiscard]] virtual auto name() const -> QString { return m_name; }
|
||||||
|
[[nodiscard]] virtual bool valid() const { return m_type != ResourceType::UNKNOWN; }
|
||||||
|
|
||||||
|
[[nodiscard]] auto shouldResolve() const -> bool { return !m_is_resolving && !m_is_resolved; }
|
||||||
|
[[nodiscard]] auto isResolving() const -> bool { return m_is_resolving; }
|
||||||
|
[[nodiscard]] auto resolutionTicket() const -> int { return m_resolution_ticket; }
|
||||||
|
|
||||||
|
void setResolving(bool resolving, int resolutionTicket)
|
||||||
|
{
|
||||||
|
m_is_resolving = resolving;
|
||||||
|
m_resolution_ticket = resolutionTicket;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all files of this resource.
|
||||||
|
bool destroy();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/* The file corresponding to this resource. */
|
||||||
|
QFileInfo m_file_info;
|
||||||
|
/* The cached date when this file was last changed. */
|
||||||
|
QDateTime m_changed_date_time;
|
||||||
|
|
||||||
|
/* Internal ID for internal purposes. Properties such as human-readability should not be assumed. */
|
||||||
|
QString m_internal_id;
|
||||||
|
/* Name as reported via the file name. In the absence of a better name, this is shown to the user. */
|
||||||
|
QString m_name;
|
||||||
|
|
||||||
|
/* The type of file we're dealing with. */
|
||||||
|
ResourceType m_type = ResourceType::UNKNOWN;
|
||||||
|
|
||||||
|
/* Used to keep trach of pending / concluded actions on the resource. */
|
||||||
|
bool m_is_resolving = false;
|
||||||
|
bool m_is_resolved = false;
|
||||||
|
int m_resolution_ticket = 0;
|
||||||
|
};
|
@ -110,7 +110,7 @@ void EnsureMetadataTask::executeTask()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Folders don't have metadata
|
// Folders don't have metadata
|
||||||
if (mod->type() == Mod::MOD_FOLDER) {
|
if (mod->type() == ResourceType::FOLDER) {
|
||||||
emitReady(mod);
|
emitReady(mod);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
void MCModInfoFrame::updateWithMod(Mod &m)
|
void MCModInfoFrame::updateWithMod(Mod &m)
|
||||||
{
|
{
|
||||||
if (m.type() == m.MOD_FOLDER)
|
if (m.type() == ResourceType::FOLDER)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user