Compare commits

..

50 Commits

Author SHA1 Message Date
janrupf
8369dbdcc0 GH-2584, GH-1663 Limit icon size to 512x512 2019-06-22 01:29:25 +02:00
Petr Mrázek
ce12f1a734 Merge pull request #2694 from Janrupf/fix-disabled-mods
Operate on copy of QString instead of appending
2019-06-17 23:21:26 +02:00
janrupf
c1953739d9 NOISSUE Don't append .disabled to string 2019-06-17 15:49:26 +02:00
Petr Mrázek
e8bf9cef24 Merge branch 'develop' of https://github.com/lelandliu/MultiMC5 into develop 2019-06-15 22:47:36 +02:00
Petr Mrázek
8aa4b9dac5 NOISSUE limit fabric intermediary selection options in UI by minecraft version 2019-06-15 22:45:56 +02:00
Petr Mrázek
4836ba22cd NOISSUE fix fabric tooltip string 2019-06-15 22:29:34 +02:00
Petr Mrázek
6c30076b6c GH-2639 Add simple fabric loader installation support 2019-06-15 21:25:23 +02:00
Petr Mrázek
83c48a0f1a Merge pull request #2690 from asiekierka/fabric-modparse
Add Fabric mod JSON parsing support
2019-06-15 20:41:42 +02:00
asie
d251097545 fix author name parsing 2019-06-15 16:36:13 +02:00
asie
c35dbd972e Add Fabric mod JSON parsing support 2019-06-15 13:54:20 +02:00
Leland Liu
0c5d121452 Fixed adding a disabled duplicate 2019-06-14 15:48:24 -04:00
Petr Mrázek
53ad5cb436 Merge pull request #2684 from isoraqathedh/patch-1
Pass command line arguments through to the executable
2019-06-08 15:53:01 +02:00
isoraqathedh
d87bd4b588 Update run.sh
Pass command line arguments through to the executable
2019-06-08 21:21:22 +08:00
Petr Mrázek
86850ef5d0 NOISSUE fix macOS build, remove bundled dependencies on linux
Your copy of MultiMC might stop working after this update
because we no longer bundle Qt and other system libraries.

Contact us at https://discord.gg/0k2zsXGNHs0fE4Wm if
you need help with installing Qt.

Qt 5.4.x or newer is required.
2019-06-08 15:08:24 +02:00
Petr Mrázek
30fba4d407 NOISSUE make the global settings button context sensitive 2019-06-01 18:05:42 +02:00
Petr Mrázek
932160818e NOISSUE add option to open global settings from instance settings
This should hopefully giude people towards using the right thing.
2019-06-01 12:28:53 +02:00
Petr Mrázek
59e1ed3d87 NOISSUE add the pocket fox icon 2019-06-01 00:59:02 +02:00
Petr Mrázek
3470a3df96 NOISSUE improve icon handling while importing and exporting instances
Now it handles formats other than png.
2019-05-31 21:53:58 +02:00
Petr Mrázek
61913daaf3 Merge pull request #2603 from AlexTMjugador/develop
Support launching profiler in offline mode
2019-04-14 23:34:10 +02:00
Alejandro González
cb71dfa605 Tweak strings as per peterix review 2019-04-14 23:02:01 +02:00
AlexTMjugador
2be98baaba Conform to existing code style 2019-04-15 00:44:59 +02:00
AlexTMjugador
0ce637bf0e Support launching profiler in offline mode
This commit adds the necessary GUI controls to let the user choose
whether they want to launch Minecraft in offline mode with a configured profiler.
2019-04-15 00:42:06 +02:00
Petr Mrázek
70ed30f9e6 GH-2591 less std::shared_ptr and more shared_qobject_ptr
This eliminates some weird crashes.
2019-04-07 23:59:04 +02:00
Petr Mrázek
414946cad9 Merge remote-tracking branch 'origin/feature/trim_server_details' into develop 2019-04-02 23:39:13 +02:00
Elise
1fc199697c GH-2551 Trim at serialization 2019-03-29 11:25:37 -04:00
Petr Mrázek
9292d846b6 Merge pull request #2565 from MultiMC/feature/deletion_harder
GH-2487 Make deleting instances harder
2019-03-23 14:23:45 +01:00
Elise
22db95ce3b Merge branch 'develop' into feature/deletion_harder 2019-03-19 16:29:40 -04:00
Elise
597fe50d37 GH-2551 Trim server name and IP strings 2019-03-19 13:28:11 -04:00
Petr Mrázek
bf93ba02e9 NOISSUE fix metadata URL 2019-03-08 02:04:08 +01:00
Petr Mrázek
07c1685ff1 NOISSUE create translations folder before starting to watch it for changes
Fixes issue where on first run, the translations don't show up.
2019-03-08 01:21:04 +01:00
Elise
a5e531d4f1 GH-2487 Make NO the default button 2019-02-26 16:56:08 -05:00
Petr Mrázek
ae956d8fd6 NOISSUE update changelog 2019-02-21 00:45:36 +01:00
Petr Mrázek
73e487a31e NOISSUE hide the game options screen again 2019-02-21 00:44:36 +01:00
Petr Mrázek
0b95d2b03f NOISSUE fix build 2019-02-19 01:11:54 +01:00
Petr Mrázek
9c82adaee5 GH-2209 Fix sounds in old (pre-1.6) versions 2019-02-19 01:00:03 +01:00
Petr Mrázek
0a99d037c4 Merge pull request #2532 from andersmmg/patch-1
Update title of Add Empty dialog
2019-02-05 08:44:07 +01:00
Joshua Anderson
6e8e4c5dfa Update title of Add Empty dialog 2019-02-05 00:06:29 -07:00
Petr Mrázek
e4599ee2d1 NOISSUE fix builds? 2019-01-30 01:12:21 +01:00
Petr Mrázek
62c9fcdc6c NOISSUE first step towards having game options management 2019-01-30 00:35:24 +01:00
Petr Mrázek
c1ea42d3d9 Merge branch 'stable' of https://github.com/Scotsguy/MultiMC5 into develop 2019-01-17 00:51:54 +01:00
AppleTheGolden
437dec91f9 Update Copyright Year 2019-01-16 21:14:24 +01:00
Petr Mrázek
7436c94976 NOISSUE Replace Quality with Completeness in language widget
Completeness does no imply quality.
2019-01-14 01:36:04 +01:00
Petr Mrázek
c08053d8b8 NOISSUE split out language selection widget, use it in settings 2019-01-09 04:38:35 +01:00
Petr Mrázek
e71786d7b9 NOISSUE language selection wizard improvements
Same needs to be applied to the application settings later.
2019-01-08 02:20:36 +01:00
Petr Mrázek
819503d530 NOISSUE bump version to 0.6.5 2019-01-06 22:56:05 +01:00
Petr Mrázek
d6ace374d8 NOISSUE update changelog some more 2019-01-06 22:54:00 +01:00
Petr Mrázek
6a21c043ce NOISSUE bump version to 0.6.4 and update changelog 2019-01-06 22:28:27 +01:00
Petr Mrázek
4474d269cc NOISSUE granular model updates for language model 2019-01-06 22:14:13 +01:00
Petr Mrázek
ec2732ccd1 NOISSUE update FTB URLs 2019-01-04 01:48:36 +01:00
Petr Mrázek
4b7971f60f NOISSUE hotloading of translations and use of local PO files
The hotloading is still inefficient
2019-01-02 01:41:07 +01:00
308 changed files with 3165 additions and 580 deletions

View File

@@ -46,7 +46,7 @@ set(MultiMC_NEWS_RSS_URL "https://multimc.org/rss.xml" CACHE STRING "URL to fetc
######## Set version numbers ########
set(MultiMC_VERSION_MAJOR 0)
set(MultiMC_VERSION_MINOR 6)
set(MultiMC_VERSION_HOTFIX 3)
set(MultiMC_VERSION_HOTFIX 5)
# Build number
set(MultiMC_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
@@ -141,7 +141,7 @@ if(MultiMC_LAYOUT_REAL STREQUAL "mac-bundle")
set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MINOR}.${MultiMC_VERSION_HOTFIX}.${MultiMC_VERSION_BUILD}")
set(MACOSX_BUNDLE_ICON_FILE MultiMC.icns)
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2018 MultiMC Contributors")
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2015-2019 MultiMC Contributors")
# directories to look for dependencies
set(DIRS ${QT_LIBS_DIR} ${QT_LIBEXECS_DIR} ${CMAKE_LIBRARY_OUTPUT_DIRECTORY} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})

View File

@@ -1,6 +1,6 @@
# MultiMC
Copyright 2012-2018 MultiMC Contributors
Copyright 2012-2019 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

View File

@@ -38,7 +38,7 @@ Apache covers reasonable use for the name - a mention of the project's origins i
## License
Copyright © 2013-2018 MultiMC Contributors
Copyright © 2013-2019 MultiMC Contributors
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this program except in compliance with the License. You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0).

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -187,8 +187,7 @@ Qt::DropActions IconList::supportedDropActions() const
return Qt::CopyAction;
}
bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column,
const QModelIndex &parent)
bool IconList::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
if (action == Qt::IgnoreAction)
return true;
@@ -255,17 +254,7 @@ void IconList::installIcons(const QStringList &iconFiles)
{
for (QString file : iconFiles)
{
QFileInfo fileinfo(file);
if (!fileinfo.isReadable() || !fileinfo.isFile())
continue;
QString target = FS::PathCombine(m_dir.dirName(), fileinfo.fileName());
QString suffix = fileinfo.suffix();
if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico" && suffix != "svg" && suffix != "gif")
continue;
if (!QFile::copy(file, target))
continue;
installIcon(file, QFileInfo(file).fileName());
}
}
@@ -273,11 +262,24 @@ void IconList::installIcon(const QString &file, const QString &name)
{
QFileInfo fileinfo(file);
if(!fileinfo.isReadable() || !fileinfo.isFile())
{
qWarning() << "Failed to install icon" << fileinfo.absoluteFilePath();
return;
}
QString target = FS::PathCombine(m_dir.dirName(), name);
QFile::copy(file, target);
QPixmap icon(fileinfo.absoluteFilePath());
if(icon.isNull())
{
qWarning() << "Icon " << fileinfo.absoluteFilePath() << "is null";
return;
}
auto currentSize = icon.size();
auto targetedWidth = qMin(currentSize.width(), 512);
auto targetedHeight = qMin(currentSize.height(), 512);
icon.scaled(targetedWidth, targetedHeight).save(target);
}
bool IconList::iconFileExists(const QString &key) const

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -80,7 +80,7 @@ protected slots:
void fileChanged(const QString &path);
void SettingChanged(const Setting & setting, QVariant value);
private:
std::shared_ptr<QFileSystemWatcher> m_watcher;
shared_qobject_ptr<QFileSystemWatcher> m_watcher;
bool is_watching;
QMap<QString, int> name_index;
QVector<MMCIcon> icons;

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -102,3 +102,17 @@ void MMCIcon::replace(IconType new_type, const QString& key)
m_images[new_type].filename = QString();
m_images[new_type].key = key;
}
QString MMCIcon::getFilePath() const
{
if(m_current_type == IconType::ToBeDeleted){
return QString();
}
return m_images[m_current_type].filename;
}
bool MMCIcon::isBuiltIn() const
{
return m_current_type == IconType::Builtin;
}

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,4 +46,6 @@ struct MULTIMC_GUI_EXPORT MMCIcon
void remove(IconType rm_type);
void replace(IconType new_type, QIcon icon, QString path = QString());
void replace(IconType new_type, const QString &key);
bool isBuiltIn() const;
QString getFilePath() const;
};

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -175,11 +175,6 @@ QString BaseInstance::instanceRoot() const
return m_rootDir;
}
InstancePtr BaseInstance::getSharedPtr()
{
return shared_from_this();
}
SettingsObjectPtr BaseInstance::settings() const
{
return m_settings;
@@ -253,7 +248,7 @@ QStringList BaseInstance::extraArguments() const
return Commandline::splitArgs(settings()->get("JvmArgs").toString());
}
std::shared_ptr<LaunchTask> BaseInstance::getLaunchTask()
shared_qobject_ptr<LaunchTask> BaseInstance::getLaunchTask()
{
return m_launchProcess;
}

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -134,8 +134,6 @@ public:
/// Sets the last launched time to 'val' milliseconds since epoch
void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch());
InstancePtr getSharedPtr();
/*!
* \brief Gets this instance's settings object.
* This settings object stores instance-specific settings.
@@ -147,10 +145,10 @@ public:
virtual shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) = 0;
/// returns a valid launcher (task container)
virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0;
virtual shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) = 0;
/// returns the current launch task (if any)
std::shared_ptr<LaunchTask> getLaunchTask();
shared_qobject_ptr<LaunchTask> getLaunchTask();
/*!
* Create envrironment variables for running the instance
@@ -241,7 +239,7 @@ signals:
*/
void propertiesChanged(BaseInstance *inst);
void launchTaskChanged(std::shared_ptr<LaunchTask>);
void launchTaskChanged(shared_qobject_ptr<LaunchTask>);
void runningStatusChanged(bool running);
@@ -255,7 +253,7 @@ protected: /* data */
SettingsObjectPtr m_settings;
// InstanceFlags m_flags;
bool m_isRunning = false;
std::shared_ptr<LaunchTask> m_launchProcess;
shared_qobject_ptr<LaunchTask> m_launchProcess;
QDateTime m_timeStarted;
private: /* data */
@@ -265,6 +263,6 @@ private: /* data */
bool m_hasBrokenVersion = false;
};
Q_DECLARE_METATYPE(std::shared_ptr<BaseInstance>)
Q_DECLARE_METATYPE(shared_qobject_ptr<BaseInstance>)
//Q_DECLARE_METATYPE(BaseInstance::InstanceFlag)
//Q_DECLARE_OPERATORS_FOR_FLAGS(BaseInstance::InstanceFlags)

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -182,9 +182,11 @@ set(NEWS_SOURCES
# Icon interface
set(ICONS_SOURCES
# News System
# Icons System and related code
icons/IIconList.h
icons/IIconList.cpp
icons/IconUtils.h
icons/IconUtils.cpp
)
# Minecraft services status checker
@@ -211,6 +213,8 @@ set(MINECRAFT_SOURCES
minecraft/auth/flows/RefreshTask.cpp
minecraft/auth/flows/ValidateTask.h
minecraft/auth/flows/ValidateTask.cpp
minecraft/gameoptions/GameOptions.h
minecraft/gameoptions/GameOptions.cpp
minecraft/update/AssetUpdateTask.h
minecraft/update/AssetUpdateTask.cpp
minecraft/update/FMLLibrariesTask.cpp
@@ -233,6 +237,8 @@ set(MINECRAFT_SOURCES
minecraft/launch/LauncherPartLaunch.h
minecraft/launch/PrintInstanceInfo.cpp
minecraft/launch/PrintInstanceInfo.h
minecraft/launch/ReconstructAssets.cpp
minecraft/launch/ReconstructAssets.h
minecraft/legacy/LegacyModList.h
minecraft/legacy/LegacyModList.cpp
minecraft/legacy/LegacyInstance.h
@@ -387,6 +393,8 @@ add_unit_test(JavaVersion
set(TRANSLATIONS_SOURCES
translations/TranslationsModel.h
translations/TranslationsModel.cpp
translations/POTranslator.h
translations/POTranslator.cpp
)
set(TOOLS_SOURCES

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*

View File

@@ -6,6 +6,7 @@
#include "NullInstance.h"
#include "settings/INISettingsObject.h"
#include "icons/IIconList.h"
#include "icons/IconUtils.h"
#include <QtConcurrentRun>
// FIXME: this does not belong here, it's Minecraft/Flame specific
@@ -393,8 +394,9 @@ void InstanceImportTask::processMultiMC()
else
{
m_instIcon = instance.iconKey();
auto importIconPath = FS::PathCombine(instance.instanceRoot(), m_instIcon + ".png");
if (QFile::exists(importIconPath))
auto importIconPath = IconUtils::findBestIconIn(instance.instanceRoot(), m_instIcon);
if (!importIconPath.isNull() && QFile::exists(importIconPath))
{
// import icon
auto iconList = ENV.icons();

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,6 @@
#pragma once
#include "BaseInstance.h"
#include "launch/LaunchTask.h"
class NullInstance: public BaseInstance
{
@@ -11,46 +12,46 @@ public:
setVersionBroken(true);
}
virtual ~NullInstance() {};
virtual void saveNow() override
void saveNow() override
{
}
virtual QString getStatusbarDescription() override
QString getStatusbarDescription() override
{
return tr("Unknown instance type");
};
virtual QSet< QString > traits() const override
QSet< QString > traits() const override
{
return {};
};
virtual QString instanceConfigFolder() const override
QString instanceConfigFolder() const override
{
return instanceRoot();
};
virtual std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr) override
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr) override
{
return nullptr;
}
virtual shared_qobject_ptr< Task > createUpdateTask(Net::Mode mode) override
shared_qobject_ptr< Task > createUpdateTask(Net::Mode mode) override
{
return nullptr;
}
virtual QProcessEnvironment createEnvironment() override
QProcessEnvironment createEnvironment() override
{
return QProcessEnvironment();
}
virtual QMap<QString, QString> getVariables() const override
QMap<QString, QString> getVariables() const override
{
return QMap<QString, QString>();
}
virtual IPathMatcher::Ptr getLogFileMatcher() override
IPathMatcher::Ptr getLogFileMatcher() override
{
return nullptr;
}
virtual QString getLogFileRoot() override
QString getLogFileRoot() override
{
return instanceRoot();
}
virtual QString typeName() const override
QString typeName() const override
{
return "Null";
}

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,62 @@
#include "IconUtils.h"
#include "FileSystem.h"
#include <QDirIterator>
#include <array>
namespace {
std::array<const char *, 6> validIconExtensions = {{
"svg",
"png",
"ico",
"gif",
"jpg",
"jpeg"
}};
}
namespace IconUtils{
QString findBestIconIn(const QString &folder, const QString & iconKey) {
int best_found = validIconExtensions.size();
QString best_filename;
QDirIterator it(folder, QDir::NoDotAndDotDot | QDir::Files, QDirIterator::NoIteratorFlags);
while (it.hasNext()) {
it.next();
auto fileInfo = it.fileInfo();
if(fileInfo.completeBaseName() != iconKey)
continue;
auto extension = fileInfo.suffix();
for(int i = 0; i < best_found; i++) {
if(extension == validIconExtensions[i]) {
best_found = i;
qDebug() << i << " : " << fileInfo.fileName();
best_filename = fileInfo.fileName();
}
}
}
return FS::PathCombine(folder, best_filename);
}
QString getIconFilter() {
QString out;
QTextStream stream(&out);
stream << '(';
for(size_t i = 0; i < validIconExtensions.size() - 1; i++) {
if(i > 0) {
stream << " ";
}
stream << "*." << validIconExtensions[i];
}
stream << " *." << validIconExtensions[validIconExtensions.size() - 1];
stream << ')';
return out;
}
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <QString>
#include "multimc_logic_export.h"
namespace IconUtils {
// Given a folder and an icon key, find 'best' of the icons with the given key in there and return its path
MULTIMC_LOGIC_EXPORT QString findBestIconIn(const QString &folder, const QString & iconKey);
// Get icon file type filter for file browser dialogs
MULTIMC_LOGIC_EXPORT QString getIconFilter();
}

View File

@@ -75,8 +75,8 @@ void JavaChecker::stderrReady()
void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
{
killTimer.stop();
QProcessPtr _process;
_process.swap(process);
QProcessPtr _process = process;
process.reset();
JavaCheckResult result;
{

View File

@@ -3,6 +3,8 @@
#include <QTimer>
#include <memory>
#include "QObjectPtr.h"
#include "multimc_logic_export.h"
#include "JavaVersion.h"
@@ -27,8 +29,8 @@ struct MULTIMC_LOGIC_EXPORT JavaCheckResult
} validity = Validity::Errored;
};
typedef std::shared_ptr<QProcess> QProcessPtr;
typedef std::shared_ptr<JavaChecker> JavaCheckerPtr;
typedef shared_qobject_ptr<QProcess> QProcessPtr;
typedef shared_qobject_ptr<JavaChecker> JavaCheckerPtr;
class MULTIMC_LOGIC_EXPORT JavaChecker : public QObject
{
Q_OBJECT

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@
#include "tasks/Task.h"
class JavaCheckerJob;
typedef std::shared_ptr<JavaCheckerJob> JavaCheckerJobPtr;
typedef shared_qobject_ptr<JavaCheckerJob> JavaCheckerJobPtr;
// FIXME: this just seems horribly redundant
class JavaCheckerJob : public Task

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -149,7 +149,7 @@ void JavaListLoadTask::executeTask()
JavaUtils ju;
QList<QString> candidate_paths = ju.FindJavaPaths();
m_job = std::shared_ptr<JavaCheckerJob>(new JavaCheckerJob("Java detection"));
m_job = new JavaCheckerJob("Java detection");
connect(m_job.get(), &Task::finished, this, &JavaListLoadTask::javaCheckerFinished);
connect(m_job.get(), &Task::progress, this, &Task::setProgress);

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,8 @@
#include "JavaCheckerJob.h"
#include "JavaInstall.h"
#include "QObjectPtr.h"
#include "multimc_logic_export.h"
class JavaListLoadTask;
@@ -75,7 +77,7 @@ public slots:
void javaCheckerFinished();
protected:
std::shared_ptr<JavaCheckerJob> m_job;
shared_qobject_ptr<JavaCheckerJob> m_job;
JavaInstallList *m_list;
JavaInstall *m_currentRecommended;
};

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -60,7 +60,7 @@ void CheckJava::executeTask()
// if timestamps are not the same, or something is missing, check!
if (javaUnixTime != storedUnixTime || storedVersion.size() == 0 || storedArchitecture.size() == 0)
{
m_JavaChecker = std::make_shared<JavaChecker>();
m_JavaChecker = new JavaChecker();
emit logLine(tr("Checking Java version..."), MessageLevel::MultiMC);
connect(m_JavaChecker.get(), &JavaChecker::checkFinished, this, &CheckJava::checkJavaFinished);
m_JavaChecker->m_path = realJavaPath;

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*
@@ -33,9 +33,9 @@ void LaunchTask::init()
m_instance->setRunning(true);
}
std::shared_ptr<LaunchTask> LaunchTask::create(InstancePtr inst)
shared_qobject_ptr<LaunchTask> LaunchTask::create(InstancePtr inst)
{
std::shared_ptr<LaunchTask> proc(new LaunchTask(inst));
shared_qobject_ptr<LaunchTask> proc(new LaunchTask(inst));
proc->init();
return proc;
}
@@ -44,12 +44,12 @@ LaunchTask::LaunchTask(InstancePtr instance): m_instance(instance)
{
}
void LaunchTask::appendStep(std::shared_ptr<LaunchStep> step)
void LaunchTask::appendStep(shared_qobject_ptr<LaunchStep> step)
{
m_steps.append(step);
}
void LaunchTask::prependStep(std::shared_ptr<LaunchStep> step)
void LaunchTask::prependStep(shared_qobject_ptr<LaunchStep> step)
{
m_steps.prepend(step);
}

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*
@@ -45,11 +45,11 @@ public:
};
public: /* methods */
static std::shared_ptr<LaunchTask> create(InstancePtr inst);
static shared_qobject_ptr<LaunchTask> create(InstancePtr inst);
virtual ~LaunchTask() {};
void appendStep(std::shared_ptr<LaunchStep> step);
void prependStep(std::shared_ptr<LaunchStep> step);
void appendStep(shared_qobject_ptr<LaunchStep> step);
void prependStep(shared_qobject_ptr<LaunchStep> step);
void setCensorFilter(QMap<QString, QString> filter);
InstancePtr instance()
@@ -117,7 +117,7 @@ private: /*methods */
protected: /* data */
InstancePtr m_instance;
shared_qobject_ptr<LogModel> m_logModel;
QList <std::shared_ptr<LaunchStep>> m_steps;
QList <shared_qobject_ptr<LaunchStep>> m_steps;
QMap<QString, QString> m_censorFilter;
int currentStep = -1;
State state = NotStarted;

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,7 +74,7 @@ Meta::BaseEntity::~BaseEntity()
QUrl Meta::BaseEntity::url() const
{
return QUrl("https://v1.meta.multimc.org").resolved(localFilename());
return QUrl("https://meta.multimc.org/v1/").resolved(localFilename());
}
bool Meta::BaseEntity::loadLocalFile()

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,6 +29,33 @@
#include "net/ChecksumValidator.h"
#include "net/URLConstants.h"
namespace {
QSet<QString> collectPathsFromDir(QString dirPath)
{
QFileInfo dirInfo(dirPath);
if (!dirInfo.exists())
{
return {};
}
QSet<QString> out;
QDirIterator iter(dirPath, QDirIterator::Subdirectories);
while (iter.hasNext())
{
QString value = iter.next();
QFileInfo info(value);
if(info.isFile())
{
out.insert(value);
qDebug() << value;
}
}
return out;
}
}
namespace AssetsUtils
{
@@ -37,7 +64,7 @@ namespace AssetsUtils
* Returns true on success, with index populated
* index is undefined otherwise
*/
bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
bool loadAssetsIndexJson(const QString &assetsId, const QString &path, AssetsIndex& index)
{
/*
{
@@ -61,7 +88,7 @@ bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
qCritical() << "Failed to read assets index file" << path;
return false;
}
index->id = assetsId;
index.id = assetsId;
// Read the file and close it.
QByteArray jsonData = file.readAll();
@@ -90,7 +117,13 @@ bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
QJsonValue isVirtual = root.value("virtual");
if (!isVirtual.isUndefined())
{
index->isVirtual = isVirtual.toBool(false);
index.isVirtual = isVirtual.toBool(false);
}
QJsonValue mapToResources = root.value("map_to_resources");
if (!mapToResources.isUndefined())
{
index.mapToResources = mapToResources.toBool(false);
}
QJsonValue objects = root.value("objects");
@@ -122,13 +155,14 @@ bool loadAssetsIndexJson(QString assetsId, QString path, AssetsIndex *index)
}
}
index->objects.insert(iter.key(), object);
index.objects.insert(iter.key(), object);
}
return true;
}
QDir reconstructAssets(QString assetsId)
// FIXME: ugly code duplication
QDir getAssetsDir(const QString &assetsId, const QString &resourcesFolder)
{
QDir assetsDir = QDir("assets/");
QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes"));
@@ -141,24 +175,77 @@ QDir reconstructAssets(QString assetsId)
if (!indexFile.exists())
{
qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets";
qCritical() << "No assets index file" << indexPath << "; can't determine assets path!";
return virtualRoot;
}
qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path()
<< objectDir.path() << virtualDir.path() << virtualRoot.path();
AssetsIndex index;
if(!AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, index))
{
qCritical() << "Failed to load asset index file" << indexPath << "; can't determine assets path!";
return virtualRoot;
}
QString targetPath;
if(index.isVirtual)
{
return virtualRoot;
}
else if(index.mapToResources)
{
return QDir(resourcesFolder);
}
return virtualRoot;
}
// FIXME: ugly code duplication
bool reconstructAssets(QString assetsId, QString resourcesFolder)
{
QDir assetsDir = QDir("assets/");
QDir indexDir = QDir(FS::PathCombine(assetsDir.path(), "indexes"));
QDir objectDir = QDir(FS::PathCombine(assetsDir.path(), "objects"));
QDir virtualDir = QDir(FS::PathCombine(assetsDir.path(), "virtual"));
QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json");
QFile indexFile(indexPath);
QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId));
if (!indexFile.exists())
{
qCritical() << "No assets index file" << indexPath << "; can't reconstruct assets!";
return false;
}
qDebug() << "reconstructAssets" << assetsDir.path() << indexDir.path() << objectDir.path() << virtualDir.path() << virtualRoot.path();
AssetsIndex index;
bool loadAssetsIndex = AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, &index);
if (loadAssetsIndex && index.isVirtual)
if(!AssetsUtils::loadAssetsIndexJson(assetsId, indexPath, index))
{
qDebug() << "Reconstructing virtual assets folder at" << virtualRoot.path();
qCritical() << "Failed to load asset index file" << indexPath << "; can't reconstruct assets!";
return false;
}
QString targetPath;
bool removeLeftovers = false;
if(index.isVirtual)
{
targetPath = virtualRoot.path();
removeLeftovers = true;
qDebug() << "Reconstructing virtual assets folder at" << targetPath;
}
else if(index.mapToResources)
{
targetPath = resourcesFolder;
qDebug() << "Reconstructing resources folder at" << targetPath;
}
if (!targetPath.isNull())
{
auto presentFiles = collectPathsFromDir(targetPath);
for (QString map : index.objects.keys())
{
AssetObject asset_object = index.objects.value(map);
QString target_path = FS::PathCombine(virtualRoot.path(), map);
QString target_path = FS::PathCombine(targetPath, map);
QFile target(target_path);
QString tlk = asset_object.hash.left(2);
@@ -167,24 +254,32 @@ QDir reconstructAssets(QString assetsId)
QFile original(original_path);
if (!original.exists())
continue;
presentFiles.remove(target_path);
if (!target.exists())
{
QFileInfo info(target_path);
QDir target_dir = info.dir();
// qDebug() << target_dir;
if (!target_dir.exists())
QDir("").mkpath(target_dir.path());
qDebug() << target_dir.path();
FS::ensureFolderPathExists(target_dir.path());
bool couldCopy = original.copy(target_path);
qDebug() << " Copying" << original_path << "to" << target_path
<< QString::number(couldCopy); // << original.errorString();
qDebug() << " Copying" << original_path << "to" << target_path << QString::number(couldCopy);
}
}
// TODO: Write last used time to virtualRoot/.lastused
if(removeLeftovers)
{
for(auto & file: presentFiles)
{
qDebug() << "Would remove" << file;
}
}
}
return virtualRoot;
return true;
}
}

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,11 +38,16 @@ struct AssetsIndex
QString id;
QMap<QString, AssetObject> objects;
bool isVirtual = false;
bool mapToResources = false;
};
/// FIXME: this is absolutely horrendous. REDO!!!!
namespace AssetsUtils
{
bool loadAssetsIndexJson(QString id, QString file, AssetsIndex* index);
bool loadAssetsIndexJson(const QString &id, const QString &file, AssetsIndex& index);
QDir getAssetsDir(const QString &assetsId, const QString &resourcesFolder);
/// Reconstruct a virtual assets folder for the given assets ID and return the folder
QDir reconstructAssets(QString assetsId);
bool reconstructAssets(QString assetsId, QString resourcesFolder);
}

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -586,6 +586,15 @@ void ComponentUpdateTask::resolveDependencies(bool checkOnly)
{
component->m_version = "3.1.2";
}
else if (add.uid == "net.fabricmc.intermediary")
{
auto minecraft = std::find_if(components.begin(), components.end(), [](ComponentPtr & cmp){
return cmp->getID() == "net.minecraft";
});
if(minecraft != components.end()) {
component->m_version = (*minecraft)->getVersion();
}
}
}
// HACK HACK HACK HACK FIXME: this is a placeholder for deciding what version to use. For now, it is hardcoded.
// ############################################################################################################

View File

@@ -20,6 +20,7 @@
#include "minecraft/launch/DirectJavaLaunch.h"
#include "minecraft/launch/ModMinecraftJar.h"
#include "minecraft/launch/ClaimAccount.h"
#include "minecraft/launch/ReconstructAssets.h"
#include "java/launch/CheckJava.h"
#include "java/JavaUtils.h"
#include "meta/Index.h"
@@ -35,6 +36,7 @@
#include "AssetsUtils.h"
#include "MinecraftUpdate.h"
#include "MinecraftLoadAndCheck.h"
#include <minecraft/gameoptions/GameOptions.h>
#define IBUS "@im=ibus"
@@ -215,6 +217,11 @@ QString MinecraftInstance::worldDir() const
return FS::PathCombine(gameRoot(), "saves");
}
QString MinecraftInstance::resourcesDir() const
{
return FS::PathCombine(gameRoot(), "resources");
}
QDir MinecraftInstance::librariesPath() const
{
return QDir::current().absoluteFilePath("libraries");
@@ -407,8 +414,7 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session) cons
token_mapping["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath();
auto assets = profile->getMinecraftAssets();
// FIXME: this is wrong and should be run as an async task
token_mapping["game_assets"] = AssetsUtils::reconstructAssets(assets->id).absolutePath();
token_mapping["game_assets"] = AssetsUtils::getAssetsDir(assets->id, resourcesDir()).absolutePath();
// 1.7.3+ assets tokens
token_mapping["assets_root"] = absAssetsDir;
@@ -771,22 +777,22 @@ shared_qobject_ptr<Task> MinecraftInstance::createUpdateTask(Net::Mode mode)
return nullptr;
}
std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session)
shared_qobject_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr session)
{
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(getSharedPtr()));
// FIXME: get rid of shared_from_this ...
auto process = LaunchTask::create(std::dynamic_pointer_cast<MinecraftInstance>(shared_from_this()));
auto pptr = process.get();
ENV.icons()->saveIcon(iconKey(), FS::PathCombine(gameRoot(), "icon.png"), "PNG");
// print a header
{
process->appendStep(std::make_shared<TextPrint>(pptr, "Minecraft folder is:\n" + gameRoot() + "\n\n", MessageLevel::MultiMC));
process->appendStep(new TextPrint(pptr, "Minecraft folder is:\n" + gameRoot() + "\n\n", MessageLevel::MultiMC));
}
// check java
{
auto step = std::make_shared<CheckJava>(pptr);
process->appendStep(step);
process->appendStep(new CheckJava(pptr));
}
// check launch method
@@ -794,14 +800,14 @@ std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr s
QString method = launchMethod();
if(!validMethods.contains(method))
{
process->appendStep(std::make_shared<TextPrint>(pptr, "Selected launch method \"" + method + "\" is not valid.\n", MessageLevel::Fatal));
process->appendStep(new TextPrint(pptr, "Selected launch method \"" + method + "\" is not valid.\n", MessageLevel::Fatal));
return process;
}
// run pre-launch command if that's needed
if(getPreLaunchCommand().size())
{
auto step = std::make_shared<PreLaunchCommand>(pptr);
auto step = new PreLaunchCommand(pptr);
step->setWorkingDirectory(gameRoot());
process->appendStep(step);
}
@@ -809,36 +815,37 @@ std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr s
// if we aren't in offline mode,.
if(session->status != AuthSession::PlayableOffline)
{
process->appendStep(std::make_shared<ClaimAccount>(pptr, session));
process->appendStep(std::make_shared<Update>(pptr, Net::Mode::Online));
process->appendStep(new ClaimAccount(pptr, session));
process->appendStep(new Update(pptr, Net::Mode::Online));
}
else
{
process->appendStep(std::make_shared<Update>(pptr, Net::Mode::Offline));
process->appendStep(new Update(pptr, Net::Mode::Offline));
}
// if there are any jar mods
{
auto step = std::make_shared<ModMinecraftJar>(pptr);
process->appendStep(step);
process->appendStep(new ModMinecraftJar(pptr));
}
// print some instance info here...
{
auto step = std::make_shared<PrintInstanceInfo>(pptr, session);
process->appendStep(step);
process->appendStep(new PrintInstanceInfo(pptr, session));
}
// create the server-resource-packs folder (workaround for Minecraft bug MCL-3732)
{
auto step = std::make_shared<CreateServerResourcePacksFolder>(pptr);
process->appendStep(step);
process->appendStep(new CreateServerResourcePacksFolder(pptr));
}
// extract native jars if needed
{
auto step = std::make_shared<ExtractNatives>(pptr);
process->appendStep(step);
process->appendStep(new ExtractNatives(pptr));
}
// reconstruct assets if needed
{
process->appendStep(new ReconstructAssets(pptr));
}
{
@@ -846,14 +853,14 @@ std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr s
auto method = launchMethod();
if(method == "LauncherPart")
{
auto step = std::make_shared<LauncherPartLaunch>(pptr);
auto step = new LauncherPartLaunch(pptr);
step->setWorkingDirectory(gameRoot());
step->setAuthSession(session);
process->appendStep(step);
}
else if (method == "DirectJava")
{
auto step = std::make_shared<DirectJavaLaunch>(pptr);
auto step = new DirectJavaLaunch(pptr);
step->setWorkingDirectory(gameRoot());
step->setAuthSession(session);
process->appendStep(step);
@@ -863,7 +870,7 @@ std::shared_ptr<LaunchTask> MinecraftInstance::createLaunchTask(AuthSessionPtr s
// run post-exit command if that's needed
if(getPostExitCommand().size())
{
auto step = std::make_shared<PostLaunchCommand>(pptr);
auto step = new PostLaunchCommand(pptr);
step->setWorkingDirectory(gameRoot());
process->appendStep(step);
}
@@ -935,6 +942,15 @@ std::shared_ptr<WorldList> MinecraftInstance::worldList() const
return m_world_list;
}
std::shared_ptr<GameOptions> MinecraftInstance::gameOptionsModel() const
{
if (!m_game_options)
{
m_game_options.reset(new GameOptions(FS::PathCombine(gameRoot(), "options.txt")));
}
return m_game_options;
}
QList< Mod > MinecraftInstance::getJarMods() const
{
auto profile = m_components->getProfile();

View File

@@ -9,6 +9,7 @@
class ModsModel;
class SimpleModList;
class WorldList;
class GameOptions;
class LaunchStep;
class ComponentList;
@@ -44,6 +45,7 @@ public:
QString modsCacheLocation() const;
QString libDir() const;
QString worldDir() const;
QString resourcesDir() const;
QDir jarmodsPath() const;
QDir librariesPath() const;
QDir versionsPath() const;
@@ -72,11 +74,11 @@ public:
std::shared_ptr<SimpleModList> resourcePackList() const;
std::shared_ptr<SimpleModList> texturePackList() const;
std::shared_ptr<WorldList> worldList() const;
std::shared_ptr<GameOptions> gameOptionsModel() const;
////// Launch stuff //////
shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
std::shared_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
shared_qobject_ptr<LaunchTask> createLaunchTask(AuthSessionPtr account) override;
QStringList extraArguments() const override;
QStringList verboseDescription(AuthSessionPtr session) override;
QList<Mod> getJarMods() const;
@@ -130,6 +132,7 @@ protected: // data
mutable std::shared_ptr<SimpleModList> m_resource_pack_list;
mutable std::shared_ptr<SimpleModList> m_texture_pack_list;
mutable std::shared_ptr<WorldList> m_world_list;
mutable std::shared_ptr<GameOptions> m_game_options;
};
typedef std::shared_ptr<MinecraftInstance> MinecraftInstancePtr;

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -96,6 +96,19 @@ void Mod::repath(const QFileInfo &file)
zip.close();
return;
}
else if (zip.setCurrentFile("fabric.mod.json"))
{
if (!file.open(QIODevice::ReadOnly))
{
zip.close();
return;
}
ReadFabricModInfo(file.readAll());
file.close();
zip.close();
return;
}
else if (zip.setCurrentFile("forgeversion.properties"))
{
if (!file.open(QIODevice::ReadOnly))
@@ -224,6 +237,48 @@ void Mod::ReadMCModInfo(QByteArray contents)
}
}
// https://fabricmc.net/wiki/documentation:fabric_mod_json
void Mod::ReadFabricModInfo(QByteArray contents)
{
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
auto object = jsonDoc.object();
auto schemaVersion = object.contains("schemaVersion") ? object.value("schemaVersion").toInt(0) : 0;
m_mod_id = object.value("id").toString();
m_version = object.value("version").toString();
m_name = object.contains("name") ? object.value("name").toString() : m_mod_id;
m_description = object.value("description").toString();
if (schemaVersion >= 1)
{
QJsonArray authors = object.value("authors").toArray();
m_authors = "";
for (int i = 0; i < authors.size(); i++)
{
QString author_name = authors.at(i).isObject()
? authors.at(i).toObject().value("name").toString()
: authors.at(i).toString();
if (i > 0)
m_authors += ", " + author_name;
else {
m_authors += author_name;
}
}
if (object.contains("contact"))
{
QJsonObject contact = object.value("contact").toObject();
if (contact.contains("homepage"))
m_homeurl = contact.value("homepage").toString();
}
}
}
void Mod::ReadForgeInfo(QByteArray contents)
{
// Read the data

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -113,6 +113,7 @@ public:
private:
void ReadMCModInfo(QByteArray contents);
void ReadFabricModInfo(QByteArray contents);
void ReadForgeInfo(QByteArray contents);
void ReadLiteModInfo(QByteArray contents);

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -123,8 +123,8 @@ bool SimpleModList::installMod(const QString &filename)
qDebug() << "Cannot recognize mod type of" << originalPath << ", ignoring it.";
return false;
}
auto newpath = FS::NormalizePath(FS::PathCombine(m_dir.path(), fileinfo.fileName()));
auto newpath = FS::NormalizePath(FS::PathCombine(m_dir.path(), fileinfo.fileName()));
if(originalPath == newpath)
{
qDebug() << "Overwriting the mod (" << originalPath << ") with itself makes no sense...";
@@ -133,7 +133,7 @@ bool SimpleModList::installMod(const QString &filename)
if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
{
if(QFile::exists(newpath))
if(QFile::exists(newpath) || QFile::exists(newpath + QString(".disabled")))
{
if(!QFile::remove(newpath))
{
@@ -349,11 +349,6 @@ bool SimpleModList::dropMimeData(const QMimeData* data, Qt::DropAction action, i
// files dropped from outside?
if (data->hasUrls())
{
bool was_watching = is_watching;
if (was_watching)
{
stopWatching();
}
auto urls = data->urls();
for (auto url : urls)
{
@@ -366,10 +361,6 @@ bool SimpleModList::dropMimeData(const QMimeData* data, Qt::DropAction action, i
// FIXME: handle errors here
installMod(url.toLocalFile());
}
if (was_watching)
{
startWatching();
}
return true;
}
return false;

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2015-2018 MultiMC Contributors
/* Copyright 2015-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
*

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -0,0 +1,144 @@
#include "GameOptions.h"
#include "FileSystem.h"
#include <QDebug>
#include <QSaveFile>
namespace {
bool load(const QString& path, std::vector<GameOptionItem> &contents, int & version)
{
contents.clear();
QFile file(path);
if (!file.open(QFile::ReadOnly))
{
qWarning() << "Failed to read options file.";
return false;
}
version = 0;
while(!file.atEnd())
{
auto line = file.readLine();
if(line.endsWith('\n'))
{
line.chop(1);
}
auto separatorIndex = line.indexOf(':');
if(separatorIndex == -1)
{
continue;
}
auto key = QString::fromUtf8(line.data(), separatorIndex);
auto value = QString::fromUtf8(line.data() + separatorIndex + 1, line.size() - 1 - separatorIndex);
qDebug() << "!!" << key << "!!";
if(key == "version")
{
version = value.toInt();
continue;
}
contents.emplace_back(GameOptionItem{key, value});
}
qDebug() << "Loaded" << path << "with version:" << version;
return true;
}
bool save(const QString& path, std::vector<GameOptionItem> &mapping, int version)
{
QSaveFile out(path);
if(!out.open(QIODevice::WriteOnly))
{
return false;
}
if(version != 0)
{
QString versionLine = QString("version:%1\n").arg(version);
out.write(versionLine.toUtf8());
}
auto iter = mapping.begin();
while (iter != mapping.end())
{
out.write(iter->key.toUtf8());
out.write(":");
out.write(iter->value.toUtf8());
out.write("\n");
iter++;
}
return out.commit();
}
}
GameOptions::GameOptions(const QString& path):
path(path)
{
reload();
}
QVariant GameOptions::headerData(int section, Qt::Orientation orientation, int role) const
{
if(role != Qt::DisplayRole)
{
return QAbstractListModel::headerData(section, orientation, role);
}
switch(section)
{
case 0:
return tr("Key");
case 1:
return tr("Value");
default:
return QVariant();
}
}
QVariant GameOptions::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
int row = index.row();
int column = index.column();
if (row < 0 || row >= int(contents.size()))
return QVariant();
switch (role)
{
case Qt::DisplayRole:
if(column == 0)
{
return contents[row].key;
}
else
{
return contents[row].value;
}
default:
return QVariant();
}
return QVariant();
}
int GameOptions::rowCount(const QModelIndex&) const
{
return contents.size();
}
int GameOptions::columnCount(const QModelIndex&) const
{
return 2;
}
bool GameOptions::isLoaded() const
{
return loaded;
}
bool GameOptions::reload()
{
beginResetModel();
loaded = load(path, contents, version);
endResetModel();
return loaded;
}
bool GameOptions::save()
{
return ::save(path, contents, version);
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include <map>
#include <QString>
#include <QAbstractListModel>
struct GameOptionItem
{
QString key;
QString value;
};
class GameOptions : public QAbstractListModel
{
Q_OBJECT
public:
explicit GameOptions(const QString& path);
virtual ~GameOptions() = default;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex & parent) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
bool isLoaded() const;
bool reload();
bool save();
private:
std::vector<GameOptionItem> contents;
bool loaded = false;
QString path;
int version = 0;
};

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,4 +1,4 @@
/* Copyright 2013-2018 MultiMC Contributors
/* Copyright 2013-2019 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

Some files were not shown because too many files have changed in this diff Show More