Merge tag '8.3' into develop
This commit is contained in:
commit
c8265567aa
41
.github/scripts/prepare_JREs.sh
vendored
41
.github/scripts/prepare_JREs.sh
vendored
@ -1,41 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
URL_JDK8="https://api.adoptium.net/v3/binary/version/jdk8u312-b07/linux/x64/jre/hotspot/normal/eclipse"
|
|
||||||
URL_JDK17="https://api.adoptium.net/v3/binary/latest/17/ga/linux/x64/jre/hotspot/normal/eclipse"
|
|
||||||
|
|
||||||
mkdir -p JREs
|
|
||||||
pushd JREs
|
|
||||||
|
|
||||||
wget --content-disposition "$URL_JDK8"
|
|
||||||
wget --content-disposition "$URL_JDK17"
|
|
||||||
|
|
||||||
for file in *;
|
|
||||||
do
|
|
||||||
mkdir temp
|
|
||||||
|
|
||||||
re='(OpenJDK([[:digit:]]+)U-jre_x64_linux_hotspot_([[:digit:]]+)(.*).tar.gz)'
|
|
||||||
if [[ $file =~ $re ]];
|
|
||||||
then
|
|
||||||
version_major=${BASH_REMATCH[2]}
|
|
||||||
version_trailing=${BASH_REMATCH[4]}
|
|
||||||
|
|
||||||
if [ $version_major = 17 ];
|
|
||||||
then
|
|
||||||
hyphen='-'
|
|
||||||
else
|
|
||||||
hyphen=''
|
|
||||||
fi
|
|
||||||
|
|
||||||
version_edit=$(echo $version_trailing | sed -e 's/_/+/g' | sed -e 's/b/-b/g')
|
|
||||||
dir_name=jdk$hyphen$version_major$version_edit-jre
|
|
||||||
mkdir jre$version_major
|
|
||||||
tar -xzf $file -C temp
|
|
||||||
pushd temp/$dir_name
|
|
||||||
cp -r . ../../jre$version_major
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
|
|
||||||
rm -rf temp
|
|
||||||
done
|
|
||||||
|
|
||||||
popd
|
|
25
.github/workflows/build.yml
vendored
25
.github/workflows/build.yml
vendored
@ -76,7 +76,7 @@ jobs:
|
|||||||
qt_ver: 6
|
qt_ver: 6
|
||||||
qt_host: windows
|
qt_host: windows
|
||||||
qt_arch: ''
|
qt_arch: ''
|
||||||
qt_version: '6.6.2'
|
qt_version: '6.6.3'
|
||||||
qt_modules: 'qt5compat qtimageformats'
|
qt_modules: 'qt5compat qtimageformats'
|
||||||
qt_tools: ''
|
qt_tools: ''
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ jobs:
|
|||||||
qt_ver: 6
|
qt_ver: 6
|
||||||
qt_host: windows
|
qt_host: windows
|
||||||
qt_arch: 'win64_msvc2019_arm64'
|
qt_arch: 'win64_msvc2019_arm64'
|
||||||
qt_version: '6.6.2'
|
qt_version: '6.6.3'
|
||||||
qt_modules: 'qt5compat qtimageformats'
|
qt_modules: 'qt5compat qtimageformats'
|
||||||
qt_tools: ''
|
qt_tools: ''
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ jobs:
|
|||||||
qt_ver: 6
|
qt_ver: 6
|
||||||
qt_host: mac
|
qt_host: mac
|
||||||
qt_arch: ''
|
qt_arch: ''
|
||||||
qt_version: '6.6.2'
|
qt_version: '6.6.3'
|
||||||
qt_modules: 'qt5compat qtimageformats'
|
qt_modules: 'qt5compat qtimageformats'
|
||||||
qt_tools: ''
|
qt_tools: ''
|
||||||
|
|
||||||
@ -259,7 +259,6 @@ jobs:
|
|||||||
|
|
||||||
wget "https://github.com/AppImageCommunity/AppImageUpdate/releases/download/continuous/AppImageUpdate-x86_64.AppImage"
|
wget "https://github.com/AppImageCommunity/AppImageUpdate/releases/download/continuous/AppImageUpdate-x86_64.AppImage"
|
||||||
|
|
||||||
${{ github.workspace }}/.github/scripts/prepare_JREs.sh
|
|
||||||
sudo apt install libopengl0
|
sudo apt install libopengl0
|
||||||
|
|
||||||
- name: Add QT_HOST_PATH var (Windows MSVC arm64)
|
- name: Add QT_HOST_PATH var (Windows MSVC arm64)
|
||||||
@ -495,7 +494,6 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_DIR }}
|
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_DIR }}
|
||||||
for l in $(find ${{ env.INSTALL_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_DIR }}/manifest.txt
|
for l in $(find ${{ env.INSTALL_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_DIR }}/manifest.txt
|
||||||
|
|
||||||
cd ${{ env.INSTALL_DIR }}
|
cd ${{ env.INSTALL_DIR }}
|
||||||
tar --owner root --group root -czf ../PollyMC.tar.gz *
|
tar --owner root --group root -czf ../PollyMC.tar.gz *
|
||||||
|
|
||||||
@ -504,9 +502,12 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }}
|
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }}
|
||||||
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
|
cmake --install ${{ env.BUILD_DIR }} --prefix ${{ env.INSTALL_PORTABLE_DIR }} --component portable
|
||||||
|
|
||||||
|
# workaround to make portable installs to work on fedora
|
||||||
|
mkdir ${{ env.INSTALL_PORTABLE_DIR }}/lib
|
||||||
|
cp /lib/x86_64-linux-gnu/libbz2.so.1.0 ${{ env.INSTALL_PORTABLE_DIR }}/lib
|
||||||
|
|
||||||
for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt
|
for l in $(find ${{ env.INSTALL_PORTABLE_DIR }} -type f); do l=${l#$(pwd)/}; l=${l#${{ env.INSTALL_PORTABLE_DIR }}/}; l=${l#./}; echo $l; done > ${{ env.INSTALL_PORTABLE_DIR }}/manifest.txt
|
||||||
|
|
||||||
|
|
||||||
cd ${{ env.INSTALL_PORTABLE_DIR }}
|
cd ${{ env.INSTALL_PORTABLE_DIR }}
|
||||||
tar -czf ../PollyMC-portable.tar.gz *
|
tar -czf ../PollyMC-portable.tar.gz *
|
||||||
|
|
||||||
@ -525,13 +526,9 @@ jobs:
|
|||||||
|
|
||||||
chmod +x linuxdeploy-*.AppImage
|
chmod +x linuxdeploy-*.AppImage
|
||||||
|
|
||||||
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-{8,17}-openjdk
|
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib
|
||||||
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
|
mkdir -p ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
|
||||||
|
|
||||||
cp -r ${{ github.workspace }}/JREs/jre8/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-8-openjdk
|
|
||||||
|
|
||||||
cp -r ${{ github.workspace }}/JREs/jre17/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk
|
|
||||||
|
|
||||||
cp -r ${{ runner.workspace }}/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
|
cp -r ${{ runner.workspace }}/Qt/${{ matrix.qt_version }}/gcc_64/plugins/iconengines/* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/plugins/iconengines
|
||||||
|
|
||||||
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
|
cp /usr/lib/x86_64-linux-gnu/libcrypto.so.1.1 ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
|
||||||
@ -539,10 +536,6 @@ jobs:
|
|||||||
cp /usr/lib/x86_64-linux-gnu/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
|
cp /usr/lib/x86_64-linux-gnu/libOpenGL.so.0* ${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/
|
||||||
|
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib"
|
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib"
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-8-openjdk/lib/amd64/server"
|
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-8-openjdk/lib/amd64"
|
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib/server"
|
|
||||||
LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${{ env.INSTALL_APPIMAGE_DIR }}/usr/lib/jvm/java-17-openjdk/lib"
|
|
||||||
export LD_LIBRARY_PATH
|
export LD_LIBRARY_PATH
|
||||||
|
|
||||||
chmod +x AppImageUpdate-x86_64.AppImage
|
chmod +x AppImageUpdate-x86_64.AppImage
|
||||||
|
@ -179,7 +179,7 @@ set(Launcher_HELP_URL "https://prismlauncher.org/wiki/help-pages/%1" CACHE STRIN
|
|||||||
|
|
||||||
######## Set version numbers ########
|
######## Set version numbers ########
|
||||||
set(Launcher_VERSION_MAJOR 8)
|
set(Launcher_VERSION_MAJOR 8)
|
||||||
set(Launcher_VERSION_MINOR 2)
|
set(Launcher_VERSION_MINOR 3)
|
||||||
|
|
||||||
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}")
|
set(Launcher_VERSION_NAME "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}")
|
||||||
set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.0.0")
|
set(Launcher_VERSION_NAME4 "${Launcher_VERSION_MAJOR}.${Launcher_VERSION_MINOR}.0.0")
|
||||||
|
@ -228,6 +228,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv)
|
|||||||
|
|
||||||
// Don't quit on hiding the last window
|
// Don't quit on hiding the last window
|
||||||
this->setQuitOnLastWindowClosed(false);
|
this->setQuitOnLastWindowClosed(false);
|
||||||
|
this->setQuitLockEnabled(false);
|
||||||
|
|
||||||
// Commandline parsing
|
// Commandline parsing
|
||||||
QCommandLineParser parser;
|
QCommandLineParser parser;
|
||||||
|
@ -801,15 +801,24 @@ QString NormalizePath(QString path)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString badFilenameChars = "\"\\/?<>:;*|!+\r\n";
|
static const QString BAD_PATH_CHARS = "\"?<>:;*|!+\r\n";
|
||||||
|
static const QString BAD_FILENAME_CHARS = BAD_PATH_CHARS + "\\/";
|
||||||
|
|
||||||
QString RemoveInvalidFilenameChars(QString string, QChar replaceWith)
|
QString RemoveInvalidFilenameChars(QString string, QChar replaceWith)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < string.length(); i++) {
|
for (int i = 0; i < string.length(); i++)
|
||||||
if (badFilenameChars.contains(string[i])) {
|
if (string.at(i) < ' ' || BAD_FILENAME_CHARS.contains(string.at(i)))
|
||||||
string[i] = replaceWith;
|
string[i] = replaceWith;
|
||||||
}
|
|
||||||
}
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RemoveInvalidPathChars(QString string, QChar replaceWith)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < string.length(); i++)
|
||||||
|
if (string.at(i) < ' ' || BAD_PATH_CHARS.contains(string.at(i)))
|
||||||
|
string[i] = replaceWith;
|
||||||
|
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1585,4 +1594,44 @@ uintmax_t hardLinkCount(const QString& path)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
// returns 8.3 file format from long path
|
||||||
|
QString shortPathName(const QString& file)
|
||||||
|
{
|
||||||
|
auto input = file.toStdWString();
|
||||||
|
std::wstring output;
|
||||||
|
long length = GetShortPathNameW(input.c_str(), NULL, 0);
|
||||||
|
if (length == 0)
|
||||||
|
return {};
|
||||||
|
// NOTE: this resizing might seem weird...
|
||||||
|
// when GetShortPathNameW fails, it returns length including null character
|
||||||
|
// when it succeeds, it returns length excluding null character
|
||||||
|
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364989(v=vs.85).aspx
|
||||||
|
output.resize(length);
|
||||||
|
if (GetShortPathNameW(input.c_str(), (LPWSTR)output.c_str(), length) == 0)
|
||||||
|
return {};
|
||||||
|
output.resize(length - 1);
|
||||||
|
QString ret = QString::fromStdWString(output);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the string survives roundtrip through local 8bit encoding...
|
||||||
|
bool fitsInLocal8bit(const QString& string)
|
||||||
|
{
|
||||||
|
return string == QString::fromLocal8Bit(string.toLocal8Bit());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getPathNameInLocal8bit(const QString& file)
|
||||||
|
{
|
||||||
|
if (!fitsInLocal8bit(file)) {
|
||||||
|
auto path = shortPathName(file);
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
// in case shortPathName fails just return the path as is
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace FS
|
} // namespace FS
|
||||||
|
@ -342,6 +342,8 @@ QString NormalizePath(QString path);
|
|||||||
|
|
||||||
QString RemoveInvalidFilenameChars(QString string, QChar replaceWith = '-');
|
QString RemoveInvalidFilenameChars(QString string, QChar replaceWith = '-');
|
||||||
|
|
||||||
|
QString RemoveInvalidPathChars(QString string, QChar replaceWith = '-');
|
||||||
|
|
||||||
QString DirNameFromString(QString string, QString inDir = ".");
|
QString DirNameFromString(QString string, QString inDir = ".");
|
||||||
|
|
||||||
/// Checks if the a given Path contains "!"
|
/// Checks if the a given Path contains "!"
|
||||||
@ -551,4 +553,8 @@ bool canLink(const QString& src, const QString& dst);
|
|||||||
|
|
||||||
uintmax_t hardLinkCount(const QString& path);
|
uintmax_t hardLinkCount(const QString& path);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
QString getPathNameInLocal8bit(const QString& file);
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace FS
|
} // namespace FS
|
||||||
|
@ -47,9 +47,6 @@
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
class QuaZip;
|
class QuaZip;
|
||||||
namespace Flame {
|
|
||||||
class FileResolvingTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InstanceImportTask : public InstanceTask {
|
class InstanceImportTask : public InstanceTask {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -79,7 +76,6 @@ class InstanceImportTask : public InstanceTask {
|
|||||||
|
|
||||||
private: /* data */
|
private: /* data */
|
||||||
NetJob::Ptr m_filesNetJob;
|
NetJob::Ptr m_filesNetJob;
|
||||||
shared_qobject_ptr<Flame::FileResolvingTask> m_modIdResolver;
|
|
||||||
QUrl m_sourceUrl;
|
QUrl m_sourceUrl;
|
||||||
QString m_archivePath;
|
QString m_archivePath;
|
||||||
bool m_downloadRequired = false;
|
bool m_downloadRequired = false;
|
||||||
|
@ -119,6 +119,7 @@ bool compressDirFiles(QuaZip* zip, QString dir, QFileInfoList files, bool follow
|
|||||||
bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks)
|
bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files, bool followSymlinks)
|
||||||
{
|
{
|
||||||
QuaZip zip(fileCompressed);
|
QuaZip zip(fileCompressed);
|
||||||
|
zip.setUtf8Enabled(true);
|
||||||
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
|
QDir().mkpath(QFileInfo(fileCompressed).absolutePath());
|
||||||
if (!zip.open(QuaZip::mdCreate)) {
|
if (!zip.open(QuaZip::mdCreate)) {
|
||||||
QFile::remove(fileCompressed);
|
QFile::remove(fileCompressed);
|
||||||
@ -141,6 +142,7 @@ bool compressDirFiles(QString fileCompressed, QString dir, QFileInfoList files,
|
|||||||
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods)
|
bool createModdedJar(QString sourceJarPath, QString targetJarPath, const QList<Mod*>& mods)
|
||||||
{
|
{
|
||||||
QuaZip zipOut(targetJarPath);
|
QuaZip zipOut(targetJarPath);
|
||||||
|
zipOut.setUtf8Enabled(true);
|
||||||
if (!zipOut.open(QuaZip::mdCreate)) {
|
if (!zipOut.open(QuaZip::mdCreate)) {
|
||||||
QFile::remove(targetJarPath);
|
QFile::remove(targetJarPath);
|
||||||
qCritical() << "Failed to open the minecraft.jar for modding";
|
qCritical() << "Failed to open the minecraft.jar for modding";
|
||||||
@ -286,10 +288,13 @@ std::optional<QStringList> extractSubDir(QuaZip* zip, const QString& subdir, con
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
QString file_name = zip->getCurrentFileName();
|
QString file_name = zip->getCurrentFileName();
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
file_name = FS::RemoveInvalidPathChars(file_name);
|
||||||
|
#endif
|
||||||
if (!file_name.startsWith(subdir))
|
if (!file_name.startsWith(subdir))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto relative_file_name = QDir::fromNativeSeparators(file_name.remove(0, subdir.size()));
|
auto relative_file_name = QDir::fromNativeSeparators(file_name.mid(subdir.size()));
|
||||||
auto original_name = relative_file_name;
|
auto original_name = relative_file_name;
|
||||||
|
|
||||||
// Fix subdirs/files ending with a / getting transformed into absolute paths
|
// Fix subdirs/files ending with a / getting transformed into absolute paths
|
||||||
|
@ -163,6 +163,7 @@ class ExportToZipTask : public Task {
|
|||||||
, m_follow_symlinks(followSymlinks)
|
, m_follow_symlinks(followSymlinks)
|
||||||
{
|
{
|
||||||
setAbortable(true);
|
setAbortable(true);
|
||||||
|
m_output.setUtf8Enabled(true);
|
||||||
};
|
};
|
||||||
ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false)
|
ExportToZipTask(QString outputPath, QString dir, QFileInfoList files, QString destinationPrefix = "", bool followSymlinks = false)
|
||||||
: ExportToZipTask(outputPath, QDir(dir), files, destinationPrefix, followSymlinks){};
|
: ExportToZipTask(outputPath, QDir(dir), files, destinationPrefix, followSymlinks){};
|
||||||
|
@ -55,6 +55,9 @@ void JavaChecker::performCheck()
|
|||||||
qDebug() << "Java checker library could not be found. Please check your installation.";
|
qDebug() << "Java checker library could not be found. Please check your installation.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
checkerJar = FS::getPathNameInLocal8bit(checkerJar);
|
||||||
|
#endif
|
||||||
|
|
||||||
QStringList args;
|
QStringList args;
|
||||||
|
|
||||||
|
@ -413,6 +413,8 @@ QList<QString> JavaUtils::FindJavaPaths()
|
|||||||
scanJavaDirs(FS::PathCombine(home, ".jdks"));
|
scanJavaDirs(FS::PathCombine(home, ".jdks"));
|
||||||
// javas downloaded by sdkman
|
// javas downloaded by sdkman
|
||||||
scanJavaDirs(FS::PathCombine(home, ".sdkman/candidates/java"));
|
scanJavaDirs(FS::PathCombine(home, ".sdkman/candidates/java"));
|
||||||
|
// javas downloaded by gradle (toolchains)
|
||||||
|
scanJavaDirs(FS::PathCombine(home, ".gradle/jdks"));
|
||||||
|
|
||||||
javas.append(getMinecraftJavaBundle());
|
javas.append(getMinecraftJavaBundle());
|
||||||
javas = addJavasFromEnv(javas);
|
javas = addJavasFromEnv(javas);
|
||||||
@ -439,26 +441,25 @@ QString JavaUtils::getJavaCheckPath()
|
|||||||
|
|
||||||
QStringList getMinecraftJavaBundle()
|
QStringList getMinecraftJavaBundle()
|
||||||
{
|
{
|
||||||
QString partialPath;
|
|
||||||
QString executable = "java";
|
QString executable = "java";
|
||||||
QStringList processpaths;
|
QStringList processpaths;
|
||||||
#if defined(Q_OS_OSX)
|
#if defined(Q_OS_OSX)
|
||||||
partialPath = FS::PathCombine(QDir::homePath(), "Library/Application Support");
|
processpaths << FS::PathCombine(QDir::homePath(), FS::PathCombine("Library", "Application Support", "minecraft", "runtime"));
|
||||||
#elif defined(Q_OS_WIN32)
|
#elif defined(Q_OS_WIN32)
|
||||||
partialPath = QProcessEnvironment::systemEnvironment().value("LOCALAPPDATA", "");
|
|
||||||
executable += "w.exe";
|
executable += "w.exe";
|
||||||
|
|
||||||
|
auto appDataPath = QProcessEnvironment::systemEnvironment().value("APPDATA", "");
|
||||||
|
processpaths << FS::PathCombine(QFileInfo(appDataPath).absolutePath(), ".minecraft", "runtime");
|
||||||
|
|
||||||
// add the microsoft store version of the launcher to the search. the current path is:
|
// add the microsoft store version of the launcher to the search. the current path is:
|
||||||
// C:\Users\USERNAME\AppData\Local\Packages\Microsoft.4297127D64EC6_8wekyb3d8bbwe\LocalCache\Local\runtime
|
// C:\Users\USERNAME\AppData\Local\Packages\Microsoft.4297127D64EC6_8wekyb3d8bbwe\LocalCache\Local\runtime
|
||||||
|
auto localAppDataPath = QProcessEnvironment::systemEnvironment().value("LOCALAPPDATA", "");
|
||||||
auto minecraftMSStorePath =
|
auto minecraftMSStorePath =
|
||||||
FS::PathCombine(QFileInfo(partialPath).absolutePath(), "Local", "Packages", "Microsoft.4297127D64EC6_8wekyb3d8bbwe");
|
FS::PathCombine(QFileInfo(localAppDataPath).absolutePath(), "Packages", "Microsoft.4297127D64EC6_8wekyb3d8bbwe");
|
||||||
minecraftMSStorePath = FS::PathCombine(minecraftMSStorePath, "LocalCache", "Local", "runtime");
|
processpaths << FS::PathCombine(minecraftMSStorePath, "LocalCache", "Local", "runtime");
|
||||||
processpaths << minecraftMSStorePath;
|
|
||||||
#else
|
#else
|
||||||
partialPath = QDir::homePath();
|
processpaths << FS::PathCombine(QDir::homePath(), ".minecraft", "runtime");
|
||||||
#endif
|
#endif
|
||||||
auto minecraftDataPath = FS::PathCombine(partialPath, ".minecraft", "runtime");
|
|
||||||
processpaths << minecraftDataPath;
|
|
||||||
|
|
||||||
QStringList javas;
|
QStringList javas;
|
||||||
while (!processpaths.isEmpty()) {
|
while (!processpaths.isEmpty()) {
|
||||||
|
@ -705,8 +705,12 @@ QStringList MinecraftInstance::processMinecraftArgs(AuthSessionPtr session, Mine
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serverToJoin && !serverToJoin->address.isEmpty()) {
|
if (serverToJoin && !serverToJoin->address.isEmpty()) {
|
||||||
args_pattern += " --server " + serverToJoin->address;
|
if (profile->hasTrait("feature:is_quick_play_multiplayer")) {
|
||||||
args_pattern += " --port " + QString::number(serverToJoin->port);
|
args_pattern += " --quickPlayMultiplayer " + serverToJoin->address + ':' + QString::number(serverToJoin->port);
|
||||||
|
} else {
|
||||||
|
args_pattern += " --server " + serverToJoin->address;
|
||||||
|
args_pattern += " --port " + QString::number(serverToJoin->port);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QString> token_mapping;
|
QMap<QString, QString> token_mapping;
|
||||||
|
@ -126,7 +126,35 @@ bool XboxAuthorizationStep::processSTSError(QNetworkReply::NetworkError error, Q
|
|||||||
emit finished(
|
emit finished(
|
||||||
AccountTaskState::STATE_FAILED_SOFT,
|
AccountTaskState::STATE_FAILED_SOFT,
|
||||||
tr("This Microsoft account is underaged and is not linked to a family.\n\nPlease set up your account according to %1.")
|
tr("This Microsoft account is underaged and is not linked to a family.\n\nPlease set up your account according to %1.")
|
||||||
.arg("<a href=\"https://help.minecraft.net/hc/en-us/articles/4403181904525\">help.minecraft.net</a>"));
|
.arg("<a href=\"https://help.minecraft.net/hc/en-us/articles/4408968616077\">help.minecraft.net</a>"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// the following codes where copied from: https://github.com/PrismarineJS/prismarine-auth/pull/44
|
||||||
|
case 2148916236: {
|
||||||
|
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
||||||
|
tr("This Microsoft account requires proof of age to play. Please login to %1 to provide proof of age.")
|
||||||
|
.arg("<a href=\"https://login.live.com/login.srf\">login.live.com</a>"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 2148916237:
|
||||||
|
emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("This Microsoft account has reached its limit for playtime. This "
|
||||||
|
"Microsoft account has been blocked from logging in."));
|
||||||
|
return true;
|
||||||
|
case 2148916227: {
|
||||||
|
emit finished(AccountTaskState::STATE_FAILED_SOFT, tr("This Microsoft account was banned by Xbox for violating one or more "
|
||||||
|
"Community Standards for Xbox and is unable to be used."));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 2148916229: {
|
||||||
|
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
||||||
|
tr("This Microsoft account is currently restricted and your guardian has not given you permission to play "
|
||||||
|
"online. Login to %1 and have your guardian change your permissions.")
|
||||||
|
.arg("<a href=\"https://account.microsoft.com/family/\">account.microsoft.com</a>"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case 2148916234: {
|
||||||
|
emit finished(AccountTaskState::STATE_FAILED_SOFT,
|
||||||
|
tr("This Microsoft account has not accepted Xbox's Terms of Service. Please login and accept them."));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -79,6 +79,7 @@ void ExtractNatives::executeTask()
|
|||||||
auto settings = minecraftInstance->settings();
|
auto settings = minecraftInstance->settings();
|
||||||
|
|
||||||
auto outputPath = minecraftInstance->getNativePath();
|
auto outputPath = minecraftInstance->getNativePath();
|
||||||
|
FS::ensureFolderPathExists(outputPath);
|
||||||
auto javaVersion = minecraftInstance->getJavaVersion();
|
auto javaVersion = minecraftInstance->getJavaVersion();
|
||||||
bool jniHackEnabled = javaVersion.major() >= 8;
|
bool jniHackEnabled = javaVersion.major() >= 8;
|
||||||
for (const auto& source : toExtract) {
|
for (const auto& source : toExtract) {
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <launch/LaunchStep.h>
|
#include <launch/LaunchStep.h>
|
||||||
#include <memory>
|
|
||||||
#include "minecraft/auth/AuthSession.h"
|
|
||||||
|
|
||||||
// FIXME: temporary wrapper for existing task.
|
// FIXME: temporary wrapper for existing task.
|
||||||
class ExtractNatives : public LaunchStep {
|
class ExtractNatives : public LaunchStep {
|
||||||
|
@ -66,32 +66,6 @@ LauncherPartLaunch::LauncherPartLaunch(LaunchTask* parent) : LaunchStep(parent)
|
|||||||
connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state);
|
connect(&m_process, &LoggedProcess::stateChanged, this, &LauncherPartLaunch::on_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
// returns 8.3 file format from long path
|
|
||||||
#include <windows.h>
|
|
||||||
QString shortPathName(const QString& file)
|
|
||||||
{
|
|
||||||
auto input = file.toStdWString();
|
|
||||||
std::wstring output;
|
|
||||||
long length = GetShortPathNameW(input.c_str(), NULL, 0);
|
|
||||||
// NOTE: this resizing might seem weird...
|
|
||||||
// when GetShortPathNameW fails, it returns length including null character
|
|
||||||
// when it succeeds, it returns length excluding null character
|
|
||||||
// See: https://msdn.microsoft.com/en-us/library/windows/desktop/aa364989(v=vs.85).aspx
|
|
||||||
output.resize(length);
|
|
||||||
GetShortPathNameW(input.c_str(), (LPWSTR)output.c_str(), length);
|
|
||||||
output.resize(length - 1);
|
|
||||||
QString ret = QString::fromStdWString(output);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// if the string survives roundtrip through local 8bit encoding...
|
|
||||||
bool fitsInLocal8bit(const QString& string)
|
|
||||||
{
|
|
||||||
return string == QString::fromLocal8Bit(string.toLocal8Bit());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LauncherPartLaunch::executeTask()
|
void LauncherPartLaunch::executeTask()
|
||||||
{
|
{
|
||||||
QString jarPath = APPLICATION->getJarPath("NewLaunch.jar");
|
QString jarPath = APPLICATION->getJarPath("NewLaunch.jar");
|
||||||
@ -139,24 +113,15 @@ void LauncherPartLaunch::executeTask()
|
|||||||
|
|
||||||
auto natPath = minecraftInstance->getNativePath();
|
auto natPath = minecraftInstance->getNativePath();
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
if (!fitsInLocal8bit(natPath)) {
|
natPath = FS::getPathNameInLocal8bit(natPath);
|
||||||
args << "-Djava.library.path=" + shortPathName(natPath);
|
|
||||||
} else {
|
|
||||||
args << "-Djava.library.path=" + natPath;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
args << "-Djava.library.path=" + natPath;
|
|
||||||
#endif
|
#endif
|
||||||
|
args << "-Djava.library.path=" + natPath;
|
||||||
|
|
||||||
args << "-cp";
|
args << "-cp";
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
QStringList processed;
|
QStringList processed;
|
||||||
for (auto& item : classPath) {
|
for (auto& item : classPath) {
|
||||||
if (!fitsInLocal8bit(item)) {
|
processed << FS::getPathNameInLocal8bit(item);
|
||||||
processed << shortPathName(item);
|
|
||||||
} else {
|
|
||||||
processed << item;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
args << processed.join(';');
|
args << processed.join(';');
|
||||||
#else
|
#else
|
||||||
|
@ -469,7 +469,7 @@ bool processZIP(Mod& mod, [[maybe_unused]] ProcessingLevel level)
|
|||||||
|
|
||||||
QuaZipFile file(&zip);
|
QuaZipFile file(&zip);
|
||||||
|
|
||||||
if (zip.setCurrentFile("META-INF/mods.toml")) {
|
if (zip.setCurrentFile("META-INF/mods.toml") || zip.setCurrentFile("META-INF/neoforge.mods.toml")) {
|
||||||
if (!file.open(QIODevice::ReadOnly)) {
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
zip.close();
|
zip.close();
|
||||||
return false;
|
return false;
|
||||||
|
@ -393,16 +393,16 @@ QByteArray FlamePackExportTask::generateIndex()
|
|||||||
version["version"] = minecraft->m_version;
|
version["version"] = minecraft->m_version;
|
||||||
QString id;
|
QString id;
|
||||||
if (quilt != nullptr)
|
if (quilt != nullptr)
|
||||||
id = "quilt-" + quilt->getVersion();
|
id = "quilt-" + quilt->m_version;
|
||||||
else if (fabric != nullptr)
|
else if (fabric != nullptr)
|
||||||
id = "fabric-" + fabric->getVersion();
|
id = "fabric-" + fabric->m_version;
|
||||||
else if (forge != nullptr)
|
else if (forge != nullptr)
|
||||||
id = "forge-" + forge->getVersion();
|
id = "forge-" + forge->m_version;
|
||||||
else if (neoforge != nullptr) {
|
else if (neoforge != nullptr) {
|
||||||
id = "neoforge-";
|
id = "neoforge-";
|
||||||
if (minecraft->m_version == "1.20.1")
|
if (minecraft->m_version == "1.20.1")
|
||||||
id += "1.20.1-";
|
id += "1.20.1-";
|
||||||
id += neoforge->getVersion();
|
id += neoforge->m_version;
|
||||||
}
|
}
|
||||||
version["modLoaders"] = QJsonArray();
|
version["modLoaders"] = QJsonArray();
|
||||||
if (!id.isEmpty()) {
|
if (!id.isEmpty()) {
|
||||||
|
@ -43,6 +43,7 @@ Modpack parseDirectory(QString path)
|
|||||||
modpack.version = Json::requireString(root, "version", "version");
|
modpack.version = Json::requireString(root, "version", "version");
|
||||||
modpack.mcVersion = Json::requireString(root, "mcVersion", "mcVersion");
|
modpack.mcVersion = Json::requireString(root, "mcVersion", "mcVersion");
|
||||||
modpack.jvmArgs = Json::ensureVariant(root, "jvmArgs", {}, "jvmArgs");
|
modpack.jvmArgs = Json::ensureVariant(root, "jvmArgs", {}, "jvmArgs");
|
||||||
|
modpack.totalPlayTime = Json::requireInteger(root, "totalPlayTime", "totalPlayTime");
|
||||||
} catch (const Exception& e) {
|
} catch (const Exception& e) {
|
||||||
qDebug() << "Couldn't load ftb instance json: " << e.cause();
|
qDebug() << "Couldn't load ftb instance json: " << e.cause();
|
||||||
return {};
|
return {};
|
||||||
|
@ -36,6 +36,7 @@ struct Modpack {
|
|||||||
QString name;
|
QString name;
|
||||||
QString version;
|
QString version;
|
||||||
QString mcVersion;
|
QString mcVersion;
|
||||||
|
int totalPlayTime;
|
||||||
// not needed for instance creation
|
// not needed for instance creation
|
||||||
QVariant jvmArgs;
|
QVariant jvmArgs;
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ void PackInstallTask::copySettings()
|
|||||||
instanceSettings->suspendSave();
|
instanceSettings->suspendSave();
|
||||||
MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
|
MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
|
||||||
instance.settings()->set("InstanceType", "OneSix");
|
instance.settings()->set("InstanceType", "OneSix");
|
||||||
|
instance.settings()->set("totalTimePlayed", m_pack.totalPlayTime / 1000);
|
||||||
|
|
||||||
if (m_pack.jvmArgs.isValid() && !m_pack.jvmArgs.toString().isEmpty()) {
|
if (m_pack.jvmArgs.isValid() && !m_pack.jvmArgs.toString().isEmpty()) {
|
||||||
instance.settings()->set("OverrideJavaArgs", true);
|
instance.settings()->set("OverrideJavaArgs", true);
|
||||||
|
@ -123,6 +123,10 @@ void ImportPage::updateState()
|
|||||||
// need to find the download link for the modpack
|
// need to find the download link for the modpack
|
||||||
// format of url curseforge://install?addonId=IDHERE&fileId=IDHERE
|
// format of url curseforge://install?addonId=IDHERE&fileId=IDHERE
|
||||||
QUrlQuery query(url);
|
QUrlQuery query(url);
|
||||||
|
if (query.allQueryItemValues("addonId").isEmpty() || query.allQueryItemValues("fileId").isEmpty()) {
|
||||||
|
qDebug() << "Invalid curseforge link:" << url;
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto addonId = query.allQueryItemValues("addonId")[0];
|
auto addonId = query.allQueryItemValues("addonId")[0];
|
||||||
auto fileId = query.allQueryItemValues("fileId")[0];
|
auto fileId = query.allQueryItemValues("fileId")[0];
|
||||||
auto array = std::make_shared<QByteArray>();
|
auto array = std::make_shared<QByteArray>();
|
||||||
@ -200,7 +204,9 @@ void ImportPage::setExtraInfo(const QMap<QString, QString>& extra_info)
|
|||||||
|
|
||||||
void ImportPage::on_modpackBtn_clicked()
|
void ImportPage::on_modpackBtn_clicked()
|
||||||
{
|
{
|
||||||
auto filter = QMimeDatabase().mimeTypeForName("application/zip").filterString();
|
const QMimeType zip = QMimeDatabase().mimeTypeForName("application/zip");
|
||||||
|
auto filter = tr("Supported files") + QString(" (%1 *.mrpack)").arg(zip.globPatterns().join(" "));
|
||||||
|
filter += ";;" + zip.filterString();
|
||||||
//: Option for filtering for *.mrpack files when importing
|
//: Option for filtering for *.mrpack files when importing
|
||||||
filter += ";;" + tr("Modrinth pack") + " (*.mrpack)";
|
filter += ";;" + tr("Modrinth pack") + " (*.mrpack)";
|
||||||
const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), filter);
|
const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Choose modpack"), modpackUrl(), filter);
|
||||||
|
@ -58,10 +58,17 @@ import org.prismlauncher.utils.Parameters;
|
|||||||
import org.prismlauncher.utils.ReflectionUtils;
|
import org.prismlauncher.utils.ReflectionUtils;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class StandardLauncher extends AbstractLauncher {
|
public final class StandardLauncher extends AbstractLauncher {
|
||||||
|
private final boolean quickPlaySupported;
|
||||||
|
|
||||||
public StandardLauncher(Parameters params) {
|
public StandardLauncher(Parameters params) {
|
||||||
super(params);
|
super(params);
|
||||||
|
|
||||||
|
List<String> traits = params.getList("traits", Collections.<String>emptyList());
|
||||||
|
quickPlaySupported = traits.contains("feature:is_quick_play_multiplayer");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -76,10 +83,16 @@ public final class StandardLauncher extends AbstractLauncher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (serverAddress != null) {
|
if (serverAddress != null) {
|
||||||
gameArgs.add("--server");
|
if (quickPlaySupported) {
|
||||||
gameArgs.add(serverAddress);
|
// as of 23w14a
|
||||||
gameArgs.add("--port");
|
gameArgs.add("--quickPlayMultiplayer");
|
||||||
gameArgs.add(serverPort);
|
gameArgs.add(serverAddress + ':' + serverPort);
|
||||||
|
} else {
|
||||||
|
gameArgs.add("--server");
|
||||||
|
gameArgs.add(serverAddress);
|
||||||
|
gameArgs.add("--port");
|
||||||
|
gameArgs.add(serverPort);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// find and invoke the main method
|
// find and invoke the main method
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
openal,
|
openal,
|
||||||
jdk8,
|
jdk8,
|
||||||
jdk17,
|
jdk17,
|
||||||
|
jdk21,
|
||||||
gamemode,
|
gamemode,
|
||||||
flite,
|
flite,
|
||||||
mesa-demos,
|
mesa-demos,
|
||||||
@ -24,7 +25,7 @@
|
|||||||
gamemodeSupport ? stdenv.isLinux,
|
gamemodeSupport ? stdenv.isLinux,
|
||||||
textToSpeechSupport ? stdenv.isLinux,
|
textToSpeechSupport ? stdenv.isLinux,
|
||||||
controllerSupport ? stdenv.isLinux,
|
controllerSupport ? stdenv.isLinux,
|
||||||
jdks ? [jdk17 jdk8],
|
jdks ? [jdk21 jdk17 jdk8],
|
||||||
additionalLibs ? [],
|
additionalLibs ? [],
|
||||||
additionalPrograms ? [],
|
additionalPrograms ? [],
|
||||||
}: let
|
}: let
|
||||||
|
Loading…
Reference in New Issue
Block a user