Skip to content

Commit

Permalink
feat: add shaderpack validation
Browse files Browse the repository at this point in the history
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
  • Loading branch information
Ryex committed Dec 24, 2022
1 parent 878614f commit ebd905e
Show file tree
Hide file tree
Showing 6 changed files with 285 additions and 4 deletions.
39 changes: 39 additions & 0 deletions launcher/minecraft/mod/ShaderPack.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
//
// SPDX-License-Identifier: GPL-3.0-only

/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "ShaderPack.h"

#include "minecraft/mod/tasks/LocalShaderPackParseTask.h"


void ShaderPack::setPackFormat(ShaderPackFormat new_format)
{
QMutexLocker locker(&m_data_lock);


m_pack_format = new_format;
}

bool ShaderPack::valid() const
{
return m_pack_format != ShaderPackFormat::INVALID;
}
63 changes: 63 additions & 0 deletions launcher/minecraft/mod/ShaderPack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
//
// SPDX-License-Identifier: GPL-3.0-only

/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#pragma once

#include "Resource.h"

/* Info:
* Currently For Optifine / Iris shader packs,
* could be expanded to support others should they exsist?
*
* This class and enum are mostly here as placeholders for validating
* that a shaderpack exsists and is in the right format,
* namely that they contain a folder named 'shaders'.
*
* In the technical sense it would be possible to parse files like `shaders/shaders.properties`
* to get information like the availble profiles but this is not all that usefull without more knoledge of the
* shader mod used to be able to change settings
*
*/

#include <QMutex>

enum ShaderPackFormat {
VALID,
INVALID
};

class ShaderPack : public Resource {
Q_OBJECT
public:
using Ptr = shared_qobject_ptr<Resource>;

ShaderPack(QObject* parent = nullptr) : Resource(parent) {}
ShaderPack(QFileInfo file_info) : Resource(file_info) {}

void setPackFormat(ShaderPackFormat new_format);

bool valid() const override;

protected:
mutable QMutex m_data_lock;

ShaderPackFormat m_pack_format = ShaderPackFormat::INVALID;
};
8 changes: 4 additions & 4 deletions launcher/minecraft/mod/tasks/LocalResourcePackParseTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,15 @@ bool processFolder(ResourcePack& pack, ProcessingLevel level)

QFileInfo image_file_info(FS::PathCombine(pack.fileinfo().filePath(), "pack.png"));
if (image_file_info.exists() && image_file_info.isFile()) {
QFile mcmeta_file(image_file_info.filePath());
if (!mcmeta_file.open(QIODevice::ReadOnly))
QFile pack_png_file(image_file_info.filePath());
if (!pack_png_file.open(QIODevice::ReadOnly))
return false; // can't open pack.png file

auto data = mcmeta_file.readAll();
auto data = pack_png_file.readAll();

bool pack_png_result = ResourcePackUtils::processPackPNG(pack, std::move(data));

mcmeta_file.close();
pack_png_file.close();
if (!pack_png_result) {
return false; // pack.png invalid
}
Expand Down
Empty file.
116 changes: 116 additions & 0 deletions launcher/minecraft/mod/tasks/LocalShaderPackParseTask.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
//
// SPDX-License-Identifier: GPL-3.0-only

/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include "LocalShaderPackParseTask.h"

#include "FileSystem.h"

#include <quazip/quazip.h>
#include <quazip/quazipfile.h>
#include <quazip/quazipdir.h>

namespace ShaderPackUtils {

bool process(ShaderPack& pack, ProcessingLevel level)
{
switch (pack.type()) {
case ResourceType::FOLDER:
return ShaderPackUtils::processFolder(pack, level);
case ResourceType::ZIPFILE:
return ShaderPackUtils::processZIP(pack, level);
default:
qWarning() << "Invalid type for shader pack parse task!";
return false;
}
}

bool processFolder(ShaderPack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::FOLDER);

QFileInfo assets_dir_info(FS::PathCombine(pack.fileinfo().filePath(), "shaders"));
if (!assets_dir_info.exists() || !assets_dir_info.isDir()) {
return false; // assets dir does not exists or isn't valid
}
pack.setPackFormat(ShaderPackFormat::VALID);

if (level == ProcessingLevel::BasicInfoOnly) {
return true; // only need basic info already checked
}

return true; // all tests passed
}

bool processZIP(ShaderPack& pack, ProcessingLevel level)
{
Q_ASSERT(pack.type() == ResourceType::ZIPFILE);

QuaZip zip(pack.fileinfo().filePath());
if (!zip.open(QuaZip::mdUnzip))
return false; // can't open zip file

QuaZipFile file(&zip);

QuaZipDir zipDir(&zip);
if (!zipDir.exists("/shaders")) {
return false; // assets dir does not exists at zip root
}
pack.setPackFormat(ShaderPackFormat::VALID);

if (level == ProcessingLevel::BasicInfoOnly) {
zip.close();
return true; // only need basic info already checked
}

zip.close();

return true;
}


bool validate(QFileInfo file)
{
ShaderPack rp{ file };
return ShaderPackUtils::process(rp, ProcessingLevel::BasicInfoOnly) && rp.valid();
}

} // namespace ShaderPackUtils

LocalShaderPackParseTask::LocalShaderPackParseTask(int token, ShaderPack& sp)
: Task(nullptr, false), m_token(token), m_shader_pack(sp)
{}

bool LocalShaderPackParseTask::abort()
{
m_aborted = true;
return true;
}

void LocalShaderPackParseTask::executeTask()
{
if (!ShaderPackUtils::process(m_shader_pack))
return;

if (m_aborted)
emitAborted();
else
emitSucceeded();
}
63 changes: 63 additions & 0 deletions launcher/minecraft/mod/tasks/LocalShaderPackParseTask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-FileCopyrightText: 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
//
// SPDX-License-Identifier: GPL-3.0-only

/*
* Prism Launcher - Minecraft Launcher
* Copyright (C) 2022 Rachel Powers <508861+Ryex@users.noreply.github.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/


#pragma once

#include <QDebug>
#include <QObject>

#include "minecraft/mod/ShaderPack.h"

#include "tasks/Task.h"

namespace ShaderPackUtils {

enum class ProcessingLevel { Full, BasicInfoOnly };

bool process(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);

bool processZIP(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);
bool processFolder(ShaderPack& pack, ProcessingLevel level = ProcessingLevel::Full);

/** Checks whether a file is valid as a resource pack or not. */
bool validate(QFileInfo file);
} // namespace ShaderPackUtils

class LocalShaderPackParseTask : public Task {
Q_OBJECT
public:
LocalShaderPackParseTask(int token, ShaderPack& rp);

[[nodiscard]] bool canAbort() const override { return true; }
bool abort() override;

void executeTask() override;

[[nodiscard]] int token() const { return m_token; }

private:
int m_token;

ShaderPack& m_shader_pack;

bool m_aborted = false;
};

0 comments on commit ebd905e

Please sign in to comment.