/* SPDX-FileCopyrightText: 2026 Project Tick * SPDX-FileContributor: Project Tick * SPDX-License-Identifier: GPL-3.0-or-later * * MeshMC - A Custom Launcher for Minecraft * Copyright (C) 2026 Project Tick * * 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, either version 3 of the License, or * (at your option) any later version. * * 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 . */ #include "CatPack.h" #include "Exception.h" #include #include #include #include #include #include // ===================== BasicCatPack ===================== BasicCatPack::BasicCatPack(const QString& id, const QString& name) : m_id(id), m_name(name) { } QString BasicCatPack::id() { return m_id; } QString BasicCatPack::name() { return m_name; } QString BasicCatPack::path() { QDate now = QDate::currentDate(); int month = now.month(); int day = now.day(); // Christmas: Dec 21 - Dec 29 if ((month == 12 && day >= 21 && day <= 29)) return QString(":/backgrounds/%1-xmas").arg(m_id); // Spooky: Oct 27 - Nov 2 if ((month == 10 && day >= 27) || (month == 11 && day <= 2)) return QString(":/backgrounds/%1-spooky").arg(m_id); // Birthday: Oct 28 - Nov 5 if ((month == 10 && day >= 28) || (month == 11 && day <= 5)) return QString(":/backgrounds/%1-bday").arg(m_id); return QString(":/backgrounds/%1").arg(m_id); } // ===================== FileCatPack ===================== FileCatPack::FileCatPack(const QFileInfo& fileInfo) : m_fileInfo(fileInfo) {} QString FileCatPack::id() { return m_fileInfo.baseName(); } QString FileCatPack::name() { return m_fileInfo.baseName(); } QString FileCatPack::path() { return m_fileInfo.absoluteFilePath(); } // ===================== JsonCatPack ===================== JsonCatPack::JsonCatPack(const QFileInfo& manifestInfo) { QFile file(manifestInfo.absoluteFilePath()); if (!file.open(QFile::ReadOnly)) throw Exception(QString("Could not open catpack manifest: %1") .arg(manifestInfo.absoluteFilePath())); QJsonParseError parseError; auto doc = QJsonDocument::fromJson(file.readAll(), &parseError); if (parseError.error != QJsonParseError::NoError) throw Exception(QString("catpack.json parse error: %1") .arg(parseError.errorString())); auto root = doc.object(); m_id = manifestInfo.dir().dirName(); m_name = root.value("name").toString(m_id); m_defaultPath = QDir(manifestInfo.absolutePath()) .absoluteFilePath(root.value("default").toString()); auto variants = root.value("variants").toArray(); for (const auto& val : variants) { auto obj = val.toObject(); JsonCatPackVariant v; v.path = QDir(manifestInfo.absolutePath()) .absoluteFilePath(obj.value("path").toString()); auto startObj = obj.value("startTime").toObject(); v.startMonth = startObj.value("month").toInt(); v.startDay = startObj.value("day").toInt(); auto endObj = obj.value("endTime").toObject(); v.endMonth = endObj.value("month").toInt(); v.endDay = endObj.value("day").toInt(); m_variants.append(v); } } QString JsonCatPack::id() { return m_id; } QString JsonCatPack::name() { return m_name; } QString JsonCatPack::path() { QDate now = QDate::currentDate(); for (const auto& v : m_variants) { bool inRange = false; if (v.startMonth <= v.endMonth) { // Same year range: e.g., Mar 1 - Jun 30 QDate start(now.year(), v.startMonth, v.startDay); QDate end(now.year(), v.endMonth, v.endDay); inRange = (now >= start && now <= end); } else { // Wraps around year boundary: e.g., Dec 20 - Jan 5 QDate startThisYear(now.year(), v.startMonth, v.startDay); QDate endNextYear(now.year() + 1, v.endMonth, v.endDay); QDate startLastYear(now.year() - 1, v.startMonth, v.startDay); QDate endThisYear(now.year(), v.endMonth, v.endDay); inRange = (now >= startThisYear && now <= endNextYear) || (now >= startLastYear && now <= endThisYear); } if (inRange) return v.path; } return m_defaultPath; }