NOISSUE dissolve util library
This commit is contained in:
@ -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());
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
483
logic/Commandline.cpp
Normal file
483
logic/Commandline.cpp
Normal file
@ -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())
|
||||
{
|
||||
}
|
||||
}
|
252
logic/Commandline.h
Normal file
252
logic/Commandline.h
Normal file
@ -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);
|
||||
};
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
|
140
logic/Version.cpp
Normal file
140
logic/Version.cpp
Normal file
@ -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;
|
||||
}
|
110
logic/Version.h
Normal file
110
logic/Version.h
Normal file
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "JavaCheckerJob.h"
|
||||
#include "pathutils.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <QStringList>
|
||||
|
||||
#include <settings/Setting.h>
|
||||
#include <pathutils.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include "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
|
||||
};
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "MMCStrings.h"
|
||||
#include "java/JavaChecker.h"
|
||||
#include "tasks/Task.h"
|
||||
#include <pathutils.h>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
#include <QEventLoop>
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QDebug>
|
||||
#include <pathutils.h>
|
||||
|
||||
#include "minecraft/MinecraftProfile.h"
|
||||
#include "ProfileUtils.h"
|
||||
|
@ -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))
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include "NetJob.h"
|
||||
#include "pathutils.h"
|
||||
#include "MD5EtagDownload.h"
|
||||
#include "ByteArrayDownload.h"
|
||||
#include "CacheDownload.h"
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "updater/UpdateChecker.h"
|
||||
#include "GoUpdate.h"
|
||||
#include "net/NetJob.h"
|
||||
#include "pathutils.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTemporaryDir>
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user