#include #include #include // Для system() #include // Для работы с файлами #include // Для работы с файловой системой (проверки папок) #include // Для очистки потока ввода // Пространство имен для работы с файловой системой namespace fs = std::filesystem; // Имя файла для хранения URL репозитория const std::string CONFIG_FILE = "launcher_config.txt"; // Функция для получения пути к папке .minecraft на macOS // На Mac путь обычно: /Users/ВАШЕ_ИМЯ_ПОЛЬЗОВАТЕЛЯ/Library/Application Support/minecraft std::string getMinecraftPath() { // Получаем домашнюю директорию пользователя из переменных окружения const char* homeDir = getenv("HOME"); if (homeDir == nullptr) { std::cerr << "Ошибка: Не удалось определить домашнюю директорию." << std::endl; return ""; } return std::string(homeDir) + "/Library/Application Support/minecraft"; } // Функция для очистки экрана консоли void clearScreen() { // Простая команда для очистки экрана в Unix-подобных системах (macOS, Linux) system("clear"); } // Функция для отображения главного меню void showMenu() { clearScreen(); std::cout << "========= Minecraft Launcher (macOS) =========\n"; std::cout << "1. Запустить Minecraft\n"; std::cout << "2. Открыть папку с модами (mods)\n"; std::cout << "3. Указать URL Git-репозитория для модов\n"; std::cout << "4. Загрузить/Обновить моды из репозитория\n"; std::cout << "5. Выход\n"; std::cout << "============================================\n"; std::cout << "Выберите опцию: "; } // Функция для приостановки выполнения до нажатия Enter void pause() { std::cout << "\nНажмите Enter для продолжения..."; // Очищаем буфер ввода перед ожиданием std::cin.ignore(std::numeric_limits::max(), '\n'); std::cin.get(); } // 1. Функция для запуска Minecraft void launchMinecraft() { std::cout << "\nЗапускаем Minecraft...\n"; // Используем стандартную для macOS команду 'open' для запуска приложения // Предполагается, что Minecraft установлен в стандартной папке /Applications int result = system("open -a Minecraft.app"); if (result != 0) { std::cerr << "Ошибка: Не удалось запустить Minecraft. Убедитесь, что игра установлена в /Applications.\n"; } pause(); } // 2. Функция для открытия папки с модами void openModsFolder() { std::string minecraftPath = getMinecraftPath(); if (minecraftPath.empty()) { pause(); return; } fs::path modsPath = minecraftPath; modsPath /= "mods"; // Создаем папку mods, если она не существует if (!fs::exists(modsPath)) { std::cout << "Папка 'mods' не найдена. Создаем ее...\n"; try { fs::create_directories(modsPath); } catch (const fs::filesystem_error& e) { std::cerr << "Ошибка при создании папки 'mods': " << e.what() << std::endl; pause(); return; } } std::cout << "Открываем папку: " << modsPath.string() << "\n"; // Команда для открытия папки в Finder. Используем кавычки для безопасности. std::string command = "open \"" + modsPath.string() + "\""; system(command.c_str()); pause(); } // 3. Функция для сохранения URL Git-репозитория void setGitRepository() { std::string repoUrl; std::cout << "\nВведите полный URL Git-репозитория (например, https://github.com/user/repo.git):\n"; std::cin.ignore(std::numeric_limits::max(), '\n'); // Очистка буфера перед считыванием строки std::getline(std::cin, repoUrl); // Открываем файл для записи. Старое содержимое будет стерто. std::ofstream configFile(CONFIG_FILE); if (!configFile.is_open()) { std::cerr << "Ошибка: Не удалось открыть файл конфигурации для записи.\n"; } else { configFile << repoUrl; std::cout << "URL репозитория успешно сохранен.\n"; } configFile.close(); pause(); } // 4. Функция для загрузки или обновления модов void updateModsFromGit() { std::cout << "\nНачинаем процесс загрузки/обновления модов...\n"; // Шаг 1: Чтение URL из файла конфигурации std::ifstream configFile(CONFIG_FILE); std::string repoUrl; if (!configFile.is_open()) { std::cerr << "Ошибка: Файл конфигурации не найден. Сначала укажите URL репозитория (опция 3).\n"; pause(); return; } std::getline(configFile, repoUrl); configFile.close(); if (repoUrl.empty()) { std::cerr << "Ошибка: URL репозитория не указан в файле конфигурации. Сначала укажите URL (опция 3).\n"; pause(); return; } std::cout << "Используется репозиторий: " << repoUrl << std::endl; // Шаг 2: Определение пути к папке mods std::string minecraftPath = getMinecraftPath(); if (minecraftPath.empty()) { pause(); return; } fs::path modsPath = minecraftPath; modsPath /= "mods"; // Создаем папку mods, если она не существует if (!fs::exists(modsPath)) { std::cout << "Папка 'mods' не найдена. Создаем ее...\n"; try { fs::create_directories(modsPath); } catch (const fs::filesystem_error& e) { std::cerr << "Ошибка при создании папки 'mods': " << e.what() << std::endl; pause(); return; } } // Шаг 3: Проверка, является ли папка mods уже Git-репозиторием fs::path gitPath = modsPath; gitPath /= ".git"; std::string command; if (fs::exists(gitPath)) { // Если папка .git существует, значит это репозиторий. Делаем pull. std::cout << "Обнаружен существующий репозиторий. Выполняем 'git pull' для обновления...\n"; // Переходим в папку mods и выполняем git pull command = "cd \"" + modsPath.string() + "\" && git pull"; } else { // Если папки .git нет, проверяем, пуста ли папка mods if (!fs::is_empty(modsPath)) { std::cerr << "Внимание: Папка 'mods' не является Git-репозиторием, но содержит файлы.\n"; std::cerr << "Для предотвращения потери данных, клонирование не будет выполнено.\n"; std::cerr << "Пожалуйста, очистите папку 'mods' вручную и попробуйте снова.\n"; pause(); return; } // Папка пуста, клонируем репозиторий std::cout << "Папка 'mods' пуста. Выполняем 'git clone' для загрузки модов...\n"; command = "git clone " + repoUrl + " \"" + modsPath.string() + "\""; } // Шаг 4: Выполнение команды Git int result = system(command.c_str()); if (result == 0) { std::cout << "Операция успешно завершена!\n"; } else { std::cerr << "Ошибка при выполнении команды Git. Убедитесь, что Git установлен и URL репозитория корректен.\n"; } pause(); } int main() { int choice = 0; while (choice != 5) { showMenu(); std::cin >> choice; // Проверка на корректность ввода if (std::cin.fail()) { std::cin.clear(); // Сброс флага ошибки // Пропуск некорректного ввода std::cin.ignore(std::numeric_limits::max(), '\n'); choice = 0; // Присваиваем неверное значение для повторного входа в цикл } switch (choice) { case 1: launchMinecraft(); break; case 2: openModsFolder(); break; case 3: setGitRepository(); break; case 4: updateModsFromGit(); break; case 5: std::cout << "Выход из программы...\n"; std::cout << "Выход из программы...\n"; break; default: std::cout << "\nНеверный выбор. Пожалуйста, попробуйте снова...\n"; pause(); break; } } return 0; }