From ff995ee5184a0faec3b42fe75a3e8eb122a7f7fe Mon Sep 17 00:00:00 2001 From: galeon Date: Tue, 23 Sep 2025 10:20:04 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9F=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=B5=D1=80=D0=B2=D0=BE=D0=B9=20=D0=B2=D0=B5?= =?UTF-8?q?=D1=80=D1=81=D0=B8=D0=B8,=20=D0=BC=D0=B8=D0=BB=D1=8C=D1=82?= =?UTF-8?q?=D0=B8=D0=BF=D0=BB=D0=B0=D1=82=D1=84=D0=BE=D1=80=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D0=BD=D0=B0=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- minecraft-launcher.cpp | 275 +++++++++++++++++++++++++++++++++++++++-- minecraft-launcher.h | 8 -- 2 files changed, 267 insertions(+), 16 deletions(-) delete mode 100644 minecraft-launcher.h diff --git a/minecraft-launcher.cpp b/minecraft-launcher.cpp index 249ff2f..ffa5a5c 100644 --- a/minecraft-launcher.cpp +++ b/minecraft-launcher.cpp @@ -1,12 +1,271 @@ -// minecraft-launcher.cpp: определяет точку входа для приложения. -// +#include +#include +#include +#include // Для system() +#include // C++17 для работы с файловой системой +#include // Для работы с файлами конфигурации -#include "minecraft-launcher.h" +// Пространство имен для удобства работы с файловой системой +namespace fs = std::filesystem; -using namespace std; +// Имя файла конфигурации для хранения URL репозитория +const std::string CONFIG_FILE = "launcher_config.txt"; -int main() -{ - cout << "Hello CMake." << endl; - return 0; +// --- Функции для работы с конфигурацией --- + +// Функция для сохранения URL Git-репозитория в файл +void saveGitRepository(const std::string& repoUrl) { + std::ofstream configFile(CONFIG_FILE); + if (configFile.is_open()) { + configFile << repoUrl; + configFile.close(); + } else { + std::cerr << "Ошибка: Не удалось открыть файл конфигурации для записи." << std::endl; + } +} + +// Функция для загрузки URL Git-репозитория из файла +std::string loadGitRepository() { + std::ifstream configFile(CONFIG_FILE); + std::string repoUrl; + if (configFile.is_open()) { + std::getline(configFile, repoUrl); + configFile.close(); + } + return repoUrl; +} + + +// --- Кроссплатформенные функции --- + +// Функция для получения пути к папке .minecraft в зависимости от ОС +fs::path getMinecraftPath() { + fs::path minecraftPath; + +#if defined(_WIN32) + // Для Windows путь обычно находится в %APPDATA%\.minecraft + char* appdata = nullptr; + size_t len; + _dupenv_s(&appdata, &len, "APPDATA"); + if (appdata != nullptr) { + minecraftPath = fs::path(appdata) / ".minecraft"; + free(appdata); + } +#elif defined(__linux__) + // Для Linux путь обычно находится в ~/.minecraft + char* home = getenv("HOME"); + if (home != nullptr) { + minecraftPath = fs::path(home) / ".minecraft"; + } +#elif defined(__APPLE__) + // Для macOS путь находится в ~/Library/Application Support/minecraft + char* home = getenv("HOME"); + if (home != nullptr) { + minecraftPath = fs::path(home) / "Library" / "Application Support" / "minecraft"; + } +#else + std::cerr << "Неизвестная операционная система!" << std::endl; +#endif + + return minecraftPath; +} + +// Функция для открытия папки в файловом менеджере по умолчанию +void openFolder(const fs::path& folderPath) { + if (!fs::exists(folderPath)) { + std::cout << "Папка не существует. Создание папки: " << folderPath.string() << std::endl; + try { + fs::create_directories(folderPath); + } catch (const fs::filesystem_error& e) { + std::cerr << "Ошибка при создании папки: " << e.what() << std::endl; + return; + } + } + + std::string command; +#if defined(_WIN32) + command = "explorer \"" + folderPath.string() + "\""; +#elif defined(__linux__) + command = "xdg-open \"" + folderPath.string() + "\""; +#elif defined(__APPLE__) + command = "open \"" + folderPath.string() + "\""; +#else + std::cerr << "Команда для открытия папки на данной ОС не поддерживается." << std::endl; + return; +#endif + + // Выполнение системной команды + system(command.c_str()); +} + +// Функция для очистки содержимого папки +void clearFolder(const fs::path& folderPath) { + if (!fs::exists(folderPath) || !fs::is_directory(folderPath)) { + return; // Если папки нет, ничего не делаем + } + for (const auto& entry : fs::directory_iterator(folderPath)) { + try { + fs::remove_all(entry.path()); + } catch (const fs::filesystem_error& e) { + std::cerr << "Не удалось удалить " << entry.path() << ": " << e.what() << std::endl; + } + } +} + + +// --- Функции меню --- + +// Функция для открытия папки с модами +void openModsFolderAction() { + fs::path minecraftPath = getMinecraftPath(); + if (minecraftPath.empty()) { + std::cerr << "Не удалось определить путь к папке Minecraft." << std::endl; + return; + } + fs::path modsPath = minecraftPath / "mods"; + std::cout << "Путь к папке модов: " << modsPath.string() << std::endl; + openFolder(modsPath); +} + +// Функция для установки URL репозитория +void setGitRepositoryAction() { + std::string repoUrl; + std::cout << "\nВведите URL Git-репозитория (например, https://github.com/user/repo.git):" << std::endl; + std::getline(std::cin >> std::ws, repoUrl); // std::ws для очистки буфера от пробельных символов + + if (repoUrl.empty()) { + std::cout << "URL не может быть пустым." << std::endl; + return; + } + + saveGitRepository(repoUrl); + std::cout << "URL репозитория успешно сохранен." << std::endl; +} + +// Функция для загрузки модов из Git +void downloadModsAction() { + std::string repoUrl = loadGitRepository(); + if (repoUrl.empty()) { + std::cout << "URL Git-репозитория не настроен. Пожалуйста, сначала установите его (пункт 2)." << std::endl; + return; + } + + fs::path modsPath = getMinecraftPath() / "mods"; + std::cout << "Папка для модов: " << modsPath.string() << std::endl; + + // Убедимся, что папка существует + if (!fs::exists(modsPath)) { + try { + fs::create_directories(modsPath); + } catch (const fs::filesystem_error& e) { + std::cerr << "Ошибка при создании папки mods: " << e.what() << std::endl; + return; + } + } + + // Запрос подтверждения перед очисткой + char confirmation; + std::cout << "\nВНИМАНИЕ! Все существующие файлы в папке 'mods' будут удалены." << std::endl; + std::cout << "Продолжить? (y/n): "; + std::cin >> confirmation; + + // Проверка, что пользователь ввел 'y' или 'Y' + if (confirmation != 'y' && confirmation != 'Y') { + std::cout << "Загрузка отменена." << std::endl; + // Очистка буфера ввода после чтения символа + std::cin.ignore(std::numeric_limits::max(), '\n'); + return; + } + // Очистка буфера ввода + std::cin.ignore(std::numeric_limits::max(), '\n'); + + + std::cout << "Очистка папки mods..." << std::endl; + clearFolder(modsPath); + std::cout << "Папка очищена." << std::endl; + + // Формирование команды для клонирования репозитория + // Клонируем содержимое репозитория прямо в папку mods + std::string command = "git clone " + repoUrl + " \"" + modsPath.string() + "\""; + + std::cout << "\nВыполнение команды: " << command << std::endl; + std::cout << "Начинается загрузка модов. Это может занять некоторое время..." << std::endl; + + int result = system(command.c_str()); + + if (result == 0) { + std::cout << "Моды успешно загружены!" << std::endl; + } else { + std::cerr << "Произошла ошибка при загрузке модов. Убедитесь, что Git установлен и URL репозитория верный." << std::endl; + } +} + +// Отображение главного меню +void printMenu() { + std::cout << "\n--- Minecraft Mod Launcher ---" << std::endl; + std::cout << "1. Открыть папку с модами (.minecraft/mods)" << std::endl; + std::cout << "2. Указать/изменить URL Git-репозитория с модами" << std::endl; + std::cout << "3. Загрузить/обновить моды из Git-репозитория" << std::endl; + std::cout << "4. Выход" << std::endl; + std::cout << "-----------------------------" << std::endl; + + std::string currentRepo = loadGitRepository(); + if (currentRepo.empty()) { + std::cout << "Текущий репозиторий: не задан" << std::endl; + } else { + std::cout << "Текущий репозиторий: " << currentRepo << std::endl; + } + + std::cout << "\nВведите ваш выбор: "; +} + + +// --- Главная функция программы --- + +int main() { + // Установка кодировки консоли для корректного отображения кириллицы в Windows +#if defined(_WIN32) + system("chcp 65001 > nul"); +#endif + + int choice; + while (true) { + printMenu(); + std::cin >> choice; + + // Проверка на корректность ввода + if (std::cin.fail()) { + std::cout << "Ошибка: введите число." << std::endl; + std::cin.clear(); // Сброс флага ошибки + // Очистка буфера ввода до следующей новой строки + std::cin.ignore(std::numeric_limits::max(), '\n'); + continue; + } + + switch (choice) { + case 1: + openModsFolderAction(); + break; + case 2: + setGitRepositoryAction(); + break; + case 3: + downloadModsAction(); + break; + case 4: + std::cout << "Выход из программы." << std::endl; + return 0; + default: + std::cout << "Неверный выбор. Пожалуйста, попробуйте снова." << std::endl; + break; + } + std::cout << "\nНажмите Enter для продолжения..."; + // Очистка буфера перед ожиданием Enter + if (choice != 3 && choice !=2) { + std::cin.ignore(std::numeric_limits::max(), '\n'); + } + std::cin.get(); + } + + return 0; } diff --git a/minecraft-launcher.h b/minecraft-launcher.h deleted file mode 100644 index 804055d..0000000 --- a/minecraft-launcher.h +++ /dev/null @@ -1,8 +0,0 @@ -// minecraft-launcher.h : включаемый файл для стандартных системных включаемых файлов -// или включаемые файлы для конкретного проекта. - -#pragma once - -#include - -// TODO: установите здесь ссылки на дополнительные заголовки, требующиеся для программы.