#!/bin/bash set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" LOCALES_DIR="$SCRIPT_DIR/install_locales" PRESETS_DIR="$SCRIPT_DIR/presets" # --- Функция для получения перевода из JSON --- T() { jq -r ".\"$1\"" "$LOCALES_DIR/$LOCALE.json" 2>/dev/null | fold -s -w "$(tput cols)" } # --- Получаем список доступных локалей (файлы без расширения .json) --- LANGUAGES=() for file in "$LOCALES_DIR"/*.json; do LANGUAGES+=("$(basename "$file" .json)") done # --- Проверяем, что локали найдены --- if [ ${#LANGUAGES[@]} -eq 0 ]; then echo "No locales found in $LOCALES_DIR" exit 1 fi # --- Select для выбора языка --- echo "Choose a language:" select lang in "${LANGUAGES[@]}"; do if [[ -n "$lang" ]]; then LOCALE="$lang" echo "You selected: $LOCALE" break else echo "Invalid selection. Please choose a number from the list." fi done echo; echo; T INFO install_dir="$(pwd)" game_version="1.21.1" fabric_version="0.17.2" now=$(date +"%Y-%m-%dT%H:%M:%S%z") tmpfile=$(mktemp) # --- выбор пресета настроек --- echo; echo; T SELECT_PRESET # --- Сканируем пресеты --- PRESETS=() OPTIONS=() # строки для select for dir in "$PRESETS_DIR"/*/; do name=$(basename "$dir") # Читаем описание из JSON для текущей локали if [[ -f "$dir/preset_info.json" ]]; then description=$(jq -r ".\"$LOCALE\" // .en_US" "$dir/preset_info.json" 2>/dev/null) # Если нет ключа для локали, fallback на en_US description=$(echo "$description" | fold -s -w "$(tput cols)") else description="No description" fi line=" $name — $description" OPTIONS+=("$(echo "$line" | fold -s -w "$(tput cols)")") PRESETS+=("$name") done # --- Выбор пресета --- COLUMNS=1 select opt in "${OPTIONS[@]}"; do index=$((REPLY-1)) if [[ $index -ge 0 && $index -lt ${#PRESETS[@]} ]]; then preset="${PRESETS[$index]}" break else echo "Invalid selection. Choose a number from the list." fi done COLUMNS= # --- Копирование файлов --- cp "$PRESETS_DIR/$preset/options.txt" "$SCRIPT_DIR/options.txt" cp -r "$PRESETS_DIR/$preset/config/." "$SCRIPT_DIR/config/" locale_lower=$(echo "$LOCALE" | tr '[:upper:]' '[:lower:]') sed -i.bak -E "s/^lang:.*/lang:$locale_lower/" $SCRIPT_DIR/options.txt T PRESET_INSTALLED # --- ввод RAM с валидацией --- echo; echo; T SELECT_RAM while true; do read -rp "> " ram # проверка формата: число + G/g или M/m if [[ "$ram" =~ ^[0-9]+[GgMm]$ ]]; then T VALID_RAM break else T INVALID_RAM fi done jq \ --arg install_dir "$install_dir" \ --arg game_version "$game_version" \ --arg fabric_version "$fabric_version" \ --arg now "$now" \ --arg ram "$ram" \ '.profiles["basicmods-" + $game_version] = { "created": $now, "gameDir" : $install_dir, "icon": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAANcmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNC40LjAtRXhpdjIiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iCiAgICB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIgogICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICAgeG1sbnM6R0lNUD0iaHR0cDovL3d3dy5naW1wLm9yZy94bXAvIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgIHhtcE1NOkRvY3VtZW50SUQ9ImdpbXA6ZG9jaWQ6Z2ltcDo3ODAxODgwOC0yY2E5LTQyMDItYmYwMy00Yjc0MTIxNmQ4NDAiCiAgIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6ODQwYzk3MjEtZThiYi00YWFhLTkyNTAtMGY5NDFhNmFiMDU0IgogICB4bXBNTTpPcmlnaW5hbERvY3VtZW50SUQ9InhtcC5kaWQ6NzJhNDcxMjEtMzA0Ny00ZmVlLWFhYzktZTJmM2M4MTE5Y2U1IgogICBkYzpGb3JtYXQ9ImltYWdlL3BuZyIKICAgR0lNUDpBUEk9IjMuMCIKICAgR0lNUDpQbGF0Zm9ybT0iTGludXgiCiAgIEdJTVA6VGltZVN0YW1wPSIxNzU4MTE4ODIwNTExNDIzIgogICBHSU1QOlZlcnNpb249IjMuMC40IgogICB0aWZmOk9yaWVudGF0aW9uPSIxIgogICB4bXA6Q3JlYXRvclRvb2w9IkdJTVAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjU6MDk6MTdUMTg6MTk6MjIrMDQ6MDAiCiAgIHhtcDpNb2RpZnlEYXRlPSIyMDI1OjA5OjE3VDE4OjE5OjIyKzA0OjAwIj4KICAgPHhtcE1NOkhpc3Rvcnk+CiAgICA8cmRmOlNlcT4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii8iCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6MzhmZDcxMTMtYTcxMi00ZWM3LWFhMWItYTFmZjBmN2U3NWJiIgogICAgICBzdEV2dDpzb2Z0d2FyZUFnZW50PSJHSU1QIDMuMC40IChMaW51eCkiCiAgICAgIHN0RXZ0OndoZW49IjIwMjUtMDktMTdUMTg6MjA6MjArMDQ6MDAiLz4KICAgIDwvcmRmOlNlcT4KICAgPC94bXBNTTpIaXN0b3J5PgogIDwvcmRmOkRlc2NyaXB0aW9uPgogPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIAo8P3hwYWNrZXQgZW5kPSJ3Ij8+5hgy8gAAAAFzUkdCAdnJLH8AAAAEZ0FNQQAAsY8L/GEFAAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAAJcEhZcwAACxMAAAsTAQCanBgAAAPwSURBVFjD7ZZPbJRVFMV/902nLS2UlrYKbWc6JSAKCxNdYFhQqlsJiVEXEKLxTwwuCUuMRo3IQrewMaIBXXRlcKGJRiQsIEiMITYGhU47OKUw7fzptJ2Z7/veccEGgraFaV1xtvfe887LO/feBw9RB/zuWdXL4VaSvG6exYrrja/oDZZaZw8q7DUOyCOB2QmOPTBPw/0WvMrbcsBnu46Al4GDsybwnOD4fQuxpR98wIPs851HQYZiEYZRSDsURviYdGjssAnpC465ZRPwCm95gE/6jprFbj+rOTAJE8jMtyedy497vJcQdihzGI/Xlxx3dRlnL29osjenyUReueS0NFhUYeO0tKsgDeVVTOWlZ/OaSRVVTBWl54qa7p/Wzd4pTSRy2sfrfjFj3qXQnW61O5OEGJ0u8cjGGJ2pmAoZD5GjlIHimBHhKF01j4O2lKN8XXT0N9C9KU46V7jncu50qy1qwjuTHJ7Ah5w5/zebuzvUu7HZwChlIq1NxChkImtLxhzOmJkI8Xh+upCVIlnkhCeyf+NdchcIqPoaI8GIeua3u7ErAdfyZYa29xgS7QkDwcxkwIXRLN57JNkv0a/qIWFagscXEWBcCi5hOLsylWNzRxe1IOT7c2l2PN7L2MSsalFoYRgxG85z2V9mm9uqkMAyXMPQg+8CAI8n/+R7VLd/RJEyl/Jpzjz2AqubGrl8bYpVq8xulIt8O/ejRn0ah/G7H6HwxIdkUx8gvK9LgBHR1Ozo7HKMPfMm57fsl49H/DmfoRLWdCr7Hdd9FkP2R/IghjGeepd4Y4MfSLYi5O7rCe7sgNumMRLrm7k6VmXNakdyfSv9/S26EBywuT8+NU9NWTJ2a+BjTCiTese6O5utvTVuclqA9z8E3OtUITnaVjewriNOqRyaRaJjXSOjWw8SHzlok33va+tAu11Jl61rbSPeR4zfCOnZ0AR4LdQBi5owxLg5VeHRria8l781VXWxuJHY0KD+vkb7uXyE7o5mm7xVZVNfK8XZgOlioK62Jpuaqixpzi/iAU+pHFELxfjNits00EIUiIlczSJ51qxpIPSemdkqkUGhFNDZ1mhSRL4cEOGtLgHDnLSrv+3gr7FZeroaKeQDJnMVre+KUyiEICjNhYQSpZkqiQ0tzMzVyOYqlNNDDPO1Lcs2fJn9As/TOy/KzFl5LmLblhZ+OJcj2dtKoVBlPvIElYhielAixjAn3bKu49tC9sphemrwolUCT3kmpBpBqVylND6EwxjmlC3rf0C7K7LTzXflvcQ+L7y1p85SSA9iwDBf3ZWjPXPevmlx1AM9P7fgLH2RvQvGtaeycj/i/5vnIR5ixfAP5P8t5wY5ZUAAAAAASUVORK5CYII=", "javaArgs" : "-Xmx" + $ram + " -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:G1NewSizePercent=20 -XX:G1ReservePercent=20 -XX:MaxGCPauseMillis=50 -XX:G1HeapRegionSize=32M", "lastUsed": $now, "lastVersionId": "fabric-loader-" + $fabric_version +"-" + $game_version, "name": "basicmods-" + $game_version, "type": "custom" } ' \ ~/.minecraft/launcher_profiles.json > "$tmpfile" && mv "$tmpfile" ~/.minecraft/launcher_profiles.json echo; echo; T DONE