Replaced tomlc99 with tomlplusplus

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97 2022-09-24 00:06:36 +03:00
parent c6bcb6228b
commit 600c49f7f0
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
13 changed files with 194 additions and 2989 deletions

4
.gitmodules vendored
View File

@ -6,3 +6,7 @@
[submodule "libraries/quazip"]
path = libraries/quazip
url = https://github.com/stachenov/quazip.git
[submodule "libraries/tomlplusplus"]
path = libraries/tomlplusplus
url = https://github.com/marzer/tomlplusplus.git
shallow = true

View File

@ -312,7 +312,7 @@ endif()
add_subdirectory(libraries/rainbow) # Qt extension for colors
add_subdirectory(libraries/LocalPeer) # fork of a library from Qt solutions
add_subdirectory(libraries/classparser) # class parser library
add_subdirectory(libraries/tomlc99) # toml parser
add_subdirectory(libraries/tomlplusplus) # toml parser
add_subdirectory(libraries/katabasis) # An OAuth2 library that tried to do too much
add_subdirectory(libraries/gamemode)
add_subdirectory(libraries/murmur2) # Hash for usage with the CurseForge API

View File

@ -315,30 +315,24 @@
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## tomlc99
## tomlplusplus
MIT License
Copyright (c) 2017 CK Tan
https://github.com/cktan/tomlc99
Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
## O2 (Katabasis fork)

View File

@ -965,7 +965,7 @@ target_link_libraries(Launcher_logic
Launcher_murmur2
nbt++
${ZLIB_LIBRARIES}
tomlc99
tomlplusplus::tomlplusplus
BuildConfig
Katabasis
Qt${QT_VERSION_MAJOR}::Widgets

View File

@ -1,17 +1,17 @@
#include "LocalModParseTask.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
#include <QString>
#include <quazip/quazip.h>
#include <quazip/quazipfile.h>
#include <toml.h>
#include <toml++/toml.h>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QString>
#include "FileSystem.h"
#include "Json.h"
#include "settings/INIFile.h"
#include "FileSystem.h"
namespace {
@ -22,8 +22,7 @@ namespace {
// https://github.com/MinecraftForge/FML/wiki/FML-mod-information-file/5bf6a2d05145ec79387acc0d45c958642fb049fc
ModDetails ReadMCModInfo(QByteArray contents)
{
auto getInfoFromArray = [&](QJsonArray arr) -> ModDetails
{
auto getInfoFromArray = [&](QJsonArray arr) -> ModDetails {
if (!arr.at(0).isObject()) {
return {};
}
@ -32,16 +31,14 @@ ModDetails ReadMCModInfo(QByteArray contents)
details.mod_id = firstObj.value("modid").toString();
auto name = firstObj.value("name").toString();
// NOTE: ignore stupid example mods copies where the author didn't even bother to change the name
if(name != "Example Mod") {
if (name != "Example Mod") {
details.name = name;
}
details.version = firstObj.value("version").toString();
auto homeurl = firstObj.value("url").toString().trimmed();
if(!homeurl.isEmpty())
{
if (!homeurl.isEmpty()) {
// fix up url.
if (!homeurl.startsWith("http://") && !homeurl.startsWith("https://") && !homeurl.startsWith("ftp://"))
{
if (!homeurl.startsWith("http://") && !homeurl.startsWith("https://") && !homeurl.startsWith("ftp://")) {
homeurl.prepend("http://");
}
}
@ -53,8 +50,7 @@ ModDetails ReadMCModInfo(QByteArray contents)
authors = firstObj.value("authors").toArray();
}
for (auto author: authors)
{
for (auto author : authors) {
details.authors.append(author.toString());
}
return details;
@ -62,14 +58,11 @@ ModDetails ReadMCModInfo(QByteArray contents)
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
// this is the very old format that had just the array
if (jsonDoc.isArray())
{
if (jsonDoc.isArray()) {
return getInfoFromArray(jsonDoc.array());
}
else if (jsonDoc.isObject())
{
} else if (jsonDoc.isObject()) {
auto val = jsonDoc.object().value("modinfoversion");
if(val.isUndefined()) {
if (val.isUndefined()) {
val = jsonDoc.object().value("modListVersion");
}
@ -79,18 +72,16 @@ ModDetails ReadMCModInfo(QByteArray contents)
if (version < 0)
version = Json::ensureString(val, "").toInt();
if (version != 2)
{
if (version != 2) {
qCritical() << "BAD stuff happened to mod json:";
qCritical() << contents;
return {};
}
auto arrVal = jsonDoc.object().value("modlist");
if(arrVal.isUndefined()) {
if (arrVal.isUndefined()) {
arrVal = jsonDoc.object().value("modList");
}
if (arrVal.isArray())
{
if (arrVal.isArray()) {
return getInfoFromArray(arrVal.toArray());
}
}
@ -102,109 +93,77 @@ ModDetails ReadMCModTOML(QByteArray contents)
{
ModDetails details;
char errbuf[200];
// top-level table
toml_table_t* tomlData = toml_parse(contents.data(), errbuf, sizeof(errbuf));
if(!tomlData)
{
// auto tomlData = toml::parse(contents.toStdString());
toml::table tomlData;
#if TOML_EXCEPTIONS
try {
tomlData = toml::parse(contents.toStdString());
} catch (const toml::parse_error& err) {
return {};
}
#else
tomlData = toml::parse(contents.toStdString());
if (!tomlData) {
return {};
}
#endif
// array defined by [[mods]]
toml_array_t* tomlModsArr = toml_array_in(tomlData, "mods");
if(!tomlModsArr)
{
auto tomlModsArr = tomlData["mods"].as_array();
if (!tomlModsArr) {
qWarning() << "Corrupted mods.toml? Couldn't find [[mods]] array!";
return {};
}
// we only really care about the first element, since multiple mods in one file is not supported by us at the moment
toml_table_t* tomlModsTable0 = toml_table_at(tomlModsArr, 0);
if(!tomlModsTable0)
{
auto tomlModsTable0 = tomlModsArr->get(0);
if (!tomlModsTable0) {
qWarning() << "Corrupted mods.toml? [[mods]] didn't have an element at index 0!";
return {};
}
auto modsTable = tomlModsTable0->as_table();
if (!tomlModsTable0) {
qWarning() << "Corrupted mods.toml? [[mods]] was not a table!";
return {};
}
// mandatory properties - always in [[mods]]
toml_datum_t modIdDatum = toml_string_in(tomlModsTable0, "modId");
if(modIdDatum.ok)
{
details.mod_id = modIdDatum.u.s;
// library says this is required for strings
free(modIdDatum.u.s);
if (auto modIdDatum = (*modsTable)["modId"].as_string()) {
details.mod_id = QString::fromStdString(modIdDatum->get());
}
toml_datum_t versionDatum = toml_string_in(tomlModsTable0, "version");
if(versionDatum.ok)
{
details.version = versionDatum.u.s;
free(versionDatum.u.s);
if (auto versionDatum = (*modsTable)["version"].as_string()) {
details.version = QString::fromStdString(versionDatum->get());
}
toml_datum_t displayNameDatum = toml_string_in(tomlModsTable0, "displayName");
if(displayNameDatum.ok)
{
details.name = displayNameDatum.u.s;
free(displayNameDatum.u.s);
if (auto displayNameDatum = (*modsTable)["displayName"].as_string()) {
details.name = QString::fromStdString(displayNameDatum->get());
}
toml_datum_t descriptionDatum = toml_string_in(tomlModsTable0, "description");
if(descriptionDatum.ok)
{
details.description = descriptionDatum.u.s;
free(descriptionDatum.u.s);
if (auto descriptionDatum = (*modsTable)["description"].as_string()) {
details.description = QString::fromStdString(descriptionDatum->get());
}
// optional properties - can be in the root table or [[mods]]
toml_datum_t authorsDatum = toml_string_in(tomlData, "authors");
QString authors = "";
if(authorsDatum.ok)
{
authors = authorsDatum.u.s;
free(authorsDatum.u.s);
if (auto authorsDatum = tomlData["authors"].as_string()) {
authors = QString::fromStdString(authorsDatum->get());
} else if (auto authorsDatum = (*modsTable)["authors"].as_string()) {
authors = QString::fromStdString(authorsDatum->get());
}
else
{
authorsDatum = toml_string_in(tomlModsTable0, "authors");
if(authorsDatum.ok)
{
authors = authorsDatum.u.s;
free(authorsDatum.u.s);
}
}
if(!authors.isEmpty())
{
if (!authors.isEmpty()) {
details.authors.append(authors);
}
toml_datum_t homeurlDatum = toml_string_in(tomlData, "displayURL");
QString homeurl = "";
if(homeurlDatum.ok)
{
homeurl = homeurlDatum.u.s;
free(homeurlDatum.u.s);
if (auto homeurlDatum = tomlData["displayURL"].as_string()) {
homeurl = QString::fromStdString(homeurlDatum->get());
} else if (auto homeurlDatum = (*modsTable)["displayURL"].as_string()) {
homeurl = QString::fromStdString(homeurlDatum->get());
}
else
{
homeurlDatum = toml_string_in(tomlModsTable0, "displayURL");
if(homeurlDatum.ok)
{
homeurl = homeurlDatum.u.s;
free(homeurlDatum.u.s);
}
}
if(!homeurl.isEmpty())
{
// fix up url.
if (!homeurl.startsWith("http://") && !homeurl.startsWith("https://") && !homeurl.startsWith("ftp://"))
{
homeurl.prepend("http://");
}
// fix up url.
if (!homeurl.isEmpty() && !homeurl.startsWith("http://") && !homeurl.startsWith("https://") && !homeurl.startsWith("ftp://")) {
homeurl.prepend("http://");
}
details.homeurl = homeurl;
// this seems to be recursive, so it should free everything
toml_free(tomlData);
return details;
}
@ -224,25 +183,20 @@ ModDetails ReadFabricModInfo(QByteArray contents)
details.name = object.contains("name") ? object.value("name").toString() : details.mod_id;
details.description = object.value("description").toString();
if (schemaVersion >= 1)
{
if (schemaVersion >= 1) {
QJsonArray authors = object.value("authors").toArray();
for (auto author: authors)
{
if(author.isObject()) {
for (auto author : authors) {
if (author.isObject()) {
details.authors.append(author.toObject().value("name").toString());
}
else {
} else {
details.authors.append(author.toString());
}
}
if (object.contains("contact"))
{
if (object.contains("contact")) {
QJsonObject contact = object.value("contact").toObject();
if (contact.contains("homepage"))
{
if (contact.contains("homepage")) {
details.homeurl = contact.value("homepage").toString();
}
}
@ -261,8 +215,7 @@ ModDetails ReadQuiltModInfo(QByteArray contents)
ModDetails details;
// https://github.com/QuiltMC/rfcs/blob/be6ba280d785395fefa90a43db48e5bfc1d15eb4/specification/0002-quilt.mod.json.md
if (schemaVersion == 1)
{
if (schemaVersion == 1) {
auto modInfo = Json::requireObject(object.value("quilt_loader"), "Quilt mod info");
details.mod_id = Json::requireString(modInfo.value("id"), "Mod ID");
@ -280,8 +233,7 @@ ModDetails ReadQuiltModInfo(QByteArray contents)
auto modContact = Json::ensureObject(modMetadata.value("contact"));
if (modContact.contains("homepage"))
{
if (modContact.contains("homepage")) {
details.homeurl = Json::requireString(modContact.value("homepage"));
}
}
@ -314,21 +266,17 @@ ModDetails ReadLiteModInfo(QByteArray contents)
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(contents, &jsonError);
auto object = jsonDoc.object();
if (object.contains("name"))
{
if (object.contains("name")) {
details.mod_id = details.name = object.value("name").toString();
}
if (object.contains("version"))
{
if (object.contains("version")) {
details.version = object.value("version").toString("");
}
else
{
} else {
details.version = object.value("revision").toString("");
}
details.mcversion = object.value("mcversion").toString();
auto author = object.value("author").toString();
if(!author.isEmpty()) {
if (!author.isEmpty()) {
details.authors.append(author);
}
details.description = object.value("description").toString();
@ -336,14 +284,10 @@ ModDetails ReadLiteModInfo(QByteArray contents)
return details;
}
}
} // namespace
LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile):
Task(nullptr, false),
m_token(token),
m_type(type),
m_modFile(modFile),
m_result(new Result())
LocalModParseTask::LocalModParseTask(int token, ResourceType type, const QFileInfo& modFile)
: Task(nullptr, false), m_token(token), m_type(type), m_modFile(modFile), m_result(new Result())
{}
void LocalModParseTask::processAsZip()
@ -354,10 +298,8 @@ void LocalModParseTask::processAsZip()
QuaZipFile file(&zip);
if (zip.setCurrentFile("META-INF/mods.toml"))
{
if (!file.open(QIODevice::ReadOnly))
{
if (zip.setCurrentFile("META-INF/mods.toml")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
return;
}
@ -366,12 +308,9 @@ void LocalModParseTask::processAsZip()
file.close();
// to replace ${file.jarVersion} with the actual version, as needed
if (m_result->details.version == "${file.jarVersion}")
{
if (zip.setCurrentFile("META-INF/MANIFEST.MF"))
{
if (!file.open(QIODevice::ReadOnly))
{
if (m_result->details.version == "${file.jarVersion}") {
if (zip.setCurrentFile("META-INF/MANIFEST.MF")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
return;
}
@ -379,10 +318,8 @@ void LocalModParseTask::processAsZip()
// quick and dirty line-by-line parser
auto manifestLines = file.readAll().split('\n');
QString manifestVersion = "";
for (auto &line : manifestLines)
{
if (QString(line).startsWith("Implementation-Version: "))
{
for (auto& line : manifestLines) {
if (QString(line).startsWith("Implementation-Version: ")) {
manifestVersion = QString(line).remove("Implementation-Version: ");
break;
}
@ -390,8 +327,7 @@ void LocalModParseTask::processAsZip()
// some mods use ${projectversion} in their build.gradle, causing this mess to show up in MANIFEST.MF
// also keep with forge's behavior of setting the version to "NONE" if none is found
if (manifestVersion.contains("task ':jar' property 'archiveVersion'") || manifestVersion == "")
{
if (manifestVersion.contains("task ':jar' property 'archiveVersion'") || manifestVersion == "") {
manifestVersion = "NONE";
}
@ -403,11 +339,8 @@ void LocalModParseTask::processAsZip()
zip.close();
return;
}
else if (zip.setCurrentFile("mcmod.info"))
{
if (!file.open(QIODevice::ReadOnly))
{
} else if (zip.setCurrentFile("mcmod.info")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
return;
}
@ -416,11 +349,8 @@ void LocalModParseTask::processAsZip()
file.close();
zip.close();
return;
}
else if (zip.setCurrentFile("quilt.mod.json"))
{
if (!file.open(QIODevice::ReadOnly))
{
} else if (zip.setCurrentFile("quilt.mod.json")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
return;
}
@ -429,11 +359,8 @@ void LocalModParseTask::processAsZip()
file.close();
zip.close();
return;
}
else if (zip.setCurrentFile("fabric.mod.json"))
{
if (!file.open(QIODevice::ReadOnly))
{
} else if (zip.setCurrentFile("fabric.mod.json")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
return;
}
@ -442,11 +369,8 @@ void LocalModParseTask::processAsZip()
file.close();
zip.close();
return;
}
else if (zip.setCurrentFile("forgeversion.properties"))
{
if (!file.open(QIODevice::ReadOnly))
{
} else if (zip.setCurrentFile("forgeversion.properties")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
return;
}
@ -463,8 +387,7 @@ void LocalModParseTask::processAsZip()
void LocalModParseTask::processAsFolder()
{
QFileInfo mcmod_info(FS::PathCombine(m_modFile.filePath(), "mcmod.info"));
if (mcmod_info.isFile())
{
if (mcmod_info.isFile()) {
QFile mcmod(mcmod_info.filePath());
if (!mcmod.open(QIODevice::ReadOnly))
return;
@ -483,10 +406,8 @@ void LocalModParseTask::processAsLitemod()
QuaZipFile file(&zip);
if (zip.setCurrentFile("litemod.json"))
{
if (!file.open(QIODevice::ReadOnly))
{
if (zip.setCurrentFile("litemod.json")) {
if (!file.open(QIODevice::ReadOnly)) {
zip.close();
return;
}
@ -505,8 +426,7 @@ bool LocalModParseTask::abort()
void LocalModParseTask::executeTask()
{
switch(m_type)
{
switch (m_type) {
case ResourceType::ZIPFILE:
processAsZip();
break;

View File

@ -1,20 +1,20 @@
// SPDX-License-Identifier: GPL-3.0-only
/*
* PolyMC - Minecraft Launcher
* Copyright (c) 2022 flowln <flowlnlnln@gmail.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/>.
*/
* PolyMC - Minecraft Launcher
* Copyright (c) 2022 flowln <flowlnlnln@gmail.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 "Packwiz.h"
@ -22,9 +22,7 @@
#include <QDir>
#include <QObject>
#include "toml.h"
#include "FileSystem.h"
#include <toml++/toml.h>
#include "minecraft/mod/Mod.h"
#include "modplatform/ModIndex.h"
@ -44,7 +42,7 @@ auto getRealIndexName(QDir& index_dir, QString normalized_fname, bool should_fin
}
}
if(should_find_match && !QString::compare(normalized_fname, real_fname, Qt::CaseSensitive)){
if (should_find_match && !QString::compare(normalized_fname, real_fname, Qt::CaseSensitive)) {
qCritical() << "Could not find a match for a valid metadata file!";
qCritical() << "File: " << normalized_fname;
return {};
@ -57,7 +55,7 @@ auto getRealIndexName(QDir& index_dir, QString normalized_fname, bool should_fin
// Helpers
static inline auto indexFileName(QString const& mod_slug) -> QString
{
if(mod_slug.endsWith(".pw.toml"))
if (mod_slug.endsWith(".pw.toml"))
return mod_slug;
return QString("%1.pw.toml").arg(mod_slug);
}
@ -65,32 +63,28 @@ static inline auto indexFileName(QString const& mod_slug) -> QString
static ModPlatform::ProviderCapabilities ProviderCaps;
// Helper functions for extracting data from the TOML file
auto stringEntry(toml_table_t* parent, const char* entry_name) -> QString
auto stringEntry(toml::table table, const std::string entry_name) -> QString
{
toml_datum_t var = toml_string_in(parent, entry_name);
if (!var.ok) {
qCritical() << QString("Failed to read str property '%1' in mod metadata.").arg(entry_name);
auto node = table[entry_name];
if (!node) {
qCritical() << QString::fromStdString("Failed to read str property '" + entry_name + "' in mod metadata.");
return {};
}
QString tmp = var.u.s;
free(var.u.s);
return tmp;
return QString::fromStdString(node.value_or(""));
}
auto intEntry(toml_table_t* parent, const char* entry_name) -> int
auto intEntry(toml::table table, const std::string entry_name) -> int
{
toml_datum_t var = toml_int_in(parent, entry_name);
if (!var.ok) {
qCritical() << QString("Failed to read int property '%1' in mod metadata.").arg(entry_name);
auto node = table[entry_name];
if (!node) {
qCritical() << QString::fromStdString("Failed to read int property '" + entry_name + "' in mod metadata.");
return {};
}
return var.u.i;
return node.value_or(0);
}
auto V1::createModFormat(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, ModPlatform::IndexedVersion& mod_version) -> Mod
{
Mod mod;
@ -99,10 +93,9 @@ auto V1::createModFormat(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, Mo
mod.name = mod_pack.name;
mod.filename = mod_version.fileName;
if(mod_pack.provider == ModPlatform::Provider::FLAME){
if (mod_pack.provider == ModPlatform::Provider::FLAME) {
mod.mode = "metadata:curseforge";
}
else {
} else {
mod.mode = "url";
mod.url = mod_version.downloadUrl;
}
@ -120,8 +113,8 @@ auto V1::createModFormat(QDir& index_dir, ModPlatform::IndexedPack& mod_pack, Mo
auto V1::createModFormat(QDir& index_dir, ::Mod& internal_mod, QString slug) -> Mod
{
// Try getting metadata if it exists
Mod mod { getIndexForMod(index_dir, slug) };
if(mod.isValid())
Mod mod{ getIndexForMod(index_dir, slug) };
if (mod.isValid())
return mod;
qWarning() << QString("Tried to create mod metadata with a Mod without metadata!");
@ -131,7 +124,7 @@ auto V1::createModFormat(QDir& index_dir, ::Mod& internal_mod, QString slug) ->
void V1::updateModIndex(QDir& index_dir, Mod& mod)
{
if(!mod.isValid()){
if (!mod.isValid()) {
qCritical() << QString("Tried to update metadata of an invalid mod!");
return;
}
@ -150,7 +143,9 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod)
// TODO: We should do more stuff here, as the user is likely trying to
// override a file. In this case, check versions and ask the user what
// they want to do!
if (index_file.exists()) { index_file.remove(); }
if (index_file.exists()) {
index_file.remove();
}
if (!index_file.open(QIODevice::ReadWrite)) {
qCritical() << QString("Could not open file %1!").arg(indexFileName(mod.name));
@ -174,15 +169,15 @@ void V1::updateModIndex(QDir& index_dir, Mod& mod)
in_stream << QString("\n[update]\n");
in_stream << QString("[update.%1]\n").arg(ProviderCaps.name(mod.provider));
switch(mod.provider){
case(ModPlatform::Provider::FLAME):
in_stream << QString("file-id = %1\n").arg(mod.file_id.toString());
in_stream << QString("project-id = %1\n").arg(mod.project_id.toString());
break;
case(ModPlatform::Provider::MODRINTH):
addToStream("mod-id", mod.mod_id().toString());
addToStream("version", mod.version().toString());
break;
switch (mod.provider) {
case (ModPlatform::Provider::FLAME):
in_stream << QString("file-id = %1\n").arg(mod.file_id.toString());
in_stream << QString("project-id = %1\n").arg(mod.project_id.toString());
break;
case (ModPlatform::Provider::MODRINTH):
addToStream("mod-id", mod.mod_id().toString());
addToStream("version", mod.version().toString());
break;
}
}
@ -230,27 +225,25 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod
if (real_fname.isEmpty())
return {};
QFile index_file(index_dir.absoluteFilePath(real_fname));
if (!index_file.open(QIODevice::ReadOnly)) {
qWarning() << QString("Failed to open mod metadata for %1").arg(slug);
toml::table table;
#if TOML_EXCEPTIONS
try {
table = toml::parse_file(index_dir.absoluteFilePath(real_fname).toStdString());
} catch (const toml::parse_error& err) {
qWarning() << QString("Could not open file %1!").arg(normalized_fname);
qWarning() << "Reason: " << QString(err.what());
return {};
}
toml_table_t* table = nullptr;
// NOLINTNEXTLINE(modernize-avoid-c-arrays)
char errbuf[200];
auto file_bytearray = index_file.readAll();
table = toml_parse(file_bytearray.data(), errbuf, sizeof(errbuf));
index_file.close();
#else
table = toml::parse_file(index_dir.absoluteFilePath(real_fname).toStdString());
if (!table) {
qWarning() << QString("Could not open file %1!").arg(normalized_fname);
qWarning() << "Reason: " << QString(errbuf);
qWarning() << "Reason: " << QString(table.error().what());
return {};
}
#endif
// index_file.close();
mod.slug = slug;
@ -261,45 +254,42 @@ auto V1::getIndexForMod(QDir& index_dir, QString slug) -> Mod
}
{ // [download] info
toml_table_t* download_table = toml_table_in(table, "download");
auto download_table = table["download"].as_table();
if (!download_table) {
qCritical() << QString("No [download] section found on mod metadata!");
return {};
}
mod.mode = stringEntry(download_table, "mode");
mod.url = stringEntry(download_table, "url");
mod.hash_format = stringEntry(download_table, "hash-format");
mod.hash = stringEntry(download_table, "hash");
mod.mode = stringEntry(*download_table, "mode");
mod.url = stringEntry(*download_table, "url");
mod.hash_format = stringEntry(*download_table, "hash-format");
mod.hash = stringEntry(*download_table, "hash");
}
{ // [update] info
{ // [update] info
using Provider = ModPlatform::Provider;
toml_table_t* update_table = toml_table_in(table, "update");
if (!update_table) {
auto update_table = table["update"];
if (!update_table || !update_table.is_table()) {
qCritical() << QString("No [update] section found on mod metadata!");
return {};
}
toml_table_t* mod_provider_table = nullptr;
if ((mod_provider_table = toml_table_in(update_table, ProviderCaps.name(Provider::FLAME)))) {
toml::table* mod_provider_table = nullptr;
if ((mod_provider_table = update_table[ProviderCaps.name(Provider::FLAME)].as_table())) {
mod.provider = Provider::FLAME;
mod.file_id = intEntry(mod_provider_table, "file-id");
mod.project_id = intEntry(mod_provider_table, "project-id");
} else if ((mod_provider_table = toml_table_in(update_table, ProviderCaps.name(Provider::MODRINTH)))) {
mod.file_id = intEntry(*mod_provider_table, "file-id");
mod.project_id = intEntry(*mod_provider_table, "project-id");
} else if ((mod_provider_table = update_table[ProviderCaps.name(Provider::MODRINTH)].as_table())) {
mod.provider = Provider::MODRINTH;
mod.mod_id() = stringEntry(mod_provider_table, "mod-id");
mod.version() = stringEntry(mod_provider_table, "version");
mod.mod_id() = stringEntry(*mod_provider_table, "mod-id");
mod.version() = stringEntry(*mod_provider_table, "version");
} else {
qCritical() << QString("No mod provider on mod metadata!");
return {};
}
}
toml_free(table);
return mod;
}

View File

@ -44,17 +44,17 @@ Java launcher part for Minecraft.
It:
* Starts a process
* Waits for a launch script on stdin
* Consumes the launch script you feed it
* Proceeds with launch when it gets the `launcher` command
- Starts a process
- Waits for a launch script on stdin
- Consumes the launch script you feed it
- Proceeds with launch when it gets the `launcher` command
This means the process is essentially idle until the final command is sent. You can, for example, attach a profiler before you send it.
A `legacy` and `onesix` launchers are available.
* `legacy` is intended for use with Minecraft versions < 1.6 and is deprecated.
* `onesix` can handle launching any Minecraft version, at the cost of some extra features `legacy` enables (custom window icon and title).
- `legacy` is intended for use with Minecraft versions < 1.6 and is deprecated.
- `onesix` can handle launching any Minecraft version, at the cost of some extra features `legacy` enables (custom window icon and title).
Example (some parts have been censored):
@ -177,11 +177,11 @@ A PolyMC-specific library for probing system information.
Apache 2.0
## tomlc99
## tomlplusplus
A TOML language parser. Used by Forge 1.14+ to store mod metadata.
See [github repo](https://github.com/cktan/tomlc99).
See [github repo](https://github.com/marzer/tomlplusplus).
Licenced under the MIT licence.

View File

@ -1,10 +0,0 @@
project(tomlc99)
set(tomlc99_SOURCES
include/toml.h
src/toml.c
)
add_library(tomlc99 STATIC ${tomlc99_SOURCES})
target_include_directories(tomlc99 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

View File

@ -1,22 +0,0 @@
MIT License
Copyright (c) 2017 CK Tan
https://github.com/cktan/tomlc99
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,197 +0,0 @@
# tomlc99
TOML in c99; v1.0 compliant.
If you are looking for a C++ library, you might try this wrapper: [https://github.com/cktan/tomlcpp](https://github.com/cktan/tomlcpp).
* Compatible with [TOML v1.0.0](https://toml.io/en/v1.0.0).
* Tested with multiple test suites, including
[BurntSushi/toml-test](https://github.com/BurntSushi/toml-test) and
[iarna/toml-spec-tests](https://github.com/iarna/toml-spec-tests).
* Provides very simple and intuitive interface.
## Usage
Please see the `toml.h` file for details. What follows is a simple example that
parses this config file:
```toml
[server]
host = "www.example.com"
port = [ 8080, 8181, 8282 ]
```
The steps for getting values from our file is usually :
1. Parse the TOML file.
2. Traverse and locate a table in TOML.
3. Extract values from the table.
4. Free up allocated memory.
Below is an example of parsing the values from the example table.
```c
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include "toml.h"
static void error(const char* msg, const char* msg1)
{
fprintf(stderr, "ERROR: %s%s\n", msg, msg1?msg1:"");
exit(1);
}
int main()
{
FILE* fp;
char errbuf[200];
// 1. Read and parse toml file
fp = fopen("sample.toml", "r");
if (!fp) {
error("cannot open sample.toml - ", strerror(errno));
}
toml_table_t* conf = toml_parse_file(fp, errbuf, sizeof(errbuf));
fclose(fp);
if (!conf) {
error("cannot parse - ", errbuf);
}
// 2. Traverse to a table.
toml_table_t* server = toml_table_in(conf, "server");
if (!server) {
error("missing [server]", "");
}
// 3. Extract values
toml_datum_t host = toml_string_in(server, "host");
if (!host.ok) {
error("cannot read server.host", "");
}
toml_array_t* portarray = toml_array_in(server, "port");
if (!portarray) {
error("cannot read server.port", "");
}
printf("host: %s\n", host.u.s);
printf("port: ");
for (int i = 0; ; i++) {
toml_datum_t port = toml_int_at(portarray, i);
if (!port.ok) break;
printf("%d ", (int)port.u.i);
}
printf("\n");
// 4. Free memory
free(host.u.s);
toml_free(conf);
return 0;
}
```
### Accessing Table Content
TOML tables are dictionaries where lookups are done using string keys. In
general, all access functions on tables are named `toml_*_in(...)`.
In the normal case, you know the key and its content type, and retrievals can be done
using one of these functions:
```c
toml_string_in(tab, key);
toml_bool_in(tab, key);
toml_int_in(tab, key);
toml_double_in(tab, key);
toml_timestamp_in(tab, key);
toml_table_in(tab, key);
toml_array_in(tab, key);
```
You can also interrogate the keys in a table using an integer index:
```c
toml_table_t* tab = toml_parse_file(...);
for (int i = 0; ; i++) {
const char* key = toml_key_in(tab, i);
if (!key) break;
printf("key %d: %s\n", i, key);
}
```
### Accessing Array Content
TOML arrays can be deref-ed using integer indices. In general, all access methods on arrays are named `toml_*_at()`.
To obtain the size of an array:
```c
int size = toml_array_nelem(arr);
```
To obtain the content of an array, use a valid index and call one of these functions:
```c
toml_string_at(arr, idx);
toml_bool_at(arr, idx);
toml_int_at(arr, idx);
toml_double_at(arr, idx);
toml_timestamp_at(arr, idx);
toml_table_at(arr, idx);
toml_array_at(arr, idx);
```
### toml_datum_t
Some `toml_*_at` and `toml_*_in` functions return a toml_datum_t
structure. The `ok` flag in the structure indicates if the function
call was successful. If so, you may proceed to read the value
corresponding to the type of the content.
For example:
```c
toml_datum_t host = toml_string_in(tab, "host");
if (host.ok) {
printf("host: %s\n", host.u.s);
free(host.u.s); /* FREE applies to string and timestamp types only */
}
```
**IMPORTANT: if the accessed value is a string or a timestamp, you must call `free(datum.u.s)` or `free(datum.u.ts)` respectively after usage.**
## Building and installing
A normal *make* suffices. You can also simply include the
`toml.c` and `toml.h` files in your project.
Invoking `make install` will install the header and library files into
/usr/local/{include,lib}.
Alternatively, specify `make install prefix=/a/file/path` to install into
/a/file/path/{include,lib}.
## Testing
To test against the standard test set provided by BurntSushi/toml-test:
```sh
% make
% cd test1
% bash build.sh # do this once
% bash run.sh # this will run the test suite
```
To test against the standard test set provided by iarna/toml:
```sh
% make
% cd test2
% bash build.sh # do this once
% bash run.sh # this will run the test suite
```

View File

@ -1,175 +0,0 @@
/*
MIT License
Copyright (c) 2017 - 2019 CK Tan
https://github.com/cktan/tomlc99
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#ifndef TOML_H
#define TOML_H
#include <stdio.h>
#include <stdint.h>
#ifdef __cplusplus
#define TOML_EXTERN extern "C"
#else
#define TOML_EXTERN extern
#endif
typedef struct toml_timestamp_t toml_timestamp_t;
typedef struct toml_table_t toml_table_t;
typedef struct toml_array_t toml_array_t;
typedef struct toml_datum_t toml_datum_t;
/* Parse a file. Return a table on success, or 0 otherwise.
* Caller must toml_free(the-return-value) after use.
*/
TOML_EXTERN toml_table_t* toml_parse_file(FILE* fp,
char* errbuf,
int errbufsz);
/* Parse a string containing the full config.
* Return a table on success, or 0 otherwise.
* Caller must toml_free(the-return-value) after use.
*/
TOML_EXTERN toml_table_t* toml_parse(char* conf, /* NUL terminated, please. */
char* errbuf,
int errbufsz);
/* Free the table returned by toml_parse() or toml_parse_file(). Once
* this function is called, any handles accessed through this tab
* directly or indirectly are no longer valid.
*/
TOML_EXTERN void toml_free(toml_table_t* tab);
/* Timestamp types. The year, month, day, hour, minute, second, z
* fields may be NULL if they are not relevant. e.g. In a DATE
* type, the hour, minute, second and z fields will be NULLs.
*/
struct toml_timestamp_t {
struct { /* internal. do not use. */
int year, month, day;
int hour, minute, second, millisec;
char z[10];
} __buffer;
int *year, *month, *day;
int *hour, *minute, *second, *millisec;
char* z;
};
/*-----------------------------------------------------------------
* Enhanced access methods
*/
struct toml_datum_t {
int ok;
union {
toml_timestamp_t* ts; /* ts must be freed after use */
char* s; /* string value. s must be freed after use */
int b; /* bool value */
int64_t i; /* int value */
double d; /* double value */
} u;
};
/* on arrays: */
/* ... retrieve size of array. */
TOML_EXTERN int toml_array_nelem(const toml_array_t* arr);
/* ... retrieve values using index. */
TOML_EXTERN toml_datum_t toml_string_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_datum_t toml_bool_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_datum_t toml_int_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_datum_t toml_double_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_datum_t toml_timestamp_at(const toml_array_t* arr, int idx);
/* ... retrieve array or table using index. */
TOML_EXTERN toml_array_t* toml_array_at(const toml_array_t* arr, int idx);
TOML_EXTERN toml_table_t* toml_table_at(const toml_array_t* arr, int idx);
/* on tables: */
/* ... retrieve the key in table at keyidx. Return 0 if out of range. */
TOML_EXTERN const char* toml_key_in(const toml_table_t* tab, int keyidx);
/* ... retrieve values using key. */
TOML_EXTERN toml_datum_t toml_string_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_datum_t toml_bool_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_datum_t toml_int_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_datum_t toml_double_in(const toml_table_t* arr, const char* key);
TOML_EXTERN toml_datum_t toml_timestamp_in(const toml_table_t* arr, const char* key);
/* .. retrieve array or table using key. */
TOML_EXTERN toml_array_t* toml_array_in(const toml_table_t* tab,
const char* key);
TOML_EXTERN toml_table_t* toml_table_in(const toml_table_t* tab,
const char* key);
/*-----------------------------------------------------------------
* lesser used
*/
/* Return the array kind: 't'able, 'a'rray, 'v'alue, 'm'ixed */
TOML_EXTERN char toml_array_kind(const toml_array_t* arr);
/* For array kind 'v'alue, return the type of values
i:int, d:double, b:bool, s:string, t:time, D:date, T:timestamp, 'm'ixed
0 if unknown
*/
TOML_EXTERN char toml_array_type(const toml_array_t* arr);
/* Return the key of an array */
TOML_EXTERN const char* toml_array_key(const toml_array_t* arr);
/* Return the number of key-values in a table */
TOML_EXTERN int toml_table_nkval(const toml_table_t* tab);
/* Return the number of arrays in a table */
TOML_EXTERN int toml_table_narr(const toml_table_t* tab);
/* Return the number of sub-tables in a table */
TOML_EXTERN int toml_table_ntab(const toml_table_t* tab);
/* Return the key of a table*/
TOML_EXTERN const char* toml_table_key(const toml_table_t* tab);
/*--------------------------------------------------------------
* misc
*/
TOML_EXTERN int toml_utf8_to_ucs(const char* orig, int len, int64_t* ret);
TOML_EXTERN int toml_ucs_to_utf8(int64_t code, char buf[6]);
TOML_EXTERN void toml_set_memutil(void* (*xxmalloc)(size_t),
void (*xxfree)(void*));
/*--------------------------------------------------------------
* deprecated
*/
/* A raw value, must be processed by toml_rto* before using. */
typedef const char* toml_raw_t;
TOML_EXTERN toml_raw_t toml_raw_in(const toml_table_t* tab, const char* key);
TOML_EXTERN toml_raw_t toml_raw_at(const toml_array_t* arr, int idx);
TOML_EXTERN int toml_rtos(toml_raw_t s, char** ret);
TOML_EXTERN int toml_rtob(toml_raw_t s, int* ret);
TOML_EXTERN int toml_rtoi(toml_raw_t s, int64_t* ret);
TOML_EXTERN int toml_rtod(toml_raw_t s, double* ret);
TOML_EXTERN int toml_rtod_ex(toml_raw_t s, double* ret, char* buf, int buflen);
TOML_EXTERN int toml_rtots(toml_raw_t s, toml_timestamp_t* ret);
#endif /* TOML_H */

File diff suppressed because it is too large Load Diff

@ -0,0 +1 @@
Subproject commit fb8ce80350bcde1d109e9b4d7a571bbc2f29a8bd