@@ -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 ;
// Функция для сохранения URL Git-репозитория в файл
return 0 ;
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 ;
}
}