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/ModFolderModel.h
|
||||
minecraft/mod/ModFolderModel.cpp
|
||||
minecraft/mod/Resource.h
|
||||
minecraft/mod/Resource.cpp
|
||||
minecraft/mod/ResourcePackFolderModel.h
|
||||
minecraft/mod/ResourcePackFolderModel.cpp
|
||||
minecraft/mod/TexturePackFolderModel.h
|
||||
|
@ -148,7 +148,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
||||
// do not merge disabled mods.
|
||||
if (!mod->enabled())
|
||||
continue;
|
||||
if (mod->type() == Mod::MOD_ZIPFILE)
|
||||
if (mod->type() == ResourceType::ZIPFILE)
|
||||
{
|
||||
if (!mergeZipFiles(&zipOut, mod->fileinfo(), addedFiles))
|
||||
{
|
||||
@ -158,7 +158,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (mod->type() == Mod::MOD_SINGLEFILE)
|
||||
else if (mod->type() == ResourceType::SINGLEFILE)
|
||||
{
|
||||
// FIXME: buggy - does not work with addedFiles
|
||||
auto filename = mod->fileinfo();
|
||||
@ -171,7 +171,7 @@ bool MMCZip::createModdedJar(QString sourceJarPath, QString targetJarPath, const
|
||||
}
|
||||
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
|
||||
// FIXME: buggy - does not work with addedFiles
|
||||
|
@ -714,7 +714,7 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session, Minecr
|
||||
});
|
||||
for(auto mod: modList)
|
||||
{
|
||||
if(mod->type() == Mod::MOD_FOLDER)
|
||||
if(mod->type() == ResourceType::FOLDER)
|
||||
{
|
||||
out << u8" [🖿] " + mod->fileinfo().completeBaseName() + " (folder)";
|
||||
continue;
|
||||
|
@ -36,13 +36,10 @@
|
||||
|
||||
#include "Mod.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QString>
|
||||
|
||||
#include <FileSystem.h>
|
||||
#include <QDebug>
|
||||
|
||||
#include "Application.h"
|
||||
#include "MetadataHandler.h"
|
||||
|
||||
namespace {
|
||||
@ -51,75 +48,27 @@ ModDetails invalidDetails;
|
||||
|
||||
}
|
||||
|
||||
Mod::Mod(const QFileInfo& file)
|
||||
Mod::Mod(const QFileInfo& file) : Resource(file)
|
||||
{
|
||||
repath(file);
|
||||
m_changedDateTime = file.lastModified();
|
||||
m_enabled = (file.suffix() != "disabled");
|
||||
}
|
||||
|
||||
Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata)
|
||||
: m_file(mods_dir.absoluteFilePath(metadata.filename))
|
||||
, m_internal_id(metadata.filename)
|
||||
, m_name(metadata.name)
|
||||
: Mod(mods_dir.absoluteFilePath(metadata.filename))
|
||||
{
|
||||
if (m_file.isDir()) {
|
||||
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_name = metadata.name;
|
||||
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
|
||||
{
|
||||
if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
|
||||
if (m_type == ResourceType::UNKNOWN || m_type == ResourceType::FOLDER)
|
||||
return false;
|
||||
|
||||
if (m_enabled == value)
|
||||
return false;
|
||||
|
||||
QString path = m_file.absoluteFilePath();
|
||||
QString path = m_file_info.absoluteFilePath();
|
||||
QFile file(path);
|
||||
if (value) {
|
||||
if (!path.endsWith(".disabled"))
|
||||
@ -136,7 +85,7 @@ auto Mod::enable(bool value) -> bool
|
||||
}
|
||||
|
||||
if (status() == ModStatus::NoMetadata)
|
||||
repath(QFileInfo(path));
|
||||
setFile(QFileInfo(path));
|
||||
|
||||
m_enabled = value;
|
||||
return true;
|
||||
@ -175,8 +124,7 @@ auto Mod::destroy(QDir& index_dir, bool preserve_metadata) -> bool
|
||||
}
|
||||
}
|
||||
|
||||
m_type = MOD_UNKNOWN;
|
||||
return FS::deletePath(m_file.filePath());
|
||||
return Resource::destroy();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
m_resolving = false;
|
||||
m_resolved = true;
|
||||
m_is_resolving = false;
|
||||
m_is_resolved = true;
|
||||
m_localDetails = details;
|
||||
|
||||
setStatus(m_temp_status);
|
||||
|
@ -39,38 +39,23 @@
|
||||
#include <QFileInfo>
|
||||
#include <QList>
|
||||
|
||||
#include "QObjectPtr.h"
|
||||
#include "Resource.h"
|
||||
#include "ModDetails.h"
|
||||
|
||||
class Mod : public QObject
|
||||
class Mod : public Resource
|
||||
{
|
||||
Q_OBJECT
|
||||
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>;
|
||||
|
||||
Mod() = default;
|
||||
Mod(const QFileInfo &file);
|
||||
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 valid() const -> bool { return m_type != MOD_UNKNOWN; }
|
||||
|
||||
auto details() const -> const ModDetails&;
|
||||
auto name() const -> QString;
|
||||
auto name() const -> QString override;
|
||||
auto version() const -> QString;
|
||||
auto homeurl() const -> QString;
|
||||
auto description() const -> QString;
|
||||
@ -85,31 +70,12 @@ public:
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
|
||||
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
|
||||
* the ModDetails when calling finishResolvingWithDetails */
|
||||
std::shared_ptr<Metadata::ModStruct> m_temp_metadata;
|
||||
@ -120,7 +86,4 @@ protected:
|
||||
std::shared_ptr<ModDetails> m_localDetails;
|
||||
|
||||
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
|
||||
if (mod->type() == Mod::MOD_FOLDER) {
|
||||
if (mod->type() == ResourceType::FOLDER) {
|
||||
emitReady(mod);
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
void MCModInfoFrame::updateWithMod(Mod &m)
|
||||
{
|
||||
if (m.type() == m.MOD_FOLDER)
|
||||
if (m.type() == ResourceType::FOLDER)
|
||||
{
|
||||
clear();
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user