aboutsummaryrefslogtreecommitdiff
path: root/launcher/minecraft/mod/Mod.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'launcher/minecraft/mod/Mod.cpp')
-rw-r--r--launcher/minecraft/mod/Mod.cpp205
1 files changed, 139 insertions, 66 deletions
diff --git a/launcher/minecraft/mod/Mod.cpp b/launcher/minecraft/mod/Mod.cpp
index b6bff29b..71a32d32 100644
--- a/launcher/minecraft/mod/Mod.cpp
+++ b/launcher/minecraft/mod/Mod.cpp
@@ -1,24 +1,48 @@
-/* Copyright 2013-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+// SPDX-License-Identifier: GPL-3.0-only
+/*
+* PolyMC - Minecraft Launcher
+* Copyright (c) 2022 flowln <flowlnlnln@gmail.com>
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, version 3.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <https://www.gnu.org/licenses/>.
+*
+* This file incorporates work covered by the following copyright and
+* permission notice:
+*
+* Copyright 2013-2021 MultiMC Contributors
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include "Mod.h"
#include <QDir>
#include <QString>
-#include "Mod.h"
-#include <QDebug>
#include <FileSystem.h>
+#include <QDebug>
+
+#include "Application.h"
+#include "MetadataHandler.h"
namespace {
@@ -26,57 +50,69 @@ ModDetails invalidDetails;
}
-
-Mod::Mod(const QFileInfo &file)
+Mod::Mod(const QFileInfo& file)
{
repath(file);
m_changedDateTime = file.lastModified();
}
-void Mod::repath(const QFileInfo &file)
+Mod::Mod(const QDir& mods_dir, const Metadata::ModStruct& metadata)
+ : m_file(mods_dir.absoluteFilePath(metadata.filename))
+ // It is weird, but name is not reliable for comparing with the JAR files name
+ // FIXME: Maybe use hash when implemented?
+ , m_internal_id(metadata.filename)
+ , m_name(metadata.name)
+{
+ 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_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_mmc_id = name_base;
+ m_internal_id = name_base;
- if (m_file.isDir())
- {
+ if (m_file.isDir()) {
m_type = MOD_FOLDER;
m_name = name_base;
- }
- else if (m_file.isFile())
- {
- if (name_base.endsWith(".disabled"))
- {
+ } else if (m_file.isFile()) {
+ if (name_base.endsWith(".disabled")) {
m_enabled = false;
name_base.chop(9);
- }
- else
- {
+ } else {
m_enabled = true;
}
- if (name_base.endsWith(".zip") || name_base.endsWith(".jar"))
- {
+ if (name_base.endsWith(".zip") || name_base.endsWith(".jar")) {
m_type = MOD_ZIPFILE;
name_base.chop(4);
- }
- else if (name_base.endsWith(".litemod"))
- {
+ } else if (name_base.endsWith(".litemod")) {
m_type = MOD_LITEMOD;
name_base.chop(8);
- }
- else
- {
+ } else {
m_type = MOD_SINGLEFILE;
}
m_name = name_base;
}
}
-bool Mod::enable(bool value)
+auto Mod::enable(bool value) -> bool
{
if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
return false;
@@ -85,67 +121,104 @@ bool Mod::enable(bool value)
return false;
QString path = m_file.absoluteFilePath();
- if (value)
- {
- QFile foo(path);
+ QFile file(path);
+ if (value) {
if (!path.endsWith(".disabled"))
return false;
path.chop(9);
- if (!foo.rename(path))
+
+ if (!file.rename(path))
return false;
- }
- else
- {
- QFile foo(path);
+ } else {
path += ".disabled";
- if (!foo.rename(path))
+
+ if (!file.rename(path))
return false;
}
- repath(QFileInfo(path));
+
+ if (status() == ModStatus::NoMetadata)
+ repath(QFileInfo(path));
+
m_enabled = value;
return true;
}
-bool Mod::destroy()
+void Mod::setStatus(ModStatus status)
{
- m_type = MOD_UNKNOWN;
- return FS::deletePath(m_file.filePath());
+ if(m_localDetails.get())
+ m_localDetails->status = status;
}
+void Mod::setMetadata(Metadata::ModStruct* metadata)
+{
+ if(status() == ModStatus::NoMetadata)
+ setStatus(ModStatus::Installed);
+ if(m_localDetails.get())
+ m_localDetails->metadata.reset(metadata);
+}
-const ModDetails & Mod::details() const
+auto Mod::destroy(QDir& index_dir) -> bool
{
- if(!m_localDetails)
- return invalidDetails;
- return *m_localDetails;
-}
+ auto n = name();
+ // FIXME: This can fail to remove the metadata if the
+ // "DontUseModMetadata" setting is on, since there could
+ // be a name mismatch!
+ Metadata::remove(index_dir, n);
+ m_type = MOD_UNKNOWN;
+ return FS::deletePath(m_file.filePath());
+}
-QString Mod::version() const
+auto Mod::details() const -> const ModDetails&
{
- return details().version;
+ return m_localDetails ? *m_localDetails : invalidDetails;
}
-QString Mod::name() const
+auto Mod::name() const -> QString
{
- auto & d = details();
- if(!d.name.isEmpty()) {
- return d.name;
+ auto d_name = details().name;
+ if (!d_name.isEmpty()) {
+ return d_name;
}
return m_name;
}
-QString Mod::homeurl() const
+auto Mod::version() const -> QString
+{
+ return details().version;
+}
+
+auto Mod::homeurl() const -> QString
{
return details().homeurl;
}
-QString Mod::description() const
+auto Mod::description() const -> QString
{
return details().description;
}
-QStringList Mod::authors() const
+auto Mod::authors() const -> QStringList
{
return details().authors;
}
+
+auto Mod::status() const -> ModStatus
+{
+ return details().status;
+}
+
+void Mod::finishResolvingWithDetails(std::shared_ptr<ModDetails> details)
+{
+ m_resolving = false;
+ m_resolved = true;
+ m_localDetails = details;
+
+ if (status() != ModStatus::NoMetadata
+ && m_temp_metadata.get()
+ && m_temp_metadata->isValid() &&
+ m_localDetails.get()) {
+
+ m_localDetails->metadata.swap(m_temp_metadata);
+ }
+}