efa414c442
Let's move off our custom QuaZip. In the olden times we needed the custom version of QuaZip, as it was basically unmaintained and on SourceForge (eww). But nowadays it's maintained and on GitHub. See new GitHub page: https://github.com/stachenov/quazip
119 lines
3.4 KiB
C++
119 lines
3.4 KiB
C++
/* 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 "ExtractNatives.h"
|
|
#include <minecraft/MinecraftInstance.h>
|
|
#include <launch/LaunchTask.h>
|
|
|
|
#include <QuaZip-Qt5-1.2/quazip/quazip.h>
|
|
#include <QuaZip-Qt5-1.2/quazip/quazipdir.h>
|
|
#include "MMCZip.h"
|
|
#include "FileSystem.h"
|
|
#include <QDir>
|
|
|
|
#ifdef major
|
|
#undef major
|
|
#endif
|
|
#ifdef minor
|
|
#undef minor
|
|
#endif
|
|
|
|
static QString replaceSuffix (QString target, const QString &suffix, const QString &replacement)
|
|
{
|
|
if (!target.endsWith(suffix))
|
|
{
|
|
return target;
|
|
}
|
|
target.resize(target.length() - suffix.length());
|
|
return target + replacement;
|
|
}
|
|
|
|
static bool unzipNatives(QString source, QString targetFolder, bool applyJnilibHack, bool nativeOpenAL, bool nativeGLFW)
|
|
{
|
|
QuaZip zip(source);
|
|
if(!zip.open(QuaZip::mdUnzip))
|
|
{
|
|
return false;
|
|
}
|
|
QDir directory(targetFolder);
|
|
if (!zip.goToFirstFile())
|
|
{
|
|
return false;
|
|
}
|
|
do
|
|
{
|
|
QString name = zip.getCurrentFileName();
|
|
auto lowercase = name.toLower();
|
|
if (nativeGLFW && name.contains("glfw")) {
|
|
continue;
|
|
}
|
|
if (nativeOpenAL && name.contains("openal")) {
|
|
continue;
|
|
}
|
|
if(applyJnilibHack)
|
|
{
|
|
name = replaceSuffix(name, ".jnilib", ".dylib");
|
|
}
|
|
QString absFilePath = directory.absoluteFilePath(name);
|
|
if (!JlCompress::extractFile(&zip, "", absFilePath))
|
|
{
|
|
return false;
|
|
}
|
|
} while (zip.goToNextFile());
|
|
zip.close();
|
|
if(zip.getZipError()!=0)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void ExtractNatives::executeTask()
|
|
{
|
|
auto instance = m_parent->instance();
|
|
std::shared_ptr<MinecraftInstance> minecraftInstance = std::dynamic_pointer_cast<MinecraftInstance>(instance);
|
|
auto toExtract = minecraftInstance->getNativeJars();
|
|
if(toExtract.isEmpty())
|
|
{
|
|
emitSucceeded();
|
|
return;
|
|
}
|
|
auto settings = minecraftInstance->settings();
|
|
bool nativeOpenAL = settings->get("UseNativeOpenAL").toBool();
|
|
bool nativeGLFW = settings->get("UseNativeGLFW").toBool();
|
|
|
|
auto outputPath = minecraftInstance->getNativePath();
|
|
auto javaVersion = minecraftInstance->getJavaVersion();
|
|
bool jniHackEnabled = javaVersion.major() >= 8;
|
|
for(const auto &source: toExtract)
|
|
{
|
|
if(!unzipNatives(source, outputPath, jniHackEnabled, nativeOpenAL, nativeGLFW))
|
|
{
|
|
const char *reason = QT_TR_NOOP("Couldn't extract native jar '%1' to destination '%2'");
|
|
emit logLine(QString(reason).arg(source, outputPath), MessageLevel::Fatal);
|
|
emitFailed(tr(reason).arg(source, outputPath));
|
|
}
|
|
}
|
|
emitSucceeded();
|
|
}
|
|
|
|
void ExtractNatives::finalize()
|
|
{
|
|
auto instance = m_parent->instance();
|
|
QString target_dir = FS::PathCombine(instance->instanceRoot(), "natives/");
|
|
QDir dir(target_dir);
|
|
dir.removeRecursively();
|
|
}
|