Skip to content
This repository has been archived by the owner on Mar 21, 2022. It is now read-only.

Commit

Permalink
Merge pull request #2 from MultiMC/develop
Browse files Browse the repository at this point in the history
Update
  • Loading branch information
golandprog authored Nov 15, 2020
2 parents 6a3b97d + 66c0999 commit 60467b8
Show file tree
Hide file tree
Showing 34 changed files with 2,420 additions and 13 deletions.
29 changes: 29 additions & 0 deletions api/logic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -306,13 +306,32 @@ set(MINECRAFT_SOURCES
# Skin upload utilities
minecraft/SkinUpload.cpp
minecraft/SkinUpload.h

mojang/PackageManifest.h
mojang/PackageManifest.cpp
)

add_unit_test(GradleSpecifier
SOURCES minecraft/GradleSpecifier_test.cpp
LIBS MultiMC_logic
)

add_executable(PackageManifest
mojang/PackageManifest_test.cpp
)
target_link_libraries(PackageManifest
MultiMC_logic
Qt5::Test
)
target_include_directories(PackageManifest
PRIVATE ../../cmake/UnitTest/
)
add_test(
NAME PackageManifest
COMMAND PackageManifest
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_unit_test(MojangVersionFormat
SOURCES minecraft/MojangVersionFormat_test.cpp
LIBS MultiMC_logic
Expand Down Expand Up @@ -458,6 +477,15 @@ set(MODPACKSCH_SOURCES
modplatform/modpacksch/FTBPackManifest.cpp
)

set(TECHNIC_SOURCES
modplatform/technic/SingleZipPackInstallTask.h
modplatform/technic/SingleZipPackInstallTask.cpp
modplatform/technic/SolderPackInstallTask.h
modplatform/technic/SolderPackInstallTask.cpp
modplatform/technic/TechnicPackProcessor.h
modplatform/technic/TechnicPackProcessor.cpp
)

add_unit_test(Index
SOURCES meta/Index_test.cpp
LIBS MultiMC_logic
Expand Down Expand Up @@ -489,6 +517,7 @@ set(LOGIC_SOURCES
${FTB_SOURCES}
${FLAME_SOURCES}
${MODPACKSCH_SOURCES}
${TECHNIC_SOURCES}
)

add_library(MultiMC_logic SHARED ${LOGIC_SOURCES})
Expand Down
1 change: 1 addition & 0 deletions api/logic/Env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ void Env::initHttpMetaCache()
m_metacache->addBase("general", QDir("cache").absolutePath());
m_metacache->addBase("FTBPacks", QDir("cache/FTBPacks").absolutePath());
m_metacache->addBase("ModpacksCHPacks", QDir("cache/ModpacksCHPacks").absolutePath());
m_metacache->addBase("TechnicPacks", QDir("cache/TechnicPacks").absolutePath());
m_metacache->addBase("TwitchPacks", QDir("cache/TwitchPacks").absolutePath());
m_metacache->addBase("skins", QDir("accounts/skins").absolutePath());
m_metacache->addBase("root", QDir::currentPath());
Expand Down
40 changes: 37 additions & 3 deletions api/logic/InstanceImportTask.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/* Copyright 2013-2020 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 "InstanceImportTask.h"
#include "BaseInstance.h"
#include "FileSystem.h"
Expand All @@ -15,6 +30,8 @@
#include "modplatform/flame/FileResolvingTask.h"
#include "modplatform/flame/PackManifest.h"
#include "Json.h"
#include <quazipdir.h>
#include "modplatform/technic/TechnicPackProcessor.h"

InstanceImportTask::InstanceImportTask(const QUrl sourceUrl)
{
Expand All @@ -23,8 +40,6 @@ InstanceImportTask::InstanceImportTask(const QUrl sourceUrl)

void InstanceImportTask::executeTask()
{
InstancePtr newInstance;

if (m_sourceUrl.isLocalFile())
{
m_archivePath = m_sourceUrl.toLocalFile();
Expand Down Expand Up @@ -82,6 +97,7 @@ void InstanceImportTask::processZipPack()

QStringList blacklist = {"instance.cfg", "manifest.json"};
QString mmcFound = MMCZip::findFolderOfFileInZip(m_packZip.get(), "instance.cfg");
bool technicFound = QuaZipDir(m_packZip.get()).exists("/bin/modpack.jar") || QuaZipDir(m_packZip.get()).exists("/bin/version.json");
QString flameFound = MMCZip::findFolderOfFileInZip(m_packZip.get(), "manifest.json");
QString root;
if(!mmcFound.isNull())
Expand All @@ -91,14 +107,21 @@ void InstanceImportTask::processZipPack()
root = mmcFound;
m_modpackType = ModpackType::MultiMC;
}
else if (technicFound)
{
// process as Technic pack
qDebug() << "Technic:" << technicFound;
extractDir.mkpath(".minecraft");
extractDir.cd(".minecraft");
m_modpackType = ModpackType::Technic;
}
else if(!flameFound.isNull())
{
// process as Flame pack
qDebug() << "Flame:" << flameFound;
root = flameFound;
m_modpackType = ModpackType::Flame;
}

if(m_modpackType == ModpackType::Unknown)
{
emitFailed(tr("Archive does not contain a recognized modpack type."));
Expand Down Expand Up @@ -161,6 +184,9 @@ void InstanceImportTask::extractFinished()
case ModpackType::MultiMC:
processMultiMC();
return;
case ModpackType::Technic:
processTechnic();
return;
case ModpackType::Unknown:
emitFailed(tr("Archive does not contain a recognized modpack type."));
return;
Expand Down Expand Up @@ -371,6 +397,14 @@ void InstanceImportTask::processFlame()
m_modIdResolver->start();
}

void InstanceImportTask::processTechnic()
{
shared_qobject_ptr<Technic::TechnicPackProcessor> packProcessor = new Technic::TechnicPackProcessor();
connect(packProcessor.get(), &Technic::TechnicPackProcessor::succeeded, this, &InstanceImportTask::emitSucceeded);
connect(packProcessor.get(), &Technic::TechnicPackProcessor::failed, this, &InstanceImportTask::emitFailed);
packProcessor->run(m_globalSettings, m_instName, m_instIcon, m_stagingPath);
}

void InstanceImportTask::processMultiMC()
{
// FIXME: copy from FolderInstanceProvider!!! FIX IT!!!
Expand Down
19 changes: 18 additions & 1 deletion api/logic/InstanceImportTask.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/* Copyright 2013-2020 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.
*/

#pragma once

#include "InstanceTask.h"
Expand Down Expand Up @@ -29,6 +44,7 @@ class MULTIMC_LOGIC_EXPORT InstanceImportTask : public InstanceTask
void processZipPack();
void processMultiMC();
void processFlame();
void processTechnic();

private slots:
void downloadSucceeded();
Expand All @@ -49,6 +65,7 @@ private slots:
enum class ModpackType{
Unknown,
MultiMC,
Flame
Flame,
Technic
} m_modpackType = ModpackType::Unknown;
};
2 changes: 1 addition & 1 deletion api/logic/MMCZip.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright 2013-2019 MultiMC Contributors
/* Copyright 2013-2020 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
3 changes: 1 addition & 2 deletions api/logic/MMCZip.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright 2013-2019 MultiMC Contributors
/* Copyright 2013-2020 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -67,5 +67,4 @@ namespace MMCZip
* \return The list of the full paths of the files extracted, empty on failure.
*/
QStringList MULTIMC_LOGIC_EXPORT extractDir(QString fileCompressed, QString dir);

}
8 changes: 6 additions & 2 deletions api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,16 +123,20 @@ void PackInstallTask::install()
auto dl = Net::Download::makeFile(file.url, path);
jobPtr->addNetAction(dl);
}

connect(jobPtr.get(), &NetJob::succeeded, this, [&]()
{
jobPtr.reset();
emitSucceeded();
});

connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
{
jobPtr.reset();
emitFailed(reason);

// FIXME: Temporarily ignore file download failures (matching FTB's installer),
// while FTB's data is fucked.
qWarning() << "Failed to download files for modpack: " + reason;
emitSucceeded();
});
connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total)
{
Expand Down
129 changes: 129 additions & 0 deletions api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/* Copyright 2013-2020 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 "SingleZipPackInstallTask.h"

#include "Env.h"
#include "MMCZip.h"
#include "TechnicPackProcessor.h"

#include <QtConcurrent>
#include <FileSystem.h>

Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion)
{
m_sourceUrl = sourceUrl;
m_minecraftVersion = minecraftVersion;
}

void Technic::SingleZipPackInstallTask::executeTask()
{
setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString()));

const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path();
auto entry = ENV.metacache()->resolveEntry("general", path);
entry->setStale(true);
m_filesNetJob.reset(new NetJob(tr("Modpack download")));
m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
m_archivePath = entry->getFullPath();
auto job = m_filesNetJob.get();
connect(job, &NetJob::succeeded, this, &Technic::SingleZipPackInstallTask::downloadSucceeded);
connect(job, &NetJob::progress, this, &Technic::SingleZipPackInstallTask::downloadProgressChanged);
connect(job, &NetJob::failed, this, &Technic::SingleZipPackInstallTask::downloadFailed);
m_filesNetJob->start();
}

void Technic::SingleZipPackInstallTask::downloadSucceeded()
{
setStatus(tr("Extracting modpack"));
QDir extractDir(FS::PathCombine(m_stagingPath, ".minecraft"));
qDebug() << "Attempting to create instance from" << m_archivePath;

// open the zip and find relevant files in it
m_packZip.reset(new QuaZip(m_archivePath));
if (!m_packZip->open(QuaZip::mdUnzip))
{
emitFailed(tr("Unable to open supplied modpack zip file."));
return;
}
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), QString(""), extractDir.absolutePath());
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &Technic::SingleZipPackInstallTask::extractFinished);
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &Technic::SingleZipPackInstallTask::extractAborted);
m_extractFutureWatcher.setFuture(m_extractFuture);
m_filesNetJob.reset();
}

void Technic::SingleZipPackInstallTask::downloadFailed(QString reason)
{
emitFailed(reason);
m_filesNetJob.reset();
}

void Technic::SingleZipPackInstallTask::downloadProgressChanged(qint64 current, qint64 total)
{
setProgress(current / 2, total);
}

void Technic::SingleZipPackInstallTask::extractFinished()
{
m_packZip.reset();
if (m_extractFuture.result().isEmpty())
{
emitFailed(tr("Failed to extract modpack"));
return;
}
QDir extractDir(m_stagingPath);

qDebug() << "Fixing permissions for extracted pack files...";
QDirIterator it(extractDir, QDirIterator::Subdirectories);
while (it.hasNext())
{
auto filepath = it.next();
QFileInfo file(filepath);
auto permissions = QFile::permissions(filepath);
auto origPermissions = permissions;
if (file.isDir())
{
// Folder +rwx for current user
permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser;
}
else
{
// File +rw for current user
permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser;
}
if (origPermissions != permissions)
{
if (!QFile::setPermissions(filepath, permissions))
{
logWarning(tr("Could not fix permissions for %1").arg(filepath));
}
else
{
qDebug() << "Fixed" << filepath;
}
}
}

shared_qobject_ptr<Technic::TechnicPackProcessor> packProcessor = new Technic::TechnicPackProcessor();
connect(packProcessor.get(), &Technic::TechnicPackProcessor::succeeded, this, &Technic::SingleZipPackInstallTask::emitSucceeded);
connect(packProcessor.get(), &Technic::TechnicPackProcessor::failed, this, &Technic::SingleZipPackInstallTask::emitFailed);
packProcessor->run(m_globalSettings, m_instName, m_instIcon, m_stagingPath, m_minecraftVersion);
}

void Technic::SingleZipPackInstallTask::extractAborted()
{
emitFailed(tr("Instance import has been aborted."));
}
Loading

0 comments on commit 60467b8

Please sign in to comment.