summaryrefslogtreecommitdiffstats
path: root/logic
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2015-10-05 01:47:27 +0200
committerPetr Mrázek <peterix@gmail.com>2015-10-05 01:47:27 +0200
commitf93f867c3da084c6d6c5e3ed23896609cff0e692 (patch)
tree3234c54d9aefb5566afc0c8ff52874e20ab35304 /logic
parent7459eb627c97d27ef6e12cdededa48e1ff03d533 (diff)
downloadMultiMC-f93f867c3da084c6d6c5e3ed23896609cff0e692.tar
MultiMC-f93f867c3da084c6d6c5e3ed23896609cff0e692.tar.gz
MultiMC-f93f867c3da084c6d6c5e3ed23896609cff0e692.tar.lz
MultiMC-f93f867c3da084c6d6c5e3ed23896609cff0e692.tar.xz
MultiMC-f93f867c3da084c6d6c5e3ed23896609cff0e692.zip
NOISSUE dissolve util library
Diffstat (limited to 'logic')
-rw-r--r--logic/BaseInstance.cpp8
-rw-r--r--logic/CMakeLists.txt10
-rw-r--r--logic/Commandline.cpp483
-rw-r--r--logic/Commandline.h252
-rw-r--r--logic/FileSystem.cpp372
-rw-r--r--logic/FileSystem.h82
-rw-r--r--logic/InstanceList.cpp16
-rw-r--r--logic/InstanceList.h2
-rw-r--r--logic/MMCZip.cpp6
-rw-r--r--logic/Version.cpp140
-rw-r--r--logic/Version.h110
-rw-r--r--logic/auth/MojangAccountList.cpp4
-rw-r--r--logic/forge/ForgeInstaller.cpp8
-rw-r--r--logic/forge/ForgeXzDownload.cpp4
-rw-r--r--logic/ftb/FTBPlugin.cpp10
-rw-r--r--logic/ftb/FTBProfileStrategy.cpp8
-rw-r--r--logic/ftb/OneSixFTBInstance.cpp6
-rw-r--r--logic/icons/IconList.cpp8
-rw-r--r--logic/java/JavaChecker.cpp8
-rw-r--r--logic/java/JavaCheckerJob.cpp1
-rw-r--r--logic/java/JavaUtils.cpp1
-rw-r--r--logic/java/JavaUtils.h5
-rw-r--r--logic/launch/LaunchTask.cpp1
-rw-r--r--logic/launch/steps/CheckJava.cpp4
-rw-r--r--logic/launch/steps/LaunchMinecraft.cpp4
-rw-r--r--logic/minecraft/AssetsUtils.cpp17
-rw-r--r--logic/minecraft/LegacyInstance.cpp29
-rw-r--r--logic/minecraft/LegacyUpdate.cpp24
-rw-r--r--logic/minecraft/MinecraftInstance.cpp8
-rw-r--r--logic/minecraft/MinecraftProfile.cpp1
-rw-r--r--logic/minecraft/MinecraftVersionList.cpp7
-rw-r--r--logic/minecraft/Mod.cpp6
-rw-r--r--logic/minecraft/ModList.cpp10
-rw-r--r--logic/minecraft/OneSixInstance.cpp24
-rw-r--r--logic/minecraft/OneSixProfileStrategy.cpp36
-rw-r--r--logic/minecraft/OneSixUpdate.cpp10
-rw-r--r--logic/minecraft/RawLibrary.cpp4
-rw-r--r--logic/minecraft/VersionFile.cpp6
-rw-r--r--logic/minecraft/World.cpp12
-rw-r--r--logic/minecraft/WorldList.cpp4
-rw-r--r--logic/net/CacheDownload.cpp4
-rw-r--r--logic/net/HttpMetaCache.cpp5
-rw-r--r--logic/net/MD5EtagDownload.cpp4
-rw-r--r--logic/net/NetJob.cpp1
-rw-r--r--logic/updater/DownloadTask.cpp1
-rw-r--r--logic/updater/GoUpdate.cpp8
46 files changed, 1603 insertions, 171 deletions
diff --git a/logic/BaseInstance.cpp b/logic/BaseInstance.cpp
index 02284d37..53e4ca6b 100644
--- a/logic/BaseInstance.cpp
+++ b/logic/BaseInstance.cpp
@@ -22,10 +22,10 @@
#include "settings/Setting.h"
#include "settings/OverrideSetting.h"
-#include "pathutils.h"
-#include <cmdutils.h>
#include "minecraft/MinecraftVersionList.h"
#include "icons/IconList.h"
+#include "FileSystem.h"
+#include "Commandline.h"
BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: QObject()
@@ -78,7 +78,7 @@ void BaseInstance::iconUpdated(QString key)
void BaseInstance::nuke()
{
- deletePath(instanceRoot());
+ FS::deletePath(instanceRoot());
emit nuked(this);
}
@@ -268,5 +268,5 @@ QString BaseInstance::windowTitle() const
QStringList BaseInstance::extraArguments() const
{
- return Util::Commandline::splitArgs(settings()->get("JvmArgs").toString());
+ return Commandline::splitArgs(settings()->get("JvmArgs").toString());
}
diff --git a/logic/CMakeLists.txt b/logic/CMakeLists.txt
index 7e9ee1d1..6d03e3bd 100644
--- a/logic/CMakeLists.txt
+++ b/logic/CMakeLists.txt
@@ -65,6 +65,14 @@ set(LOGIC_SOURCES
GZip.h
GZip.cpp
+ # Command line parameter parsing
+ Commandline.h
+ Commandline.cpp
+
+ # Version number string support
+ Version.h
+ Version.cpp
+
# network stuffs
net/NetAction.h
net/MD5EtagDownload.h
@@ -312,7 +320,7 @@ set_target_properties(MultiMC_logic PROPERTIES CXX_VISIBILITY_PRESET hidden VISI
generate_export_header(MultiMC_logic)
# Link
-target_link_libraries(MultiMC_logic xz-embedded unpack200 iconfix MultiMC_util LogicalGui ${QUAZIP_LIBRARIES} nbt++ ${ZLIB_LIBRARIES})
+target_link_libraries(MultiMC_logic xz-embedded unpack200 iconfix LogicalGui ${QUAZIP_LIBRARIES} nbt++ ${ZLIB_LIBRARIES})
qt5_use_modules(MultiMC_logic Core Xml Widgets Network Concurrent)
add_dependencies(MultiMC_logic QuaZIP)
diff --git a/logic/Commandline.cpp b/logic/Commandline.cpp
new file mode 100644
index 00000000..9a8ddbf1
--- /dev/null
+++ b/logic/Commandline.cpp
@@ -0,0 +1,483 @@
+/* Copyright 2013-2015 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * 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 "Commandline.h"
+
+/**
+ * @file libutil/src/cmdutils.cpp
+ */
+
+namespace Commandline
+{
+
+// commandline splitter
+QStringList splitArgs(QString args)
+{
+ QStringList argv;
+ QString current;
+ bool escape = false;
+ QChar inquotes;
+ for (int i = 0; i < args.length(); i++)
+ {
+ QChar cchar = args.at(i);
+
+ // \ escaped
+ if (escape)
+ {
+ current += cchar;
+ escape = false;
+ // in "quotes"
+ }
+ else if (!inquotes.isNull())
+ {
+ if (cchar == 0x5C)
+ escape = true;
+ else if (cchar == inquotes)
+ inquotes = 0;
+ else
+ current += cchar;
+ // otherwise
+ }
+ else
+ {
+ if (cchar == 0x20)
+ {
+ if (!current.isEmpty())
+ {
+ argv << current;
+ current.clear();
+ }
+ }
+ else if (cchar == 0x22 || cchar == 0x27)
+ inquotes = cchar;
+ else
+ current += cchar;
+ }
+ }
+ if (!current.isEmpty())
+ argv << current;
+ return argv;
+}
+
+Parser::Parser(FlagStyle::Enum flagStyle, ArgumentStyle::Enum argStyle)
+{
+ m_flagStyle = flagStyle;
+ m_argStyle = argStyle;
+}
+
+// styles setter/getter
+void Parser::setArgumentStyle(ArgumentStyle::Enum style)
+{
+ m_argStyle = style;
+}
+ArgumentStyle::Enum Parser::argumentStyle()
+{
+ return m_argStyle;
+}
+
+void Parser::setFlagStyle(FlagStyle::Enum style)
+{
+ m_flagStyle = style;
+}
+FlagStyle::Enum Parser::flagStyle()
+{
+ return m_flagStyle;
+}
+
+// setup methods
+void Parser::addSwitch(QString name, bool def)
+{
+ if (m_params.contains(name))
+ throw "Name not unique";
+
+ OptionDef *param = new OptionDef;
+ param->type = otSwitch;
+ param->name = name;
+ param->metavar = QString("<%1>").arg(name);
+ param->def = def;
+
+ m_options[name] = param;
+ m_params[name] = (CommonDef *)param;
+ m_optionList.append(param);
+}
+
+void Parser::addOption(QString name, QVariant def)
+{
+ if (m_params.contains(name))
+ throw "Name not unique";
+
+ OptionDef *param = new OptionDef;
+ param->type = otOption;
+ param->name = name;
+ param->metavar = QString("<%1>").arg(name);
+ param->def = def;
+
+ m_options[name] = param;
+ m_params[name] = (CommonDef *)param;
+ m_optionList.append(param);
+}
+
+void Parser::addArgument(QString name, bool required, QVariant def)
+{
+ if (m_params.contains(name))
+ throw "Name not unique";
+
+ PositionalDef *param = new PositionalDef;
+ param->name = name;
+ param->def = def;
+ param->required = required;
+ param->metavar = name;
+
+ m_positionals.append(param);
+ m_params[name] = (CommonDef *)param;
+}
+
+void Parser::addDocumentation(QString name, QString doc, QString metavar)
+{
+ if (!m_params.contains(name))
+ throw "Name does not exist";
+
+ CommonDef *param = m_params[name];
+ param->doc = doc;
+ if (!metavar.isNull())
+ param->metavar = metavar;
+}
+
+void Parser::addShortOpt(QString name, QChar flag)
+{
+ if (!m_params.contains(name))
+ throw "Name does not exist";
+ if (!m_options.contains(name))
+ throw "Name is not an Option or Swtich";
+
+ OptionDef *param = m_options[name];
+ m_flags[flag] = param;
+ param->flag = flag;
+}
+
+// help methods
+QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags)
+{
+ QStringList help;
+ help << compileUsage(progName, useFlags) << "\r\n";
+
+ // positionals
+ if (!m_positionals.isEmpty())
+ {
+ help << "\r\n";
+ help << "Positional arguments:\r\n";
+ QListIterator<PositionalDef *> it2(m_positionals);
+ while (it2.hasNext())
+ {
+ PositionalDef *param = it2.next();
+ help << " " << param->metavar;
+ help << " " << QString(helpIndent - param->metavar.length() - 1, ' ');
+ help << param->doc << "\r\n";
+ }
+ }
+
+ // Options
+ if (!m_optionList.isEmpty())
+ {
+ help << "\r\n";
+ QString optPrefix, flagPrefix;
+ getPrefix(optPrefix, flagPrefix);
+
+ help << "Options & Switches:\r\n";
+ QListIterator<OptionDef *> it(m_optionList);
+ while (it.hasNext())
+ {
+ OptionDef *option = it.next();
+ help << " ";
+ int nameLength = optPrefix.length() + option->name.length();
+ if (!option->flag.isNull())
+ {
+ nameLength += 3 + flagPrefix.length();
+ help << flagPrefix << option->flag << ", ";
+ }
+ help << optPrefix << option->name;
+ if (option->type == otOption)
+ {
+ QString arg = QString("%1%2").arg(
+ ((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar);
+ nameLength += arg.length();
+ help << arg;
+ }
+ help << " " << QString(helpIndent - nameLength - 1, ' ');
+ help << option->doc << "\r\n";
+ }
+ }
+
+ return help.join("");
+}
+
+QString Parser::compileUsage(QString progName, bool useFlags)
+{
+ QStringList usage;
+ usage << "Usage: " << progName;
+
+ QString optPrefix, flagPrefix;
+ getPrefix(optPrefix, flagPrefix);
+
+ // options
+ QListIterator<OptionDef *> it(m_optionList);
+ while (it.hasNext())
+ {
+ OptionDef *option = it.next();
+ usage << " [";
+ if (!option->flag.isNull() && useFlags)
+ usage << flagPrefix << option->flag;
+ else
+ usage << optPrefix << option->name;
+ if (option->type == otOption)
+ usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar;
+ usage << "]";
+ }
+
+ // arguments
+ QListIterator<PositionalDef *> it2(m_positionals);
+ while (it2.hasNext())
+ {
+ PositionalDef *param = it2.next();
+ usage << " " << (param->required ? "<" : "[");
+ usage << param->metavar;
+ usage << (param->required ? ">" : "]");
+ }
+
+ return usage.join("");
+}
+
+// parsing
+QHash<QString, QVariant> Parser::parse(QStringList argv)
+{
+ QHash<QString, QVariant> map;
+
+ QStringListIterator it(argv);
+ QString programName = it.next();
+
+ QString optionPrefix;
+ QString flagPrefix;
+ QListIterator<PositionalDef *> positionals(m_positionals);
+ QStringList expecting;
+
+ getPrefix(optionPrefix, flagPrefix);
+
+ while (it.hasNext())
+ {
+ QString arg = it.next();
+
+ if (!expecting.isEmpty())
+ // we were expecting an argument
+ {
+ QString name = expecting.first();
+/*
+ if (map.contains(name))
+ throw ParsingError(
+ QString("Option %2%1 was given multiple times").arg(name, optionPrefix));
+*/
+ map[name] = QVariant(arg);
+
+ expecting.removeFirst();
+ continue;
+ }
+
+ if (arg.startsWith(optionPrefix))
+ // we have an option
+ {
+ // qDebug("Found option %s", qPrintable(arg));
+
+ QString name = arg.mid(optionPrefix.length());
+ QString equals;
+
+ if ((m_argStyle == ArgumentStyle::Equals ||
+ m_argStyle == ArgumentStyle::SpaceAndEquals) &&
+ name.contains("="))
+ {
+ int i = name.indexOf("=");
+ equals = name.mid(i + 1);
+ name = name.left(i);
+ }
+
+ if (m_options.contains(name))
+ {
+ /*
+ if (map.contains(name))
+ throw ParsingError(QString("Option %2%1 was given multiple times")
+ .arg(name, optionPrefix));
+*/
+ OptionDef *option = m_options[name];
+ if (option->type == otSwitch)
+ map[name] = true;
+ else // if (option->type == otOption)
+ {
+ if (m_argStyle == ArgumentStyle::Space)
+ expecting.append(name);
+ else if (!equals.isNull())
+ map[name] = equals;
+ else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
+ expecting.append(name);
+ else
+ throw ParsingError(QString("Option %2%1 reqires an argument.")
+ .arg(name, optionPrefix));
+ }
+
+ continue;
+ }
+
+ throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix));
+ }
+
+ if (arg.startsWith(flagPrefix))
+ // we have (a) flag(s)
+ {
+ // qDebug("Found flags %s", qPrintable(arg));
+
+ QString flags = arg.mid(flagPrefix.length());
+ QString equals;
+
+ if ((m_argStyle == ArgumentStyle::Equals ||
+ m_argStyle == ArgumentStyle::SpaceAndEquals) &&
+ flags.contains("="))
+ {
+ int i = flags.indexOf("=");
+ equals = flags.mid(i + 1);
+ flags = flags.left(i);
+ }
+
+ for (int i = 0; i < flags.length(); i++)
+ {
+ QChar flag = flags.at(i);
+
+ if (!m_flags.contains(flag))
+ throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix));
+
+ OptionDef *option = m_flags[flag];
+/*
+ if (map.contains(option->name))
+ throw ParsingError(QString("Option %2%1 was given multiple times")
+ .arg(option->name, optionPrefix));
+*/
+ if (option->type == otSwitch)
+ map[option->name] = true;
+ else // if (option->type == otOption)
+ {
+ if (m_argStyle == ArgumentStyle::Space)
+ expecting.append(option->name);
+ else if (!equals.isNull())
+ if (i == flags.length() - 1)
+ map[option->name] = equals;
+ else
+ throw ParsingError(QString("Flag %4%2 of Argument-requiring Option "
+ "%1 not last flag in %4%3")
+ .arg(option->name, flag, flags, flagPrefix));
+ else if (m_argStyle == ArgumentStyle::SpaceAndEquals)
+ expecting.append(option->name);
+ else
+ throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)")
+ .arg(option->name, flag, flagPrefix));
+ }
+ }
+
+ continue;
+ }
+
+ // must be a positional argument
+ if (!positionals.hasNext())
+ throw ParsingError(QString("Don't know what to do with '%1'").arg(arg));
+
+ PositionalDef *param = positionals.next();
+
+ map[param->name] = arg;
+ }
+
+ // check if we're missing something
+ if (!expecting.isEmpty())
+ throw ParsingError(QString("Was still expecting arguments for %2%1").arg(
+ expecting.join(QString(", ") + optionPrefix), optionPrefix));
+
+ while (positionals.hasNext())
+ {
+ PositionalDef *param = positionals.next();
+ if (param->required)
+ throw ParsingError(
+ QString("Missing required positional argument '%1'").arg(param->name));
+ else
+ map[param->name] = param->def;
+ }
+
+ // fill out gaps
+ QListIterator<OptionDef *> iter(m_optionList);
+ while (iter.hasNext())
+ {
+ OptionDef *option = iter.next();
+ if (!map.contains(option->name))
+ map[option->name] = option->def;
+ }
+
+ return map;
+}
+
+// clear defs
+void Parser::clear()
+{
+ m_flags.clear();
+ m_params.clear();
+ m_options.clear();
+
+ QMutableListIterator<OptionDef *> it(m_optionList);
+ while (it.hasNext())
+ {
+ OptionDef *option = it.next();
+ it.remove();
+ delete option;
+ }
+
+ QMutableListIterator<PositionalDef *> it2(m_positionals);
+ while (it2.hasNext())
+ {
+ PositionalDef *arg = it2.next();
+ it2.remove();
+ delete arg;
+ }
+}
+
+// Destructor
+Parser::~Parser()
+{
+ clear();
+}
+
+// getPrefix
+void Parser::getPrefix(QString &opt, QString &flag)
+{
+ if (m_flagStyle == FlagStyle::Windows)
+ opt = flag = "/";
+ else if (m_flagStyle == FlagStyle::Unix)
+ opt = flag = "-";
+ // else if (m_flagStyle == FlagStyle::GNU)
+ else
+ {
+ opt = "--";
+ flag = "-";
+ }
+}
+
+// ParsingError
+ParsingError::ParsingError(const QString &what) : std::runtime_error(what.toStdString())
+{
+}
+} \ No newline at end of file
diff --git a/logic/Commandline.h b/logic/Commandline.h
new file mode 100644
index 00000000..bee02bad
--- /dev/null
+++ b/logic/Commandline.h
@@ -0,0 +1,252 @@
+/* Copyright 2013-2015 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <exception>
+#include <stdexcept>
+
+#include <QString>
+#include <QVariant>
+#include <QHash>
+#include <QStringList>
+
+#include "multimc_logic_export.h"
+
+/**
+ * @file libutil/include/cmdutils.h
+ * @brief commandline parsing and processing utilities
+ */
+
+namespace Commandline
+{
+
+/**
+ * @brief split a string into argv items like a shell would do
+ * @param args the argument string
+ * @return a QStringList containing all arguments
+ */
+MULTIMC_LOGIC_EXPORT QStringList splitArgs(QString args);
+
+/**
+ * @brief The FlagStyle enum
+ * Specifies how flags are decorated
+ */
+
+namespace FlagStyle
+{
+enum Enum
+{
+ GNU, /**< --option and -o (GNU Style) */
+ Unix, /**< -option and -o (Unix Style) */
+ Windows, /**< /option and /o (Windows Style) */
+#ifdef Q_OS_WIN32
+ Default = Windows
+#else
+ Default = GNU
+#endif
+};
+}
+
+/**
+ * @brief The ArgumentStyle enum
+ */
+namespace ArgumentStyle
+{
+enum Enum
+{
+ Space, /**< --option=value */
+ Equals, /**< --option value */
+ SpaceAndEquals, /**< --option[= ]value */
+#ifdef Q_OS_WIN32
+ Default = Equals
+#else
+ Default = SpaceAndEquals
+#endif
+};
+}
+
+/**
+ * @brief The ParsingError class
+ */
+class MULTIMC_LOGIC_EXPORT ParsingError : public std::runtime_error
+{
+public:
+ ParsingError(const QString &what);
+};
+
+/**
+ * @brief The Parser class
+ */
+class MULTIMC_LOGIC_EXPORT Parser
+{
+public:
+ /**
+ * @brief Parser constructor
+ * @param flagStyle the FlagStyle to use in this Parser
+ * @param argStyle the ArgumentStyle to use in this Parser
+ */
+ Parser(FlagStyle::Enum flagStyle = FlagStyle::Default,
+ ArgumentStyle::Enum argStyle = ArgumentStyle::Default);
+
+ /**
+ * @brief set the flag style
+ * @param style
+ */
+ void setFlagStyle(FlagStyle::Enum style);
+
+ /**
+ * @brief get the flag style
+ * @return
+ */
+ FlagStyle::Enum flagStyle();
+
+ /**
+ * @brief set the argument style
+ * @param style
+ */
+ void setArgumentStyle(ArgumentStyle::Enum style);
+
+ /**
+ * @brief get the argument style
+ * @return
+ */
+ ArgumentStyle::Enum argumentStyle();
+
+ /**
+ * @brief define a boolean switch
+ * @param name the parameter name
+ * @param def the default value
+ */
+ void addSwitch(QString name, bool def = false);
+
+ /**
+ * @brief define an option that takes an additional argument
+ * @param name the parameter name
+ * @param def the default value
+ */
+ void addOption(QString name, QVariant def = QVariant());
+
+ /**
+ * @brief define a positional argument
+ * @param name the parameter name
+ * @param required wether this argument is required
+ * @param def the default value
+ */
+ void addArgument(QString name, bool required = true, QVariant def = QVariant());
+
+ /**
+ * @brief adds a flag to an existing parameter
+ * @param name the (existing) parameter name
+ * @param flag the flag character
+ * @see addSwitch addArgument addOption
+ * Note: any one parameter can only have one flag
+ */
+ void addShortOpt(QString name, QChar flag);
+
+ /**
+ * @brief adds documentation to a Parameter
+ * @param name the parameter name
+ * @param metavar a string to be displayed as placeholder for the value
+ * @param doc a QString containing the documentation
+ * Note: on positional arguments, metavar replaces the name as displayed.
+ * on options , metavar replaces the value placeholder
+ */
+ void addDocumentation(QString name, QString doc, QString metavar = QString());
+
+ /**
+ * @brief generate a help message
+ * @param progName the program name to use in the help message
+ * @param helpIndent how much the parameter documentation should be indented
+ * @param flagsInUsage whether we should use flags instead of options in the usage
+ * @return a help message
+ */
+ QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true);
+
+ /**
+ * @brief generate a short usage message
+ * @param progName the program name to use in the usage message
+ * @param useFlags whether we should use flags instead of options
+ * @return a usage message
+ */
+ QString compileUsage(QString progName, bool useFlags = true);
+
+ /**
+ * @brief parse
+ * @param argv a QStringList containing the program ARGV
+ * @return a QHash mapping argument names to their values
+ */
+ QHash<QString, QVariant> parse(QStringList argv);
+
+ /**
+ * @brief clear all definitions
+ */
+ void clear();
+
+ ~Parser();
+
+private:
+ FlagStyle::Enum m_flagStyle;
+ ArgumentStyle::Enum m_argStyle;
+
+ enum OptionType
+ {
+ otSwitch,
+ otOption
+ };
+
+ // Important: the common part MUST BE COMMON ON ALL THREE structs
+ struct CommonDef
+ {
+ QString name;
+ QString doc;
+ QString metavar;
+ QVariant def;
+ };
+
+ struct OptionDef
+ {
+ // common
+ QString name;
+ QString doc;
+ QString metavar;
+ QVariant def;
+ // option
+ OptionType type;
+ QChar flag;
+ };
+
+ struct PositionalDef
+ {
+ // common
+ QString name;
+ QString doc;
+ QString metavar;
+ QVariant def;
+ // positional
+ bool required;
+ };
+
+ QHash<QString, OptionDef *> m_options;
+ QHash<QChar, OptionDef *> m_flags;
+ QHash<QString, CommonDef *> m_params;
+ QList<PositionalDef *> m_positionals;
+ QList<OptionDef *> m_optionList;
+
+ void getPrefix(QString &opt, QString &flag);
+};
+}
diff --git a/logic/FileSystem.cpp b/logic/FileSystem.cpp
index b8d82c51..ca4a3ba0 100644
--- a/logic/FileSystem.cpp
+++ b/logic/FileSystem.cpp
@@ -5,6 +5,9 @@
#include <QDir>
#include <QSaveFile>
#include <QFileInfo>
+#include <QDebug>
+#include <QDesktopServices>
+#include <QUrl>
void ensureExists(const QDir &dir)
{
@@ -54,3 +57,372 @@ QByteArray FS::read(const QString &filename)
}
return data;
}
+
+bool FS::ensureFilePathExists(QString filenamepath)
+{
+ QFileInfo a(filenamepath);
+ QDir dir;
+ QString ensuredPath = a.path();
+ bool success = dir.mkpath(ensuredPath);
+ return success;
+}
+
+bool FS::ensureFolderPathExists(QString foldernamepath)
+{
+ QFileInfo a(foldernamepath);
+ QDir dir;
+ QString ensuredPath = a.filePath();
+ bool success = dir.mkpath(ensuredPath);
+ return success;
+}
+
+bool FS::copyPath(const QString &src, const QString &dst, bool follow_symlinks)
+{
+ //NOTE always deep copy on windows. the alternatives are too messy.
+ #if defined Q_OS_WIN32
+ follow_symlinks = true;
+ #endif
+
+ QDir dir(src);
+ if (!dir.exists())
+ return false;
+ if (!ensureFolderPathExists(dst))
+ return false;
+
+ bool OK = true;
+
+ qDebug() << "Looking at " << dir.absolutePath();
+ foreach(QString f, dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System))
+ {
+ QString inner_src = src + QDir::separator() + f;
+ QString inner_dst = dst + QDir::separator() + f;
+ qDebug() << f << "translates to"<< inner_src << "to" << inner_dst;
+ QFileInfo fileInfo(inner_src);
+ if(!follow_symlinks && fileInfo.isSymLink())
+ {
+ qDebug() << "creating symlink" << inner_src << " - " << inner_dst;
+ OK &= QFile::link(fileInfo.symLinkTarget(),inner_dst);
+ }
+ else if (fileInfo.isDir())
+ {
+ qDebug() << "recursing" << inner_src << " - " << inner_dst;
+ OK &= copyPath(inner_src, inner_dst, follow_symlinks);
+ }
+ else if (fileInfo.isFile())
+ {
+ qDebug() << "copying file" << inner_src << " - " << inner_dst;
+ OK &= QFile::copy(inner_src, inner_dst);
+ }
+ else
+ {
+ OK = false;
+ qCritical() << "Copy ERROR: Unknown filesystem object:" << inner_src;
+ }
+ }
+ return OK;
+}
+#if defined Q_OS_WIN32
+#include <windows.h>
+#include <string>
+#endif
+bool FS::deletePath(QString path)
+{
+ bool OK = true;
+ QDir dir(path);
+
+ if (!dir.exists())
+ {
+ return OK;
+ }
+ auto allEntries = dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden |
+ QDir::AllDirs | QDir::Files,
+ QDir::DirsFirst);
+
+ for(QFileInfo info: allEntries)
+ {
+#if defined Q_OS_WIN32
+ QString nativePath = QDir::toNativeSeparators(info.absoluteFilePath());
+ auto wString = nativePath.toStdWString();
+ DWORD dwAttrs = GetFileAttributesW(wString.c_str());
+ // Windows: check for junctions, reparse points and other nasty things of that sort
+ if(dwAttrs & FILE_ATTRIBUTE_REPARSE_POINT)
+ {
+ if (info.isFile())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+ else if (info.isDir())
+ {
+ OK &= dir.rmdir(info.absoluteFilePath());
+ }
+ }
+#else
+ // We do not trust Qt with reparse points, but do trust it with unix symlinks.
+ if(info.isSymLink())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+#endif
+ else if (info.isDir())
+ {
+ OK &= deletePath(info.absoluteFilePath());
+ }
+ else if (info.isFile())
+ {
+ OK &= QFile::remove(info.absoluteFilePath());
+ }
+ else
+ {
+ OK = false;
+ qCritical() << "Delete ERROR: Unknown filesystem object:" << info.absoluteFilePath();
+ }
+ }
+ OK &= dir.rmdir(dir.absolutePath());
+ return OK;
+}
+
+
+QString FS::PathCombine(QString path1, QString path2)
+{
+ if(!path1.size())
+ return path2;
+ if(!path2.size())
+ return path1;
+ return QDir::cleanPath(path1 + QDir::separator() + path2);
+}
+
+QString FS::PathCombine(QString path1, QString path2, QString path3)
+{
+ return PathCombine(PathCombine(path1, path2), path3);
+}
+
+QString FS::AbsolutePath(QString path)
+{
+ return QFileInfo(path).absolutePath();
+}
+
+QString FS::ResolveExecutable(QString path)
+{
+ if (path.isEmpty())
+ {
+ return QString();
+ }
+ if(!path.contains('/'))
+ {
+ path = QStandardPaths::findExecutable(path);
+ }
+ QFileInfo pathInfo(path);
+ if(!pathInfo.exists() || !pathInfo.isExecutable())
+ {
+ return QString();
+ }
+ return pathInfo.absoluteFilePath();
+}
+
+/**
+ * Normalize path
+ *
+ * Any paths inside the current directory will be normalized to relative paths (to current)
+ * Other paths will be made absolute
+ */
+QString FS::NormalizePath(QString path)
+{
+ QDir a = QDir::currentPath();
+ QString currentAbsolute = a.absolutePath();
+
+ QDir b(path);
+ QString newAbsolute = b.absolutePath();
+
+ if (newAbsolute.startsWith(currentAbsolute))
+ {
+ return a.relativeFilePath(newAbsolute);
+ }
+ else
+ {
+ return newAbsolute;
+ }
+}
+
+QString badFilenameChars = "\"\\/?<>:*|!";
+
+QString FS::RemoveInvalidFilenameChars(QString string, QChar replaceWith)
+{
+ for (int i = 0; i < string.length(); i++)
+ {
+ if (badFilenameChars.contains(string[i]))
+ {
+ string[i] = replaceWith;
+ }
+ }
+ return string;
+}
+
+QString FS::DirNameFromString(QString string, QString inDir)
+{
+ int num = 0;
+ QString baseName = RemoveInvalidFilenameChars(string, '-');
+ QString dirName;
+ do
+ {
+ if(num == 0)
+ {
+ dirName = baseName;
+ }
+ else
+ {
+ dirName = baseName + QString::number(num);;
+ }
+
+ // If it's over 9000
+ if (num > 9000)
+ return "";
+ num++;
+ } while (QFileInfo(PathCombine(inDir, dirName)).exists());
+ return dirName;
+}
+
+void FS::openDirInDefaultProgram(QString path, bool ensureExists)
+{
+ QDir parentPath;
+ QDir dir(path);
+ if (!dir.exists())
+ {
+ parentPath.mkpath(dir.absolutePath());
+ }
+ QDesktopServices::openUrl(QUrl::fromLocalFile(dir.absolutePath()));
+}
+
+void FS::openFileInDefaultProgram(QString filename)
+{
+ QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
+}
+
+// Does the directory path contain any '!'? If yes, return true, otherwise false.
+// (This is a problem for Java)
+bool FS::checkProblemticPathJava(QDir folder)
+{
+ QString pathfoldername = folder.absolutePath();
+ return pathfoldername.contains("!", Qt::CaseInsensitive);
+}
+
+#include <QStandardPaths>
+#include <QFile>
+#include <QTextStream>
+
+// Win32 crap
+#if defined Q_OS_WIN
+
+#include <windows.h>
+#include <winnls.h>
+#include <shobjidl.h>
+#include <objbase.h>
+#include <objidl.h>
+#include <shlguid.h>
+#include <shlobj.h>
+
+bool called_coinit = false;
+
+HRESULT CreateLink(LPCSTR linkPath, LPCSTR targetPath, LPCSTR args)
+{
+ HRESULT hres;
+
+ if (!called_coinit)
+ {
+ hres = CoInitialize(NULL);
+ called_coinit = true;
+
+ if (!SUCCEEDED(hres))
+ {
+ qWarning("Failed to initialize COM. Error 0x%08X", hres);
+ return hres;
+ }
+ }
+
+ IShellLink *link;
+ hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink,
+ (LPVOID *)&link);
+
+ if (SUCCEEDED(hres))
+ {
+ IPersistFile *persistFile;
+
+ link->SetPath(targetPath);
+ link->SetArguments(args);
+
+ hres = link->QueryInterface(IID_IPersistFile, (LPVOID *)&persistFile);
+ if (SUCCEEDED(hres))
+ {
+ WCHAR wstr[MAX_PATH];
+
+ MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH);
+
+ hres = persistFile->Save(wstr, TRUE);
+ persistFile->Release();
+ }
+ link->Release();
+ }
+ return hres;
+}
+
+#endif
+
+QString FS::getDesktopDir()
+{
+ return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
+}
+
+// Cross-platform Shortcut creation
+bool FS::createShortCut(QString location, QString dest, QStringList args, QString name,
+ QString icon)
+{
+#if defined Q_OS_LINUX
+ location = PathCombine(location, name + ".desktop");
+
+ QFile f(location);
+ f.open(QIODevice::WriteOnly | QIODevice::Text);
+ QTextStream stream(&f);
+
+ QString argstring;
+ if (!args.empty())
+ argstring = " '" + args.join("' '") + "'";
+
+ stream << "[Desktop Entry]"
+ << "\n";
+ stream << "Type=Application"
+ << "\n";
+ stream << "TryExec=" << dest.toLocal8Bit() << "\n";
+ stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n";
+ stream << "Name=" << name.toLocal8Bit() << "\n";
+ stream << "Icon=" << icon.toLocal8Bit() << "\n";
+
+ stream.flush();
+ f.close();
+
+ f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup |
+ QFileDevice::ExeOther);
+
+ return true;
+#elif defined Q_OS_WIN
+ // TODO: Fix
+ // QFile file(PathCombine(location, name + ".lnk"));
+ // WCHAR *file_w;
+ // WCHAR *dest_w;
+ // WCHAR *args_w;
+ // file.fileName().toWCharArray(file_w);
+ // dest.toWCharArray(dest_w);
+
+ // QString argStr;
+ // for (int i = 0; i < args.count(); i++)
+ // {
+ // argStr.append(args[i]);
+ // argStr.append(" ");
+ // }
+ // argStr.toWCharArray(args_w);
+
+ // return SUCCEEDED(CreateLink(file_w, dest_w, args_w));
+ return false;
+#else
+ qWarning("Desktop Shortcuts not supported on your platform!");
+ return false;
+#endif
+}
diff --git a/logic/FileSystem.h b/logic/FileSystem.h
index a66e7ead..5055eb6c 100644
--- a/logic/FileSystem.h
+++ b/logic/FileSystem.h
@@ -5,6 +5,7 @@
#include "Exception.h"
#include "multimc_logic_export.h"
+#include <QDir>
namespace FS
{
@@ -15,6 +16,83 @@ public:
FileSystemException(const QString &message) : Exception(message) {}
};
-void MULTIMC_LOGIC_EXPORT write(const QString &filename, const QByteArray &data);
-QByteArray MULTIMC_LOGIC_EXPORT read(const QString &filename);
+/**
+ * write data to a file safely
+ */
+MULTIMC_LOGIC_EXPORT void write(const QString &filename, const QByteArray &data);
+
+/**
+ * read data from a file safely\
+ */
+MULTIMC_LOGIC_EXPORT QByteArray read(const QString &filename);
+
+/**
+ * Creates all the folders in a path for the specified path
+ * last segment of the path is treated as a file name and is ignored!
+ */
+MULTIMC_LOGIC_EXPORT bool ensureFilePathExists(QString filenamepath);
+
+/**
+ * Creates all the folders in a path for the specified path
+ * last segment of the path is treated as a folder name and is created!
+ */
+MULTIMC_LOGIC_EXPORT bool ensureFolderPathExists(QString filenamepath);
+
+/**
+ * Copy a folder recursively
+ */
+MULTIMC_LOGIC_EXPORT bool copyPath(const QString &src, const QString &dst, bool follow_symlinks = true);
+
+/**
+ * Delete a folder recursively
+ */
+MULTIMC_LOGIC_EXPORT bool deletePath(QString path);
+
+MULTIMC_LOGIC_EXPORT QString PathCombine(QString path1, QString path2);
+MULTIMC_LOGIC_EXPORT QString PathCombine(QString path1, QString path2, QString path3);
+
+MULTIMC_LOGIC_EXPORT QString AbsolutePath(QString path);
+
+/**
+ * Resolve an executable
+ *
+ * Will resolve:
+ * single executable (by name)
+ * relative path
+ * absolute path
+ *
+ * @return absolute path to executable or null string
+ */
+MULTIMC_LOGIC_EXPORT QString ResolveExecutable(QString path);
+
+/**
+ * Normalize path
+ *
+ * Any paths inside the current directory will be normalized to relative paths (to current)
+ * Other paths will be made absolute
+ *
+ * Returns false if the path logic somehow filed (and normalizedPath in invalid)
+ */
+MULTIMC_LOGIC_EXPORT QString NormalizePath(QString path);
+
+MULTIMC_LOGIC_EXPORT QString RemoveInvalidFilenameChars(QString string, QChar replaceWith = '-');
+
+MULTIMC_LOGIC_EXPORT QString DirNameFromString(QString string, QString inDir = ".");
+
+/// Opens the given file in the default application.
+MULTIMC_LOGIC_EXPORT void openFileInDefaultProgram(QString filename);
+
+/// Opens the given directory in the default application.
+MULTIMC_LOGIC_EXPORT void openDirInDefaultProgram(QString dirpath, bool ensureExists = false);
+
+/// Checks if the a given Path contains "!"
+MULTIMC_LOGIC_EXPORT bool checkProblemticPathJava(QDir folder);
+
+// Get the Directory representing the User's Desktop
+MULTIMC_LOGIC_EXPORT QString getDesktopDir();
+
+// Create a shortcut at *location*, pointing to *dest* called with the arguments *args*
+// call it *name* and assign it the icon *icon*
+// return true if operation succeeded
+MULTIMC_LOGIC_EXPORT bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation);
}
diff --git a/logic/InstanceList.cpp b/logic/InstanceList.cpp
index 22b36748..c3a6a9c4 100644
--- a/logic/InstanceList.cpp
+++ b/logic/InstanceList.cpp
@@ -24,7 +24,6 @@
#include <QJsonArray>
#include <QXmlStreamReader>
#include <QRegularExpression>
-#include <pathutils.h>
#include <QDebug>
#include "InstanceList.h"
@@ -38,6 +37,7 @@
#include "settings/INISettingsObject.h"
#include "ftb/FTBPlugin.h"
#include "NullInstance.h"
+#include "FileSystem.h"
const static int GROUP_FILE_FORMAT_VERSION = 1;
@@ -299,7 +299,7 @@ InstanceList::InstListError InstanceList::loadList()
while (iter.hasNext())
{
QString subDir = iter.next();
- if (!QFileInfo(PathCombine(subDir, "instance.cfg")).exists())
+ if (!QFileInfo(FS::PathCombine(subDir, "instance.cfg")).exists())
continue;
qDebug() << "Loading MultiMC instance from " << subDir;
InstancePtr instPtr;
@@ -432,7 +432,7 @@ bool InstanceList::continueProcessInstance(InstancePtr instPtr, const int error,
InstanceList::InstLoadError
InstanceList::loadInstance(InstancePtr &inst, const QString &instDir)
{
- auto instanceSettings = std::make_shared<INISettingsObject>(PathCombine(instDir, "instance.cfg"));
+ auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instDir, "instance.cfg"));
instanceSettings->registerSetting("InstanceType", "Legacy");
@@ -473,7 +473,7 @@ InstanceList::createInstance(InstancePtr &inst, BaseVersionPtr version, const QS
return InstanceList::NoSuchVersion;
}
- auto instanceSettings = std::make_shared<INISettingsObject>(PathCombine(instDir, "instance.cfg"));
+ auto instanceSettings = std::make_shared<INISettingsObject>(FS::PathCombine(instDir, "instance.cfg"));
instanceSettings->registerSetting("InstanceType", "Legacy");
auto minecraftVersion = std::dynamic_pointer_cast<MinecraftVersion>(version);
@@ -490,18 +490,18 @@ InstanceList::createInstance(InstancePtr &inst, BaseVersionPtr version, const QS
}
InstanceList::InstCreateError
-InstanceList::copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance, const QString &instDir)
+InstanceList::copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance, const QString &instDir, bool copySaves)
{
QDir rootDir(instDir);
qDebug() << instDir.toUtf8();
- if (!copyPath(oldInstance->instanceRoot(), instDir, false))
+ if (!FS::copyPath(oldInstance->instanceRoot(), instDir, false))
{
- deletePath(instDir);
+ FS::deletePath(instDir);
return InstanceList::CantCreateDir;
}
- INISettingsObject settings_obj(PathCombine(instDir, "instance.cfg"));
+ INISettingsObject settings_obj(FS::PathCombine(instDir, "instance.cfg"));
settings_obj.registerSetting("InstanceType", "Legacy");
QString inst_type = settings_obj.get("InstanceType").toString();
diff --git a/logic/InstanceList.h b/logic/InstanceList.h
index 1799080a..3dbfaf70 100644
--- a/logic/InstanceList.h
+++ b/logic/InstanceList.h
@@ -140,7 +140,7 @@ public:
* - CantCreateDir if the given instance directory cannot be created.
*/
InstCreateError copyInstance(InstancePtr &newInstance, InstancePtr &oldInstance,
- const QString &instDir);
+ const QString &instDir, bool copySaves);
/*!
* \brief Loads an instance from the given directory.
diff --git a/logic/MMCZip.cpp b/logic/MMCZip.cpp
index 62904fa5..0f35bc70 100644
--- a/logic/MMCZip.cpp
+++ b/logic/MMCZip.cpp
@@ -23,11 +23,11 @@ Original ZIP package is copyrighted by Gilles Vollant and contributors,
see quazip/(un)MMCZip.h files for details. Basically it's the zlib license.
*/
-#include <pathutils.h>
#include <quazip.h>
#include <JlCompress.h>
#include <quazipdir.h>
#include "MMCZip.h"
+#include "FileSystem.h"
#include <QDebug>
@@ -111,7 +111,7 @@ bool MMCZip::compressSubDir(QuaZip* zip, QString dir, QString origDir, QSet<QStr
if(!blacklist || !blacklist->covers(internalDirName))
{
QuaZipFile dirZipFile(zip);
- auto dirPrefix = PathCombine(prefix, origDirectory.relativeFilePath(dir)) + "/";
+ auto dirPrefix = FS::PathCombine(prefix, origDirectory.relativeFilePath(dir)) + "/";
if (!dirZipFile.open(QIODevice::WriteOnly, QuaZipNewInfo(dirPrefix, dir), 0, 0, 0))
{
return false;
@@ -153,7 +153,7 @@ bool MMCZip::compressSubDir(QuaZip* zip, QString dir, QString origDir, QSet<QStr
}
if(prefix.size())
{
- filename = PathCombine(prefix, filename);
+ filename = FS::PathCombine(prefix, filename);
}
added.insert(filename);
if (!compressFile(zip,file.absoluteFilePath(),filename))
diff --git a/logic/Version.cpp b/logic/Version.cpp
new file mode 100644
index 00000000..3c4727ad
--- /dev/null
+++ b/logic/Version.cpp
@@ -0,0 +1,140 @@
+#include "Version.h"
+
+#include <QStringList>
+#include <QUrl>
+#include <QRegularExpression>
+#include <QRegularExpressionMatch>
+
+Version::Version(const QString &str) : m_string(str)
+{
+ parse();
+}
+
+bool Version::operator<(const Version &other) const
+{
+ const int size = qMax(m_sections.size(), other.m_sections.size());
+ for (int i = 0; i < size; ++i)
+ {
+ const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
+ const Section sec2 =
+ (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
+ if (sec1 != sec2)
+ {
+ return sec1 < sec2;
+ }
+ }
+
+ return false;
+}
+bool Version::operator<=(const Version &other) const
+{
+ return *this < other || *this == other;
+}
+bool Version::operator>(const Version &other) const
+{
+ const int size = qMax(m_sections.size(), other.m_sections.size());
+ for (int i = 0; i < size; ++i)
+ {
+ const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
+ const Section sec2 =
+ (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
+ if (sec1 != sec2)
+ {
+ return sec1 > sec2;
+ }
+ }
+
+ return false;
+}
+bool Version::operator>=(const Version &other) const
+{
+ return *this > other || *this == other;
+}
+bool Version::operator==(const Version &other) const
+{
+ const int size = qMax(m_sections.size(), other.m_sections.size());
+ for (int i = 0; i < size; ++i)
+ {
+ const Section sec1 = (i >= m_sections.size()) ? Section("0") : m_sections.at(i);
+ const Section sec2 =
+ (i >= other.m_sections.size()) ? Section("0") : other.m_sections.at(i);
+ if (sec1 != sec2)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+bool Version::operator!=(const Version &other) const
+{
+ return !operator==(other);
+}
+
+void Version::parse()
+{
+ m_sections.clear();
+
+ QStringList parts = m_string.split('.');
+
+ for (const auto part : parts)
+ {
+ m_sections.append(Section(part));
+ }
+}
+
+bool versionIsInInterval(const QString &version, const QString &interval)
+{
+ return versionIsInInterval(Version(version), interval);
+}
+bool versionIsInInterval(const Version &version, const QString &interval)
+{
+ if (interval.isEmpty() || version.toString() == interval)
+ {
+ return true;
+ }
+
+ // Interval notation is used
+ QRegularExpression exp(
+ "(?<start>[\\[\\]\\(\\)])(?<bottom>.*?)(,(?<top>.*?))?(?<end>[\\[\\]\\(\\)]),?");
+ QRegularExpressionMatch match = exp.match(interval);
+ if (match.hasMatch())
+ {
+ const QChar start = match.captured("start").at(0);
+ const QChar end = match.captured("end").at(0);
+ const QString bottom = match.captured("bottom");
+ const QString top = match.captured("top");
+
+ // check if in range (bottom)
+ if (!bottom.isEmpty())
+ {
+ const auto bottomVersion = Version(bottom);
+ if ((start == '[') && !(version >= bottomVersion))
+ {
+ return false;
+ }
+ else if ((start == '(') && !(version > bottomVersion))
+ {
+ return false;
+ }
+ }
+
+ // check if in range (top)
+ if (!top.isEmpty())
+ {
+ const auto topVersion = Version(top);
+ if ((end == ']') && !(version <= topVersion))
+ {
+ return false;
+ }
+ else if ((end == ')') && !(version < topVersion))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+}
diff --git a/logic/Version.h b/logic/Version.h
new file mode 100644
index 00000000..b5946ced
--- /dev/null
+++ b/logic/Version.h
@@ -0,0 +1,110 @@
+#pragma once
+
+#include <QString>
+#include <QList>
+
+#include "multimc_logic_export.h"
+
+class QUrl;
+
+struct MULTIMC_LOGIC_EXPORT Version
+{
+ Version(const QString &str);
+ Version() {}
+
+ bool operator<(const Version &other) const;
+ bool operator<=(const Version &other) const;
+ bool operator>(const Version &other) const;
+ bool operator>=(const Version &other) const;
+ bool operator==(const Version &other) const;
+ bool operator!=(const Version &other) const;
+
+ QString toString() const
+ {
+ return m_string;
+ }
+
+private:
+ QString m_string;
+ struct Section
+ {
+ explicit Section(const QString &fullString)
+ {
+ m_fullString = fullString;
+ int cutoff = m_fullString.size();
+ for(int i = 0; i < m_fullString.size(); i++)
+ {
+ if(!m_fullString[i].isDigit())
+ {
+ cutoff = i;
+ break;
+ }
+ }
+ auto numPart = m_fullString.leftRef(cutoff);
+ if(numPart.size())
+ {
+ numValid = true;
+ m_numPart = numPart.toInt();
+ }
+ auto stringPart = m_fullString.midRef(cutoff);
+ if(stringPart.size())
+ {
+ m_stringPart = stringPart.toString();
+ }
+ }
+ explicit Section() {}
+ bool numValid = false;
+ int m_numPart = 0;
+ QString m_stringPart;
+ QString m_fullString;
+
+ inline bool operator!=(const Section &other) const
+ {
+ if(numValid && other.numValid)
+ {
+ return m_numPart != other.m_numPart || m_stringPart != other.m_stringPart;
+ }
+ else
+ {
+ return m_fullString != other.m_fullString;
+ }
+ }
+ inline bool operator<(const Section &other) const
+ {
+ if(numValid && other.numValid)
+ {
+ if(m_numPart < other.m_numPart)
+ return true;
+ if(m_numPart == other.m_numPart && m_stringPart < other.m_stringPart)
+ return true;
+ return false;
+ }
+ else
+ {
+ return m_fullString < other.m_fullString;
+ }
+ }
+ inline bool operator>(const Section &other) const
+ {
+ if(numValid && other.numValid)
+ {
+ if(m_numPart > other.m_numPart)
+ return true;
+ if(m_numPart == other.m_numPart && m_stringPart > other.m_stringPart)
+ return true;
+ return false;
+ }
+ else
+ {
+ return m_fullString > other.m_fullString;
+ }
+ }
+ };
+ QList<Section> m_sections;
+
+ void parse();
+};
+
+MULTIMC_LOGIC_EXPORT bool versionIsInInterval(const QString &version, const QString &interval);
+MULTIMC_LOGIC_EXPORT bool versionIsInInterval(const Version &version, const QString &interval);
+
diff --git a/logic/auth/MojangAccountList.cpp b/logic/auth/MojangAccountList.cpp
index b69b9b81..dac3d67f 100644
--- a/logic/auth/MojangAccountList.cpp
+++ b/logic/auth/MojangAccountList.cpp
@@ -27,7 +27,7 @@
#include <QDebug>
#include "auth/MojangAccount.h"
-#include <pathutils.h>
+#include <FileSystem.h>
#define ACCOUNT_LIST_FORMAT_VERSION 2
@@ -348,7 +348,7 @@ bool MojangAccountList::saveList(const QString &filePath)
}
// make sure the parent folder exists
- if(!ensureFilePathExists(path))
+ if(!FS::ensureFilePathExists(path))
return false;
// make sure the file wasn't overwritten with a folder before (fixes a bug)
diff --git a/logic/forge/ForgeInstaller.cpp b/logic/forge/ForgeInstaller.cpp
index 60dce822..cdbb5f18 100644
--- a/logic/forge/ForgeInstaller.cpp
+++ b/logic/forge/ForgeInstaller.cpp
@@ -23,10 +23,10 @@
#include "minecraft/VersionFilterData.h"
#include "Env.h"
#include "Exception.h"
+#include <FileSystem.h>
#include <quazip.h>
#include <quazipfile.h>
-#include <pathutils.h>
#include <QStringList>
#include <QRegularExpression>
#include <QRegularExpressionMatch>
@@ -90,7 +90,7 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr
auto cacheentry = ENV.metacache()->resolveEntry("libraries", lib.storageSuffix());
finalPath = "libraries/" + lib.storageSuffix();
- if (!ensureFilePathExists(finalPath))
+ if (!FS::ensureFilePathExists(finalPath))
return;
if (!zip.setCurrentFile(internalPath))
@@ -278,8 +278,8 @@ bool ForgeInstaller::addLegacy(OneSixInstance *to)
return false;
}
auto entry = ENV.metacache()->resolveEntry("minecraftforge", m_forge_version->filename());
- finalPath = PathCombine(to->jarModsDir(), m_forge_version->filename());
- if (!ensureFilePathExists(finalPath))
+ finalPath = FS::PathCombine(to->jarModsDir(), m_forge_version->filename());
+ if (!FS::ensureFilePathExists(finalPath))
{
return false;
}
diff --git a/logic/forge/ForgeXzDownload.cpp b/logic/forge/ForgeXzDownload.cpp
index 56320ced..6009e31e 100644
--- a/logic/forge/ForgeXzDownload.cpp
+++ b/logic/forge/ForgeXzDownload.cpp
@@ -15,7 +15,7 @@
#include "Env.h"
#include "ForgeXzDownload.h"
-#include <pathutils.h>
+#include <FileSystem.h>
#include <QCryptographicHash>
#include <QFileInfo>
@@ -49,7 +49,7 @@ void ForgeXzDownload::start()
return;
}
// can we actually create the real, final file?
- if (!ensureFilePathExists(m_target_path))
+ if (!FS::ensureFilePathExists(m_target_path))
{
m_status = Job_Failed;
emit failed(m_index_within_job);
diff --git a/logic/ftb/FTBPlugin.cpp b/logic/ftb/FTBPlugin.cpp
index aa2c3ca9..201b5d3b 100644
--- a/logic/ftb/FTBPlugin.cpp
+++ b/logic/ftb/FTBPlugin.cpp
@@ -7,7 +7,7 @@
#include <InstanceList.h>
#include <minecraft/MinecraftVersionList.h>
#include <settings/INISettingsObject.h>
-#include <pathutils.h>
+#include <FileSystem.h>
#include "QDebug"
#include <QXmlStreamReader>
#include <QRegularExpression>
@@ -137,7 +137,7 @@ InstancePtr loadInstance(SettingsObjectPtr globalSettings, QMap<QString, QString
{
InstancePtr inst;
- auto m_settings = std::make_shared<INISettingsObject>(PathCombine(record.instanceDir, "instance.cfg"));
+ auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg"));
m_settings->registerSetting("InstanceType", "Legacy");
qDebug() << "Loading existing " << record.name;
@@ -206,7 +206,7 @@ InstancePtr createInstance(SettingsObjectPtr globalSettings, QMap<QString, QStri
return nullptr;
}
- auto m_settings = std::make_shared<INISettingsObject>(PathCombine(record.instanceDir, "instance.cfg"));
+ auto m_settings = std::make_shared<INISettingsObject>(FS::PathCombine(record.instanceDir, "instance.cfg"));
m_settings->registerSetting("InstanceType", "Legacy");
if (mcVersion->usesLegacyLauncher())
@@ -257,8 +257,8 @@ void FTBPlugin::loadInstances(SettingsObjectPtr globalSettings, QMap<QString, QS
{
qDebug() << "Loading FTB instance from " << record.instanceDir;
QString iconKey = record.iconKey;
- ENV.icons()->addIcon(iconKey, iconKey, PathCombine(record.templateDir, record.logo), MMCIcon::Transient);
- auto settingsFilePath = PathCombine(record.instanceDir, "instance.cfg");
+ ENV.icons()->addIcon(iconKey, iconKey, FS::PathCombine(record.templateDir, record.logo), MMCIcon::Transient);
+ auto settingsFilePath = FS::PathCombine(record.instanceDir, "instance.cfg");
qDebug() << "ICON get!";
if (QFileInfo(settingsFilePath).exists())
diff --git a/logic/ftb/FTBProfileStrategy.cpp b/logic/ftb/FTBProfileStrategy.cpp
index 293d0fdc..ac55bbe7 100644
--- a/logic/ftb/FTBProfileStrategy.cpp
+++ b/logic/ftb/FTBProfileStrategy.cpp
@@ -2,8 +2,8 @@
#include "minecraft/VersionBuildError.h"
#include "ftb/OneSixFTBInstance.h"
#include "minecraft/MinecraftVersionList.h"
+#include <FileSystem.h>
-#include <pathutils.h>
#include <QDir>
#include <QUuid>
#include <QJsonDocument>
@@ -67,7 +67,7 @@ void FTBProfileStrategy::loadDefaultBuiltinPatches()
if(file->version.isEmpty())
{
file->version = QObject::tr("Unknown");
- QFile versionFile (PathCombine(m_instance->instanceRoot(), "version"));
+ QFile versionFile (FS::PathCombine(m_instance->instanceRoot(), "version"));
if(versionFile.exists())
{
if(versionFile.open(QIODevice::ReadOnly))
@@ -94,8 +94,8 @@ void FTBProfileStrategy::loadUserPatches()
{
// load all patches, put into map for ordering, apply in the right order
ProfileUtils::PatchOrder userOrder;
- ProfileUtils::readOverrideOrders(PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
- QDir patches(PathCombine(m_instance->instanceRoot(),"patches"));
+ ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
+ QDir patches(FS::PathCombine(m_instance->instanceRoot(),"patches"));
// first, load things by sort order.
for (auto id : userOrder)
diff --git a/logic/ftb/OneSixFTBInstance.cpp b/logic/ftb/OneSixFTBInstance.cpp
index 1fc5b49b..7a0fdf4d 100644
--- a/logic/ftb/OneSixFTBInstance.cpp
+++ b/logic/ftb/OneSixFTBInstance.cpp
@@ -7,7 +7,7 @@
#include "forge/ForgeInstaller.h"
#include "forge/ForgeVersionList.h"
#include <settings/INISettingsObject.h>
-#include "pathutils.h"
+#include <FileSystem.h>
OneSixFTBInstance::OneSixFTBInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir) :
OneSixInstance(globalSettings, settings, rootDir)
@@ -63,7 +63,7 @@ void OneSixFTBInstance::copy(const QDir &newDir)
root.insert("name", name());
root.insert("mcVersion", intendedVersionId());
root.insert("version", intendedVersionId());
- ensureFilePathExists(newDir.absoluteFilePath("patches/ftb.json"));
+ FS::ensureFilePathExists(newDir.absoluteFilePath("patches/ftb.json"));
QFile out(newDir.absoluteFilePath("patches/ftb.json"));
if (!out.open(QFile::WriteOnly | QFile::Truncate))
{
@@ -83,7 +83,7 @@ void OneSixFTBInstance::copy(const QDir &newDir)
{
continue;
}
- if (!ensureFilePathExists(out))
+ if (!FS::ensureFilePathExists(out))
{
qCritical() << "Couldn't create folder structure for" << out;
}
diff --git a/logic/icons/IconList.cpp b/logic/icons/IconList.cpp
index 45d39575..99def3b7 100644
--- a/logic/icons/IconList.cpp
+++ b/logic/icons/IconList.cpp
@@ -14,7 +14,7 @@
*/
#include "IconList.h"
-#include <pathutils.h>
+#include <FileSystem.h>
#include <QMap>
#include <QEventLoop>
#include <QMimeData>
@@ -57,7 +57,7 @@ void IconList::directoryChanged(const QString &path)
startWatching();
}
if(!m_dir.exists())
- if(!ensureFolderPathExists(m_dir.absolutePath()))
+ if(!FS::ensureFolderPathExists(m_dir.absolutePath()))
return;
m_dir.refresh();
auto new_list = m_dir.entryList(QDir::Files, QDir::Name);
@@ -149,7 +149,7 @@ void IconList::SettingChanged(const Setting &setting, QVariant value)
void IconList::startWatching()
{
auto abs_path = m_dir.absolutePath();
- ensureFolderPathExists(abs_path);
+ FS::ensureFolderPathExists(abs_path);
is_watching = m_watcher->addPath(abs_path);
if (is_watching)
{
@@ -250,7 +250,7 @@ void IconList::installIcons(QStringList iconFiles)
QFileInfo fileinfo(file);
if (!fileinfo.isReadable() || !fileinfo.isFile())
continue;
- QString target = PathCombine(m_dir.dirName(), fileinfo.fileName());
+ QString target = FS::PathCombine(m_dir.dirName(), fileinfo.fileName());
QString suffix = fileinfo.suffix();
if (suffix != "jpeg" && suffix != "png" && suffix != "jpg" && suffix != "ico")
diff --git a/logic/java/JavaChecker.cpp b/logic/java/JavaChecker.cpp
index 9c8d5f68..dfda464f 100644
--- a/logic/java/JavaChecker.cpp
+++ b/logic/java/JavaChecker.cpp
@@ -1,6 +1,6 @@
#include "JavaChecker.h"
-#include <pathutils.h>
-#include <cmdutils.h>
+#include <FileSystem.h>
+#include <Commandline.h>
#include <QFile>
#include <QProcess>
#include <QMap>
@@ -14,14 +14,14 @@ JavaChecker::JavaChecker(QObject *parent) : QObject(parent)
void JavaChecker::performCheck()
{
- QString checkerJar = PathCombine(QCoreApplication::applicationDirPath(), "jars", "JavaCheck.jar");
+ QString checkerJar = FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "JavaCheck.jar");
QStringList args;
process.reset(new QProcess());
if(m_args.size())
{
- auto extraArgs = Util::Commandline::splitArgs(m_args);
+ auto extraArgs = Commandline::splitArgs(m_args);
args.append(extraArgs);
}
if(m_minMem != 0)
diff --git a/logic/java/JavaCheckerJob.cpp b/logic/java/JavaCheckerJob.cpp
index bf4271c2..0b040e43 100644
--- a/logic/java/JavaCheckerJob.cpp
+++ b/logic/java/JavaCheckerJob.cpp
@@ -14,7 +14,6 @@
*/
#include "JavaCheckerJob.h"
-#include "pathutils.h"
#include <QDebug>
diff --git a/logic/java/JavaUtils.cpp b/logic/java/JavaUtils.cpp
index ac1d60e4..80ded3ee 100644
--- a/logic/java/JavaUtils.cpp
+++ b/logic/java/JavaUtils.cpp
@@ -19,7 +19,6 @@
#include <QStringList>
#include <settings/Setting.h>
-#include <pathutils.h>
#include <QDebug>
#include "java/JavaUtils.h"
diff --git a/logic/java/JavaUtils.h b/logic/java/JavaUtils.h
index d4dd2409..78693b37 100644
--- a/logic/java/JavaUtils.h
+++ b/logic/java/JavaUtils.h
@@ -18,12 +18,11 @@
#include <QStringList>
#include <QWidget>
-#include <osutils.h>
#include "JavaCheckerJob.h"
#include "JavaChecker.h"
#include "JavaVersionList.h"
-#if WINDOWS
+#ifdef Q_OS_WIN
#include <windows.h>
#endif
@@ -39,7 +38,7 @@ public:
QList<QString> FindJavaPaths();
JavaVersionPtr GetDefaultJava();
-#if WINDOWS
+#ifdef Q_OS_WIN
QList<JavaVersionPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName);
#endif
};
diff --git a/logic/launch/LaunchTask.cpp b/logic/launch/LaunchTask.cpp
index 1defeba3..5b7ff182 100644
--- a/logic/launch/LaunchTask.cpp
+++ b/logic/launch/LaunchTask.cpp
@@ -20,7 +20,6 @@
#include "MMCStrings.h"
#include "java/JavaChecker.h"
#include "tasks/Task.h"
-#include <pathutils.h>
#include <QDebug>
#include <QDir>
#include <QEventLoop>
diff --git a/logic/launch/steps/CheckJava.cpp b/logic/launch/steps/CheckJava.cpp
index 7482624f..66f7cc2b 100644
--- a/logic/launch/steps/CheckJava.cpp
+++ b/logic/launch/steps/CheckJava.cpp
@@ -15,7 +15,7 @@
#include "CheckJava.h"
#include <launch/LaunchTask.h>
-#include <pathutils.h>
+#include <FileSystem.h>
#include <QStandardPaths>
#include <QFileInfo>
@@ -23,7 +23,7 @@ void CheckJava::executeTask()
{
auto instance = m_parent->instance();
auto settings = instance->settings();
- m_javaPath = ResolveExecutable(settings->get("JavaPath").toString());
+ m_javaPath = FS::ResolveExecutable(settings->get("JavaPath").toString());
bool perInstance = settings->get("OverrideJava").toBool() || settings->get("OverrideJavaLocation").toBool();
auto realJavaPath = QStandardPaths::findExecutable(m_javaPath);
diff --git a/logic/launch/steps/LaunchMinecraft.cpp b/logic/launch/steps/LaunchMinecraft.cpp
index 84abb375..3d75f5f2 100644
--- a/logic/launch/steps/LaunchMinecraft.cpp
+++ b/logic/launch/steps/LaunchMinecraft.cpp
@@ -16,7 +16,7 @@
#include "LaunchMinecraft.h"
#include <launch/LaunchTask.h>
#include <minecraft/OneSixInstance.h>
-#include <pathutils.h>
+#include <FileSystem.h>
#include <QStandardPaths>
LaunchMinecraft::LaunchMinecraft(LaunchTask *parent) : LaunchStep(parent)
@@ -34,7 +34,7 @@ void LaunchMinecraft::executeTask()
QString allArgs = args.join(", ");
emit logLine("Java Arguments:\n[" + m_parent->censorPrivateInfo(allArgs) + "]\n\n", MessageLevel::MultiMC);
- auto javaPath = ResolveExecutable(instance->settings()->get("JavaPath").toString());
+ auto javaPath = FS::ResolveExecutable(instance->settings()->get("JavaPath").toString());
m_process.setProcessEnvironment(instance->createEnvironment());
diff --git a/logic/minecraft/AssetsUtils.cpp b/logic/minecraft/AssetsUtils.cpp
index 63179228..b3589cb8 100644
--- a/logic/minecraft/AssetsUtils.cpp
+++ b/logic/minecraft/AssetsUtils.cpp
@@ -23,7 +23,7 @@
#include <QDebug>
#include "AssetsUtils.h"
-#include <pathutils.h>
+#include <FileSystem.h>
namespace AssetsUtils
{
@@ -125,13 +125,13 @@ bool loadAssetsIndexJson(QString path, AssetsIndex *index)
QDir reconstructAssets(QString assetsId)
{
QDir assetsDir = QDir("assets/");
- QDir indexDir = QDir(PathCombine(assetsDir.path(), "indexes"));
- QDir objectDir = QDir(PathCombine(assetsDir.path(), "objects"));
- QDir virtualDir = QDir(PathCombine(assetsDir.path(), "virtual"));
+ 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 = PathCombine(indexDir.path(), assetsId + ".json");
+ QString indexPath = FS::PathCombine(indexDir.path(), assetsId + ".json");
QFile indexFile(indexPath);
- QDir virtualRoot(PathCombine(virtualDir.path(), assetsId));
+ QDir virtualRoot(FS::PathCombine(virtualDir.path(), assetsId));
if (!indexFile.exists())
{
@@ -152,13 +152,12 @@ QDir reconstructAssets(QString assetsId)
for (QString map : index.objects.keys())
{
AssetObject asset_object = index.objects.value(map);
- QString target_path = PathCombine(virtualRoot.path(), map);
+ QString target_path = FS::PathCombine(virtualRoot.path(), map);
QFile target(target_path);
QString tlk = asset_object.hash.left(2);
- QString original_path =
- PathCombine(PathCombine(objectDir.path(), tlk), asset_object.hash);
+ QString original_path = FS::PathCombine(objectDir.path(), tlk, asset_object.hash);
QFile original(original_path);
if (!original.exists())
continue;
diff --git a/logic/minecraft/LegacyInstance.cpp b/logic/minecraft/LegacyInstance.cpp
index 342a6f2d..227fd601 100644
--- a/logic/minecraft/LegacyInstance.cpp
+++ b/logic/minecraft/LegacyInstance.cpp
@@ -17,8 +17,6 @@
#include <QDir>
#include <QImage>
#include <settings/Setting.h>
-#include <pathutils.h>
-#include <cmdutils.h>
#include "LegacyInstance.h"
@@ -35,6 +33,7 @@
#include "minecraft/ModList.h"
#include "minecraft/WorldList.h"
#include <MMCZip.h>
+#include <FileSystem.h>
LegacyInstance::LegacyInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: MinecraftInstance(globalSettings, settings, rootDir)
@@ -109,7 +108,7 @@ std::shared_ptr<LaunchTask> LegacyInstance::createLaunchTask(AuthSessionPtr sess
QString launchScript;
QIcon icon = ENV.icons()->getIcon(iconKey());
auto pixmap = icon.pixmap(128, 128);
- pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG");
+ pixmap.save(FS::PathCombine(minecraftRoot(), "icon.png"), "PNG");
// create the launch script
{
@@ -331,56 +330,56 @@ std::shared_ptr<WorldList> LegacyInstance::worldList() const
QString LegacyInstance::jarModsDir() const
{
- return PathCombine(instanceRoot(), "instMods");
+ return FS::PathCombine(instanceRoot(), "instMods");
}
QString LegacyInstance::binDir() const
{
- return PathCombine(minecraftRoot(), "bin");
+ return FS::PathCombine(minecraftRoot(), "bin");
}
QString LegacyInstance::libDir() const
{
- return PathCombine(minecraftRoot(), "lib");
+ return FS::PathCombine(minecraftRoot(), "lib");
}
QString LegacyInstance::savesDir() const
{
- return PathCombine(minecraftRoot(), "saves");
+ return FS::PathCombine(minecraftRoot(), "saves");
}
QString LegacyInstance::loaderModsDir() const
{
- return PathCombine(minecraftRoot(), "mods");
+ return FS::PathCombine(minecraftRoot(), "mods");
}
QString LegacyInstance::coreModsDir() const
{
- return PathCombine(minecraftRoot(), "coremods");
+ return FS::PathCombine(minecraftRoot(), "coremods");
}
QString LegacyInstance::resourceDir() const
{
- return PathCombine(minecraftRoot(), "resources");
+ return FS::PathCombine(minecraftRoot(), "resources");
}
QString LegacyInstance::texturePacksDir() const
{
- return PathCombine(minecraftRoot(), "texturepacks");
+ return FS::PathCombine(minecraftRoot(), "texturepacks");
}
QString LegacyInstance::runnableJar() const
{
- return PathCombine(binDir(), "minecraft.jar");
+ return FS::PathCombine(binDir(), "minecraft.jar");
}
QString LegacyInstance::modListFile() const
{
- return PathCombine(instanceRoot(), "modlist");
+ return FS::PathCombine(instanceRoot(), "modlist");
}
QString LegacyInstance::instanceConfigFolder() const
{
- return PathCombine(minecraftRoot(), "config");
+ return FS::PathCombine(minecraftRoot(), "config");
}
bool LegacyInstance::shouldRebuild() const
@@ -442,7 +441,7 @@ QString LegacyInstance::defaultBaseJar() const
QString LegacyInstance::defaultCustomBaseJar() const
{
- return PathCombine(binDir(), "mcbackup.jar");
+ return FS::PathCombine(binDir(), "mcbackup.jar");
}
QString LegacyInstance::lwjglFolder() const
diff --git a/logic/minecraft/LegacyUpdate.cpp b/logic/minecraft/LegacyUpdate.cpp
index c48984c4..2fd8e3cb 100644
--- a/logic/minecraft/LegacyUpdate.cpp
+++ b/logic/minecraft/LegacyUpdate.cpp
@@ -14,7 +14,6 @@
*/
#include <QStringList>
-#include <pathutils.h>
#include <quazip.h>
#include <quazipfile.h>
#include <QDebug>
@@ -30,6 +29,7 @@
#include "minecraft/MinecraftVersionList.h"
#include "minecraft/ModList.h"
#include "minecraft/LegacyInstance.h"
+#include <FileSystem.h>
LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
{
@@ -92,7 +92,7 @@ void LegacyUpdate::fmllibsStart()
// now check the lib folder inside the instance for files.
for (auto &lib : libList)
{
- QFileInfo libInfo(PathCombine(inst->libDir(), lib.filename));
+ QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
if (libInfo.exists())
continue;
fmlLibsToProcess.append(lib);
@@ -137,13 +137,13 @@ void LegacyUpdate::fmllibsFinished()
{
progress(index, fmlLibsToProcess.size());
auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = PathCombine(inst->libDir(), lib.filename);
- if(!ensureFilePathExists(path))
+ auto path = FS::PathCombine(inst->libDir(), lib.filename);
+ if(!FS::ensureFilePathExists(path))
{
emitFailed(tr("Failed creating FML library folder inside the instance."));
return;
}
- if (!QFile::copy(entry->getFullPath(), PathCombine(inst->libDir(), lib.filename)))
+ if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
{
emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
return;
@@ -166,11 +166,11 @@ void LegacyUpdate::lwjglStart()
LegacyInstance *inst = (LegacyInstance *)m_inst;
lwjglVersion = inst->lwjglVersion();
- lwjglTargetPath = PathCombine(inst->lwjglFolder(), lwjglVersion);
- lwjglNativesPath = PathCombine(lwjglTargetPath, "natives");
+ lwjglTargetPath = FS::PathCombine(inst->lwjglFolder(), lwjglVersion);
+ lwjglNativesPath = FS::PathCombine(lwjglTargetPath, "natives");
// if the 'done' file exists, we don't have to download this again
- QFileInfo doneFile(PathCombine(lwjglTargetPath, "done"));
+ QFileInfo doneFile(FS::PathCombine(lwjglTargetPath, "done"));
if (doneFile.exists())
{
jarStart();
@@ -256,7 +256,7 @@ void LegacyUpdate::extractLwjgl()
{
// make sure the directories are there
- bool success = ensureFolderPathExists(lwjglNativesPath);
+ bool success = FS::ensureFolderPathExists(lwjglNativesPath);
if (!success)
{
@@ -295,7 +295,7 @@ void LegacyUpdate::extractLwjgl()
{
if (name.endsWith(jarNames[i]))
{
- destFileName = PathCombine(lwjglTargetPath, jarNames[i]);
+ destFileName = FS::PathCombine(lwjglTargetPath, jarNames[i]);
}
}
// Not found? look for the natives
@@ -318,7 +318,7 @@ void LegacyUpdate::extractLwjgl()
name = name.mid(lastSlash + 1);
else if (lastBackSlash != -1)
name = name.mid(lastBackSlash + 1);
- destFileName = PathCombine(lwjglNativesPath, name);
+ destFileName = FS::PathCombine(lwjglNativesPath, name);
}
}
// Now if destFileName is still empty, go to the next file.
@@ -334,7 +334,7 @@ void LegacyUpdate::extractLwjgl()
}
zip.close();
m_reply.reset();
- QFile doneFile(PathCombine(lwjglTargetPath, "done"));
+ QFile doneFile(FS::PathCombine(lwjglTargetPath, "done"));
doneFile.open(QIODevice::WriteOnly);
doneFile.write("done.");
doneFile.close();
diff --git a/logic/minecraft/MinecraftInstance.cpp b/logic/minecraft/MinecraftInstance.cpp
index 8fd65d50..0dab4dfe 100644
--- a/logic/minecraft/MinecraftInstance.cpp
+++ b/logic/minecraft/MinecraftInstance.cpp
@@ -1,12 +1,12 @@
#include "MinecraftInstance.h"
#include <settings/Setting.h>
#include "settings/SettingsObject.h"
-#include <pathutils.h>
#include "Env.h"
#include "minecraft/MinecraftVersionList.h"
#include <MMCStrings.h>
#include <pathmatcher/RegexpMatcher.h>
#include <pathmatcher/MultiMatcher.h>
+#include <FileSystem.h>
#define IBUS "@im=ibus"
@@ -67,8 +67,8 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO
QString MinecraftInstance::minecraftRoot() const
{
- QFileInfo mcDir(PathCombine(instanceRoot(), "minecraft"));
- QFileInfo dotMCDir(PathCombine(instanceRoot(), ".minecraft"));
+ QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft"));
+ QFileInfo dotMCDir(FS::PathCombine(instanceRoot(), ".minecraft"));
if (dotMCDir.exists() && !mcDir.exists())
return dotMCDir.filePath();
@@ -115,7 +115,7 @@ QStringList MinecraftInstance::javaArguments() const
}
args << "-Duser.language=en";
- args << "-jar" << PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
+ args << "-jar" << FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "NewLaunch.jar");
return args;
}
diff --git a/logic/minecraft/MinecraftProfile.cpp b/logic/minecraft/MinecraftProfile.cpp
index efeb254b..4f33920b 100644
--- a/logic/minecraft/MinecraftProfile.cpp
+++ b/logic/minecraft/MinecraftProfile.cpp
@@ -18,7 +18,6 @@
#include <QJsonDocument>
#include <QJsonArray>
#include <QDebug>
-#include <pathutils.h>
#include "minecraft/MinecraftProfile.h"
#include "ProfileUtils.h"
diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp
index afa7c4c5..8d52c23b 100644
--- a/logic/minecraft/MinecraftVersionList.cpp
+++ b/logic/minecraft/MinecraftVersionList.cpp
@@ -27,8 +27,7 @@
#include "ParseUtils.h"
#include "ProfileUtils.h"
#include "VersionFilterData.h"
-
-#include <pathutils.h>
+#include <FileSystem.h>
static const char * localVersionCache = "versions/versions.dat";
@@ -548,7 +547,7 @@ void MCVListVersionUpdateTask::json_downloaded()
auto doc = file->toJson(false);
auto newdata = doc.toBinaryData();
QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".dat";
- ensureFilePathExists(targetPath);
+ FS::ensureFilePathExists(targetPath);
QSaveFile vfile1(targetPath);
if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly))
{
@@ -582,7 +581,7 @@ std::shared_ptr<Task> MinecraftVersionList::createUpdateTask(QString version)
void MinecraftVersionList::saveCachedList()
{
// FIXME: throw.
- if (!ensureFilePathExists(localVersionCache))
+ if (!FS::ensureFilePathExists(localVersionCache))
return;
QSaveFile tfile(localVersionCache);
if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
diff --git a/logic/minecraft/Mod.cpp b/logic/minecraft/Mod.cpp
index f8eb4faf..879ca195 100644
--- a/logic/minecraft/Mod.cpp
+++ b/logic/minecraft/Mod.cpp
@@ -23,8 +23,8 @@
#include <quazipfile.h>
#include "Mod.h"
-#include <pathutils.h>
#include "settings/INIFile.h"
+#include <FileSystem.h>
#include <QDebug>
Mod::Mod(const QFileInfo &file)
@@ -113,7 +113,7 @@ void Mod::repath(const QFileInfo &file)
}
else if (m_type == MOD_FOLDER)
{
- QFileInfo mcmod_info(PathCombine(m_file.filePath(), "mcmod.info"));
+ QFileInfo mcmod_info(FS::PathCombine(m_file.filePath(), "mcmod.info"));
if (mcmod_info.isFile())
{
QFile mcmod(mcmod_info.filePath());
@@ -278,7 +278,7 @@ bool Mod::replace(Mod &with)
}
if (t == MOD_FOLDER)
{
- success = copyPath(with.m_file.filePath(), m_file.path());
+ success = FS::copyPath(with.m_file.filePath(), m_file.path());
}
if (success)
{
diff --git a/logic/minecraft/ModList.cpp b/logic/minecraft/ModList.cpp
index 8f1bc041..60f8b012 100644
--- a/logic/minecraft/ModList.cpp
+++ b/logic/minecraft/ModList.cpp
@@ -14,7 +14,7 @@
*/
#include "ModList.h"
-#include <pathutils.h>
+#include <FileSystem.h>
#include <QMimeData>
#include <QUrl>
#include <QUuid>
@@ -25,7 +25,7 @@
ModList::ModList(const QString &dir, const QString &list_file)
: QAbstractListModel(), m_dir(dir), m_list_file(list_file)
{
- ensureFolderPathExists(m_dir.absolutePath());
+ FS::ensureFolderPathExists(m_dir.absolutePath());
m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
QDir::NoSymLinks);
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
@@ -270,7 +270,7 @@ bool ModList::installMod(const QFileInfo &filename, int index)
return false;
if (type == Mod::MOD_SINGLEFILE || type == Mod::MOD_ZIPFILE || type == Mod::MOD_LITEMOD)
{
- QString newpath = PathCombine(m_dir.path(), filename.fileName());
+ QString newpath = FS::PathCombine(m_dir.path(), filename.fileName());
if (!QFile::copy(filename.filePath(), newpath))
return false;
m.repath(newpath);
@@ -285,8 +285,8 @@ bool ModList::installMod(const QFileInfo &filename, int index)
{
QString from = filename.filePath();
- QString to = PathCombine(m_dir.path(), filename.fileName());
- if (!copyPath(from, to))
+ QString to = FS::PathCombine(m_dir.path(), filename.fileName());
+ if (!FS::copyPath(from, to))
return false;
m.repath(to);
beginInsertRows(QModelIndex(), index, index);
diff --git a/logic/minecraft/OneSixInstance.cpp b/logic/minecraft/OneSixInstance.cpp
index a5be8354..da1b21cb 100644
--- a/logic/minecraft/OneSixInstance.cpp
+++ b/logic/minecraft/OneSixInstance.cpp
@@ -14,7 +14,6 @@
*/
#include <QIcon>
-#include <pathutils.h>
#include <QDebug>
#include "minecraft/OneSixInstance.h"
@@ -36,6 +35,7 @@
#include "minecraft/AssetsUtils.h"
#include "icons/IconList.h"
#include "minecraft/WorldList.h"
+#include <FileSystem.h>
OneSixInstance::OneSixInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr settings, const QString &rootDir)
: MinecraftInstance(globalSettings, settings, rootDir)
@@ -136,7 +136,7 @@ std::shared_ptr<LaunchTask> OneSixInstance::createLaunchTask(AuthSessionPtr sess
QString launchScript;
QIcon icon = ENV.icons()->getIcon(iconKey());
auto pixmap = icon.pixmap(128, 128);
- pixmap.save(PathCombine(minecraftRoot(), "icon.png"), "PNG");
+ pixmap.save(FS::PathCombine(minecraftRoot(), "icon.png"), "PNG");
if (!m_version)
return nullptr;
@@ -222,7 +222,7 @@ std::shared_ptr<LaunchTask> OneSixInstance::createLaunchTask(AuthSessionPtr sess
// native libraries (mostly LWJGL)
{
- QDir natives_dir(PathCombine(instanceRoot(), "natives/"));
+ QDir natives_dir(FS::PathCombine(instanceRoot(), "natives/"));
for (auto native : m_version->getActiveNativeLibs())
{
QFileInfo finfo(native->storagePath());
@@ -348,7 +348,7 @@ std::shared_ptr<Task> OneSixInstance::createJarModdingTask()
void OneSixInstance::cleanupAfterRun()
{
- QString target_dir = PathCombine(instanceRoot(), "natives/");
+ QString target_dir = FS::PathCombine(instanceRoot(), "natives/");
QDir dir(target_dir);
dir.removeRecursively();
}
@@ -515,42 +515,42 @@ bool OneSixInstance::reload()
QString OneSixInstance::loaderModsDir() const
{
- return PathCombine(minecraftRoot(), "mods");
+ return FS::PathCombine(minecraftRoot(), "mods");
}
QString OneSixInstance::coreModsDir() const
{
- return PathCombine(minecraftRoot(), "coremods");
+ return FS::PathCombine(minecraftRoot(), "coremods");
}
QString OneSixInstance::resourcePacksDir() const
{
- return PathCombine(minecraftRoot(), "resourcepacks");
+ return FS::PathCombine(minecraftRoot(), "resourcepacks");
}
QString OneSixInstance::texturePacksDir() const
{
- return PathCombine(minecraftRoot(), "texturepacks");
+ return FS::PathCombine(minecraftRoot(), "texturepacks");
}
QString OneSixInstance::instanceConfigFolder() const
{
- return PathCombine(minecraftRoot(), "config");
+ return FS::PathCombine(minecraftRoot(), "config");
}
QString OneSixInstance::jarModsDir() const
{
- return PathCombine(instanceRoot(), "jarmods");
+ return FS::PathCombine(instanceRoot(), "jarmods");
}
QString OneSixInstance::libDir() const
{
- return PathCombine(minecraftRoot(), "lib");
+ return FS::PathCombine(minecraftRoot(), "lib");
}
QString OneSixInstance::worldDir() const
{
- return PathCombine(minecraftRoot(), "saves");
+ return FS::PathCombine(minecraftRoot(), "saves");
}
QStringList OneSixInstance::extraArguments() const
diff --git a/logic/minecraft/OneSixProfileStrategy.cpp b/logic/minecraft/OneSixProfileStrategy.cpp
index f5de690b..85e9491c 100644
--- a/logic/minecraft/OneSixProfileStrategy.cpp
+++ b/logic/minecraft/OneSixProfileStrategy.cpp
@@ -3,8 +3,8 @@
#include "minecraft/OneSixInstance.h"
#include "minecraft/MinecraftVersionList.h"
#include "Env.h"
+#include <FileSystem.h>
-#include <pathutils.h>
#include <QDir>
#include <QUuid>
#include <QJsonDocument>
@@ -17,9 +17,9 @@ OneSixProfileStrategy::OneSixProfileStrategy(OneSixInstance* instance)
void OneSixProfileStrategy::upgradeDeprecatedFiles()
{
- auto versionJsonPath = PathCombine(m_instance->instanceRoot(), "version.json");
- auto customJsonPath = PathCombine(m_instance->instanceRoot(), "custom.json");
- auto mcJson = PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
+ auto versionJsonPath = FS::PathCombine(m_instance->instanceRoot(), "version.json");
+ auto customJsonPath = FS::PathCombine(m_instance->instanceRoot(), "custom.json");
+ auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
QString sourceFile;
QString renameFile;
@@ -36,7 +36,7 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles()
}
if(!sourceFile.isEmpty() && !QFile::exists(mcJson))
{
- if(!ensureFilePathExists(mcJson))
+ if(!FS::ensureFilePathExists(mcJson))
{
qWarning() << "Couldn't create patches folder for" << m_instance->name();
return;
@@ -79,7 +79,7 @@ void OneSixProfileStrategy::upgradeDeprecatedFiles()
void OneSixProfileStrategy::loadDefaultBuiltinPatches()
{
{
- auto mcJson = PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
+ auto mcJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "net.minecraft.json");
// load up the base minecraft patch
ProfilePatchPtr minecraftPatch;
if(QFile::exists(mcJson))
@@ -107,7 +107,7 @@ void OneSixProfileStrategy::loadDefaultBuiltinPatches()
}
{
- auto lwjglJson = PathCombine(m_instance->instanceRoot(), "patches" , "org.lwjgl.json");
+ auto lwjglJson = FS::PathCombine(m_instance->instanceRoot(), "patches" , "org.lwjgl.json");
ProfilePatchPtr lwjglPatch;
if(QFile::exists(lwjglJson))
{
@@ -138,8 +138,8 @@ void OneSixProfileStrategy::loadUserPatches()
{
// load all patches, put into map for ordering, apply in the right order
ProfileUtils::PatchOrder userOrder;
- ProfileUtils::readOverrideOrders(PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
- QDir patches(PathCombine(m_instance->instanceRoot(),"patches"));
+ ProfileUtils::readOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), userOrder);
+ QDir patches(FS::PathCombine(m_instance->instanceRoot(),"patches"));
// first, load things by sort order.
for (auto id : userOrder)
@@ -215,7 +215,7 @@ void OneSixProfileStrategy::load()
bool OneSixProfileStrategy::saveOrder(ProfileUtils::PatchOrder order)
{
- return ProfileUtils::writeOverrideOrders(PathCombine(m_instance->instanceRoot(), "order.json"), order);
+ return ProfileUtils::writeOverrideOrders(FS::PathCombine(m_instance->instanceRoot(), "order.json"), order);
}
bool OneSixProfileStrategy::resetOrder()
@@ -241,7 +241,7 @@ bool OneSixProfileStrategy::removePatch(ProfilePatchPtr patch)
auto preRemoveJarMod = [&](JarmodPtr jarMod) -> bool
{
- QString fullpath = PathCombine(m_instance->jarModsDir(), jarMod->name);
+ QString fullpath = FS::PathCombine(m_instance->jarModsDir(), jarMod->name);
QFileInfo finfo (fullpath);
if(finfo.exists())
{
@@ -270,8 +270,8 @@ bool OneSixProfileStrategy::customizePatch(ProfilePatchPtr patch)
return false;
}
- auto filename = PathCombine(m_instance->instanceRoot(), "patches" , patch->getPatchID() + ".json");
- if(!ensureFilePathExists(filename))
+ auto filename = FS::PathCombine(m_instance->instanceRoot(), "patches" , patch->getPatchID() + ".json");
+ if(!FS::ensureFilePathExists(filename))
{
return false;
}
@@ -333,13 +333,13 @@ bool OneSixProfileStrategy::revertPatch(ProfilePatchPtr patch)
bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
{
- QString patchDir = PathCombine(m_instance->instanceRoot(), "patches");
- if(!ensureFolderPathExists(patchDir))
+ QString patchDir = FS::PathCombine(m_instance->instanceRoot(), "patches");
+ if(!FS::ensureFolderPathExists(patchDir))
{
return false;
}
- if (!ensureFolderPathExists(m_instance->jarModsDir()))
+ if (!FS::ensureFolderPathExists(m_instance->jarModsDir()))
{
return false;
}
@@ -352,7 +352,7 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
QString target_filename = id + ".jar";
QString target_id = "org.multimc.jarmod." + id;
QString target_name = sourceInfo.completeBaseName() + " (jar mod)";
- QString finalPath = PathCombine(m_instance->jarModsDir(), target_filename);
+ QString finalPath = FS::PathCombine(m_instance->jarModsDir(), target_filename);
QFileInfo targetInfo(finalPath);
if(targetInfo.exists())
@@ -373,7 +373,7 @@ bool OneSixProfileStrategy::installJarMods(QStringList filepaths)
f->name = target_name;
f->fileId = target_id;
f->order = profile->getFreeOrderNumber();
- QString patchFileName = PathCombine(patchDir, target_id + ".json");
+ QString patchFileName = FS::PathCombine(patchDir, target_id + ".json");
f->filename = patchFileName;
f->setMovable(true);
f->setRemovable(true);
diff --git a/logic/minecraft/OneSixUpdate.cpp b/logic/minecraft/OneSixUpdate.cpp
index 34bd7de9..73d48461 100644
--- a/logic/minecraft/OneSixUpdate.cpp
+++ b/logic/minecraft/OneSixUpdate.cpp
@@ -22,7 +22,6 @@
#include <QFileInfo>
#include <QTextStream>
#include <QDataStream>
-#include <pathutils.h>
#include <JlCompress.h>
#include "BaseInstance.h"
@@ -35,6 +34,7 @@
#include "minecraft/AssetsUtils.h"
#include "Exception.h"
#include "MMCZip.h"
+#include <FileSystem.h>
OneSixUpdate::OneSixUpdate(OneSixInstance *inst, QObject *parent) : Task(parent), m_inst(inst)
{
@@ -344,7 +344,7 @@ void OneSixUpdate::fmllibsStart()
// now check the lib folder inside the instance for files.
for (auto &lib : libList)
{
- QFileInfo libInfo(PathCombine(inst->libDir(), lib.filename));
+ QFileInfo libInfo(FS::PathCombine(inst->libDir(), lib.filename));
if (libInfo.exists())
continue;
fmlLibsToProcess.append(lib);
@@ -389,13 +389,13 @@ void OneSixUpdate::fmllibsFinished()
{
progress(index, fmlLibsToProcess.size());
auto entry = metacache->resolveEntry("fmllibs", lib.filename);
- auto path = PathCombine(inst->libDir(), lib.filename);
- if (!ensureFilePathExists(path))
+ auto path = FS::PathCombine(inst->libDir(), lib.filename);
+ if (!FS::ensureFilePathExists(path))
{
emitFailed(tr("Failed creating FML library folder inside the instance."));
return;
}
- if (!QFile::copy(entry->getFullPath(), PathCombine(inst->libDir(), lib.filename)))
+ if (!QFile::copy(entry->getFullPath(), FS::PathCombine(inst->libDir(), lib.filename)))
{
emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename));
return;
diff --git a/logic/minecraft/RawLibrary.cpp b/logic/minecraft/RawLibrary.cpp
index ceaa9dd0..7da743e4 100644
--- a/logic/minecraft/RawLibrary.cpp
+++ b/logic/minecraft/RawLibrary.cpp
@@ -2,7 +2,7 @@
using namespace Json;
#include "RawLibrary.h"
-#include <pathutils.h>
+#include <FileSystem.h>
RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &filename)
{
@@ -314,7 +314,7 @@ QString RawLibrary::storageSuffix() const
QString RawLibrary::storagePath() const
{
- return PathCombine(storagePrefix(), storageSuffix());
+ return FS::PathCombine(storagePrefix(), storageSuffix());
}
bool RawLibrary::storagePathIsDefault() const
diff --git a/logic/minecraft/VersionFile.cpp b/logic/minecraft/VersionFile.cpp
index 24f2eb9c..922ba470 100644
--- a/logic/minecraft/VersionFile.cpp
+++ b/logic/minecraft/VersionFile.cpp
@@ -1,6 +1,5 @@
#include <QJsonArray>
#include <QJsonDocument>
-#include <modutils.h>
#include <QDebug>
@@ -14,6 +13,7 @@
using namespace Json;
#include "VersionBuildError.h"
+#include <Version.h>
#define CURRENT_MINIMUM_LAUNCHER_VERSION 14
@@ -427,8 +427,8 @@ void VersionFile::applyTo(MinecraftProfile *version)
// otherwise apply differences, if allowed
auto existingLibrary = version->libraries.at(index);
- const Util::Version addedVersion = addedLibrary->version();
- const Util::Version existingVersion = existingLibrary->version();
+ const Version addedVersion(addedLibrary->version());
+ const Version existingVersion(existingLibrary->version());
// if the existing version is a hard dependency we can either use it or
// fail, but we can't change it
if (existingLibrary->dependType == OneSixLibrary::Hard)
diff --git a/logic/minecraft/World.cpp b/logic/minecraft/World.cpp
index 41d62b1b..e4734556 100644
--- a/logic/minecraft/World.cpp
+++ b/logic/minecraft/World.cpp
@@ -18,10 +18,10 @@
#include <QDebug>
#include <QSaveFile>
#include "World.h"
-#include <pathutils.h>
#include "GZip.h"
#include <MMCZip.h>
+#include <FileSystem.h>
#include <sstream>
#include <io/stream_reader.h>
#include <tag_string.h>
@@ -179,8 +179,8 @@ void World::readFromZip(const QFileInfo &file)
bool World::install(const QString &to, const QString &name)
{
- auto finalPath = PathCombine(to, DirNameFromString(m_actualName, to));
- if(!ensureFolderPathExists(finalPath))
+ auto finalPath = FS::PathCombine(to, FS::DirNameFromString(m_actualName, to));
+ if(!FS::ensureFolderPathExists(finalPath))
{
return false;
}
@@ -197,7 +197,7 @@ bool World::install(const QString &to, const QString &name)
else if(m_containerFile.isDir())
{
QString from = m_containerFile.filePath();
- ok = copyPath(from, finalPath);
+ ok = FS::copyPath(from, finalPath);
}
if(ok && !name.isEmpty() && m_actualName != name)
@@ -245,7 +245,7 @@ bool World::rename(const QString &newName)
QDir parentDir(m_containerFile.absoluteFilePath());
parentDir.cdUp();
QFile container(m_containerFile.absoluteFilePath());
- auto dirName = DirNameFromString(m_actualName, parentDir.absolutePath());
+ auto dirName = FS::DirNameFromString(m_actualName, parentDir.absolutePath());
container.rename(parentDir.absoluteFilePath(dirName));
return true;
@@ -350,7 +350,7 @@ bool World::replace(World &with)
{
if (!destroy())
return false;
- bool success = copyPath(with.m_containerFile.filePath(), m_containerFile.path());
+ bool success = FS::copyPath(with.m_containerFile.filePath(), m_containerFile.path());
if (success)
{
m_folderName = with.m_folderName;
diff --git a/logic/minecraft/WorldList.cpp b/logic/minecraft/WorldList.cpp
index fff4f74a..42c8a3e6 100644
--- a/logic/minecraft/WorldList.cpp
+++ b/logic/minecraft/WorldList.cpp
@@ -14,7 +14,7 @@
*/
#include "WorldList.h"
-#include <pathutils.h>
+#include <FileSystem.h>
#include <QMimeData>
#include <QUrl>
#include <QUuid>
@@ -25,7 +25,7 @@
WorldList::WorldList(const QString &dir)
: QAbstractListModel(), m_dir(dir)
{
- ensureFolderPathExists(m_dir.absolutePath());
+ FS::ensureFolderPathExists(m_dir.absolutePath());
m_dir.setFilter(QDir::Readable | QDir::NoDotAndDotDot | QDir::Files | QDir::Dirs |
QDir::NoSymLinks);
m_dir.setSorting(QDir::Name | QDir::IgnoreCase | QDir::LocaleAware);
diff --git a/logic/net/CacheDownload.cpp b/logic/net/CacheDownload.cpp
index b125a3d9..1d48170a 100644
--- a/logic/net/CacheDownload.cpp
+++ b/logic/net/CacheDownload.cpp
@@ -14,13 +14,13 @@
*/
#include "CacheDownload.h"
-#include <pathutils.h>
#include <QCryptographicHash>
#include <QFileInfo>
#include <QDateTime>
#include <QDebug>
#include "Env.h"
+#include <FileSystem.h>
CacheDownload::CacheDownload(QUrl url, MetaEntryPtr entry)
: NetAction(), md5sum(QCryptographicHash::Md5)
@@ -44,7 +44,7 @@ void CacheDownload::start()
m_output_file.reset(new QSaveFile(m_target_path));
// if there already is a file and md5 checking is in effect and it can be opened
- if (!ensureFilePathExists(m_target_path))
+ if (!FS::ensureFilePathExists(m_target_path))
{
qCritical() << "Could not create folder for " + m_target_path;
m_status = Job_Failed;
diff --git a/logic/net/HttpMetaCache.cpp b/logic/net/HttpMetaCache.cpp
index 977e3a90..3d6aef0d 100644
--- a/logic/net/HttpMetaCache.cpp
+++ b/logic/net/HttpMetaCache.cpp
@@ -16,7 +16,6 @@
#include "Env.h"
#include "HttpMetaCache.h"
#include "FileSystem.h"
-#include <pathutils.h>
#include <QFileInfo>
#include <QFile>
@@ -33,7 +32,7 @@
QString MetaEntry::getFullPath()
{
// FIXME: make local?
- return PathCombine(ENV.metacache()->getBasePath(base), path);
+ return FS::PathCombine(ENV.metacache()->getBasePath(base), path);
}
HttpMetaCache::HttpMetaCache(QString path) : QObject()
@@ -77,7 +76,7 @@ MetaEntryPtr HttpMetaCache::resolveEntry(QString base, QString resource_path,
}
auto &selected_base = m_entries[base];
- QString real_path = PathCombine(selected_base.base_path, resource_path);
+ QString real_path = FS::PathCombine(selected_base.base_path, resource_path);
QFileInfo finfo(real_path);
// is the file really there? if not -> stale
diff --git a/logic/net/MD5EtagDownload.cpp b/logic/net/MD5EtagDownload.cpp
index 7593c87e..3b4d5dcd 100644
--- a/logic/net/MD5EtagDownload.cpp
+++ b/logic/net/MD5EtagDownload.cpp
@@ -15,7 +15,7 @@
#include "Env.h"
#include "MD5EtagDownload.h"
-#include <pathutils.h>
+#include <FileSystem.h>
#include <QCryptographicHash>
#include <QDebug>
@@ -55,7 +55,7 @@ void MD5EtagDownload::start()
// no expected md5. we use the local md5sum as an ETag
}
}
- if (!ensureFilePathExists(filename))
+ if (!FS::ensureFilePathExists(filename))
{
emit failed(m_index_within_job);
return;
diff --git a/logic/net/NetJob.cpp b/logic/net/NetJob.cpp
index 52307e2a..76c61c35 100644
--- a/logic/net/NetJob.cpp
+++ b/logic/net/NetJob.cpp
@@ -14,7 +14,6 @@
*/
#include "NetJob.h"
-#include "pathutils.h"
#include "MD5EtagDownload.h"
#include "ByteArrayDownload.h"
#include "CacheDownload.h"
diff --git a/logic/updater/DownloadTask.cpp b/logic/updater/DownloadTask.cpp
index 1bbb0edf..6947e8bf 100644
--- a/logic/updater/DownloadTask.cpp
+++ b/logic/updater/DownloadTask.cpp
@@ -18,7 +18,6 @@
#include "updater/UpdateChecker.h"
#include "GoUpdate.h"
#include "net/NetJob.h"
-#include "pathutils.h"
#include <QFile>
#include <QTemporaryDir>
diff --git a/logic/updater/GoUpdate.cpp b/logic/updater/GoUpdate.cpp
index a43c5e7c..60d50e04 100644
--- a/logic/updater/GoUpdate.cpp
+++ b/logic/updater/GoUpdate.cpp
@@ -1,9 +1,9 @@
#include "GoUpdate.h"
-#include <pathutils.h>
#include <QDebug>
#include <QDomDocument>
#include <QFile>
#include <Env.h>
+#include <FileSystem.h>
namespace GoUpdate
{
@@ -80,7 +80,7 @@ bool processFileLists
// delete anything in the current one version's list that isn't in the new version's list.
for (VersionFileEntry entry : currentVersion)
{
- QFileInfo toDelete(PathCombine(rootPath, entry.path));
+ QFileInfo toDelete(FS::PathCombine(rootPath, entry.path));
if (!toDelete.exists())
{
qCritical() << "Expected file " << toDelete.absoluteFilePath()
@@ -114,7 +114,7 @@ bool processFileLists
// TODO: Let's not MD5sum a ton of files on the GUI thread. We should probably find a
// way to do this in the background.
QString fileMD5;
- QString realEntryPath = PathCombine(rootPath, entry.path);
+ QString realEntryPath = FS::PathCombine(rootPath, entry.path);
QFile entryFile(realEntryPath);
QFileInfo entryInfo(realEntryPath);
@@ -186,7 +186,7 @@ bool processFileLists
// Download it to updatedir/<filepath>-<md5> where filepath is the file's
// path with slashes replaced by underscores.
- QString dlPath = PathCombine(tempPath, QString(entry.path).replace("/", "_"));
+ QString dlPath = FS::PathCombine(tempPath, QString(entry.path).replace("/", "_"));
// We need to download the file to the updatefiles folder and add a task
// to copy it to its install path.