Проверка первой версии, мильтиплатформенная

This commit is contained in:
2025-09-23 10:20:04 +03:00
parent 7adcd780b0
commit ff995ee518
2 changed files with 267 additions and 16 deletions

View File

@@ -1,12 +1,271 @@
// minecraft-launcher.cpp: определяет точку входа для приложения.
//
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib> // Для system()
#include <filesystem> // C++17 для работы с файловой системой
#include <fstream> // Для работы с файлами конфигурации
#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<std::streamsize>::max(), '\n');
return;
}
// Очистка буфера ввода
std::cin.ignore(std::numeric_limits<std::streamsize>::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<std::streamsize>::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<std::streamsize>::max(), '\n');
}
std::cin.get();
}
return 0;
}