mirror of
https://github.com/UltimMC/Launcher.git
synced 2025-12-13 20:22:13 +00:00
Compare commits
166 Commits
0.6.4
...
feature/me
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2378c79ff | ||
|
|
08f85f1a93 | ||
|
|
bc98181ec2 | ||
|
|
6a095deea6 | ||
|
|
355e5e24da | ||
|
|
8bdff97ac0 | ||
|
|
6288805f37 | ||
|
|
0d157d86b5 | ||
|
|
f413e61cd8 | ||
|
|
3581f5384f | ||
|
|
480b298635 | ||
|
|
b54b25231e | ||
|
|
43628556ed | ||
|
|
b5adff14ab | ||
|
|
af5120c828 | ||
|
|
47ed2f48d4 | ||
|
|
0c9340a3d2 | ||
|
|
9cc5ebcdd1 | ||
|
|
c60647523e | ||
|
|
9165232ba4 | ||
|
|
31d0507e07 | ||
|
|
cca766cfd9 | ||
|
|
0d41bc5e13 | ||
|
|
e27309d08a | ||
|
|
dec6759e61 | ||
|
|
ce7917048a | ||
|
|
e6936212d6 | ||
|
|
1210d3abf1 | ||
|
|
ffe84d6ec7 | ||
|
|
19015de258 | ||
|
|
5c0c26cd25 | ||
|
|
4cc7427eb4 | ||
|
|
6531aaa7bc | ||
|
|
a35a2e877e | ||
|
|
4e93c4d012 | ||
|
|
7bb23b4142 | ||
|
|
b420f4bafb | ||
|
|
0e0a017175 | ||
|
|
137fe7e3c0 | ||
|
|
9689e5cea7 | ||
|
|
1ede75aa79 | ||
|
|
9ee3a84817 | ||
|
|
8750ca8b36 | ||
|
|
1747f413b9 | ||
|
|
6d975748c0 | ||
|
|
b050c7c075 | ||
|
|
84e0cb1daa | ||
|
|
5074a97cb3 | ||
|
|
441e8980b8 | ||
|
|
84c53273ce | ||
|
|
c291946d2a | ||
|
|
dfb30d9139 | ||
|
|
4ed67413ac | ||
|
|
d31184f9a4 | ||
|
|
b75ba53d4b | ||
|
|
9037873928 | ||
|
|
ce4a55bc3b | ||
|
|
6b82e942d0 | ||
|
|
a3ffa3d665 | ||
|
|
7d13e31198 | ||
|
|
40c9af1a8b | ||
|
|
f5f3149dcf | ||
|
|
7b00d47fe0 | ||
|
|
930d39b5f2 | ||
|
|
bafcf93eb1 | ||
|
|
bd93c3b4e0 | ||
|
|
09f7a426ab | ||
|
|
e4fd50e210 | ||
|
|
3ee5a63c5c | ||
|
|
7dfe73df0c | ||
|
|
c3e61536a3 | ||
|
|
a0e45c5d1d | ||
|
|
bf38021937 | ||
|
|
1e5b595923 | ||
|
|
d6c6653872 | ||
|
|
3b32730526 | ||
|
|
1703dbeb57 | ||
|
|
81fdde6fdd | ||
|
|
3d5869e1cf | ||
|
|
edc5378333 | ||
|
|
95febe5436 | ||
|
|
5b153a5165 | ||
|
|
decd4ae7ab | ||
|
|
2eec1df1a0 | ||
|
|
6fde775b90 | ||
|
|
80b3efff11 | ||
|
|
e4273d6a17 | ||
|
|
62e1bf327d | ||
|
|
280e0e6e36 | ||
|
|
3a67990acd | ||
|
|
23eab74e6d | ||
|
|
b9d4293552 | ||
|
|
5110b58def | ||
|
|
791a8227b6 | ||
|
|
725ec35635 | ||
|
|
739a86f171 | ||
|
|
48b2f95129 | ||
|
|
497d9bec02 | ||
|
|
c01d020afc | ||
|
|
ee83d432f6 | ||
|
|
8ee11b1a8e | ||
|
|
0b86a7ebf3 | ||
|
|
63330bf111 | ||
|
|
f74e3db804 | ||
|
|
a55fa04353 | ||
|
|
fde43c993e | ||
|
|
917f148fc4 | ||
|
|
34611c00e3 | ||
|
|
44a7c5867b | ||
|
|
75ddbc8851 | ||
|
|
2f1d31cf43 | ||
|
|
e7c5b266c8 | ||
|
|
384979bf94 | ||
|
|
b5a16935b7 | ||
|
|
320637e8dc | ||
|
|
77f3f028fa | ||
|
|
2a96e16902 | ||
|
|
1ed84eddd5 | ||
|
|
7b52b8689b | ||
|
|
d21700ee91 | ||
|
|
f87c890912 | ||
|
|
306b98edac | ||
|
|
ce12f1a734 | ||
|
|
c1953739d9 | ||
|
|
e8bf9cef24 | ||
|
|
8aa4b9dac5 | ||
|
|
4836ba22cd | ||
|
|
6c30076b6c | ||
|
|
83c48a0f1a | ||
|
|
d251097545 | ||
|
|
c35dbd972e | ||
|
|
0c5d121452 | ||
|
|
53ad5cb436 | ||
|
|
d87bd4b588 | ||
|
|
86850ef5d0 | ||
|
|
30fba4d407 | ||
|
|
932160818e | ||
|
|
59e1ed3d87 | ||
|
|
3470a3df96 | ||
|
|
61913daaf3 | ||
|
|
cb71dfa605 | ||
|
|
2be98baaba | ||
|
|
0ce637bf0e | ||
|
|
70ed30f9e6 | ||
|
|
414946cad9 | ||
|
|
1fc199697c | ||
|
|
9292d846b6 | ||
|
|
22db95ce3b | ||
|
|
597fe50d37 | ||
|
|
bf93ba02e9 | ||
|
|
07c1685ff1 | ||
|
|
a5e531d4f1 | ||
|
|
ae956d8fd6 | ||
|
|
73e487a31e | ||
|
|
0b95d2b03f | ||
|
|
9c82adaee5 | ||
|
|
0a99d037c4 | ||
|
|
6e8e4c5dfa | ||
|
|
e4599ee2d1 | ||
|
|
62c9fcdc6c | ||
|
|
c1ea42d3d9 | ||
|
|
437dec91f9 | ||
|
|
7436c94976 | ||
|
|
c08053d8b8 | ||
|
|
e71786d7b9 | ||
|
|
819503d530 |
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"project_id": "MultiMC5",
|
||||
"conduit_uri": "http://ph.multimc.org"
|
||||
}
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
UseTab: false
|
||||
IndentWidth: 4
|
||||
TabWidth: 4
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
AccessModifierOffset: -4
|
||||
IndentCaseLabels: false
|
||||
IndentFunctionDeclarationAfterType: false
|
||||
NamespaceIndentation: None
|
||||
|
||||
BreakBeforeBraces: Allman
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
ColumnLimit: 160
|
||||
MaxEmptyLinesToKeep: 1
|
||||
|
||||
Standard: Cpp11
|
||||
Cpp11BracedListStyle: true
|
||||
|
||||
SpacesInParentheses: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpaceAfterControlStatementKeyword: true
|
||||
|
||||
AlignTrailingComments: true
|
||||
SpacesBeforeTrailingComments: 1
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,5 +1,5 @@
|
||||
Thumbs.db
|
||||
.kdev4
|
||||
*.kdev4
|
||||
.user
|
||||
.directory
|
||||
resources/CMakeFiles
|
||||
@@ -9,8 +9,7 @@ resources/MultiMCLauncher.jar
|
||||
html/
|
||||
|
||||
# Project Files
|
||||
MultiMC5.kdev4
|
||||
MultiMC.pro.user
|
||||
*.pro.user
|
||||
CMakeLists.txt.user
|
||||
CMakeLists.txt.user.*
|
||||
/.project
|
||||
|
||||
38
.travis.yml
38
.travis.yml
@@ -1,38 +0,0 @@
|
||||
# General set up
|
||||
language: cpp
|
||||
cache: apt
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
dist: precise
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
env: TRAVIS_DIST=precise QT_VERSION=5.4.2
|
||||
- os: linux
|
||||
dist: precise
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
env: TRAVIS_DIST=precise QT_VERSION=5.6.2
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
env: TRAVIS_DIST=trusty QT_VERSION=5.4.2
|
||||
- os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
compiler: gcc
|
||||
env: TRAVIS_DIST=trusty QT_VERSION=5.6.2
|
||||
|
||||
# Install dependencies
|
||||
install:
|
||||
- source travis/prepare.sh # installs qt and cmake. need to source because some env vars are set from there
|
||||
|
||||
# Actual work
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH ..
|
||||
script:
|
||||
- make -j4 && make test ARGS="-V"
|
||||
@@ -32,7 +32,7 @@ set(CMAKE_C_STANDARD_REQUIRED true)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
include(GenerateExportHeader)
|
||||
set(CMAKE_CXX_FLAGS " -Wall -pedantic -Werror -D_GLIBCXX_USE_CXX11_ABI=0 -fstack-protector-strong --param=ssp-buffer-size=4 -O3 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS " -Wall -pedantic -Werror -Wno-deprecated-declarations -D_GLIBCXX_USE_CXX11_ABI=0 -fstack-protector-strong --param=ssp-buffer-size=4 -O3 -D_FORTIFY_SOURCE=2 ${CMAKE_CXX_FLAGS}")
|
||||
if(UNIX AND APPLE)
|
||||
set(CMAKE_CXX_FLAGS " -stdlib=libc++ ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
@@ -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 4)
|
||||
set(MultiMC_VERSION_HOTFIX 8)
|
||||
|
||||
# Build number
|
||||
set(MultiMC_VERSION_BUILD -1 CACHE STRING "Build number. -1 for no build number.")
|
||||
@@ -77,6 +77,7 @@ set(MultiMC_RELEASE_VERSION_NAME "${MultiMC_VERSION_MAJOR}.${MultiMC_VERSION_MIN
|
||||
|
||||
#### Custom target to just print the version.
|
||||
add_custom_target(version echo "Version: ${MultiMC_RELEASE_VERSION_NAME}")
|
||||
add_custom_target(tcversion echo "\\#\\#teamcity[setParameter name=\\'env.MULTIMC_VERSION\\' value=\\'${MultiMC_RELEASE_VERSION_NAME}\\']")
|
||||
|
||||
################################ 3rd Party Libs ################################
|
||||
|
||||
@@ -87,6 +88,7 @@ find_package(Qt5Concurrent REQUIRED)
|
||||
find_package(Qt5Network REQUIRED)
|
||||
find_package(Qt5Test REQUIRED)
|
||||
find_package(Qt5Xml REQUIRED)
|
||||
find_package(Qt5Multimedia REQUIRED)
|
||||
|
||||
# The Qt5 cmake files don't provide its install paths, so ask qmake.
|
||||
include(QMakeQuery)
|
||||
@@ -141,7 +143,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})
|
||||
|
||||
@@ -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
|
||||
|
||||
50
README.md
50
README.md
@@ -13,21 +13,22 @@ The project uses C++ and Qt5 as the language and base framework. This might seem
|
||||
|
||||
We can do more, with less, on worse hardware and leave more resources for the game while keeping the launcher running and providing extra features.
|
||||
|
||||
If you want to contribute, either talk to us on [Discord](https://discord.gg/0k2zsXGNHs0fE4Wm), [IRC](http://webchat.esper.net/?nick=&channels=MultiMC)(esper.net/#MultiMC) or pick up some item from [workflowy](https://workflowy.com/s/2EyDMcp7CU) - there are many.
|
||||
If you want to contribute, either talk to us on [Discord](https://discord.gg/0k2zsXGNHs0fE4Wm), [IRC](http://webchat.esper.net/?nick=&channels=MultiMC)(esper.net/#MultiMC) or pick up some item from the github issues [workflowy](https://github.com/MultiMC/MultiMC5/issues) - there is always plenty of ideas around.
|
||||
|
||||
### Building
|
||||
If you want to build MultiMC yourself, check [BUILD.md](BUILD.md) for build instructions.
|
||||
|
||||
The ci server is running at [ci.multimc.org](http://ci.multimc.org), where you can watch the builds happen in (or very close to) real time. It can also serve as a nice reference on how to set up the build environment on your end.
|
||||
|
||||
According to travis.ci, the builds are currently [](https://travis-ci.org/MultiMC/MultiMC5)
|
||||
|
||||
### Code formatting
|
||||
We use [Clang Format](http://clang.llvm.org/docs/ClangFormat.html) to format the project. We highly recommend setting it up so the project stays well formatted.
|
||||
Just follow the existing formatting.
|
||||
|
||||
In general:
|
||||
* Indent with 4 space unless it's in a submodule
|
||||
* Keep lists (of arguments, parameters, initializators...) as lists, not paragraphs.
|
||||
* Prefer readability over dogma.
|
||||
|
||||
|
||||
## Translations
|
||||
Translations can be done either directly in the [translations repository](https://github.com/MultiMC/MultiMC5). For more details, see: [Translating-MultiMC](https://github.com/MultiMC/MultiMC5/wiki/Translating-MultiMC).
|
||||
Translations can be done [on crowdin](https://translate.multimc.org).
|
||||
|
||||
## Forking/Redistributing
|
||||
We keep MultiMC open source because we think it's important to be able to see the source code for a project like this, and we do so using the Apache license.
|
||||
@@ -38,8 +39,41 @@ 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).
|
||||
|
||||
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.
|
||||
|
||||
## Build status
|
||||
### Linux (Intel32)
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_Linux32_Build&guest=1">
|
||||
Build: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_Linux32_Build)/statusIcon"/>
|
||||
</a>
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_Linux32_Deploy&guest=1">
|
||||
Deploy: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_Linux32_Deploy)/statusIcon"/>
|
||||
</a>
|
||||
|
||||
### Linux (AMD64)
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_Linux64_Build&guest=1">
|
||||
Build: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_Linux64_Build)/statusIcon"/>
|
||||
</a>
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_Linux64_Deploy&guest=1">
|
||||
Deploy: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_Linux64_Deploy)/statusIcon"/>
|
||||
</a>
|
||||
|
||||
### macOS (AMD64)
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_MacOS_Build&guest=1">
|
||||
Build: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_MacOS_Build)/statusIcon"/>
|
||||
</a>
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_MacOS_Deploy&guest=1">
|
||||
Deploy: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_MacOS_Deploy)/statusIcon"/>
|
||||
</a>
|
||||
|
||||
### Windows (Intel32)
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_Windows_Build&guest=1">
|
||||
Build: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_Windows_Build)/statusIcon"/>
|
||||
</a>
|
||||
<a href="https://teamcity.multimc.org/viewType.html?buildTypeId=MultiMC_Launcher_Windows_Deploy&guest=1">
|
||||
Deploy: <img src="https://teamcity.multimc.org/app/rest/builds/buildType:(id:MultiMC_Launcher_Windows_Deploy)/statusIcon"/>
|
||||
</a>
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,10 @@ 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
|
||||
@@ -219,6 +225,7 @@ set(MINECRAFT_SOURCES
|
||||
minecraft/update/FoldersTask.h
|
||||
minecraft/update/LibrariesTask.cpp
|
||||
minecraft/update/LibrariesTask.h
|
||||
|
||||
minecraft/launch/ClaimAccount.cpp
|
||||
minecraft/launch/ClaimAccount.h
|
||||
minecraft/launch/CreateServerResourcePacksFolder.cpp
|
||||
@@ -233,12 +240,18 @@ set(MINECRAFT_SOURCES
|
||||
minecraft/launch/LauncherPartLaunch.h
|
||||
minecraft/launch/PrintInstanceInfo.cpp
|
||||
minecraft/launch/PrintInstanceInfo.h
|
||||
minecraft/launch/ReconstructAssets.cpp
|
||||
minecraft/launch/ReconstructAssets.h
|
||||
minecraft/launch/ScanModFolders.cpp
|
||||
minecraft/launch/ScanModFolders.h
|
||||
|
||||
minecraft/legacy/LegacyModList.h
|
||||
minecraft/legacy/LegacyModList.cpp
|
||||
minecraft/legacy/LegacyInstance.h
|
||||
minecraft/legacy/LegacyInstance.cpp
|
||||
minecraft/legacy/LegacyUpgradeTask.h
|
||||
minecraft/legacy/LegacyUpgradeTask.cpp
|
||||
|
||||
minecraft/GradleSpecifier.h
|
||||
minecraft/MinecraftInstance.cpp
|
||||
minecraft/MinecraftInstance.h
|
||||
@@ -273,15 +286,21 @@ set(MINECRAFT_SOURCES
|
||||
minecraft/VersionFile.h
|
||||
minecraft/VersionFilterData.h
|
||||
minecraft/VersionFilterData.cpp
|
||||
minecraft/Mod.h
|
||||
minecraft/Mod.cpp
|
||||
minecraft/SimpleModList.h
|
||||
minecraft/SimpleModList.cpp
|
||||
minecraft/World.h
|
||||
minecraft/World.cpp
|
||||
minecraft/WorldList.h
|
||||
minecraft/WorldList.cpp
|
||||
|
||||
minecraft/mod/Mod.h
|
||||
minecraft/mod/Mod.cpp
|
||||
minecraft/mod/ModDetails.h
|
||||
minecraft/mod/ModFolderModel.h
|
||||
minecraft/mod/ModFolderModel.cpp
|
||||
minecraft/mod/ModFolderLoadTask.h
|
||||
minecraft/mod/ModFolderLoadTask.cpp
|
||||
minecraft/mod/LocalModParseTask.h
|
||||
minecraft/mod/LocalModParseTask.cpp
|
||||
|
||||
# Assets
|
||||
minecraft/AssetsUtils.h
|
||||
minecraft/AssetsUtils.cpp
|
||||
@@ -312,8 +331,8 @@ add_unit_test(Library
|
||||
)
|
||||
|
||||
# FIXME: shares data with FileSystem test
|
||||
add_unit_test(SimpleModList
|
||||
SOURCES minecraft/SimpleModList_test.cpp
|
||||
add_unit_test(ModFolderModel
|
||||
SOURCES minecraft/mod/ModFolderModel_test.cpp
|
||||
DATA testdata
|
||||
LIBS MultiMC_logic
|
||||
)
|
||||
@@ -420,15 +439,14 @@ set(META_SOURCES
|
||||
)
|
||||
|
||||
set(FTB_SOURCES
|
||||
modplatform/ftb/FtbPackFetchTask.h
|
||||
modplatform/ftb/FtbPackFetchTask.cpp
|
||||
modplatform/ftb/FtbPackInstallTask.h
|
||||
modplatform/ftb/FtbPackInstallTask.cpp
|
||||
modplatform/legacy_ftb/PackFetchTask.h
|
||||
modplatform/legacy_ftb/PackFetchTask.cpp
|
||||
modplatform/legacy_ftb/PackInstallTask.h
|
||||
modplatform/legacy_ftb/PackInstallTask.cpp
|
||||
modplatform/legacy_ftb/PrivatePackManager.h
|
||||
modplatform/legacy_ftb/PrivatePackManager.cpp
|
||||
|
||||
modplatform/ftb/FtbPrivatePackManager.h
|
||||
modplatform/ftb/FtbPrivatePackManager.cpp
|
||||
|
||||
modplatform/ftb/PackHelpers.h
|
||||
modplatform/legacy_ftb/PackHelpers.h
|
||||
)
|
||||
|
||||
set(FLAME_SOURCES
|
||||
@@ -471,8 +489,6 @@ set(LOGIC_SOURCES
|
||||
${FLAME_SOURCES}
|
||||
)
|
||||
|
||||
message(STATUS "FOO! ${LOGIC_SOURCES}")
|
||||
|
||||
add_library(MultiMC_logic SHARED ${LOGIC_SOURCES})
|
||||
set_target_properties(MultiMC_logic PROPERTIES CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2013-2018 MultiMC Contributors
|
||||
/* Copyright 2013-2019 MultiMC Contributors
|
||||
*
|
||||
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2013-2018 MultiMC Contributors
|
||||
/* Copyright 2013-2019 MultiMC Contributors
|
||||
*
|
||||
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
|
||||
*
|
||||
@@ -69,8 +69,8 @@ namespace ArgumentStyle
|
||||
{
|
||||
enum Enum
|
||||
{
|
||||
Space, /**< --option=value */
|
||||
Equals, /**< --option value */
|
||||
Space, /**< --option value */
|
||||
Equals, /**< --option=value */
|
||||
SpaceAndEquals, /**< --option[= ]value */
|
||||
#ifdef Q_OS_WIN32
|
||||
Default = Equals
|
||||
|
||||
@@ -174,6 +174,11 @@ bool copy::operator()(const QString &offset)
|
||||
bool deletePath(QString path)
|
||||
{
|
||||
bool OK = true;
|
||||
QFileInfo finfo(path);
|
||||
if(finfo.isFile()) {
|
||||
return QFile::remove(path);
|
||||
}
|
||||
|
||||
QDir dir(path);
|
||||
|
||||
if (!dir.exists())
|
||||
@@ -294,7 +299,7 @@ QString NormalizePath(QString path)
|
||||
}
|
||||
}
|
||||
|
||||
QString badFilenameChars = "\"\\/?<>:*|!+\r\n";
|
||||
QString badFilenameChars = "\"\\/?<>:;*|!+\r\n";
|
||||
|
||||
QString RemoveInvalidFilenameChars(QString string, QChar replaceWith)
|
||||
{
|
||||
|
||||
@@ -5,9 +5,10 @@
|
||||
#include "pathmatcher/RegexpMatcher.h"
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, bool copySaves)
|
||||
InstanceCopyTask::InstanceCopyTask(InstancePtr origInstance, bool copySaves, bool keepPlaytime)
|
||||
{
|
||||
m_origInstance = origInstance;
|
||||
m_keepPlaytime = keepPlaytime;
|
||||
|
||||
if(!copySaves)
|
||||
{
|
||||
@@ -46,6 +47,9 @@ void InstanceCopyTask::copyFinished()
|
||||
InstancePtr inst(new NullInstance(m_globalSettings, instanceSettings, m_stagingPath));
|
||||
inst->setName(m_instName);
|
||||
inst->setIconKey(m_instIcon);
|
||||
if(!m_keepPlaytime) {
|
||||
inst->resetTimePlayed();
|
||||
}
|
||||
emitSucceeded();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class MULTIMC_LOGIC_EXPORT InstanceCopyTask : public InstanceTask
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves);
|
||||
explicit InstanceCopyTask(InstancePtr origInstance, bool copySaves, bool keepPlaytime);
|
||||
|
||||
protected:
|
||||
//! Entry point for tasks.
|
||||
@@ -28,4 +28,5 @@ private: /* data */
|
||||
QFuture<bool> m_copyFuture;
|
||||
QFutureWatcher<bool> m_copyFutureWatcher;
|
||||
std::unique_ptr<IPathMatcher> m_matcher;
|
||||
bool m_keepPlaytime;
|
||||
};
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
@@ -100,6 +100,10 @@ QVariant InstanceList::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
return pdata->name();
|
||||
}
|
||||
case Qt::AccessibleTextRole:
|
||||
{
|
||||
return tr("%1 Instance").arg(pdata->name());
|
||||
}
|
||||
case Qt::ToolTipRole:
|
||||
{
|
||||
return pdata->instanceRoot();
|
||||
@@ -156,8 +160,8 @@ GroupId InstanceList::getInstanceGroup(const InstanceId& id) const
|
||||
{
|
||||
return GroupId();
|
||||
}
|
||||
auto iter = m_groupMap.find(inst->id());
|
||||
if(iter != m_groupMap.end())
|
||||
auto iter = m_instanceGroupIndex.find(inst->id());
|
||||
if(iter != m_instanceGroupIndex.end())
|
||||
{
|
||||
return *iter;
|
||||
}
|
||||
@@ -174,8 +178,8 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
auto iter = m_groupMap.find(inst->id());
|
||||
if(iter != m_groupMap.end())
|
||||
auto iter = m_instanceGroupIndex.find(inst->id());
|
||||
if(iter != m_instanceGroupIndex.end())
|
||||
{
|
||||
if(*iter != name)
|
||||
{
|
||||
@@ -186,12 +190,12 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
|
||||
else
|
||||
{
|
||||
changed = true;
|
||||
m_groupMap[id] = name;
|
||||
m_instanceGroupIndex[id] = name;
|
||||
}
|
||||
|
||||
if(changed)
|
||||
{
|
||||
m_groups.insert(name);
|
||||
m_groupNameCache.insert(name);
|
||||
auto idx = getInstIndex(inst.get());
|
||||
emit dataChanged(index(idx), index(idx), {GroupRole});
|
||||
saveGroupList();
|
||||
@@ -200,7 +204,7 @@ void InstanceList::setInstanceGroup(const InstanceId& id, const GroupId& name)
|
||||
|
||||
QStringList InstanceList::getGroups()
|
||||
{
|
||||
return m_groups.toList();
|
||||
return m_groupNameCache.toList();
|
||||
}
|
||||
|
||||
void InstanceList::deleteGroup(const QString& name)
|
||||
@@ -213,7 +217,7 @@ void InstanceList::deleteGroup(const QString& name)
|
||||
auto instGroupName = getInstanceGroup(instID);
|
||||
if(instGroupName == name)
|
||||
{
|
||||
m_groupMap.remove(instID);
|
||||
m_instanceGroupIndex.remove(instID);
|
||||
qDebug() << "Remove" << instID << "from group" << name;
|
||||
removed = true;
|
||||
auto idx = getInstIndex(instance.get());
|
||||
@@ -229,16 +233,21 @@ void InstanceList::deleteGroup(const QString& name)
|
||||
}
|
||||
}
|
||||
|
||||
bool InstanceList::isGroupCollapsed(const QString& group)
|
||||
{
|
||||
return m_collapsedGroups.contains(group);
|
||||
}
|
||||
|
||||
void InstanceList::deleteInstance(const InstanceId& id)
|
||||
{
|
||||
auto inst = getInstanceById(id);
|
||||
if(!inst)
|
||||
{
|
||||
qDebug() << "Cannot delete instance" << id << " No such instance is present.";
|
||||
qDebug() << "Cannot delete instance" << id << ". No such instance is present (deleted externally?).";
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_groupMap.remove(id))
|
||||
if(m_instanceGroupIndex.remove(id))
|
||||
{
|
||||
saveGroupList();
|
||||
}
|
||||
@@ -511,7 +520,7 @@ void InstanceList::saveGroupList()
|
||||
WatchLock foo(m_watcher, m_instDir);
|
||||
QString groupFileName = m_instDir + "/instgroups.json";
|
||||
QMap<QString, QSet<QString>> reverseGroupMap;
|
||||
for (auto iter = m_groupMap.begin(); iter != m_groupMap.end(); iter++)
|
||||
for (auto iter = m_instanceGroupIndex.begin(); iter != m_instanceGroupIndex.end(); iter++)
|
||||
{
|
||||
QString id = iter.key();
|
||||
QString group = iter.value();
|
||||
@@ -544,7 +553,7 @@ void InstanceList::saveGroupList()
|
||||
auto name = iter.key();
|
||||
QJsonObject groupObj;
|
||||
QJsonArray instanceArr;
|
||||
groupObj.insert("hidden", QJsonValue(QString("false")));
|
||||
groupObj.insert("hidden", QJsonValue(m_collapsedGroups.contains(name)));
|
||||
for (auto item : list)
|
||||
{
|
||||
instanceArr.append(QJsonValue(item));
|
||||
@@ -568,7 +577,6 @@ void InstanceList::saveGroupList()
|
||||
void InstanceList::loadGroupList()
|
||||
{
|
||||
qDebug() << "Will load group list now.";
|
||||
QSet<QString> groupSet;
|
||||
|
||||
QString groupFileName = m_instDir + "/instgroups.json";
|
||||
|
||||
@@ -619,7 +627,8 @@ void InstanceList::loadGroupList()
|
||||
return;
|
||||
}
|
||||
|
||||
m_groupMap.clear();
|
||||
QSet<QString> groupSet;
|
||||
m_instanceGroupIndex.clear();
|
||||
|
||||
// Iterate through all the groups.
|
||||
QJsonObject groupMapping = rootObj.value("groups").toObject();
|
||||
@@ -630,37 +639,35 @@ void InstanceList::loadGroupList()
|
||||
// If not an object, complain and skip to the next one.
|
||||
if (!iter.value().isObject())
|
||||
{
|
||||
qWarning() << QString("Group '%1' in the group list should "
|
||||
"be an object.")
|
||||
.arg(groupName)
|
||||
.toUtf8();
|
||||
qWarning() << QString("Group '%1' in the group list should be an object.").arg(groupName).toUtf8();
|
||||
continue;
|
||||
}
|
||||
|
||||
QJsonObject groupObj = iter.value().toObject();
|
||||
if (!groupObj.value("instances").isArray())
|
||||
{
|
||||
qWarning() << QString("Group '%1' in the group list is invalid. "
|
||||
"It should contain an array "
|
||||
"called 'instances'.")
|
||||
.arg(groupName)
|
||||
.toUtf8();
|
||||
qWarning() << QString("Group '%1' in the group list is invalid. It should contain an array called 'instances'.").arg(groupName).toUtf8();
|
||||
continue;
|
||||
}
|
||||
|
||||
// keep a list/set of groups for choosing
|
||||
groupSet.insert(groupName);
|
||||
|
||||
auto hidden = groupObj.value("hidden").toBool(false);
|
||||
if(hidden) {
|
||||
m_collapsedGroups.insert(groupName);
|
||||
}
|
||||
|
||||
// Iterate through the list of instances in the group.
|
||||
QJsonArray instancesArray = groupObj.value("instances").toArray();
|
||||
|
||||
for (QJsonArray::iterator iter2 = instancesArray.begin(); iter2 != instancesArray.end(); iter2++)
|
||||
{
|
||||
m_groupMap[(*iter2).toString()] = groupName;
|
||||
m_instanceGroupIndex[(*iter2).toString()] = groupName;
|
||||
}
|
||||
}
|
||||
m_groupsLoaded = true;
|
||||
m_groups.unite(groupSet);
|
||||
m_groupNameCache.unite(groupSet);
|
||||
qDebug() << "Group list loaded.";
|
||||
}
|
||||
|
||||
@@ -685,6 +692,17 @@ void InstanceList::on_InstFolderChanged(const Setting &setting, QVariant value)
|
||||
}
|
||||
}
|
||||
|
||||
void InstanceList::on_GroupStateChanged(const QString& group, bool collapsed)
|
||||
{
|
||||
qDebug() << "Group" << group << (collapsed ? "collapsed" : "expanded");
|
||||
if(collapsed) {
|
||||
m_collapsedGroups.insert(group);
|
||||
} else {
|
||||
m_collapsedGroups.remove(group);
|
||||
}
|
||||
saveGroupList();
|
||||
}
|
||||
|
||||
class InstanceStaging : public Task
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -815,10 +833,11 @@ bool InstanceList::commitStagedInstance(const QString& path, const QString& inst
|
||||
qWarning() << "Failed to move" << path << "to" << destination;
|
||||
return false;
|
||||
}
|
||||
m_groupMap[instID] = groupName;
|
||||
m_instanceGroupIndex[instID] = groupName;
|
||||
instanceSet.insert(instID);
|
||||
m_groups.insert(groupName);
|
||||
m_groupNameCache.insert(groupName);
|
||||
emit instancesChanged();
|
||||
emit instanceSelectRequest(instID);
|
||||
}
|
||||
saveGroupList();
|
||||
return true;
|
||||
|
||||
@@ -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.
|
||||
@@ -99,6 +99,8 @@ public:
|
||||
InstancePtr getInstanceById(QString id) const;
|
||||
QModelIndex getInstanceIndexById(const QString &id) const;
|
||||
QStringList getGroups();
|
||||
bool isGroupCollapsed(const QString &groupName);
|
||||
|
||||
GroupId getInstanceGroup(const InstanceId & id) const;
|
||||
void setInstanceGroup(const InstanceId & id, const GroupId& name);
|
||||
|
||||
@@ -129,10 +131,12 @@ public:
|
||||
signals:
|
||||
void dataIsInvalid();
|
||||
void instancesChanged();
|
||||
void instanceSelectRequest(QString instanceId);
|
||||
void groupsChanged(QSet<QString> groups);
|
||||
|
||||
public slots:
|
||||
void on_InstFolderChanged(const Setting &setting, QVariant value);
|
||||
void on_GroupStateChanged(const QString &group, bool collapsed);
|
||||
|
||||
private slots:
|
||||
void propertiesChanged(BaseInstance *inst);
|
||||
@@ -153,12 +157,14 @@ private:
|
||||
int m_watchLevel = 0;
|
||||
bool m_dirty = false;
|
||||
QList<InstancePtr> m_instances;
|
||||
QSet<QString> m_groups;
|
||||
QSet<QString> m_groupNameCache;
|
||||
|
||||
SettingsObjectPtr m_globalSettings;
|
||||
QString m_instDir;
|
||||
QFileSystemWatcher * m_watcher;
|
||||
QMap<InstanceId, GroupId> m_groupMap;
|
||||
// FIXME: this is so inefficient that looking at it is almost painful.
|
||||
QSet<QString> m_collapsedGroups;
|
||||
QMap<InstanceId, GroupId> m_instanceGroupIndex;
|
||||
QSet<InstanceId> instanceSet;
|
||||
bool m_groupsLoaded = false;
|
||||
bool m_instancesProbed = false;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -18,7 +18,7 @@
|
||||
#include <QString>
|
||||
#include <QFileInfo>
|
||||
#include <QSet>
|
||||
#include "minecraft/Mod.h"
|
||||
#include "minecraft/mod/Mod.h"
|
||||
#include <functional>
|
||||
|
||||
#include "multimc_logic_export.h"
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
62
api/logic/icons/IconUtils.cpp
Normal file
62
api/logic/icons/IconUtils.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
14
api/logic/icons/IconUtils.h
Normal file
14
api/logic/icons/IconUtils.h
Normal 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();
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -43,6 +43,8 @@ ComponentList::ComponentList(MinecraftInstance * instance)
|
||||
d->m_instance = instance;
|
||||
d->m_saveTimer.setSingleShot(true);
|
||||
d->m_saveTimer.setInterval(5000);
|
||||
d->interactionDisabled = instance->isRunning();
|
||||
connect(d->m_instance, &BaseInstance::runningStatusChanged, this, &ComponentList::disableInteraction);
|
||||
connect(&d->m_saveTimer, &QTimer::timeout, this, &ComponentList::save_internal);
|
||||
}
|
||||
|
||||
@@ -635,6 +637,9 @@ void ComponentList::componentDataChanged()
|
||||
qWarning() << "ComponentList got dataChenged signal from a non-Component!";
|
||||
return;
|
||||
}
|
||||
if(objPtr->getID() == "net.minecraft") {
|
||||
emit minecraftChanged();
|
||||
}
|
||||
// figure out which one is it... in a seriously dumb way.
|
||||
int index = 0;
|
||||
for (auto component: d->components)
|
||||
@@ -762,8 +767,9 @@ QVariant ComponentList::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case NameColumn:
|
||||
return d->components.at(row)->isEnabled() ? Qt::Checked : Qt::Unchecked;
|
||||
case NameColumn: {
|
||||
return patch->isEnabled() ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
@@ -773,7 +779,7 @@ QVariant ComponentList::data(const QModelIndex &index, int role) const
|
||||
switch (column)
|
||||
{
|
||||
case NameColumn:
|
||||
return d->components.at(row)->getName();
|
||||
return patch->getName();
|
||||
case VersionColumn:
|
||||
{
|
||||
if(patch->isCustom())
|
||||
@@ -853,21 +859,25 @@ QVariant ComponentList::headerData(int section, Qt::Orientation orientation, int
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// FIXME: zero precision mess
|
||||
Qt::ItemFlags ComponentList::flags(const QModelIndex &index) const
|
||||
{
|
||||
if (!index.isValid())
|
||||
if (!index.isValid()) {
|
||||
return Qt::NoItemFlags;
|
||||
}
|
||||
|
||||
Qt::ItemFlags outFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
|
||||
int row = index.row();
|
||||
|
||||
if (row < 0 || row >= d->components.size())
|
||||
if (row < 0 || row >= d->components.size()) {
|
||||
return Qt::NoItemFlags;
|
||||
}
|
||||
|
||||
auto patch = d->components.at(row);
|
||||
// TODO: this will need fine-tuning later...
|
||||
if(patch->canBeDisabled())
|
||||
if(patch->canBeDisabled() && !d->interactionDisabled)
|
||||
{
|
||||
outFlags |= Qt::ItemIsUserCheckable;
|
||||
}
|
||||
@@ -1202,3 +1212,14 @@ QString ComponentList::getComponentVersion(const QString& uid) const
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
void ComponentList::disableInteraction(bool disable)
|
||||
{
|
||||
if(d->interactionDisabled != disable) {
|
||||
d->interactionDisabled = disable;
|
||||
auto size = d->components.size();
|
||||
if(size) {
|
||||
emit dataChanged(index(0), index(size - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -104,6 +104,9 @@ public:
|
||||
/// if there is a save scheduled, do it now.
|
||||
void saveNow();
|
||||
|
||||
signals:
|
||||
void minecraftChanged();
|
||||
|
||||
public:
|
||||
/// get the profile component by id
|
||||
Component * getComponent(const QString &id);
|
||||
@@ -131,6 +134,7 @@ private slots:
|
||||
void updateSucceeded();
|
||||
void updateFailed(const QString & error);
|
||||
void componentDataChanged();
|
||||
void disableInteraction(bool disable);
|
||||
|
||||
private:
|
||||
bool load();
|
||||
|
||||
@@ -38,5 +38,6 @@ struct ComponentListData
|
||||
QTimer m_saveTimer;
|
||||
shared_qobject_ptr<Task> m_updateTask;
|
||||
bool loaded = false;
|
||||
bool interactionDisabled = true;
|
||||
};
|
||||
|
||||
|
||||
@@ -451,13 +451,17 @@ static bool getTrivialComponentChanges(const ComponentIndex & index, const Requi
|
||||
auto & comp = (*compIter);
|
||||
if(comp->getVersion() != req.equalsVersion)
|
||||
{
|
||||
if(comp->m_dependencyOnly)
|
||||
{
|
||||
decision = Decision::VersionNotSame;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(comp->isCustom()) {
|
||||
decision = Decision::LockedVersionNotSame;
|
||||
} else {
|
||||
if(comp->m_dependencyOnly)
|
||||
{
|
||||
decision = Decision::VersionNotSame;
|
||||
}
|
||||
else
|
||||
{
|
||||
decision = Decision::LockedVersionNotSame;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -586,6 +590,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.
|
||||
// ############################################################################################################
|
||||
|
||||
@@ -20,12 +20,14 @@
|
||||
#include "minecraft/launch/DirectJavaLaunch.h"
|
||||
#include "minecraft/launch/ModMinecraftJar.h"
|
||||
#include "minecraft/launch/ClaimAccount.h"
|
||||
#include "minecraft/launch/ReconstructAssets.h"
|
||||
#include "minecraft/launch/ScanModFolders.h"
|
||||
#include "java/launch/CheckJava.h"
|
||||
#include "java/JavaUtils.h"
|
||||
#include "meta/Index.h"
|
||||
#include "meta/VersionList.h"
|
||||
|
||||
#include "SimpleModList.h"
|
||||
#include "mod/ModFolderModel.h"
|
||||
#include "WorldList.h"
|
||||
|
||||
#include "icons/IIconList.h"
|
||||
@@ -35,6 +37,7 @@
|
||||
#include "AssetsUtils.h"
|
||||
#include "MinecraftUpdate.h"
|
||||
#include "MinecraftLoadAndCheck.h"
|
||||
#include <minecraft/gameoptions/GameOptions.h>
|
||||
|
||||
#define IBUS "@im=ibus"
|
||||
|
||||
@@ -215,6 +218,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 +415,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;
|
||||
@@ -544,37 +551,38 @@ QStringList MinecraftInstance::verboseDescription(AuthSessionPtr session)
|
||||
out << "";
|
||||
}
|
||||
|
||||
if(loaderModList()->size())
|
||||
{
|
||||
out << "Mods:";
|
||||
for(auto & mod: loaderModList()->allMods())
|
||||
auto printModList = [&](const QString & label, ModFolderModel & model) {
|
||||
if(model.size())
|
||||
{
|
||||
if(!mod.enabled())
|
||||
continue;
|
||||
if(mod.type() == Mod::MOD_FOLDER)
|
||||
continue;
|
||||
// TODO: proper implementation would need to descend into folders.
|
||||
out << QString("%1:").arg(label);
|
||||
auto modList = model.allMods();
|
||||
std::sort(modList.begin(), modList.end(), [](Mod &a, Mod &b) {
|
||||
auto aName = a.filename().completeBaseName();
|
||||
auto bName = b.filename().completeBaseName();
|
||||
return aName.localeAwareCompare(bName) < 0;
|
||||
});
|
||||
for(auto & mod: modList)
|
||||
{
|
||||
if(mod.type() == Mod::MOD_FOLDER)
|
||||
{
|
||||
out << u8" [📁] " + mod.filename().completeBaseName() + " (folder)";
|
||||
continue;
|
||||
}
|
||||
|
||||
out << " " + mod.filename().completeBaseName();
|
||||
if(mod.enabled()) {
|
||||
out << u8" [✔️] " + mod.filename().completeBaseName();
|
||||
}
|
||||
else {
|
||||
out << u8" [❌] " + mod.filename().completeBaseName() + " (disabled)";
|
||||
}
|
||||
|
||||
}
|
||||
out << "";
|
||||
}
|
||||
out << "";
|
||||
}
|
||||
};
|
||||
|
||||
if(coreModList()->size())
|
||||
{
|
||||
out << "Core Mods:";
|
||||
for(auto & coremod: coreModList()->allMods())
|
||||
{
|
||||
if(!coremod.enabled())
|
||||
continue;
|
||||
if(coremod.type() == Mod::MOD_FOLDER)
|
||||
continue;
|
||||
// TODO: proper implementation would need to descend into folders.
|
||||
|
||||
out << " " + coremod.filename().completeBaseName();
|
||||
}
|
||||
out << "";
|
||||
}
|
||||
printModList("Mods", *(loaderModList().get()));
|
||||
printModList("Core Mods", *(coreModList().get()));
|
||||
|
||||
auto & jarMods = profile->getJarMods();
|
||||
if(jarMods.size())
|
||||
@@ -642,8 +650,7 @@ QMap<QString, QString> MinecraftInstance::createCensorFilterFromSession(AuthSess
|
||||
auto i = sessionRef.u.properties.begin();
|
||||
while (i != sessionRef.u.properties.end())
|
||||
{
|
||||
if(i.key() == "preferredLanguage")
|
||||
{
|
||||
if(i.value().length() <= 3) {
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
@@ -771,22 +778,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 +801,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 +816,42 @@ 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));
|
||||
}
|
||||
|
||||
// if there are any jar mods
|
||||
{
|
||||
process->appendStep(new ScanModFolders(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 +859,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 +876,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);
|
||||
}
|
||||
@@ -886,43 +899,47 @@ JavaVersion MinecraftInstance::getJavaVersion() const
|
||||
return JavaVersion(settings()->get("JavaVersion").toString());
|
||||
}
|
||||
|
||||
std::shared_ptr<SimpleModList> MinecraftInstance::loaderModList() const
|
||||
std::shared_ptr<ModFolderModel> MinecraftInstance::loaderModList() const
|
||||
{
|
||||
if (!m_loader_mod_list)
|
||||
{
|
||||
m_loader_mod_list.reset(new SimpleModList(loaderModsDir()));
|
||||
m_loader_mod_list.reset(new ModFolderModel(loaderModsDir()));
|
||||
m_loader_mod_list->disableInteraction(isRunning());
|
||||
connect(this, &BaseInstance::runningStatusChanged, m_loader_mod_list.get(), &ModFolderModel::disableInteraction);
|
||||
}
|
||||
m_loader_mod_list->update();
|
||||
return m_loader_mod_list;
|
||||
}
|
||||
|
||||
std::shared_ptr<SimpleModList> MinecraftInstance::coreModList() const
|
||||
std::shared_ptr<ModFolderModel> MinecraftInstance::coreModList() const
|
||||
{
|
||||
if (!m_core_mod_list)
|
||||
{
|
||||
m_core_mod_list.reset(new SimpleModList(coreModsDir()));
|
||||
m_core_mod_list.reset(new ModFolderModel(coreModsDir()));
|
||||
m_core_mod_list->disableInteraction(isRunning());
|
||||
connect(this, &BaseInstance::runningStatusChanged, m_core_mod_list.get(), &ModFolderModel::disableInteraction);
|
||||
}
|
||||
m_core_mod_list->update();
|
||||
return m_core_mod_list;
|
||||
}
|
||||
|
||||
std::shared_ptr<SimpleModList> MinecraftInstance::resourcePackList() const
|
||||
std::shared_ptr<ModFolderModel> MinecraftInstance::resourcePackList() const
|
||||
{
|
||||
if (!m_resource_pack_list)
|
||||
{
|
||||
m_resource_pack_list.reset(new SimpleModList(resourcePacksDir()));
|
||||
m_resource_pack_list.reset(new ModFolderModel(resourcePacksDir()));
|
||||
m_resource_pack_list->disableInteraction(isRunning());
|
||||
connect(this, &BaseInstance::runningStatusChanged, m_resource_pack_list.get(), &ModFolderModel::disableInteraction);
|
||||
}
|
||||
m_resource_pack_list->update();
|
||||
return m_resource_pack_list;
|
||||
}
|
||||
|
||||
std::shared_ptr<SimpleModList> MinecraftInstance::texturePackList() const
|
||||
std::shared_ptr<ModFolderModel> MinecraftInstance::texturePackList() const
|
||||
{
|
||||
if (!m_texture_pack_list)
|
||||
{
|
||||
m_texture_pack_list.reset(new SimpleModList(texturePacksDir()));
|
||||
m_texture_pack_list.reset(new ModFolderModel(texturePacksDir()));
|
||||
m_texture_pack_list->disableInteraction(isRunning());
|
||||
connect(this, &BaseInstance::runningStatusChanged, m_texture_pack_list.get(), &ModFolderModel::disableInteraction);
|
||||
}
|
||||
m_texture_pack_list->update();
|
||||
return m_texture_pack_list;
|
||||
}
|
||||
|
||||
@@ -935,6 +952,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();
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#pragma once
|
||||
#include "BaseInstance.h"
|
||||
#include <java/JavaVersion.h>
|
||||
#include "minecraft/Mod.h"
|
||||
#include "minecraft/mod/Mod.h"
|
||||
#include <QProcess>
|
||||
#include <QDir>
|
||||
#include "multimc_logic_export.h"
|
||||
|
||||
class ModsModel;
|
||||
class SimpleModList;
|
||||
class ModFolderModel;
|
||||
class WorldList;
|
||||
class GameOptions;
|
||||
class LaunchStep;
|
||||
class ComponentList;
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
QString modsCacheLocation() const;
|
||||
QString libDir() const;
|
||||
QString worldDir() const;
|
||||
QString resourcesDir() const;
|
||||
QDir jarmodsPath() const;
|
||||
QDir librariesPath() const;
|
||||
QDir versionsPath() const;
|
||||
@@ -66,17 +67,16 @@ public:
|
||||
std::shared_ptr<ComponentList> getComponentList() const;
|
||||
|
||||
////// Mod Lists //////
|
||||
std::shared_ptr<ModsModel> modsModel() const;
|
||||
std::shared_ptr<SimpleModList> loaderModList() const;
|
||||
std::shared_ptr<SimpleModList> coreModList() const;
|
||||
std::shared_ptr<SimpleModList> resourcePackList() const;
|
||||
std::shared_ptr<SimpleModList> texturePackList() const;
|
||||
std::shared_ptr<ModFolderModel> loaderModList() const;
|
||||
std::shared_ptr<ModFolderModel> coreModList() const;
|
||||
std::shared_ptr<ModFolderModel> resourcePackList() const;
|
||||
std::shared_ptr<ModFolderModel> 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;
|
||||
@@ -111,9 +111,6 @@ public:
|
||||
|
||||
virtual JavaVersion getJavaVersion() const;
|
||||
|
||||
signals:
|
||||
void versionReloaded();
|
||||
|
||||
protected:
|
||||
QMap<QString, QString> createCensorFilterFromSession(AuthSessionPtr session);
|
||||
QStringList validLaunchMethods();
|
||||
@@ -124,12 +121,12 @@ private:
|
||||
|
||||
protected: // data
|
||||
std::shared_ptr<ComponentList> m_components;
|
||||
mutable std::shared_ptr<ModsModel> m_mods_model;
|
||||
mutable std::shared_ptr<SimpleModList> m_loader_mod_list;
|
||||
mutable std::shared_ptr<SimpleModList> m_core_mod_list;
|
||||
mutable std::shared_ptr<SimpleModList> m_resource_pack_list;
|
||||
mutable std::shared_ptr<SimpleModList> m_texture_pack_list;
|
||||
mutable std::shared_ptr<ModFolderModel> m_loader_mod_list;
|
||||
mutable std::shared_ptr<ModFolderModel> m_core_mod_list;
|
||||
mutable std::shared_ptr<ModFolderModel> m_resource_pack_list;
|
||||
mutable std::shared_ptr<ModFolderModel> 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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,378 +0,0 @@
|
||||
/* Copyright 2013-2018 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 <QDir>
|
||||
#include <QString>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonValue>
|
||||
#include <quazip.h>
|
||||
#include <quazipfile.h>
|
||||
|
||||
#include "Mod.h"
|
||||
#include "settings/INIFile.h"
|
||||
#include <FileSystem.h>
|
||||
#include <QDebug>
|
||||
|
||||
Mod::Mod(const QFileInfo &file)
|
||||
{
|
||||
repath(file);
|
||||
m_changedDateTime = file.lastModified();
|
||||
}
|
||||
|
||||
void Mod::repath(const QFileInfo &file)
|
||||
{
|
||||
m_file = file;
|
||||
QString name_base = file.fileName();
|
||||
|
||||
m_type = Mod::MOD_UNKNOWN;
|
||||
|
||||
if (m_file.isDir())
|
||||
{
|
||||
m_type = MOD_FOLDER;
|
||||
m_name = name_base;
|
||||
m_mmc_id = name_base;
|
||||
}
|
||||
else if (m_file.isFile())
|
||||
{
|
||||
if (name_base.endsWith(".disabled"))
|
||||
{
|
||||
m_enabled = false;
|
||||
name_base.chop(9);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_enabled = true;
|
||||
}
|
||||
m_mmc_id = name_base;
|
||||
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;
|
||||
}
|
||||
|
||||
if (m_type == MOD_ZIPFILE)
|
||||
{
|
||||
QuaZip zip(m_file.filePath());
|
||||
if (!zip.open(QuaZip::mdUnzip))
|
||||
return;
|
||||
|
||||
QuaZipFile file(&zip);
|
||||
|
||||
if (zip.setCurrentFile("mcmod.info"))
|
||||
{
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
|
||||
ReadMCModInfo(file.readAll());
|
||||
file.close();
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
else if (zip.setCurrentFile("forgeversion.properties"))
|
||||
{
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
|
||||
ReadForgeInfo(file.readAll());
|
||||
file.close();
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
|
||||
zip.close();
|
||||
}
|
||||
else if (m_type == MOD_FOLDER)
|
||||
{
|
||||
QFileInfo mcmod_info(FS::PathCombine(m_file.filePath(), "mcmod.info"));
|
||||
if (mcmod_info.isFile())
|
||||
{
|
||||
QFile mcmod(mcmod_info.filePath());
|
||||
if (!mcmod.open(QIODevice::ReadOnly))
|
||||
return;
|
||||
auto data = mcmod.readAll();
|
||||
if (data.isEmpty() || data.isNull())
|
||||
return;
|
||||
ReadMCModInfo(data);
|
||||
}
|
||||
}
|
||||
else if (m_type == MOD_LITEMOD)
|
||||
{
|
||||
QuaZip zip(m_file.filePath());
|
||||
if (!zip.open(QuaZip::mdUnzip))
|
||||
return;
|
||||
|
||||
QuaZipFile file(&zip);
|
||||
|
||||
if (zip.setCurrentFile("litemod.json"))
|
||||
{
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
zip.close();
|
||||
return;
|
||||
}
|
||||
|
||||
ReadLiteModInfo(file.readAll());
|
||||
file.close();
|
||||
}
|
||||
zip.close();
|
||||
}
|
||||
}
|
||||
|
||||
// NEW format
|
||||
// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/6f62b37cea040daf350dc253eae6326dd9c822c3
|
||||
|
||||
// OLD format:
|
||||
// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/5bf6a2d05145ec79387acc0d45c958642fb049fc
|
||||
void Mod::ReadMCModInfo(QByteArray contents)
|
||||
{
|
||||
auto getInfoFromArray = [&](QJsonArray arr)->void
|
||||
{
|
||||
if (!arr.at(0).isObject())
|
||||
return;
|
||||
auto firstObj = arr.at(0).toObject();
|
||||
m_mod_id = firstObj.value("modid").toString();
|
||||
m_name = firstObj.value("name").toString();
|
||||
m_version = firstObj.value("version").toString();
|
||||
m_homeurl = firstObj.value("url").toString();
|
||||
m_updateurl = firstObj.value("updateUrl").toString();
|
||||
m_homeurl = m_homeurl.trimmed();
|
||||
if(!m_homeurl.isEmpty())
|
||||
{
|
||||
// fix up url.
|
||||
if (!m_homeurl.startsWith("http://") && !m_homeurl.startsWith("https://") &&
|
||||
!m_homeurl.startsWith("ftp://"))
|
||||
{
|
||||
m_homeurl.prepend("http://");
|
||||
}
|
||||
}
|
||||
m_description = firstObj.value("description").toString();
|
||||
QJsonArray authors = firstObj.value("authorList").toArray();
|
||||
if (authors.size() == 0)
|
||||
authors = firstObj.value("authors").toArray();
|
||||
|
||||
if (authors.size() == 0)
|
||||
m_authors = "";
|
||||
else if (authors.size() >= 1)
|
||||
{
|
||||
m_authors = authors.at(0).toString();
|
||||
for (int i = 1; i < authors.size(); i++)
|
||||
{
|
||||
m_authors += ", " + authors.at(i).toString();
|
||||
}
|
||||
}
|
||||
m_credits = firstObj.value("credits").toString();
|
||||
return;
|
||||
}
|
||||
;
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
|
||||
// this is the very old format that had just the array
|
||||
if (jsonDoc.isArray())
|
||||
{
|
||||
getInfoFromArray(jsonDoc.array());
|
||||
}
|
||||
else if (jsonDoc.isObject())
|
||||
{
|
||||
auto val = jsonDoc.object().value("modinfoversion");
|
||||
if(val.isUndefined())
|
||||
val = jsonDoc.object().value("modListVersion");
|
||||
int version = val.toDouble();
|
||||
if (version != 2)
|
||||
{
|
||||
qCritical() << "BAD stuff happened to mod json:";
|
||||
qCritical() << contents;
|
||||
return;
|
||||
}
|
||||
auto arrVal = jsonDoc.object().value("modlist");
|
||||
if(arrVal.isUndefined())
|
||||
arrVal = jsonDoc.object().value("modList");
|
||||
if (arrVal.isArray())
|
||||
{
|
||||
getInfoFromArray(arrVal.toArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mod::ReadForgeInfo(QByteArray contents)
|
||||
{
|
||||
// Read the data
|
||||
m_name = "Minecraft Forge";
|
||||
m_mod_id = "Forge";
|
||||
m_homeurl = "http://www.minecraftforge.net/forum/";
|
||||
INIFile ini;
|
||||
if (!ini.loadFile(contents))
|
||||
return;
|
||||
|
||||
QString major = ini.get("forge.major.number", "0").toString();
|
||||
QString minor = ini.get("forge.minor.number", "0").toString();
|
||||
QString revision = ini.get("forge.revision.number", "0").toString();
|
||||
QString build = ini.get("forge.build.number", "0").toString();
|
||||
|
||||
m_version = major + "." + minor + "." + revision + "." + build;
|
||||
}
|
||||
|
||||
void Mod::ReadLiteModInfo(QByteArray contents)
|
||||
{
|
||||
QJsonParseError jsonError;
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
|
||||
auto object = jsonDoc.object();
|
||||
if (object.contains("name"))
|
||||
{
|
||||
m_mod_id = m_name = object.value("name").toString();
|
||||
}
|
||||
if (object.contains("version"))
|
||||
{
|
||||
m_version = object.value("version").toString("");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_version = object.value("revision").toString("");
|
||||
}
|
||||
m_mcversion = object.value("mcversion").toString();
|
||||
m_authors = object.value("author").toString();
|
||||
m_description = object.value("description").toString();
|
||||
m_homeurl = object.value("url").toString();
|
||||
}
|
||||
|
||||
bool Mod::replace(Mod &with)
|
||||
{
|
||||
if (!destroy())
|
||||
return false;
|
||||
bool success = false;
|
||||
auto t = with.type();
|
||||
|
||||
if (t == MOD_ZIPFILE || t == MOD_SINGLEFILE || t == MOD_LITEMOD)
|
||||
{
|
||||
qDebug() << "Copy: " << with.m_file.filePath() << " to " << m_file.filePath();
|
||||
success = QFile::copy(with.m_file.filePath(), m_file.filePath());
|
||||
}
|
||||
if (t == MOD_FOLDER)
|
||||
{
|
||||
success = FS::copy(with.m_file.filePath(), m_file.path())();
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
m_name = with.m_name;
|
||||
m_mmc_id = with.m_mmc_id;
|
||||
m_mod_id = with.m_mod_id;
|
||||
m_version = with.m_version;
|
||||
m_mcversion = with.m_mcversion;
|
||||
m_description = with.m_description;
|
||||
m_authors = with.m_authors;
|
||||
m_credits = with.m_credits;
|
||||
m_homeurl = with.m_homeurl;
|
||||
m_type = with.m_type;
|
||||
m_file.refresh();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
bool Mod::destroy()
|
||||
{
|
||||
if (m_type == MOD_FOLDER)
|
||||
{
|
||||
QDir d(m_file.filePath());
|
||||
if (d.removeRecursively())
|
||||
{
|
||||
m_type = MOD_UNKNOWN;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (m_type == MOD_SINGLEFILE || m_type == MOD_ZIPFILE || m_type == MOD_LITEMOD)
|
||||
{
|
||||
QFile f(m_file.filePath());
|
||||
if (f.remove())
|
||||
{
|
||||
m_type = MOD_UNKNOWN;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QString Mod::version() const
|
||||
{
|
||||
switch (type())
|
||||
{
|
||||
case MOD_ZIPFILE:
|
||||
case MOD_LITEMOD:
|
||||
return m_version;
|
||||
case MOD_FOLDER:
|
||||
return "Folder";
|
||||
case MOD_SINGLEFILE:
|
||||
return "File";
|
||||
default:
|
||||
return "VOID";
|
||||
}
|
||||
}
|
||||
|
||||
bool Mod::enable(bool value)
|
||||
{
|
||||
if (m_type == Mod::MOD_UNKNOWN || m_type == Mod::MOD_FOLDER)
|
||||
return false;
|
||||
|
||||
if (m_enabled == value)
|
||||
return false;
|
||||
|
||||
QString path = m_file.absoluteFilePath();
|
||||
if (value)
|
||||
{
|
||||
QFile foo(path);
|
||||
if (!path.endsWith(".disabled"))
|
||||
return false;
|
||||
path.chop(9);
|
||||
if (!foo.rename(path))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
QFile foo(path);
|
||||
path += ".disabled";
|
||||
if (!foo.rename(path))
|
||||
return false;
|
||||
}
|
||||
m_file = QFileInfo(path);
|
||||
m_enabled = value;
|
||||
return true;
|
||||
}
|
||||
bool Mod::operator==(const Mod &other) const
|
||||
{
|
||||
return mmc_id() == other.mmc_id();
|
||||
}
|
||||
bool Mod::strongCompare(const Mod &other) const
|
||||
{
|
||||
return mmc_id() == other.mmc_id() && version() == other.version() && type() == other.type();
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -33,7 +33,7 @@ slots:
|
||||
|
||||
auto time_parsed = timeFromS3Time(timestamp);
|
||||
auto time_serialized = timeToS3Time(time_parsed);
|
||||
|
||||
|
||||
QCOMPARE(time_serialized, timestamp);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -429,7 +429,3 @@ bool World::operator==(const World &other) const
|
||||
{
|
||||
return is_valid == other.is_valid && folderName() == other.folderName();
|
||||
}
|
||||
bool World::strongCompare(const World &other) const
|
||||
{
|
||||
return is_valid == other.is_valid && folderName() == other.folderName();
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -76,7 +76,6 @@ public:
|
||||
|
||||
// WEAK compare operator - used for replacing worlds
|
||||
bool operator==(const World &other) const;
|
||||
bool strongCompare(const World &other) const;
|
||||
|
||||
private:
|
||||
void readFromZip(const QFileInfo &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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2013-2018 MultiMC Contributors
|
||||
/* Copyright 2013-2019 MultiMC Contributors
|
||||
*
|
||||
* Authors: Orochimarufan <orochimarufan.x3@gmail.com>
|
||||
*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user