#!/bin/bash #?────────────────────────────────────────────────────────────────────────────────────────── #* Informationen Kopfzeile #?────────────────────────────────────────────────────────────────────────────────────────── # https://github.com/ManfredAabye/opensimMULTITOOLS-II/blob/main/osmtool.sh tput reset # Bildschirmausgabe loeschen inklusive dem Scrollbereich. SCRIPTNAME="opensimMULTITOOL II" VERSION="V25.4.59.154" echo -e "\e[36m$SCRIPTNAME\e[0m $VERSION" echo "Dies ist ein Tool welches der Verwaltung von OpenSim Servern dient." echo "Bitte beachten Sie, dass die Anwendung auf eigene Gefahr und Verantwortung erfolgt." echo -e "\e[33mZum Abbrechen bitte STRG+C oder CTRL+C drücken.\e[0m" echo " " #?────────────────────────────────────────────────────────────────────────────────────────── #* Variablen setzen #?────────────────────────────────────────────────────────────────────────────────────────── #* FARBDEFINITIONEN COLOR_OK='\e[32m' # Grün (Haken) COLOR_BAD='\e[31m' # Rot (Kreuz) COLOR_HEADING='\e[97m' # Weiß (Überschriften) COLOR_START='\e[92m' # Hellgrün (Startaktionen) COLOR_STOP='\e[91m' # Hellrot (Stopaktionen) COLOR_SERVER='\e[36m' # Cyan (Server/Verzeichnisse/IPs) COLOR_DIR='\e[90m' # Grau (Pfade) COLOR_LABEL='\e[97m' # Weiß (Beschriftungen) COLOR_WARNING='\e[33m' # Gelb (Warnungen) COLOR_VALUE='\e[36m' # Cyan für Werte COLOR_ACTION='\e[92m' # Hellgrün für Aktionen COLOR_RESET='\e[0m' # Farbreset #* SYMBOLDEFINITIONEN SYM_OK="${COLOR_OK}✓${COLOR_RESET}" SYM_BAD="${COLOR_BAD}✗${COLOR_RESET}" SYM_INFO="${COLOR_VALUE}☛${COLOR_RESET}" # Alternative: ▲ ● ◆ ☛ ⚑ ⓘ SYM_WAIT="${COLOR_VALUE}⏳${COLOR_RESET}" SYM_LOG="${COLOR_VALUE}📋${COLOR_RESET}" COLOR_SECTION='\e[0;35m' # Magenta für Sektionsnamen COLOR_FILE='\e[0;33m' # Gelb für Dateipfade function blankline() { echo " ";} # Hauptpfad des Skripts automatisch setzen SCRIPT_DIR="$(dirname "$(realpath "$0")")" cd "$SCRIPT_DIR" || exit 1 system_ip=$(hostname -I | awk '{print $1}') echo -e "${COLOR_LABEL}Das Arbeitsverzeichnis ist:${COLOR_RESET} ${COLOR_VALUE}$SCRIPT_DIR${COLOR_RESET}" echo -e "${COLOR_LABEL}Ihre IP Adresse ist:${COLOR_RESET} ${COLOR_VALUE}$system_ip${COLOR_RESET}" blankline KOMMANDO=$1 # Eingabeauswertung fuer Funktionen. #?────────────────────────────────────────────────────────────────────────────────────────── #* Abhängigkeiten installieren #?────────────────────────────────────────────────────────────────────────────────────────── # Fehlende Abhängigkeiten installieren function servercheck() { # Direkt kompatible Distributionen: # Debian 11+ (Bullseye, Bookworm) – Offiziell unterstützt für .NET 8 # Ubuntu 18.04, 20.04, 22.04 – Microsoft bietet direkt kompatible Pakete # Linux Mint (basierend auf Ubuntu 20.04 oder 22.04) # Pop!_OS (System76, basiert auf Ubuntu) # MX Linux (Debian-basiert, integriert Ubuntu-Funktionen) # Arch Linux – Offiziell unterstützte Pakete über pacman # Manjaro – Bietet .NET-Pakete direkt über die Arch-Repositorys # Mögliche kompatible Distributionen (mit Anpassungen): # Kali Linux (basierend auf Debian 12, Anpassungen nötig für .NET-Pakete) # Zorin OS (Ubuntu-basiert, Unterstützung abhängig von Version) # elementary OS (Ubuntu-basiert, kann .NET aus Ubuntu-Quellen beziehen) # Raspberry Pi OS (Debian-basiert, erfordert manuelle Installation für .NET) echo -e "${COLOR_HEADING}🔍 Server-Kompatibilitätscheck wird durchgeführt...${COLOR_RESET}" # Ermitteln der Distribution und Version os_id=$(grep '^ID=' /etc/os-release | cut -d= -f2 | tr -d '"') os_version=$(grep '^VERSION_ID=' /etc/os-release | cut -d= -f2 | tr -d '"') echo -e "${COLOR_LABEL}Server läuft mit:${COLOR_RESET} ${COLOR_SERVER}$os_id $os_version${COLOR_RESET}" # Prüfen, welche .NET-Version installiert werden muss if [[ "$os_id" == "ubuntu" || "$os_id" == "linuxmint" || "$os_id" == "pop_os" ]]; then if [[ "$os_version" == "22.04" || "$os_version" == "20.04" ]]; then required_dotnet="dotnet-sdk-8.0" elif [[ "$os_version" == "18.04" ]]; then required_dotnet="dotnet-sdk-6.0" fi elif [[ "$os_id" == "debian" && "$os_version" -ge "11" ]]; then required_dotnet="dotnet-sdk-8.0" elif [[ "$os_id" == "arch" || "$os_id" == "manjaro" ]]; then required_dotnet="dotnet-sdk-8.0" else echo -e "${SYM_BAD} ${COLOR_WARNING}Keine unterstützte Version für .NET gefunden!${COLOR_RESET}" return 1 fi # .NET-Installationsstatus prüfen echo -e "${COLOR_HEADING}🔄 .NET Runtime-Überprüfung:${COLOR_RESET}" if [[ "$os_id" == "arch" || "$os_id" == "manjaro" ]]; then if ! pacman -Qi "$required_dotnet" >/dev/null 2>&1; then echo -e "${SYM_OK} ${COLOR_ACTION}Installiere ${COLOR_SERVER}$required_dotnet${COLOR_RESET}..." sudo pacman -S --noconfirm "$required_dotnet" echo -e "${SYM_OK} ${COLOR_SERVER}$required_dotnet${COLOR_RESET} ${COLOR_ACTION}wurde erfolgreich installiert.${COLOR_RESET}" else echo -e "${SYM_OK} ${COLOR_SERVER}$required_dotnet${COLOR_RESET} ${COLOR_ACTION}ist bereits installiert.${COLOR_RESET}" fi else if ! dpkg -s "$required_dotnet" >/dev/null 2>&1; then echo -e "${SYM_OK} ${COLOR_ACTION}Installiere ${COLOR_SERVER}$required_dotnet${COLOR_RESET}..." sudo apt-get install -y "$required_dotnet" echo -e "${SYM_OK} ${COLOR_SERVER}$required_dotnet${COLOR_RESET} ${COLOR_ACTION}wurde erfolgreich installiert.${COLOR_RESET}" else echo -e "${SYM_OK} ${COLOR_SERVER}$required_dotnet${COLOR_RESET} ${COLOR_ACTION}ist bereits installiert.${COLOR_RESET}" fi fi # Fehlende Pakete prüfen und installieren required_packages=("libc6" "libgcc-s1" "libgssapi-krb5-2" "libicu70" "liblttng-ust1" "libssl3" "libstdc++6" "libunwind8" "zlib1g" "libgdiplus" "zip" "screen") echo -e "${COLOR_HEADING}📦 Überprüfe fehlende Pakete...${COLOR_RESET}" for package in "${required_packages[@]}"; do if [[ "$os_id" == "arch" || "$os_id" == "manjaro" ]]; then if ! pacman -Qi "$package" >/dev/null 2>&1; then echo -e "${SYM_OK} ${COLOR_ACTION}Installiere ${COLOR_SERVER}$package${COLOR_RESET}..." sudo pacman -S --noconfirm "$package" fi else if ! dpkg -s "$package" >/dev/null 2>&1; then echo -e "${SYM_OK} ${COLOR_ACTION}Installiere ${COLOR_SERVER}$package${COLOR_RESET}..." sudo apt-get install -y "$package" fi fi done echo -e "${SYM_OK} ${COLOR_HEADING}Alle benötigten Pakete wurden installiert.${COLOR_RESET}" blankline } #?────────────────────────────────────────────────────────────────────────────────────────── #* Start Stop Standalone #?────────────────────────────────────────────────────────────────────────────────────────── function standalonestart() { cd opensim/bin || exit 1 screen -fa -S opensim -d -U -m dotnet OpenSim.dll blankline } function standalonestop() { screen -S opensim -p 0 -X stuff "shutdown^M" blankline } #?────────────────────────────────────────────────────────────────────────────────────────── #* Start Stop Grid #?────────────────────────────────────────────────────────────────────────────────────────── #* OpenSim starten (robust → money → sim1 bis sim999) function opensimstart() { echo -e "${SYM_WAIT} ${COLOR_START}Starte das Grid!${COLOR_RESET}" # RobustServer starten if [[ -d "robust/bin" && -f "robust/bin/Robust.dll" ]]; then echo -e "${SYM_OK} ${COLOR_START}Starte ${COLOR_SERVER}RobustServer${COLOR_RESET} ${COLOR_START}aus ${COLOR_DIR}robust/bin...${COLOR_RESET}" cd robust/bin || exit 1 screen -fa -S robustserver -d -U -m dotnet Robust.dll cd - >/dev/null 2>&1 || exit 1 sleep 30 else echo -e "${SYM_BAD} ${COLOR_SERVER}RobustServer: ${COLOR_BAD}Robust.dll nicht gefunden.${COLOR_RESET} ${COLOR_START}Überspringe Start.${COLOR_RESET}" fi # MoneyServer starten if [[ -f "robust/bin/MoneyServer.dll" ]]; then echo -e "${SYM_OK} ${COLOR_START}Starte ${COLOR_SERVER}MoneyServer${COLOR_RESET} ${COLOR_START}aus ${COLOR_DIR}robust/bin...${COLOR_RESET}" cd robust/bin || exit 1 screen -fa -S moneyserver -d -U -m dotnet MoneyServer.dll cd - >/dev/null 2>&1 || exit 1 sleep 30 else echo -e "${SYM_BAD} ${COLOR_SERVER}MoneyServer: ${COLOR_BAD}MoneyServer.dll nicht gefunden.${COLOR_RESET} ${COLOR_START}Überspringe Start.${COLOR_RESET}" fi # Sim-Regionen starten for ((i=1; i<=999; i++)); do sim_dir="sim$i/bin" if [[ -d "$sim_dir" && -f "$sim_dir/OpenSim.dll" ]]; then echo -e "${SYM_OK} ${COLOR_START}Starte ${COLOR_SERVER}sim$i${COLOR_RESET} ${COLOR_START}aus ${COLOR_DIR}$sim_dir...${COLOR_RESET}" cd "$sim_dir" || continue screen -fa -S "sim$i" -d -U -m dotnet OpenSim.dll cd - >/dev/null 2>&1 || continue sleep 20 fi done blankline } #* OpenSim stoppen (sim999 bis sim1 → money → robust) function opensimstop() { echo -e "${SYM_WAIT} ${COLOR_STOP}Stoppe das Grid!${COLOR_RESET}" # Sim-Regionen stoppen for ((i=999; i>=1; i--)); do sim_dir="sim$i" if screen -list | grep -q "$sim_dir"; then screen -S "sim$i" -p 0 -X stuff "shutdown^M" echo -e "${SYM_OK} ${COLOR_STOP}Stoppe ${COLOR_SERVER}sim$i${COLOR_RESET} ${COLOR_STOP}...${COLOR_RESET}" sleep 15 fi done # MoneyServer stoppen if screen -list | grep -q "moneyserver"; then echo -e "${SYM_OK} ${COLOR_STOP}Stoppe ${COLOR_SERVER}MoneyServer${COLOR_RESET} ${COLOR_STOP}...${COLOR_RESET}" screen -S moneyserver -p 0 -X stuff "shutdown^M" sleep 30 else echo -e "${SYM_BAD} ${COLOR_SERVER}MoneyServer: ${COLOR_BAD}Läuft nicht.${COLOR_RESET} ${COLOR_STOP}Überspringe Stopp.${COLOR_RESET}" fi # RobustServer stoppen if screen -list | grep -q "robust"; then echo -e "${SYM_OK} ${COLOR_STOP}Stoppe ${COLOR_SERVER}RobustServer${COLOR_RESET} ${COLOR_STOP}...${COLOR_RESET}" screen -S robustserver -p 0 -X stuff "shutdown^M" sleep 30 else echo -e "${SYM_BAD} ${COLOR_SERVER}RobustServer: ${COLOR_BAD}Läuft nicht.${COLOR_RESET} ${COLOR_STOP}Überspringe Stopp.${COLOR_RESET}" fi blankline } # check_screens ist eine Grid Funktion und funktioniert nicht im Standalone. function check_screens() { # echo "Überprüfung der laufenden OpenSim-Prozesse..." restart_all=false # Überprüfen, ob RobustServer läuft if [[ -d "robust/bin" && -f "robust/bin/Robust.dll" ]]; then screenRO=$(screen -ls | grep -w "robustserver") if [[ -z "$screenRO" ]]; then echo "$(date '+%Y-%m-%d %H:%M:%S') - RobustServer läuft nicht und muss neu gestartet werden." >> ProblemRestarts.log restart_all=true fi fi # Überprüfen, ob MoneyServer läuft if [[ -d "robust/bin" && -f "robust/bin/MoneyServer.dll" ]];then screenMoney=$(screen -ls | grep -w "moneyserver") if [[ -z "$screenMoney" ]]; then echo "$(date '+%Y-%m-%d %H:%M:%S') - MoneyServer läuft nicht und muss neu gestartet werden." >> ProblemRestarts.log restart_all=true fi fi # Überprüfen, ob sim1 läuft if [[ -d "sim1/bin" && -f "sim1/bin/OpenSim.dll" ]]; then screenSim1=$(screen -ls | grep -w "sim1") if [[ -z "$screenSim1" ]]; then echo "$(date '+%Y-%m-%d %H:%M:%S') - Sim1 läuft nicht und muss neu gestartet werden." >> ProblemRestarts.log restart_all=true fi fi # Falls eines der kritischen Systeme ausgefallen ist, alles neu starten if [[ "$restart_all" == true ]]; then echo "$(date '+%Y-%m-%d %H:%M:%S') - Kritische Prozesse sind ausgefallen! OpenSim wird komplett neu gestartet." >> ProblemRestarts.log # opensimstart opensimrestart return 0 fi # Überprüfen, ob andere simulierte Regionen (sim2 bis sim999) einzeln neu gestartet werden müssen for ((i=2; i<=999; i++)); do sim_dir="sim$i/bin" if [[ -d "$sim_dir" && -f "$sim_dir/OpenSim.dll" ]]; then screenSim=$(screen -ls | grep -w "sim$i") if [[ -z "$screenSim" ]]; then echo "$(date '+%Y-%m-%d %H:%M:%S') - Sim$i läuft nicht und wird einzeln neu gestartet." >> ProblemRestarts.log cd "$sim_dir" || continue screen -fa -S "sim$i" -d -U -m dotnet OpenSim.dll cd - >/dev/null 2>&1 || continue sleep 20 fi fi done blankline } #?────────────────────────────────────────────────────────────────────────────────────────── #* Erstellen eines OpenSimulators #?────────────────────────────────────────────────────────────────────────────────────────── function opensimgitcopy() { echo -e "${COLOR_HEADING}🔄 OpenSimulator GitHub-Verwaltung${COLOR_RESET}" echo -e "${COLOR_LABEL}Möchten Sie den OpenSimulator vom GitHub verwenden oder aktualisieren? (${COLOR_OK}[upgrade]${COLOR_LABEL}/new)${COLOR_RESET}" read -r user_choice user_choice=${user_choice:-upgrade} if [[ "$user_choice" == "new" ]]; then # Falls eine alte Version existiert, wird sie gelöscht if [[ -d "opensim" ]]; then echo -e "${COLOR_ACTION}Vorhandene OpenSimulator-Version wird gelöscht...${COLOR_RESET}" rm -rf opensim echo -e "${SYM_OK} ${COLOR_ACTION}Alte OpenSimulator-Version wurde erfolgreich entfernt.${COLOR_RESET}" fi echo -e "${COLOR_ACTION}OpenSimulator wird von GitHub geholt...${COLOR_RESET}" git clone git://opensimulator.org/git/opensim opensim echo -e "${SYM_OK} ${COLOR_ACTION}OpenSimulator wurde erfolgreich heruntergeladen.${COLOR_RESET}" elif [[ "$user_choice" == "upgrade" ]]; then if [[ -d "opensim/.git" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Repository gefunden. Aktualisiere mit 'git pull'...${COLOR_RESET}" cd opensim || { echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Kann nicht ins Verzeichnis wechseln!${COLOR_RESET}"; return 1; } git pull origin master && echo -e "${COLOR_OK}✅ ${COLOR_ACTION}OpenSimulator erfolgreich aktualisiert!${COLOR_RESET}" cd .. else echo -e "${COLOR_WARNING}⚠ ${COLOR_ACTION}OpenSimulator-Verzeichnis nicht gefunden. Klone Repository neu...${COLOR_RESET}" git clone git://opensimulator.org/git/opensim opensim && echo -e "${COLOR_OK}✅ ${COLOR_ACTION}OpenSimulator erfolgreich heruntergeladen!${COLOR_RESET}" fi else echo -e "${SYM_BAD} ${COLOR_ERROR}Abbruch: Keine Aktion durchgeführt.${COLOR_RESET}" return 1 fi # .NET-Version auswählen echo -e "${COLOR_LABEL}Möchten Sie diese Version mit .NET 6 oder .NET 8 betreiben? (${COLOR_OK}[8]${COLOR_LABEL}/6)${COLOR_RESET}" read -r dotnet_version dotnet_version=${dotnet_version:-8} if [[ "$dotnet_version" == "6" ]]; then echo -e "${COLOR_ACTION}Wechsle zu .NET 6-Version...${COLOR_RESET}" cd opensim || { echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Verzeichnis 'opensim' nicht gefunden.${COLOR_RESET}"; return 1; } git checkout dotnet6 echo -e "${SYM_OK} ${COLOR_ACTION}OpenSimulator wurde für .NET 6 umgebaut.${COLOR_RESET}" else echo -e "${SYM_OK} ${COLOR_ACTION}Standardmäßig wird .NET 8 verwendet.${COLOR_RESET}" fi blankline } function moneygitcopy() { echo -e "${COLOR_HEADING}💰 MoneyServer GitHub-Verwaltung${COLOR_RESET}" echo -e "${COLOR_LABEL}Möchten Sie den MoneyServer vom GitHub verwenden oder aktualisieren? (${COLOR_OK}[upgrade]${COLOR_LABEL}/new)${COLOR_RESET}" read -r user_choice user_choice=${user_choice:-upgrade} if [[ "$user_choice" == "new" ]]; then if [[ -d "opensimcurrencyserver" ]]; then echo -e "${COLOR_ACTION}Vorhandene MoneyServer-Version wird gelöscht...${COLOR_RESET}" rm -rf opensimcurrencyserver echo -e "${SYM_OK} ${COLOR_ACTION}Alte MoneyServer-Version wurde erfolgreich entfernt.${COLOR_RESET}" fi echo -e "${COLOR_ACTION}MONEYSERVER: MoneyServer wird vom GIT geholt...${COLOR_RESET}" git clone https://github.com/ManfredAabye/opensimcurrencyserver-dotnet.git opensimcurrencyserver echo -e "${SYM_OK} ${COLOR_ACTION}MoneyServer wurde erfolgreich heruntergeladen.${COLOR_RESET}" elif [[ "$user_choice" == "upgrade" ]]; then if [[ -d "opensimcurrencyserver/.git" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Repository gefunden. Aktualisiere mit 'git pull'...${COLOR_RESET}" cd opensimcurrencyserver || { echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Kann nicht ins Verzeichnis wechseln!${COLOR_RESET}"; return 1; } # Automatische Branch-Erkennung branch_name=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@') git pull origin "$branch_name" && echo -e "${COLOR_OK}✅ ${COLOR_ACTION}MoneyServer erfolgreich aktualisiert!${COLOR_RESET}" cd .. else echo -e "${COLOR_WARNING}⚠ ${COLOR_ACTION}MoneyServer-Verzeichnis nicht gefunden. Klone Repository neu...${COLOR_RESET}" git clone https://github.com/ManfredAabye/opensimcurrencyserver-dotnet.git opensimcurrencyserver && echo -e "${COLOR_OK}✅ ${COLOR_ACTION}MoneyServer erfolgreich heruntergeladen!${COLOR_RESET}" fi else echo -e "${SYM_BAD} ${COLOR_ERROR}Abbruch: Keine Aktion durchgeführt.${COLOR_RESET}" return 1 fi # Prüfen, ob das Verzeichnis existiert, bevor es kopiert wird if [[ -d "opensimcurrencyserver/addon-modules" ]]; then cp -r opensimcurrencyserver/addon-modules opensim/ echo -e "${SYM_OK} ${COLOR_ACTION}MONEYSERVER: addon-modules wurde nach opensim kopiert${COLOR_RESET}" else echo -e "${SYM_BAD} ${COLOR_ERROR}MONEYSERVER: addon-modules existiert nicht${COLOR_RESET}" fi if [[ -d "opensimcurrencyserver/bin" ]]; then cp -r opensimcurrencyserver/bin opensim/ echo -e "${SYM_OK} ${COLOR_ACTION}MONEYSERVER: bin wurde nach opensim kopiert${COLOR_RESET}" else echo -e "${SYM_BAD} ${COLOR_ERROR}MONEYSERVER: bin existiert nicht${COLOR_RESET}" fi blankline return 0 } function ruthrothgit() { # Schritt 1 das bereitstellen der Pakete zur weiteren bearbeitung. echo -e "${COLOR_HEADING}👥 Ruth & Roth Avatar-Assets Vorbereitung${COLOR_RESET}" base_dir="ruthroth" mkdir -p "$base_dir" declare -A repos=( ["Ruth2"]="https://github.com/ManfredAabye/Ruth2.git" ["Roth2"]="https://github.com/ManfredAabye/Roth2.git" ) for avatar in "${!repos[@]}"; do repo_url="${repos[$avatar]}" target_dir="$avatar" if [[ ! -d "$target_dir" ]]; then echo -e " ${COLOR_ACTION}➜ Klone ${COLOR_SERVER}$avatar${COLOR_ACTION} von GitHub...${COLOR_RESET}" git clone "$repo_url" "$target_dir" && echo -e " ${COLOR_OK}✅ ${COLOR_SERVER}$avatar${COLOR_RESET} ${COLOR_ACTION}wurde heruntergeladen.${COLOR_RESET}" else echo -e " ${COLOR_OK}✅ ${COLOR_SERVER}$avatar${COLOR_RESET} ${COLOR_ACTION}ist bereits vorhanden, überspringe Download.${COLOR_RESET}" fi # Kopiere nur die relevanten IAR-Dateien direkt nach ruthroth echo -e " ${COLOR_ACTION}➜ Kopiere benötigte IAR-Dateien nach ${COLOR_DIR}$base_dir${COLOR_ACTION}...${COLOR_RESET}" cp "$target_dir/Artifacts/IAR/"*.iar "$base_dir/" 2>/dev/null && echo -e " ${SYM_OK} IAR-Dateien von ${COLOR_SERVER}$avatar${COLOR_RESET} kopiert.${COLOR_RESET}" done # Kopiere das updatelibrary.py-Skript ins Hauptverzeichnis ruthroth echo -e " ${COLOR_ACTION}➜ Kopiere updatelibrary.py nach ${COLOR_DIR}$base_dir${COLOR_ACTION}...${COLOR_RESET}" cp "updatelibrary.py" "$base_dir/" && echo -e " ${SYM_OK} updatelibrary.py wurde kopiert.${COLOR_RESET}" echo "Verzeichniswechsel in $base_dir" # Wechsel ins ruthroth-Verzeichnis cd "$base_dir" || { echo -e "${SYM_BAD} Fehler beim Wechsel ins Verzeichnis ${COLOR_DIR}$base_dir${COLOR_RESET}"; return 1; } # Entpacke die IAR-Dateien direkt in ruthroth echo -e " ${COLOR_ACTION}➜ Entpacke IAR-Pakete in ${COLOR_DIR}$base_dir${COLOR_ACTION}...${COLOR_RESET}" for iar_file in *.iar; do if [[ -f "$iar_file" ]]; then target_dir="${iar_file%.iar}" # Erstellt Verzeichnisname basierend auf Dateiname ohne .iar mkdir -p "$target_dir" tar -xzf "$iar_file" -C "$target_dir/" && echo -e " ✓ ${iar_file} entpackt nach ${target_dir}" else echo -e " ⚠ IAR-Datei ${iar_file} nicht gefunden. Überspringe..." fi done echo -e "${COLOR_OK}✅ ${COLOR_ACTION}Grundlage für die OpenSimulator-Pakete wurde erfolgreich erstellt!${COLOR_RESET}" # Schritt 2 die verwendung von updatelibrary.py. cd ruthroth python3 updatelibrary.py -n "Roth2-v1" -s "Roth2-v1" -a Roth2-v1 -i Roth2-v1 python3 updatelibrary.py -n "Roth2-v2" -s "Roth2-v2" -a Roth2-v2 -i Roth2-v2 python3 updatelibrary.py -n "Ruth2-v3" -s "Ruth2-v3" -a Ruth2-v3 -i Ruth2-v3 python3 updatelibrary.py -n "Ruth2-v4" -s "Ruth2-v4" -a Ruth2-v4 -i Ruth2-v4 cd .. # Schritt 3 das kopieren der Daten. Das einfügen der Daten in den Dateien ähnlich wie bei PBR. } function osslscriptsgit() { echo -e "${COLOR_HEADING}📜 OSSL Beispiel-Skripte GitHub-Verwaltung${COLOR_RESET}" echo -e "${COLOR_LABEL}Möchten Sie die OpenSim OSSL Beispiel-Skripte vom GitHub verwenden oder aktualisieren? (${COLOR_OK}[upgrade]${COLOR_LABEL}/new)${COLOR_RESET}" read -r user_choice user_choice=${user_choice:-upgrade} repo_name="opensim-ossl-example-scripts" repo_url="https://github.com/ManfredAabye/opensim-ossl-example-scripts.git" if [[ "$user_choice" == "new" ]]; then if [[ -d "$repo_name" ]]; then echo -e "${COLOR_ACTION}Vorhandene Version wird gelöscht...${COLOR_RESET}" rm -rf "$repo_name" echo -e "${SYM_OK} ${COLOR_ACTION}Alte Version wurde erfolgreich entfernt.${COLOR_RESET}" fi echo -e "${COLOR_ACTION}Beispiel-Skripte werden vom GitHub heruntergeladen...${COLOR_RESET}" git clone "$repo_url" "$repo_name" && echo -e "${SYM_OK} ${COLOR_ACTION}Repository wurde erfolgreich heruntergeladen.${COLOR_RESET}" elif [[ "$user_choice" == "upgrade" ]]; then if [[ -d "$repo_name/.git" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Repository gefunden. Aktualisiere mit 'git pull'...${COLOR_RESET}" cd "$repo_name" || { echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler beim Wechsel ins Verzeichnis!${COLOR_RESET}"; return 1; } branch_name=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@') git pull origin "$branch_name" && echo -e "${COLOR_OK}✅ ${COLOR_ACTION}Repository erfolgreich aktualisiert.${COLOR_RESET}" cd .. else echo -e "${COLOR_WARNING}⚠ ${COLOR_ACTION}Verzeichnis nicht gefunden oder kein Git-Repo. Klone Repository neu...${COLOR_RESET}" git clone "$repo_url" "$repo_name" && echo -e "${COLOR_OK}✅ ${COLOR_ACTION}Repository wurde erfolgreich heruntergeladen.${COLOR_RESET}" fi else echo -e "${SYM_BAD} ${COLOR_ERROR}Abbruch: Keine Aktion durchgeführt.${COLOR_RESET}" return 1 fi # Zielverzeichnisse erstellen falls nicht vorhanden mkdir -p opensim/bin/assets/ mkdir -p opensim/bin/inventory/ # Kopieren der Verzeichnisse if [[ -d "$repo_name/ScriptsAssetSet" ]]; then cp -r "$repo_name/ScriptsAssetSet" opensim/bin/assets/ echo -e "${SYM_OK} ${COLOR_ACTION}ScriptsAssetSet wurde nach opensim/bin/assets kopiert.${COLOR_RESET}" else echo -e "${SYM_BAD} ${COLOR_ERROR}ScriptsAssetSet Verzeichnis nicht gefunden!${COLOR_RESET}" fi if [[ -d "$repo_name/inventory/ScriptsLibrary" ]]; then cp -r "$repo_name/inventory/ScriptsLibrary" opensim/bin/inventory/ echo -e "${SYM_OK} ${COLOR_ACTION}ScriptsLibrary wurde nach opensim/bin/inventory kopiert.${COLOR_RESET}" else echo -e "${SYM_BAD} ${COLOR_ERROR}ScriptsLibrary Verzeichnis nicht gefunden!${COLOR_RESET}" fi blankline return 0 } # Es werden die Konfiguartionen jetzt auch geändert. function pbrtexturesgit() { echo -e "${COLOR_HEADING}🎨 PBR Texturen Installation${COLOR_RESET}" textures_zip_url="https://github.com/ManfredAabye/OpenSim_PBR_Textures/releases/download/PBR/OpenSim_PBR_Textures.zip" zip_file="OpenSim_PBR_Textures.zip" unpacked_dir="OpenSim_PBR_Textures" target_dir="opensim" # ZIP herunterladen, wenn nicht vorhanden if [[ ! -f "$zip_file" ]]; then echo -e "${COLOR_ACTION}Lade OpenSim PBR Texturen herunter...${COLOR_RESET}" if ! wget -q --show-progress -O "$zip_file" "$textures_zip_url"; then echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler beim Herunterladen der Texturen!${COLOR_RESET}" return 1 fi echo -e "${SYM_OK} ${COLOR_ACTION}Download abgeschlossen: ${COLOR_DIR}$zip_file${COLOR_RESET}" else echo -e "${SYM_OK} ${COLOR_ACTION}ZIP-Datei bereits vorhanden: ${COLOR_DIR}$zip_file${COLOR_RESET}" fi # Entpacken, wenn Verzeichnis noch nicht existiert if [[ ! -d "$unpacked_dir" ]]; then echo -e "${COLOR_ACTION}Entpacke Texturen nach ${COLOR_DIR}$unpacked_dir${COLOR_ACTION}...${COLOR_RESET}" unzip -q "$zip_file" -d . echo -e "${SYM_OK} ${COLOR_ACTION}Entpackt.${COLOR_RESET}" else echo -e "${SYM_OK} ${COLOR_ACTION}Verzeichnis ${COLOR_DIR}$unpacked_dir${COLOR_ACTION} existiert bereits – überspringe Entpacken.${COLOR_RESET}" fi # Kopieren nach opensim/bin if [[ -d "$unpacked_dir/bin" ]]; then echo -e "${COLOR_ACTION}Kopiere Texturen nach ${COLOR_DIR}$target_dir${COLOR_ACTION}...${COLOR_RESET}" cp -r "$unpacked_dir/bin" "$target_dir" echo -e "${SYM_OK} ${COLOR_ACTION}Texturen erfolgreich installiert in ${COLOR_DIR}$target_dir${COLOR_RESET}" else echo -e "${SYM_BAD} ${COLOR_ERROR}Verzeichnis ${COLOR_DIR}$unpacked_dir/bin${COLOR_ERROR} nicht gefunden!${COLOR_RESET}" return 1 fi local asset_sets_file="opensim/bin/assets/AssetSets.xml" local libraries_file="opensim/bin/inventory/Libraries.xml" # Funktion zur Überprüfung und Hinzufügung eines Eintrags add_xml_section() { local file="$1" local section_name="$2" local content="$3" # Überprüfen ob der Abschnitt bereits existiert if ! grep -q "
" "$file"; then # Abschnitt vor einfügen sed -i "s||
\n$content\n
\n|" "$file" echo "Added $section_name to $file" else echo "$section_name already exists in $file - no changes made" fi } # AssetSets.xml bearbeiten add_xml_section "$asset_sets_file" "PBR Textures AssetSet" \ " " # Libraries.xml bearbeiten add_xml_section "$libraries_file" "PBRTextures Library" \ " \n " blankline return 0 } function versionrevision() { file="opensim/OpenSim/Framework/VersionInfo.cs" if [[ ! -f "$file" ]]; then echo -e "${SYM_BAD} ${COLOR_ERROR}Datei nicht gefunden: ${COLOR_DIR}$file${COLOR_RESET}" return 1 fi echo -e "${SYM_OK} ${COLOR_ACTION}Bearbeite Datei: ${COLOR_DIR}$file${COLOR_RESET}" # Ändere Flavour.Dev zu Flavour.Extended sed -i 's/public const Flavour VERSION_FLAVOUR = Flavour\.Dev;/public const Flavour VERSION_FLAVOUR = Flavour.Extended;/' "$file" # Entferne "Nessie" aus dem Versions-String sed -i 's/OpenSim {versionNumber} Nessie {flavour}/OpenSim {versionNumber} {flavour}/' "$file" echo -e "${SYM_OK} ${COLOR_ACTION}Änderungen wurden erfolgreich vorgenommen.${COLOR_RESET}" blankline return 0 } function opensimbuild() { echo -e "${COLOR_HEADING}🏗️ OpenSimulator Build-Prozess${COLOR_RESET}" echo -e "${COLOR_LABEL}Möchten Sie den OpenSimulator jetzt erstellen? (${COLOR_OK}[ja]${COLOR_LABEL}/nein)${COLOR_RESET}" read -r user_choice user_choice=${user_choice:-ja} if [[ "$user_choice" == "ja" ]]; then if [[ -d "opensim" ]]; then cd opensim || { echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Verzeichnis 'opensim' nicht gefunden.${COLOR_RESET}"; return 1; } echo -e "${COLOR_ACTION}Starte Prebuild-Skript...${COLOR_RESET}" bash runprebuild.sh echo -e "${COLOR_ACTION}Baue OpenSimulator...${COLOR_RESET}" dotnet build --configuration Release OpenSim.sln echo -e "${SYM_OK} ${COLOR_ACTION}OpenSimulator wurde erfolgreich erstellt.${COLOR_RESET}" else echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Das Verzeichnis 'opensim' existiert nicht.${COLOR_RESET}" return 1 fi else echo -e "${SYM_BAD} ${COLOR_ERROR}Abbruch: OpenSimulator wird nicht erstellt.${COLOR_RESET}" fi blankline } #?────────────────────────────────────────────────────────────────────────────────────────── #* Erstellen eines OpenSimulators Grids #?────────────────────────────────────────────────────────────────────────────────────────── function createdirectory() { echo -e "${COLOR_HEADING}📂 Verzeichniserstellung${COLOR_RESET}" echo -e "${COLOR_LABEL}Möchten Sie einen Gridserver oder einen Regionsserver erstellen? (${COLOR_OK}[grid]${COLOR_LABEL}/region)${COLOR_RESET}" read -r server_type # Standardmäßig Gridserver wählen, falls keine Eingabe erfolgt server_type=${server_type:-grid} if [[ "$server_type" == "grid" ]]; then echo -e "${COLOR_ACTION}Erstelle robust Verzeichnis...${COLOR_RESET}" mkdir -p robust/bin echo -e "${SYM_OK} ${COLOR_ACTION}Robust Verzeichnis wurde erstellt.${COLOR_RESET}" # Nach der Erstellung des Gridservers auch die Regionsserver erstellen lassen echo -e "${COLOR_LABEL}Wie viele Regionsserver benötigen Sie?${COLOR_RESET}" read -r num_regions elif [[ "$server_type" == "region" ]]; then echo -e "${COLOR_LABEL}Wie viele Regionsserver benötigen Sie?${COLOR_RESET}" read -r num_regions else echo -e "${SYM_BAD} ${COLOR_ERROR}Ungültige Eingabe. Bitte geben Sie 'grid' oder 'region' ein.${COLOR_RESET}" return 1 fi # Überprüfen, ob die Anzahl der Regionsserver bis 999 geht if [[ "$num_regions" =~ ^[0-9]+$ && "$num_regions" -le 999 ]]; then for ((i=1; i<=num_regions; i++)); do dir_name="sim$i" if [[ ! -d "$dir_name" ]]; then mkdir -p "$dir_name/bin" echo -e "${SYM_OK} ${COLOR_DIR}$dir_name${COLOR_RESET} ${COLOR_ACTION}wurde erstellt.${COLOR_RESET}" else echo -e "${SYM_OK} ${COLOR_DIR}$dir_name${COLOR_RESET} ${COLOR_WARNING}existiert bereits und wird übersprungen.${COLOR_RESET}" fi done else echo -e "${SYM_BAD} ${COLOR_ERROR}Ungültige Anzahl an Regionsserver. Bitte geben Sie eine gültige Zahl zwischen 1 und 999 ein.${COLOR_RESET}" fi blankline } function opensimcopy() { echo -e "${COLOR_HEADING}📦 OpenSim Dateikopie${COLOR_RESET}" # Prüfen, ob das Verzeichnis "opensim" existiert if [[ ! -d "opensim" ]]; then echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Das Verzeichnis 'opensim' existiert nicht.${COLOR_RESET}" return 1 fi # Prüfen, ob das Unterverzeichnis "opensim/bin" existiert if [[ ! -d "opensim/bin" ]]; then echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Das Verzeichnis 'opensim/bin' existiert nicht.${COLOR_RESET}" return 1 fi # Prüfen, ob das Verzeichnis "robust" existiert und Dateien kopieren if [[ -d "robust/bin" ]]; then cp -r opensim/bin/* robust/bin echo -e "${SYM_OK} ${COLOR_ACTION}Dateien aus ${COLOR_DIR}opensim/bin${COLOR_RESET} ${COLOR_ACTION}wurden nach ${COLOR_DIR}robust/bin${COLOR_RESET} ${COLOR_ACTION}kopiert.${COLOR_RESET}" else echo -e "${COLOR_WARNING}⚠ ${COLOR_ACTION}Hinweis: 'robust' Verzeichnis nicht gefunden, keine Kopie durchgeführt.${COLOR_RESET}" fi # Alle simX-Verzeichnisse suchen und Dateien kopieren for sim_dir in sim*; do if [[ -d "$sim_dir/bin" ]]; then cp -r opensim/bin/* "$sim_dir/bin/" echo -e "${SYM_OK} ${COLOR_ACTION}Dateien aus ${COLOR_DIR}opensim/bin${COLOR_RESET} ${COLOR_ACTION}wurden nach ${COLOR_DIR}$sim_dir/bin${COLOR_RESET} ${COLOR_ACTION}kopiert.${COLOR_RESET}" fi done blankline } function database_setup() { echo -e "${COLOR_SECTION}=== MariaDB/MySQL Datenbank-Setup ===${COLOR_RESET}" # 1. Distribution Detection detect_distro() { if [[ -f /etc/os-release ]]; then awk -F= '/^ID=/ {print $2}' /etc/os-release | tr -d '"' elif [[ -f /etc/debian_version ]]; then echo "debian" elif [[ -f /etc/centos-release ]]; then echo "centos" else echo "unknown" fi } current_distro=$(detect_distro) supported_distros=("debian" "ubuntu" "linuxmint" "pop" "mx" "kali" "zorin" "elementary" "raspbian" "centos" "fedora") # 2. Support-Check if ! printf '%s\n' "${supported_distros[@]}" | grep -q "^${current_distro}$"; then echo -e "${SYM_BAD} ${COLOR_BAD}Nicht unterstützte Distribution: '${current_distro}'${COLOR_RESET}" echo -e "${SYM_INFO} Unterstützt: ${supported_distros[*]}" return 1 fi # 3. Installation Check if ! command -v mariadb &> /dev/null && ! command -v mysql &> /dev/null; then echo -e "${SYM_WAIT} ${COLOR_WARNING}MariaDB/MySQL ist nicht installiert${COLOR_RESET}" read -rp "$(echo -e "${COLOR_ACTION}MariaDB installieren? (j/n) ${COLOR_RESET}")" install_choice [[ "$install_choice" =~ ^[jJ] ]] || { echo -e "${SYM_BAD} Installation abgebrochen"; return 0; } case $current_distro in debian|ubuntu|*mint|pop|zorin|elementary|kali|mx|raspbian) echo -e "${SYM_INFO} ${COLOR_ACTION}Installiere MariaDB...${COLOR_RESET}" sudo apt-get update && sudo apt-get install -y mariadb-server ;; centos|fedora) echo -e "${SYM_INFO} ${COLOR_ACTION}Installiere MariaDB...${COLOR_RESET}" sudo yum install -y mariadb-server sudo systemctl start mariadb sudo systemctl enable mariadb ;; *) echo -e "${SYM_BAD} ${COLOR_BAD}Automatische Installation nicht verfügbar${COLOR_RESET}"; return 1 ;; esac sudo mysql_secure_installation else echo -e "${SYM_OK} ${COLOR_OK}MariaDB/MySQL ist bereits installiert${COLOR_RESET}" fi # 4. Benutzeranmeldedaten echo -e "\n${COLOR_SECTION}=== Datenbank-Zugangsdaten ===${COLOR_RESET}" read -rp "$(echo -e "${COLOR_ACTION}Standard-Zugangsdaten verwenden? (j/n) ${COLOR_RESET}")" default_cred_choice if [[ "$default_cred_choice" =~ ^[jJ] ]]; then db_user="simuser" db_pass=$(tr -dc 'A-Za-z0-9!@#$%^&*()' < /dev/urandom | head -c 16) echo -e "${SYM_INFO} ${COLOR_LABEL}Generiertes Passwort: ${COLOR_VALUE}${db_pass}${COLOR_RESET}" else read -rp "$(echo -e "${COLOR_ACTION}Benutzername: ${COLOR_RESET}")" db_user read -rsp "$(echo -e "${COLOR_ACTION}Passwort: ${COLOR_RESET}")" db_pass echo fi # 5. Datenbankeinrichtung echo -e "\n${COLOR_SECTION}=== Datenbank-Konfiguration ===${COLOR_RESET}" # RobustServer DB if [[ -d "robust" ]]; then if ! sudo mysql -e "USE robust" &> /dev/null; then sudo mysql -e "CREATE DATABASE robust CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" echo -e "${SYM_OK} ${COLOR_VALUE}robust${COLOR_RESET} Datenbank angelegt" else echo -e "${SYM_INFO} ${COLOR_WARNING}robust-Datenbank existiert bereits${COLOR_RESET}" fi fi # simX Server DBs for ((i=1; i<=1000; i++)); do if [[ -d "sim${i}" ]]; then db_name="sim${i}" if ! sudo mysql -e "USE ${db_name}" &> /dev/null; then sudo mysql -e "CREATE DATABASE ${db_name} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci" echo -e "${SYM_OK} ${COLOR_VALUE}${db_name}${COLOR_RESET} Datenbank angelegt" else echo -e "${SYM_INFO} ${COLOR_WARNING}${db_name}-Datenbank existiert bereits${COLOR_RESET}" fi fi done # Benutzerverwaltung if ! sudo mysql -e "SELECT user FROM mysql.user WHERE user='${db_user}' AND host='localhost'" | grep -q "${db_user}"; then sudo mysql -e "CREATE USER '${db_user}'@'localhost' IDENTIFIED BY '${db_pass}'" echo -e "${SYM_OK} ${COLOR_VALUE}${db_user}${COLOR_RESET} Benutzer angelegt" else echo -e "${SYM_INFO} ${COLOR_WARNING}Benutzer ${db_user} existiert bereits${COLOR_RESET}" fi # Rechte vergeben [[ -d "robust" ]] && sudo mysql -e "GRANT ALL PRIVILEGES ON robust.* TO '${db_user}'@'localhost'" for ((i=1; i<=1000; i++)); do [[ -d "sim${i}" ]] && sudo mysql -e "GRANT ALL PRIVILEGES ON sim${i}.* TO '${db_user}'@'localhost'" done sudo mysql -e "FLUSH PRIVILEGES" # 6. Zusammenfassung echo -e "\n${COLOR_SECTION}=== Zusammenfassung ===${COLOR_RESET}" echo -e "${COLOR_LABEL}Benutzername: ${COLOR_VALUE}${db_user}${COLOR_RESET}" echo -e "${COLOR_LABEL}Passwort: ${COLOR_VALUE}${db_pass}${COLOR_RESET}" if sudo mysql -e "SELECT user FROM mysql.user WHERE user='${db_user}' AND host='localhost'" | grep -q "${db_user}"; then echo -e "${COLOR_LABEL}Berechtigungen:${COLOR_RESET}" sudo mysql -e "SHOW GRANTS FOR '${db_user}'@'localhost'" else echo -e "${SYM_BAD} ${COLOR_WARNING}Benutzerberechtigungen nicht verfügbar${COLOR_RESET}" fi # Zugangsdaten speichern echo -e "\n${SYM_LOG} ${COLOR_LABEL}Zugangsdaten gespeichert in: ${COLOR_FILE}${SCRIPT_DIR}/mariadb_passwords.txt${COLOR_RESET}" echo "Benutzername: ${db_user} Passwort: ${db_pass}" | sudo tee "${SCRIPT_DIR}/mariadb_passwords.txt" >/dev/null } function setcrontab() { # Strict Mode: Fehler sofort erkennen set -euo pipefail echo -e "${COLOR_HEADING}⏰ Cron-Job Einrichtung${COLOR_RESET}" # Sicherheitsabfrage: Nur als root/sudo ausführen if [ "$(id -u)" -ne 0 ]; then echo -e "${SYM_BAD} ${COLOR_ERROR}FEHLER: Dieses Skript benötigt root-Rechte! (sudo verwenden)${COLOR_RESET}" >&2 return 1 fi # Prüfen, ob SCRIPT_DIR gesetzt und gültig ist if [ -z "${SCRIPT_DIR:-}" ]; then echo -e "${SYM_BAD} ${COLOR_ERROR}FEHLER: 'SCRIPT_DIR' muss gesetzt sein!${COLOR_RESET}" >&2 return 1 fi if [ ! -d "$SCRIPT_DIR" ]; then echo -e "${SYM_BAD} ${COLOR_ERROR}FEHLER: Verzeichnis '${COLOR_DIR}$SCRIPT_DIR${COLOR_ERROR}' existiert nicht!${COLOR_RESET}" >&2 return 1 fi # Temporäre Datei für neue Cron-Jobs local temp_cron temp_cron=$(mktemp) || { echo -e "${SYM_BAD} ${COLOR_ERROR}FEHLER: Temp-Datei konnte nicht erstellt werden${COLOR_RESET}" >&2 return 1 } # Neue Cron-Jobs schreiben (ERSETZT alle alten) cat << EOF > "$temp_cron" # === OpenSimGrid-Automatisierung === # Minute Stunde Tag Monat Jahr Befehl # Server-Neustart am 1. jedes Monats 40 4 1 * * bash '$SCRIPT_DIR/osmtool.sh' cacheclean 45 4 1 * * bash '$SCRIPT_DIR/osmtool.sh' reboot # Taegliche Wartung 55 4 * * * bash '$SCRIPT_DIR/osmtool.sh' logclean 0 5 * * * bash '$SCRIPT_DIR/osmtool.sh' autorestart # Ueberwachung alle 30 Minuten */30 * * * * bash '$SCRIPT_DIR/osmtool.sh' check_screens EOF # Cron-Jobs installieren if crontab "$temp_cron"; then rm -f "$temp_cron" echo -e "${SYM_OK} ${COLOR_ACTION}Cron-Jobs wurden ERFOLGREICH ersetzt:${COLOR_RESET}" crontab -l | grep -v '^#' | sed '/^$/d' | while read -r line; do echo -e "${COLOR_DIR}$line${COLOR_RESET}" done return 0 else echo -e "${SYM_BAD} ${COLOR_ERROR}FEHLER: Installation fehlgeschlagen. Prüfe $temp_cron manuell.${COLOR_RESET}" >&2 return 1 fi } #?────────────────────────────────────────────────────────────────────────────────────────── #* Upgrade des OpenSimulators Grids #?────────────────────────────────────────────────────────────────────────────────────────── function opensimupgrade() { echo -e "\n${COLOR_WARNING}⚠ Der OpenSimulator muss zuerst im Verzeichnis 'opensim' vorliegen!${COLOR_RESET}" echo -e "${COLOR_LABEL}Möchten Sie den OpenSimulator aktualisieren? (${COLOR_BAD}[no]${COLOR_LABEL}/yes)${COLOR_RESET}" read -r user_choice user_choice=${user_choice:-no} # Prüfe, ob das Verzeichnis vorhanden ist if [[ ! -d "opensim" ]]; then echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Das Verzeichnis '${COLOR_DIR}opensim${COLOR_ERROR}' existiert nicht${COLOR_RESET}" return 1 fi # Prüfe, ob im Verzeichnis 'opensim/bin' die Dateien OpenSim.dll und Robust.dll vorhanden sind if [[ ! -f "opensim/bin/OpenSim.dll" || ! -f "opensim/bin/Robust.dll" ]]; then echo -e "${SYM_BAD} ${COLOR_ERROR}Fehler: Benötigte Dateien (OpenSim.dll und/oder Robust.dll) fehlen im Verzeichnis '${COLOR_DIR}opensim/bin${COLOR_ERROR}'${COLOR_RESET}" echo -e "\n${COLOR_WARNING}❓ Haben Sie vergessen den OpenSimulator zuerst zu Kompilieren?${COLOR_RESET}" return 1 fi if [[ "$user_choice" == "yes" ]]; then echo -e "${COLOR_ACTION}OpenSimulator wird gestoppt...${COLOR_RESET}" opensimstop sleep 30 echo -e "${COLOR_ACTION}OpenSimulator wird kopiert...${COLOR_RESET}" opensimcopy echo -e "${COLOR_ACTION}OpenSimulator wird gestartet...${COLOR_RESET}" opensimstart echo -e "${COLOR_OK}✔ ${COLOR_ACTION}Upgrade abgeschlossen.${COLOR_RESET}" else echo -e "${COLOR_WARNING}Upgrade vom Benutzer abgebrochen.${COLOR_RESET}" fi blankline } #?────────────────────────────────────────────────────────────────────────────────────────── #* Bereinigen des OpenSimulators Grids #?────────────────────────────────────────────────────────────────────────────────────────── function dataclean() { echo -e "${COLOR_HEADING}🧹 Datenbereinigung wird durchgeführt...${COLOR_RESET}" # RobustServer bereinigen if [[ -d "robust/bin" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Lösche Dateien im RobustServer...${COLOR_RESET}" find "robust/bin" -maxdepth 1 -type f \( -name "*.log" -o -name "*.dll" -o -name "*.exe" -o -name "*.so" -o -name "*.xml" -o -name "*.dylib" -o -name "*.example" -o -name "*.sample" -o -name "*.txt" -o -name "*.config" -o -name "*.py" -o -name "*.old" -o -name "*.pdb" \) -delete fi # Alle simX-Server bereinigen for ((i=1; i<=999; i++)); do sim_dir="sim$i/bin" if [[ -d "$sim_dir" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Lösche Dateien in ${COLOR_DIR}$sim_dir...${COLOR_RESET}" find "$sim_dir" -maxdepth 1 -type f \( -name "*.log" -o -name "*.dll" -o -name "*.exe" -o -name "*.so" -o -name "*.xml" -o -name "*.dylib" -o -name "*.example" -o -name "*.sample" -o -name "*.txt" -o -name "*.config" -o -name "*.py" -o -name "*.old" -o -name "*.pdb" \) -delete fi done echo -e "${COLOR_HEADING}✅ Datenbereinigung abgeschlossen${COLOR_RESET}" blankline } function pathclean() { directories=("assetcache" "maptiles" "MeshCache" "j2kDecodeCache" "ScriptEngines" "bakes" "addon-modules") wildcard_dirs=("addin-db-*") # Separate Liste für Wildcard-Verzeichnisse echo -e "${COLOR_HEADING}🗂️ Verzeichnisbereinigung wird durchgeführt...${COLOR_RESET}" # RobustServer bereinigen if [[ -d "robust/bin" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Lösche komplette Verzeichnisse im RobustServer...${COLOR_RESET}" # Normale Verzeichnisse for dir in "${directories[@]}"; do target="robust/bin/$dir" if [[ -d "$target" ]]; then rm -rf "$target" echo -e " ${COLOR_ACTION}Verzeichnis gelöscht: ${COLOR_DIR}$target${COLOR_RESET}" fi done # Wildcard-Verzeichnisse for pattern in "${wildcard_dirs[@]}"; do for target in robust/bin/$pattern; do if [[ -d "$target" ]]; then rm -rf "$target" echo -e " ${COLOR_WARNING}Verzeichnis gelöscht: ${COLOR_DIR}$target${COLOR_RESET}" fi done done fi # Alle simX-Server bereinigen for ((i=1; i<=999; i++)); do sim_dir="sim$i/bin" if [[ -d "$sim_dir" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Lösche komplette Verzeichnisse in ${COLOR_DIR}$sim_dir...${COLOR_RESET}" # Normale Verzeichnisse for dir in "${directories[@]}"; do target="$sim_dir/$dir" if [[ -d "$target" ]]; then rm -rf "$target" echo -e " ${COLOR_ACTION}Verzeichnis gelöscht: ${COLOR_DIR}$target${COLOR_RESET}" fi done # Wildcard-Verzeichnisse for pattern in "${wildcard_dirs[@]}"; do for target in $sim_dir/$pattern; do if [[ -d "$target" ]]; then rm -rf "$target" echo -e " ${COLOR_WARNING}Verzeichnis gelöscht: ${COLOR_DIR}$target${COLOR_RESET}" fi done done fi done echo -e "${COLOR_HEADING}✅ Verzeichnisbereinigung abgeschlossen${COLOR_RESET}" blankline } function cacheclean() { cache_dirs=("assetcache" "maptiles" "MeshCache" "j2kDecodeCache" "ScriptEngines") echo -e "${COLOR_HEADING}♻️ Cache-Bereinigung wird durchgeführt...${COLOR_RESET}" # RobustServer bereinigen if [[ -d "robust/bin" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Leere Cache-Verzeichnisse im RobustServer...${COLOR_RESET}" for dir in "${cache_dirs[@]}"; do target="robust/bin/$dir" if [[ -d "$target" ]]; then find "$target" -mindepth 1 -delete echo -e " ${COLOR_ACTION}Inhalt geleert: ${COLOR_DIR}$target${COLOR_RESET}" fi done fi # Alle simX-Server bereinigen for ((i=1; i<=999; i++)); do sim_dir="sim$i/bin" if [[ -d "$sim_dir" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Leere Cache-Verzeichnisse in ${COLOR_DIR}$sim_dir...${COLOR_RESET}" for dir in "${cache_dirs[@]}"; do target="$sim_dir/$dir" if [[ -d "$target" ]]; then find "$target" -mindepth 1 -delete echo -e " ${COLOR_ACTION}Inhalt geleert: ${COLOR_DIR}$target${COLOR_RESET}" fi done fi done echo -e "${COLOR_HEADING}✅ Cache-Bereinigung abgeschlossen${COLOR_RESET}" blankline } function logclean() { echo -e "${SYM_LOG}${COLOR_HEADING} Log-Bereinigung wird durchgeführt...${COLOR_RESET}" # RobustServer bereinigen if [[ -d "robust/bin" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Lösche Log-Dateien in ${COLOR_DIR}robust/bin...${COLOR_RESET}" rm -f robust/bin/*.log fi # Alle simX-Server bereinigen (sim1 bis sim999) for ((i=1; i<=999; i++)); do sim_dir="sim$i/bin" if [[ -d "$sim_dir" ]]; then echo -e "${SYM_OK} ${COLOR_ACTION}Lösche Log-Dateien in ${COLOR_DIR}$sim_dir...${COLOR_RESET}" rm -f "$sim_dir"/*.log fi done echo -e "${COLOR_HEADING}Log-Bereinigung abgeschlossen${COLOR_RESET}" blankline } function mapclean() { echo -e "${COLOR_HEADING}🗺️ Map-Tile-Bereinigung wird durchgeführt...${COLOR_RESET}" # Sicherheitscheck für robust/bin/maptiles if [[ -d "robust/bin/maptiles" ]]; then rm -rf -- "robust/bin/maptiles/"* echo -e "${SYM_OK} ${COLOR_ACTION}robust/bin/maptiles geleert${COLOR_RESET}" fi # Sicherheitscheck für alle simX/bin/maptiles for ((i=1; i<=999; i++)); do local sim_dir="sim$i/bin/maptiles" if [[ -d "$sim_dir" ]]; then # shellcheck disable=SC2115 rm -rf -- "${sim_dir}/"* echo -e "${SYM_OK} ${COLOR_ACTION}${COLOR_DIR}$sim_dir${COLOR_RESET} ${COLOR_ACTION}geleert${COLOR_RESET}" fi done echo -e "${COLOR_HEADING}✅ Map-Tile-Bereinigung abgeschlossen${COLOR_RESET}" blankline } function autoallclean() { local confirm # Warnung in Gelb (konsistenter mit \e anstelle von \033) echo -e "\e[33m" cat >&2 <<'WARNUNG' === WARNUNG: Alle Daten-, Verzeichnis-, Cache-, Log- und Map-Daten werden bereinigt! === === DIESE OPERATION KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN! === === DER OPENSIMULATOR MUSS IM ANSCHLUSS NEU INSTALLIERT WERDEN! === WARNUNG echo -e "\e[0m" # Bestätigung mit Timeout (10 Sekunden) für Sicherheit read -t 30 -r -p "Fortfahren? (ja/NEIN): " confirm || { echo -e "\n\e[31mTimeout: Keine Bestätigung erhalten. Abbruch.\e[0m" >&2 return 1 } case "${confirm,,}" in ja|j|y|yes) echo -e "\e[32mBereinigung wird gestartet...\e[0m" >&2 # Jede Clean-Funktion mit Fehlerprüfung local clean_functions=(dataclean pathclean cacheclean logclean mapclean) for func in "${clean_functions[@]}"; do if ! command -v "$func" &>/dev/null; then echo -e "\e[31mFehler: '$func' ist keine gültige Funktion!\e[0m" >&2 return 1 fi "$func" || { echo -e "\e[31mFehler bei $func!\e[0m" >&2 return 1 } done echo -e "\e[32mBereinigung abgeschlossen.\e[0m" >&2 ;; *) echo -e "\e[33mAbbruch: Bereinigung wurde nicht durchgeführt.\e[0m" >&2 return 1 ;; esac blankline } #?────────────────────────────────────────────────────────────────────────────────────────── #* Konfigurationen #?────────────────────────────────────────────────────────────────────────────────────────── # shellcheck disable=SC2317 function verify_ini_section() { local file="$1" local section="$2" if [ ! -f "$file" ]; then echo -e "${SYM_BAD} Error: File ${file} does not exist" >&2 return 2 fi if grep -q "^\[${section}\]" "$file"; then echo -e "${SYM_OK} Section [${section}] exists in ${file}" return 0 else echo -e "${SYM_BAD} Section [${section}] not found in ${file}" return 1 fi } # shellcheck disable=SC2317 function verify_ini_key() { local file="$1" local section="$2" local key="$3" if [ ! -f "$file" ]; then echo -e "${SYM_BAD} Error: File ${file} does not exist" >&2 return 2 fi # Finde den Abschnitt und dann den Key darin if awk -v section="[${section}]" -v key="^${key}=" ' $0 == section { in_section=1; next } in_section && /^\[/ { in_section=0; next } in_section && $0 ~ key { found=1; exit } END { exit !found }' "$file"; then echo -e "${SYM_OK} Key ${key} in section [${section}] exists in ${file}" return 0 else echo -e "${SYM_BAD} Key ${key} in section [${section}] not found in ${file}" return 1 fi } # shellcheck disable=SC2317 function add_ini_section() { local file="$1" local section="$2" if verify_ini_section "$file" "$section" >/dev/null; then return 0 fi echo -e "${SYM_INFO} Adding section [${section}] to ${file}" # Abschnitt am Ende der Datei hinzufügen if printf "\n[%s]\n" "$section" >> "$file"; then echo -e "${SYM_OK} Successfully added section [${section}] to ${file}" return 0 else echo -e "${SYM_BAD} Failed to add section [${section}] to ${file}" >&2 return 1 fi } # shellcheck disable=SC2317 function set_ini_key() { local file="$1" section="$2" key="$3" value="$4" local temp_file temp_file=$(mktemp) || { echo -e "${COLOR_BAD}Failed to create temp file${COLOR_RESET}" >&2 return 1 } # Verarbeitung mit awk if ! awk -v section="[${section}]" -v key="$key" -v value="$value" ' BEGIN { in_section = 0; modified = 0 } $0 == section { in_section = 1; print; next } in_section && /^\[/ { # Neue Sektion beginnt, Key einfügen printf "%s=%s\n\n", key, value modified = 1 in_section = 0 } in_section && $0 ~ "^[[:blank:]]*" key "=" { # Existierenden Key ersetzen (ignoriert führende Leerzeichen/Tabs) printf "%s=%s\n", key, value modified = 1 in_section = 0 next } { print } END { if (!modified && in_section) { # Am Ende der Sektion einfügen printf "%s=%s\n", key, value } else if (!modified) { # Neue Sektion am Dateiende printf "\n[%s]\n%s=%s\n", section, key, value } } ' "$file" > "$temp_file"; then echo -e "${COLOR_BAD}AWK processing failed${COLOR_RESET}" >&2 rm -f "$temp_file" return 1 fi if ! mv "$temp_file" "$file"; then echo -e "${COLOR_BAD}Failed to update ${COLOR_FILE}${file}${COLOR_RESET}" >&2 return 1 fi echo -e "${COLOR_OK}Set ${COLOR_KEY}${key}=${COLOR_VALUE}${value}${COLOR_OK} in [${section}]${COLOR_RESET}" return 0 } # shellcheck disable=SC2317 function del_ini_section() { local file="$1" local section="$2" # Verifizieren ob der Abschnitt existiert (still, ohne Ausgabe) if ! verify_ini_section "$file" "$section" >/dev/null; then echo -e "${SYM_INFO} Section [${section}] not found in ${COLOR_FILE}${file}${COLOR_RESET}" return 0 fi echo -e "${SYM_INFO} Removing section [${COLOR_SECTION}${section}${COLOR_RESET}] from ${COLOR_FILE}${file}${COLOR_RESET}" # Temporäre Datei mit Fehlerbehandlung local temp_file temp_file=$(mktemp) || { echo -e "${SYM_BAD} Failed to create temporary file" >&2 return 1 } # Abschnitt entfernen if awk -v section="[${section}]" ' $0 == section { skip=1; next } skip && /^\[/ { skip=0 } !skip { print } ' "$file" > "$temp_file"; then if mv "$temp_file" "$file"; then echo -e "${SYM_OK} Successfully removed section [${COLOR_SECTION}${section}${COLOR_RESET}]" return 0 else echo -e "${SYM_BAD} Failed to update ${COLOR_FILE}${file}${COLOR_RESET}" >&2 rm -f "$temp_file" return 1 fi else echo -e "${SYM_BAD} AWK processing failed" >&2 rm -f "$temp_file" return 1 fi } # shellcheck disable=SC2317 function uncomment_ini_line() { local file="$1" local search_key="$2" # Sicherheitsprüfungen [ ! -f "$file" ] && { echo -e "${COLOR_BAD}Datei nicht gefunden: ${file}${COLOR_RESET}" >&2; return 1; } [ -z "$search_key" ] && { echo -e "${COLOR_BAD}Suchschlüssel darf nicht leer sein${COLOR_RESET}" >&2; return 1; } # Temporäre Datei erstellen local temp_file temp_file=$(mktemp) || { echo -e "${COLOR_BAD}Temp-Datei konnte nicht erstellt werden${COLOR_RESET}" >&2; return 1; } # Entkommentieren der Zeile sed -E "/^[[:space:]]*;[[:space:]]*${search_key}[[:space:]]*=/s/^[[:space:]]*;//" "$file" > "$temp_file" || { rm -f "$temp_file" echo -e "${COLOR_BAD}Sed-Verarbeitung fehlgeschlagen${COLOR_RESET}" >&2 return 1 } # Originaldatei ersetzen if mv "$temp_file" "$file"; then echo -e "${COLOR_OK}Zeile '${search_key}' erfolgreich entkommentiert${COLOR_RESET}" return 0 else echo -e "${COLOR_BAD}Datei konnte nicht aktualisiert werden${COLOR_RESET}" >&2 return 1 fi } #* Beispiel Implementierung function configure_example_ini() { local config_file="example.ini" echo -e "\n${COLOR_HEADING}=== Example INI Configuration ===${COLOR_RESET}" # Abschnitt erstellen add_ini_section "$config_file" "database" # Keys setzen set_ini_key "$config_file" "database" "host" "localhost" set_ini_key "$config_file" "database" "port" "3306" set_ini_key "$config_file" "database" "user" "admin" # Verifizieren verify_ini_key "$config_file" "database" "host" verify_ini_key "$config_file" "database" "port" # Zum Testen des Löschens folgende Zeile einkommentieren: # del_ini_section "$config_file" "database" } # shellcheck disable=SC2317 function verify_xml_section() { local file="$1" local section_name="$2" if [ ! -f "$file" ]; then echo -e "${SYM_BAD} ${COLOR_BAD}Error: File ${COLOR_DIR}${file}${COLOR_BAD} does not exist${COLOR_RESET}" >&2 return 2 fi if grep -q "
" "$file"; then echo -e "${SYM_OK} ${COLOR_LABEL}Section ${COLOR_VALUE}'$section_name'${COLOR_LABEL} exists in ${COLOR_DIR}${file}${COLOR_RESET}" return 0 else echo -e "${SYM_BAD} ${COLOR_LABEL}Section ${COLOR_VALUE}'$section_name'${COLOR_LABEL} not found in ${COLOR_DIR}${file}${COLOR_RESET}" return 1 fi } # shellcheck disable=SC2317 function add_xml_section() { local file="$1" local section_name="$2" local content="$3" local closing_tag="${4:-}" # Standard ist , kann überschrieben werden # Verifizieren ob der Abschnitt bereits existiert if verify_xml_section "$file" "$section_name" >/dev/null; then return 0 fi # Temporäre Datei für Sicherheitskopie local temp_file temp_file=$(mktemp) echo -e "${SYM_INFO} ${COLOR_ACTION}Adding section ${COLOR_VALUE}'$section_name'${COLOR_ACTION} to ${COLOR_DIR}${file}${COLOR_RESET}" # Abschnitt vor dem schließenden Tag einfügen if sed "s|$closing_tag|
\n$content\n
\n$closing_tag|" "$file" > "$temp_file"; then if mv "$temp_file" "$file"; then echo -e "${SYM_OK} ${COLOR_OK}Successfully added section ${COLOR_VALUE}'$section_name'${COLOR_OK} to ${COLOR_DIR}${file}${COLOR_RESET}" return 0 fi fi echo -e "${SYM_BAD} ${COLOR_BAD}Failed to add section ${COLOR_VALUE}'$section_name'${COLOR_BAD} to ${COLOR_DIR}${file}${COLOR_RESET}" >&2 return 1 } # shellcheck disable=SC2317 function del_xml_section() { local file="$1" local section_name="$2" # Verifizieren ob der Abschnitt existiert if ! verify_xml_section "$file" "$section_name" >/dev/null; then return 0 # Abschnitt existiert nicht - nichts zu tun fi # Temporäre Datei für Sicherheitskopie local temp_file temp_file=$(mktemp) echo -e "${SYM_INFO} ${COLOR_ACTION}Removing section ${COLOR_VALUE}'$section_name'${COLOR_ACTION} from ${COLOR_DIR}${file}${COLOR_RESET}" # Abschnitt entfernen (inklusive aller Zeilen zwischen Section-Tags) if sed "/
/,/<\/Section>/d" "$file" > "$temp_file"; then if mv "$temp_file" "$file"; then echo -e "${SYM_OK} ${COLOR_OK}Successfully removed section ${COLOR_VALUE}'$section_name'${COLOR_OK} from ${COLOR_DIR}${file}${COLOR_RESET}" return 0 fi fi echo -e "${SYM_BAD} ${COLOR_BAD}Failed to remove section ${COLOR_VALUE}'$section_name'${COLOR_BAD} from ${COLOR_DIR}${file}${COLOR_RESET}" >&2 return 1 } #* Beispiel Implementierung für PBR Textures ohne Test eingefügt. function configure_pbr_textures() { local asset_sets_file="opensim/bin/assets/AssetSets.xml" local libraries_file="opensim/bin/inventory/Libraries.xml" echo -e "\n${COLOR_HEADING}=== Configuring PBR Textures ===${COLOR_RESET}" # AssetSets.xml bearbeiten add_xml_section "$asset_sets_file" "PBR Textures AssetSet" \ " " || return 1 # Libraries.xml bearbeiten add_xml_section "$libraries_file" "PBRTextures Library" \ " \n " || return 1 echo -e "${SYM_OK} ${COLOR_OK}PBR Textures configuration completed successfully${COLOR_RESET}" } # Funktion zur Generierung von UUIDs function generate_uuid() { uuidgen | tr '[:upper:]' '[:lower:]' } # Funktion zur Generierung von Zufallsnamen function generate_name() { local adjectives=( # Mystisch & Magisch (25) "Mystic" "Arcane" "Eldritch" "Enigmatic" "Esoteric" "Occult" "Cryptic" "Celestial" "Astral" "Ethereal" "Luminous" "Radiant" "Prismatic" "Iridescent" "Phantasmal" "Spectral" "Otherworldly" "Transcendent" "Timeless" "Unearthly" "Enchanted" "Charmed" "Bewitched" "Mythic" "Legendary" # Natürlich & Elementar (25) "Verdant" "Sylvan" "Petrified" "Thundering" "Whispering" "Howling" "Roaring" "Rumbling" "Crystalline" "Obsidian" "Amber" "Jade" "Sapphire" "Emerald" "Ruby" "Topaz" "Opaline" "Pearlescent" "Gilded" "Argent" "Solar" "Lunar" "Stellar" "Nebular" "Galactic" ) local nouns=( # Natürliche Orte (25) "Forest" "Grove" "Copse" "Thicket" "Wildwood" "Jungle" "Rainforest" "Mangrove" "Taiga" "Tundra" "Mountain" "Peak" "Summit" "Cliff" "Crag" "Bluff" "Mesa" "Plateau" "Canyon" "Ravine" "Valley" "Dale" "Glen" "Hollow" "Basin" # Gewässer (15) "River" "Stream" "Brook" "Creek" "Fjord" "Lagoon" "Estuary" "Delta" "Bayou" "Wetland" "Oasis" "Geyser" "Spring" "Well" "Aquifer" # Künstliche Strukturen (10) "Observatory" "Planetarium" "Orrery" "Reflectory" "Conservatory" "Atrium" "Rotunda" "Gazebo" "Pavilion" "Terrace" ) echo "${adjectives[$RANDOM % 50]}${nouns[$RANDOM % 50]}$((RANDOM % 900 + 100))" } # Hauptfunktion function regionsconfig() { # Konstanten local center_x=4000 local center_y=4000 local base_port=9000 # Variablen local regions_per_sim local system_ip local sim_num local region_num local sim_dir local offset local pos_x local pos_y local location local port local region_name local region_uuid local config_file declare -A used_locations # Assoziatives Array für bereits verwendete Positionen # Überprüfen, ob crudini installiert ist if ! command -v crudini &> /dev/null; then echo -e "\e[31mFehler: crudini ist nicht installiert. Bitte installieren Sie es zuerst.\e[0m" >&2 return 1 fi # Benutzereingabe echo "Wie viele Zufallsregionen sollen pro Simulator erstellt werden?" read -r regions_per_sim # Eingabeprüfung if ! [[ "$regions_per_sim" =~ ^[1-9][0-9]*$ ]]; then echo -e "\e[31mUngültige Eingabe: Bitte eine positive Zahl eingeben\e[0m" >&2 return 1 fi system_ip=$(hostname -I | awk '{print $1}') echo -e "\e[33mStarte Regionserstellung...\e[0m" echo "--------------------------" # Simulatoren durchlaufen for ((sim_num=1; sim_num<=999; sim_num++)); do sim_dir="sim${sim_num}/bin/Regions" if [[ -d "$sim_dir" ]]; then echo -e "\e[33mSimulator $sim_num: Erstelle $regions_per_sim Region(en)\e[0m" >&2 # Regionen erstellen for ((region_num=1; region_num<=regions_per_sim; region_num++)); do # Position berechnen und sicherstellen, dass sie eindeutig ist local attempts=0 local max_attempts=100 while true; do # Position berechnen offset=$(( (RANDOM % 2000) - 1000 )) # Zufälliger Offset zwischen -1000 und +1000 pos_x=$((center_x + offset)) offset=$(( (RANDOM % 2000) - 1000 )) # Unabhängiger Offset für Y pos_y=$((center_y + offset)) location="$pos_x,$pos_y" # Prüfen, ob die Position bereits verwendet wurde if [[ -z "${used_locations[$location]}" ]]; then used_locations[$location]=1 break fi attempts=$((attempts + 1)) if (( attempts >= max_attempts )); then echo -e "\e[31mFehler: Konnte nach $max_attempts Versuchen keine eindeutige Position finden\e[0m" >&2 return 1 fi done port=$((base_port + sim_num * 100 + region_num)) # Eindeutige Werte region_name=$(generate_name) region_uuid=$(generate_uuid) config_file="${sim_dir}/${region_name}.ini" # Config-Datei mit crudini erstellen crudini --set "$config_file" "$region_name" "RegionUUID" "$region_uuid" crudini --set "$config_file" "$region_name" "Location" "$location" crudini --set "$config_file" "$region_name" "SizeX" "256" crudini --set "$config_file" "$region_name" "SizeY" "256" crudini --set "$config_file" "$region_name" "SizeZ" "256" crudini --set "$config_file" "$region_name" "InternalPort" "$port" crudini --set "$config_file" "$region_name" "ExternalHostName" "$system_ip" crudini --set "$config_file" "$region_name" "MaxPrims" "15000" crudini --set "$config_file" "$region_name" "MaxAgents" "40" crudini --set "$config_file" "$region_name" "MaptileStaticUUID" "$region_uuid" crudini --set "$config_file" "$region_name" "InternalAddress" "0.0.0.0" crudini --set "$config_file" "$region_name" "AllowAlternatePorts" "False" crudini --set "$config_file" "$region_name" "NonPhysicalPrimMax" "512" crudini --set "$config_file" "$region_name" "PhysicalPrimMax" "128" # Optionale Parameter als Kommentare crudini --set "$config_file" "$region_name" ";RegionType" "Estate" crudini --set "$config_file" "$region_name" ";MasterAvatarFirstName" "System" crudini --set "$config_file" "$region_name" ";MasterAvatarLastName" "Admin" crudini --set "$config_file" "$region_name" ";MasterAvatarSandboxPassword" "$(openssl rand -base64 12)" echo -e "\e[36m ✓ ${region_name} (${location}, Port ${port})\e[0m" >&2 done fi done echo "--------------------------" echo -e "\e[32mRegionserstellung abgeschlossen!\e[0m" blankline return 0 } function regionsclean() { echo -e "\033[33mWARNUNG: Dies wird ALLE Regionskonfigurationen in allen Simulatoren löschen!\033[0m" echo "Sicher fortfahren? (j/N): " read -r confirm if [[ "$confirm" =~ ^[jJ] ]]; then echo "Starte Bereinigung..." deleted_count=0 # Durch alle Simulatoren iterieren for ((sim_num=1; sim_num<=999; sim_num++)); do sim_dir="sim${sim_num}/bin/Regions" if [[ -d "$sim_dir" ]]; then echo -e "\033[33m ✓ Überprüfe $sim_dir...\033[0m" # Lösche nur .ini-Dateien (keine anderen Dateitypen) while IFS= read -r -d $'\0' config_file; do if [[ "$config_file" == *.ini ]]; then rm -v "$config_file" ((deleted_count++)) fi done < <(find "$sim_dir" -maxdepth 1 -type f -name "*.ini" -print0) fi done echo -e "\033[32mFertig! Gelöschte Regionen: $deleted_count\033[0m" else echo "Abbruch: Keine Dateien wurden gelöscht." fi blankline } function renamefiles() { timestamp=$(date +"%Y%m%d_%H%M%S") if [ ! -d "$SCRIPT_DIR" ]; then echo -e "${RED}Fehler: Verzeichnis $SCRIPT_DIR nicht gefunden!${RESET}" return 1 fi echo -e "${CYAN}Starte Umbenennung aller *.example Dateien in ${SCRIPT_DIR} und Unterverzeichnissen...${RESET}" # Verarbeite robust/bin zuerst find "$SCRIPT_DIR" -type f -name "*.example" 2>/dev/null | while read -r example_file; do local target_file="${example_file%.example}" # Entfernt .example if [ -f "$target_file" ]; then local backup_file="${target_file}_${timestamp}.bak" mv "$target_file" "$backup_file" echo -e "${YELLOW}Gesichert: ${target_file} → ${backup_file}${RESET}" fi mv "$example_file" "$target_file" echo -e "${GREEN}Umbenannt: ${example_file} → ${target_file}${RESET}" done # Jetzt alle simX/bin Verzeichnisse durchlaufen for ((i=999; i>=1; i--)); do sim_dir="${SCRIPT_DIR}/sim$i/bin" if [ -d "$sim_dir" ]; then echo -e "${CYAN}Verarbeite: $sim_dir ${RESET}" find "$sim_dir" -type f -name "*.example" 2>/dev/null | while read -r example_file; do local target_file="${example_file%.example}" if [ -f "$target_file" ]; then local backup_file="${target_file}_${timestamp}.bak" mv "$target_file" "$backup_file" echo -e "${YELLOW}Gesichert: ${target_file} → ${backup_file}${RESET}" fi mv "$example_file" "$target_file" echo -e "${GREEN}Umbenannt: ${example_file} → ${target_file}${RESET}" done fi done echo -e "${GREEN}Alle *.example Dateien wurden erfolgreich verarbeitet.${RESET}" blankline return 0 } # Standalone ist die erste Funktion, die funktioniert. function standalone() { echo -e "\e[33m[Standalone] Setup wird durchgeführt...\e[0m" # Prüfen ob SCRIPT_DIR gesetzt ist if [ -z "${SCRIPT_DIR}" ]; then echo -e "\e[31mFehler: SCRIPT_DIR ist nicht gesetzt!\e[0m" return 1 fi local opensim_bin="${SCRIPT_DIR}/opensim/bin" local renamed=0 local skipped=0 # Sicherstellen, dass das Verzeichnis existiert if [ ! -d "${opensim_bin}" ]; then echo -e "\e[31mFehler: Verzeichnis ${opensim_bin} nicht gefunden!\e[0m" return 1 fi # Verarbeite alle .example Dateien while IFS= read -r -d '' file; do target="${file%.example}" if [ -e "${target}" ]; then echo -e "\e[33mÜbersprungen: ${target} existiert bereits\e[0m" ((skipped++)) else if mv "${file}" "${target}"; then echo -e "\e[32mUmbenannt: ${file} → ${target}\e[0m" ((renamed++)) else echo -e "\e[31mFehler beim Umbenennen von ${file}\e[0m" ((skipped++)) fi fi done < <(find "${opensim_bin}" -type f -name "*.example" -print0) echo -e "\n\e[36mZusammenfassung:\e[0m" echo -e "\e[32mUmbenannte Dateien: ${renamed}\e[0m" echo -e "\e[33mÜbersprungene Dateien: ${skipped}\e[0m" echo -e "\e[32mStandalone-Konfiguration abgeschlossen!\e[0m" blankline } # Helper to clean config files (remove leading spaces/tabs) clean_config() { local file=$1 sed -i 's/^[ \t]*//' "$file" } function setrobusthg() { local robust_ini="${SCRIPT_DIR}/robust/bin/Robust.HG.ini.example" local target_ini="${SCRIPT_DIR}/robust/bin/Robust.ini" local backup_file="${SCRIPT_DIR}/robust/bin/Robust.ini.bak" # Prüfe, ob Robust.ini existiert und erstelle ein Backup if [ -f "$target_ini" ]; then echo "Sichere bestehende Datei: $target_ini -> $backup_file" mv "$target_ini" "$backup_file" fi # Kopiere Robust.HG.ini nach Robust.ini if [ -f "$robust_ini" ]; then cp "$robust_ini" "$target_ini" echo "$robust_ini wurde nach $target_ini kopiert." else echo "Warnung: $robust_ini nicht gefunden!" return 1 fi # Bereinige die Datei, damit crudini korrekt arbeitet clean_config "$target_ini" # Basis-Konfiguration crudini --set "$target_ini" Const BaseHostname "\"$system_ip\"" crudini --set "$target_ini" Const BaseURL "\"http://\${Const|BaseHostname}\"" crudini --set "$target_ini" Const PublicPort "\"8002\"" crudini --set "$target_ini" Const PrivatePort "\"8003\"" # Dienste aktivieren (ServiceList) services=( "OfflineIMServiceConnector" "GroupsServiceConnector" "BakedTextureService" "UserProfilesServiceConnector" "HGGroupsServiceConnector" ) for service in "${services[@]}"; do sed -i "/^; *$service/s/^;//" "$target_ini" done # Hypergrid Konfiguration crudini --set "$target_ini" Hypergrid HomeURI "\"\${Const|BaseURL}:\${Const|PublicPort}\"" crudini --set "$target_ini" Hypergrid GatekeeperURI "\"\${Const|BaseURL}:\${Const|PublicPort}\"" # Access Control - Verbotene Clients crudini --set "$target_ini" AccessControl DeniedClients "\"Imprudence|CopyBot|Twisted|Crawler|Cryolife|darkstorm|DarkStorm|Darkstorm|hydrastorm viewer|kinggoon copybot|goon squad copybot|copybot pro|darkstorm viewer|copybot club|darkstorm second life|copybot download|HydraStorm Copybot Viewer|Copybot|Firestorm Pro|DarkStorm v3|DarkStorm v2|ShoopedStorm|HydraStorm|hydrastorm|kinggoon|goon squad|goon|copybot|Shooped|ShoopedStorm|Triforce|Triforce Viewer|Firestorm Professional|ShoopedLife|Sombrero|Sombrero Firestorm|GoonSquad|Solar|SolarStorm\"" # Datenbank-Konfiguration crudini --set "$target_ini" DatabaseService ConnectionString "\"Data Source=localhost;Database=opensim;User ID=opensim;Password=$DB_PASSWORD;Old Guids=true;SslMode=None;\"" # Grid-Dienste crudini --set "$target_ini" GridService MapTileDirectory "\"./maptiles\"" crudini --set "$target_ini" GridService Region_Welcome_Area "\"DefaultRegion, DefaultHGRegion\"" # Login-Service crudini --set "$target_ini" LoginService DestinationGuide "\"\${Const|BaseURL}/guide.php\"" crudini --set "$target_ini" LoginService GridSearch "\"\${Const|BaseURL}/searchservice.php\"" # Map-Bild-Service crudini --set "$target_ini" MapImageService TilesStoragePath "\"maptiles\"" crudini --set "$target_ini" MapImageService GridService "\"OpenSim.Services.GridService.dll:GridService\"" # Grid-Info-Service crudini --set "$target_ini" GridInfoService welcome "\${Const|BaseURL}/welcomesplashpage.php" crudini --set "$target_ini" GridInfoService economy "\${Const|BaseURL}:8008/" crudini --set "$target_ini" GridInfoService about "\${Const|BaseURL}/aboutinformation.php" crudini --set "$target_ini" GridInfoService register "\${Const|BaseURL}/createavatar.php" crudini --set "$target_ini" GridInfoService help "\${Const|BaseURL}/help.php" crudini --set "$target_ini" GridInfoService password "\${Const|BaseURL}/passwordreset.php" crudini --set "$target_ini" GridInfoService partner "\${Const|BaseURL}/partner.php" crudini --set "$target_ini" GridInfoService GridStatus "\${Const|BaseURL}:\${Const|PublicPort}/gridstatus.php" crudini --set "$target_ini" GridInfoService GridStatusRSS "\${Const|BaseURL}:\${Const|PublicPort}/gridstatusrss.php" # User-Agent-Service crudini --set "$target_ini" UserAgentService LevelOutsideContacts "0" crudini --set "$target_ini" UserAgentService ShowUserDetailsInHGProfile "True" # Bereinige die Datei (entferne führende Leerzeichen) clean_config "$target_ini" echo "Konfiguration von Robust.ini erfolgreich abgeschlossen." blankline } function setopensim() { local base_dir="${SCRIPT_DIR}/" # Durchsuche alle vorhandenen simX-Ordner (sim1 bis sim999) for i in {1..999}; do local sim_dir="${base_dir}sim$i/bin" local opensim_example="$sim_dir/OpenSim.ini.example" local opensim_ini="$sim_dir/OpenSim.ini" local backup_ini="$sim_dir/OpenSim.ini.bak" # Prüfen, ob das Verzeichnis existiert if [ -d "$sim_dir" ]; then echo "Konfiguriere OpenSim.ini für $sim_dir" # Falls OpenSim.ini existiert, sichere sie zuerst if [ -f "$opensim_ini" ]; then echo "Sichere bestehende Datei: $opensim_ini -> $backup_ini" mv "$opensim_ini" "$backup_ini" fi # Kopiere OpenSim.ini.example nach OpenSim.ini if [ -f "$opensim_example" ]; then cp "$opensim_example" "$opensim_ini" echo "$opensim_example wurde nach $opensim_ini kopiert." else echo "Warnung: $opensim_example nicht gefunden! Überspringe sim$i." continue fi # Bereinige die Datei, damit crudini korrekt arbeitet clean_config "$opensim_ini" # Konfiguration mit crudini setzen #Const-Konfiguration crudini --set "$opensim_ini" Const BaseHostname "\"$system_ip\"" crudini --set "$opensim_ini" Const BaseURL "\"http://\${Const|BaseHostname}\"" #crudini --set "$opensim_ini" Const PublicPort "\"9000\"" crudini --set "$opensim_ini" Const PublicPort "\"8002\"" crudini --set "$opensim_ini" Const PrivURL "\"\${Const|BaseURL}\"" crudini --set "$opensim_ini" Const PrivatePort "\"8003\"" # Startup-Einstellungen crudini --set "$opensim_ini" Startup async_call_method "SmartThreadPool" crudini --set "$opensim_ini" Startup MaxPoolThreads "300" crudini --set "$opensim_ini" Startup MinPoolThreads "32" crudini --set "$opensim_ini" Startup CacheSculptMaps "false" crudini --set "$opensim_ini" Startup DefaultScriptEngine "\"YEngine\"" # Map-Konfiguration crudini --set "$opensim_ini" Map MaptileStaticUUID "\"00000000-0000-0000-0000-000000000000\"" # Berechtigungen crudini --set "$opensim_ini" Permissions automatic_gods "false" crudini --set "$opensim_ini" Permissions implicit_gods "false" crudini --set "$opensim_ini" Permissions allow_grid_gods "true" # Netzwerk-Konfiguration crudini --set "$opensim_ini" Network http_listener_port "9010" crudini --set "$opensim_ini" Network shard "\"OpenSim\"" crudini --set "$opensim_ini" Network user_agent "\"OpenSim LSL (Mozilla Compatible)\"" # BulletSim-Einstellungen crudini --set "$opensim_ini" BulletSim AvatarToAvatarCollisionsByDefault "true" crudini --set "$opensim_ini" BulletSim UseSeparatePhysicsThread "true" crudini --set "$opensim_ini" BulletSim TerrainImplementation "0" # Materialeinstellungen crudini --set "$opensim_ini" Materials MaxMaterialsPerTransaction "250" # Benutzerprofile crudini --set "$opensim_ini" UserProfiles ProfileServiceURL "\"http://services.osgrid.org\"" # Skript-Engines crudini --set "$opensim_ini" YEngine Enabled "true" crudini --set "$opensim_ini" XEngine Enabled "false" # OSSL-Einstellungen crudini --set "$opensim_ini" OSSL Include-osslDefaultEnable "\"config-include/osslDefaultEnable.ini\"" # NPC-Einstellungen crudini --set "$opensim_ini" NPC Enabled "true" # Terrain-Konfiguration crudini --set "$opensim_ini" Terrain InitialTerrain "\"flat\"" # XBakes-Konfiguration crudini --set "$opensim_ini" XBakes URL "\"\${Const|PrivURL}:\${Const|PrivatePort}\"" # Architektur crudini --set "$opensim_ini" Architecture Include-Architecture "\"config-include/GridHypergrid.ini\"" echo "Konfiguration von OpenSim.ini erfolgreich abgeschlossen." fi done blankline } function setgridcommon() { local base_dir="${SCRIPT_DIR}/" for i in {1..999}; do local sim_dir="${base_dir}sim$i/bin/config-include" local gridcommon_example="$sim_dir/GridCommon.ini.example" local gridcommon_ini="$sim_dir/GridCommon.ini" local backup_ini="$sim_dir/GridCommon.ini.bak" if [ -d "$sim_dir" ]; then echo "Konfiguriere GridCommon.ini für $sim_dir" if [ -f "$gridcommon_ini" ]; then echo "Sichere bestehende Datei: $gridcommon_ini -> $backup_ini" mv "$gridcommon_ini" "$backup_ini" fi if [ -f "$gridcommon_example" ]; then # 1. Erstelle neue GridCommon.ini mit Const-Bereich echo "[Const]" > "$gridcommon_ini" crudini --set "$gridcommon_ini" Const BaseHostname "\"$system_ip\"" crudini --set "$gridcommon_ini" Const BaseURL "\"http://\${Const|BaseHostname}\"" crudini --set "$gridcommon_ini" Const PublicPort "\"8002\"" crudini --set "$gridcommon_ini" Const PrivatePort "\"8003\"" # 2. Füge eine Leerzeile ein für bessere Lesbarkeit echo "" >> "$gridcommon_ini" # 3. Füge den kompletten Inhalt der Beispiel-Datei hinzu cat "$gridcommon_example" >> "$gridcommon_ini" echo "GridCommon.ini wurde erstellt mit Const-Bereich und Inhalt von $gridcommon_example." else echo "Warnung: $gridcommon_example nicht gefunden! Überspringe sim$i." continue fi clean_config "$gridcommon_ini" echo "Konfiguration von GridCommon.ini für $sim_dir erfolgreich abgeschlossen." fi done blankline } function setflotsamcache() { local base_dir="${SCRIPT_DIR}/" # Durchsuche alle existierenden simX-Ordner (sim1 bis sim999) for i in {1..999}; do local sim_dir="${base_dir}sim$i/bin/config-include" local flotsam_ini="$sim_dir/FlotsamCache.ini" local backup_ini="$sim_dir/FlotsamCache.ini.bak" # Prüfe, ob das Sim-Verzeichnis existiert if [ -d "$sim_dir" ]; then echo "Erstelle FlotsamCache.ini für $sim_dir" # Falls die Datei existiert, sichere sie zuerst if [ -f "$flotsam_ini" ]; then echo "Sichere bestehende Datei: $flotsam_ini -> $backup_ini" mv "$flotsam_ini" "$backup_ini" fi # Ersetze den kompletten Inhalt mit der neuen Konfiguration cat > "$flotsam_ini" << EOF [AssetCache] CacheDirectory = ./assetcache LogLevel = 0 HitRateDisplay = 100 MemoryCacheEnabled = false UpdateFileTimeOnCacheHit = false NegativeCacheEnabled = true NegativeCacheTimeout = 120 NegativeCacheSliding = false FileCacheEnabled = true MemoryCacheTimeout = .016 FileCacheTimeout = 48 FileCleanupTimer = 1.0 EOF # Bereinige die Datei clean_config "$flotsam_ini" echo "Konfiguration von FlotsamCache.ini für $sim_dir abgeschlossen." fi done blankline } # setwelcome - Sets the Welcome_Area.ini function setwelcome() { local welcome_ini="${SCRIPT_DIR}/sim1/bin/Regions/Welcome_Area.ini" region_uuid=$(uuidgen) cat > "$welcome_ini" << EOF [Welcome Area] RegionUUID = $region_uuid Location = 3000,3000 SizeX = 256 SizeY = 256 SizeZ = 256 InternalPort = 9010 ExternalHostName = "$system_ip" MaxPrims = 15000 MaxAgents = 40 MaptileStaticUUID = $region_uuid InternalAddress = 0.0.0.0 AllowAlternatePorts = False ;NonPhysicalPrimMax = 512 ;PhysicalPrimMax = 128 ;MasterAvatarSandboxPassword = "$(openssl rand -base64 12)" ;MasterAvatarLastName = Admin ;MasterAvatarFirstName = System ;RegionType = Estate EOF clean_config "$welcome_ini" echo "Welcome_Area.ini configuration completed" blankline } function setosslenable() { local base_dir="${SCRIPT_DIR}/" for i in {1..999}; do local sim_dir="${base_dir}sim$i/bin/config-include" local osslenable_ini="$sim_dir/osslEnable.ini" local backup_ini="$sim_dir/osslEnable.ini.bak" # Prüfen, ob das Sim-Verzeichnis existiert if [ -d "$sim_dir" ]; then echo "Erstelle osslEnable.ini für $sim_dir" # Falls die Datei existiert, sichere sie zuerst if [ -f "$osslenable_ini" ]; then echo "Sichere bestehende Datei: $osslenable_ini -> $backup_ini" mv "$osslenable_ini" "$backup_ini" fi # Ersetze den kompletten Inhalt mit der neuen Konfiguration cat > "$osslenable_ini" << EOF [OSSL] AllowOSFunctions = true AllowMODFunctions = true AllowLightShareFunctions = true PermissionErrorToOwner = false OSFunctionThreatLevel = High osslParcelO = "PARCEL_OWNER," osslParcelOG = "PARCEL_GROUP_MEMBER,PARCEL_OWNER," osslNPC = \${OSSL|osslParcelOG}ESTATE_MANAGER,ESTATE_OWNER EOF echo "Konfiguration von osslEnable.ini für $sim_dir abgeschlossen." fi done blankline } function clean_comments_and_empty_lines() { echo -e "\e[33mBereinige Kommentare und Leerzeilen in allen Konfigurationsdateien...\e[0m" # Durch alle simX-Verzeichnisse iterieren for ((i=999; i>=1; i--)); do sim_dir="sim$i" if [ -d "$sim_dir" ]; then echo -e "\e[36mVerarbeite $sim_dir...\e[0m" # Liste aller relevanten Konfigurationsdateien config_files=( "${sim_dir}/bin/Robust.ini.example" "${sim_dir}/bin/Robust.HG.ini.example" "${sim_dir}/bin/OpenSim.ini.example" "${sim_dir}/bin/config-include/FlotsamCache.ini.example" "${sim_dir}/bin/config-include/GridCommon.ini.example" "${sim_dir}/bin/config-include/osslEnable.ini.example" "${sim_dir}/bin/config-include/StandaloneCommon.ini.example" ) # Jede Konfigurationsdatei bearbeiten for config_file in "${config_files[@]}"; do if [[ -f "$config_file" ]]; then echo -e "\e[34mBearbeite $config_file\e[0m" # Vorher-Nachher-Vergleich original_lines=$(wc -l < "$config_file") # 1. Behalte nur Zeilen mit = oder gültigen Sektionen # 2. Entferne führende/trailing Whitespace # 3. Lösche leere Zeilen perl -i.bak -ne ' if (/^\s*\[.+\]\s*$/ || /=/) { s/^\s+//; # Entferne führende Leerzeichen/Tabs s/\s+$//; # Entferne trailing Leerzeichen print "$_\n"; } ' "$config_file" # Nachher-Zeilenanzahl cleaned_lines=$(wc -l < "$config_file") # Veränderungen anzeigen removed=$((original_lines - cleaned_lines)) if [[ $removed -gt 0 ]]; then echo -e "\e[32m✓ Entfernt $removed Zeilen aus $config_file\e[0m" echo -e "\e[37mVorher/Nachher Beispiel:\e[0m" diff --unchanged-line-format= --old-line-format='- %L' --new-line-format='+ %L' \ "${config_file}.bak" "$config_file" | head -5 else echo -e "\e[35mℹ Keine Änderungen in $config_file\e[0m" fi fi done fi done echo -e "\e[32mBereinigung abgeschlossen!\e[0m" blankline } function cleandoublecomments() { echo -e "\e[33mBereinige doppelt kommentierte Zeilen in allen Konfigurationsdateien...\e[0m" # Durch alle simX-Verzeichnisse iterieren for ((i=999; i>=1; i--)); do sim_dir="sim$i" if [ -d "$sim_dir" ]; then echo -e "\e[36mVerarbeite $sim_dir...\e[0m" # Liste aller relevanten Konfigurationsdateien config_files=( "${sim_dir}/bin/Robust.ini" "${sim_dir}/bin/Robust.HG.ini" "${sim_dir}/bin/OpenSim.ini" ) # Jede Konfigurationsdatei bearbeiten for config_file in "${config_files[@]}"; do if [[ -f "$config_file" ]]; then echo -e "\e[34mBearbeite $config_file\e[0m" # Vorher-Nachher-Vergleich original_lines=$(wc -l < "$config_file") # Doppelt kommentierte Zeilen mit führenden Leerzeichen/Tabs entfernen perl -i.bak -ne 'print unless /^\s*;;|^\s*;#/' "$config_file" # Nachher-Zeilenanzahl cleaned_lines=$(wc -l < "$config_file") # Veränderungen anzeigen removed=$((original_lines - cleaned_lines)) if [[ $removed -gt 0 ]]; then echo -e "\e[32m✓ Entfernt $removed Zeilen aus $config_file\e[0m" echo -e "\e[37mErste entfernte Zeile:\e[0m" diff "${config_file}.bak" "$config_file" | grep '^<' | head -1 else echo -e "\e[35mℹ Keine doppelt kommentierten Zeilen in $config_file gefunden\e[0m" # Debug-Ausgabe echo -e "\e[37mBeispielzeilen:\e[0m" grep -m 2 '^\s*[;#]' "$config_file" || echo "Keine kommentierten Zeilen gefunden" fi fi done fi done echo -e "\e[32mBereinigung abgeschlossen!\e[0m" blankline } function cleanall() { echo "Möchtest du OpenSim komplett mit Konfigurationen entfernen? (ja/nein)" read -r answer if [ "$answer" = "ja" ]; then echo "Lösche OpenSim vollständig..." # robust/bin Verzeichnis leeren, falls vorhanden if [ -d "robust/bin" ]; then rm -rf robust/bin/* fi # Überprüfen, welche simX/bin Verzeichnisse existieren und leeren for i in {1..999}; do dir="sim$i/bin" if [ -d "$dir" ]; then rm -rf "${dir:?}/"* fi done echo "Alle bin-Verzeichnisse wurden geleert." elif [ "$answer" = "nein" ]; then echo "OpenSim bleibt erhalten." else echo "Ungültige Eingabe. Bitte 'ja' oder 'nein' eingeben." fi blankline } #?────────────────────────────────────────────────────────────────────────────────────────── #* ZUSAMMENFASSUNG DER FUNKTIONEN IN LOGISCHE GRUPPEN #?────────────────────────────────────────────────────────────────────────────────────────── # Standalone-Service-Neustart (ohne Logbereinigung) function standalonerestart() { standalonestop sleep 30 # Wartezeit für sauberen Shutdown standalonestart } # Kompletter OpenSim-Neustart mit Logrotation function opensimrestart() { opensimstop sleep 30 # Wartezeit für Dienst-Stopp logclean # Logbereinigung sleep 15 # Wartezeit vor Neustart opensimstart echo -e "\033[36mAktive Screen-Sessions:\033[0m" screen -ls || echo "Keine Screen-Sessions gefunden" } # Basis-Konfiguration für alle Dienste ⚡ Vorsicht function configall() { setrobusthg # Hypergrid-Konfig setopensim # Regionsserver setgridcommon # Grid-weite Einstellungen setflotsamcache # Cache-System setosslenable # OSSL-Funktionen setwelcome # Startregion echo -e "\033[32mAlle Konfigurationen wurden angewendet.\033[0m" } # Vollautomatische Installation ⚡ Vorsicht function autosetinstall() { # Sicherheitsabfrage echo -e "\033[1;33m⚠ WARNUNG: Komplette Serverinstallation!\033[0m" read -rp "Fortfahren? (j/N): " antwort [[ "${antwort,,}" != "j" ]] && { echo -e "\033[31m✖ Abbruch durch Benutzer\033[0m" return 1 } # Installationsphasen echo -e "\033[1;34m\n[Phase 1] Systemchecks\033[0m" servercheck || return $? echo -e "\033[1;34m\n[Phase 2] Quellcode\033[0m" opensimgitcopy && moneygitcopy || return $? echo -e "\033[1;34m\n[Phase 3] Build-Prozess\033[0m" opensimbuild || return $? echo -e "\033[1;34m\n[Phase 4] Deployment\033[0m" createdirectory sqlsetup opensimcopy echo -e "\033[1;34m\n[Phase 5] Konfiguration\033[0m" regionsconfig setwelcome configall # Nutzt die oben definierte Gruppenfunktion echo -e "\033[1;34m\n[Phase 6] Automatisierung\033[0m" setcrontab echo -e "\033[1;32m\n✔ Installation abgeschlossen! Auto-Start in 30 Min.\033[0m" } # Server-Reboot mit Vorbereitung function reboot() { echo -e "\033[1;33m⚠ Server-Neustart wird eingeleitet...\033[0m" opensimstop sleep 30 shutdown -r now } # OpenSim komplett herunterladen ⚡ Vorsicht function downloadallgit() { # Downloads aus dem Github. opensimgitcopy moneygitcopy #ruthrothgit # Funktioniert nicht richtig. #avatarassetsgit # Funktioniert nicht richtig. osslscriptsgit pbrtexturesgit # Versionierung des OpenSimulators. versionrevision # OpenSimulator erstellen aus dem Source Code. opensimbuild } #?────────────────────────────────────────────────────────────────────────────────────────── #* Hilfefunktionen #?────────────────────────────────────────────────────────────────────────────────────────── function help() { # Überschriften printf "%b\n" "${COLOR_SERVER}OpenSim Grid Starten Stoppen und Restarten:${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_START}opensimstart${COLOR_RESET}" "OpenSim starten" printf "\t%-30b # %s\n" "${COLOR_STOP}opensimstop${COLOR_RESET}" "OpenSim stoppen" printf "\t%-30b # %s\n" "${COLOR_START}opensimrestart${COLOR_RESET}" "OpenSim neu starten" printf "\t%-30b # %s\n" "${COLOR_OK}check_screens${COLOR_RESET}" "Laufende OpenSim Prozesse prüfen und restarten" echo " " # Erstellung/Aktualisierung printf "%b\n" "${COLOR_SERVER}Ein OpenSim Grid erstellen oder aktualisieren:${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_OK}servercheck${COLOR_RESET}" "Serverbereitschaft prüfen und nachinstallieren" printf "\t%-30b # %s\n" "${COLOR_OK}createdirectory${COLOR_RESET}" "Verzeichnisse erstellen (robust, sim1, sim2,...)" printf "\t%-30b # %s\n" "${COLOR_OK}opensimbuild${COLOR_RESET}" "OpenSim Programm erstellen" printf "\t%-30b # %s\n" "${COLOR_OK}opensimcopy${COLOR_RESET}" "OpenSim kopieren/upgraden" printf "\t%-30b # %s\n" "${COLOR_OK}database_setup${COLOR_RESET}" "SQL Datenbanken erstellen" printf "\t%-30b # %s\n" "${COLOR_OK}setcrontab${COLOR_RESET}" "Crontab Automatisierungen erstellen" #printf "\t%-30b # %s\n" "${COLOR_OK}opensimupgrade${COLOR_RESET}" "OpenSim aktualisieren" echo " " # Git Downloads printf "%b\n" "${COLOR_SERVER}Git Downloads:${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_OK}opensimgitcopy${COLOR_RESET}" "OpenSim herunterladen" printf "\t%-30b # %s\n" "${COLOR_OK}moneygitcopy${COLOR_RESET}" "MoneyServer herunterladen" #printf "\t%-30b # %s\n" "${COLOR_WARNING}ruthrothgit${COLOR_RESET}" "Ruth Roth als IAR ${COLOR_BAD}(Vorsicht)${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_WARNING}avatarassetsgit${COLOR_RESET}" "Ruth Roth Assets ${COLOR_BAD}(Vorsicht)${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_OK}osslscriptsgit${COLOR_RESET}" "OSSL Beispiel-Skripte ${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_WARNING}pbrtexturesgit${COLOR_RESET}" "PBR Texturen ${COLOR_BAD}(Vorsicht)${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_OK}downloadallgit${COLOR_RESET}" "Alle Git-Repos herunterladen" printf "\t%-30b # %s\n" "${COLOR_OK}versionrevision${COLOR_RESET}" "Versionsrevision auf Expanded setzen" echo " " # Konfiguration #printf "%b\n" "${COLOR_SERVER}Konfigurationsmanagement:${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_WARNING}configall${COLOR_RESET}" "Testkonfiguration ${COLOR_BAD}(Vorsicht)${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_WARNING}opensimconfig${COLOR_RESET}" "Konfiguration (in Entwicklung)" #printf "\t%-30b # %s\n" "${COLOR_OK}regionsconfig${COLOR_RESET}" "Regionen konfigurieren" #printf "\t%-30b # %s\n" "${COLOR_OK}cleandoublecomments${COLOR_RESET}" "Doppelte Kommentare bereinigen" #printf "\t%-30b # %s\n" "${COLOR_OK}clean_comments_and_empty_lines${COLOR_RESET}" "Kommentare/Leerzeilen löschen" #printf "\t%-30b # %s\n" "${COLOR_OK}generate_name${COLOR_RESET}" "Zufälligen Namen generieren" #printf "\t%-30b # %s\n" "${COLOR_OK}clean_config${COLOR_RESET}" "Konfigurationsdatei bereinigen" #echo " " # INI-Operationen #printf "%b\n" "${COLOR_SERVER}INI-Datei Operationen:${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_OK}verify_ini_section${COLOR_RESET}" "INI-Abschnitt verifizieren" #printf "\t%-30b # %s\n" "${COLOR_OK}verify_ini_key${COLOR_RESET}" "INI-Schlüssel verifizieren" #printf "\t%-30b # %s\n" "${COLOR_OK}add_ini_section${COLOR_RESET}" "INI-Abschnitt hinzufügen" #printf "\t%-30b # %s\n" "${COLOR_OK}set_ini_key${COLOR_RESET}" "INI-Schlüssel setzen" #printf "\t%-30b # %s\n" "${COLOR_WARNING}del_ini_section${COLOR_RESET}" "INI-Abschnitt löschen ${COLOR_BAD}(Vorsicht)${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_OK}uncomment_ini_line${COLOR_RESET}" "INI-Zeile entkommentieren" #echo " " # XML-Operationen #printf "%b\n" "${COLOR_SERVER}XML-Datei Operationen:${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_OK}verify_xml_section${COLOR_RESET}" "XML-Abschnitt verifizieren" #printf "\t%-30b # %s\n" "${COLOR_OK}add_xml_section${COLOR_RESET}" "XML-Abschnitt hinzufügen" #printf "\t%-30b # %s\n" "${COLOR_WARNING}del_xml_section${COLOR_RESET}" "XML-Abschnitt löschen ${COLOR_BAD}(Vorsicht)${COLOR_RESET}" #echo " " # Autokonfiguration #printf "%b\n" "${COLOR_SERVER}Automatische Konfiguration:${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_OK}setrobusthg${COLOR_RESET}" "Robust-HG einstellen" #printf "\t%-30b # %s\n" "${COLOR_OK}setopensim${COLOR_RESET}" "OpenSim-Pfade einstellen" #printf "\t%-30b # %s\n" "${COLOR_OK}setgridcommon${COLOR_RESET}" "Grid-Konfiguration einstellen" #printf "\t%-30b # %s\n" "${COLOR_OK}setflotsamcache${COLOR_RESET}" "Flotsam-Cache konfigurieren" #printf "\t%-30b # %s\n" "${COLOR_OK}setosslenable${COLOR_RESET}" "OSSL-Funktionen aktivieren" #printf "\t%-30b # %s\n" "${COLOR_OK}setwelcome${COLOR_RESET}" "Willkommensregion setzen" #printf "\t%-30b # %s\n" "${COLOR_OK}autosetinstall${COLOR_RESET}" "Automatische Installation" #printf "\t%-30b # %s\n" "${COLOR_WARNING}configure_pbr_textures${COLOR_RESET}" "PBR-Texturen (experimentell)" #printf "\t%-30b # %s\n" "${COLOR_WARNING}configure_example_ini${COLOR_RESET}" "Beispiel-INI (experimentell)" #echo " " # Standalone-Modus #printf "%b\n" "${COLOR_SERVER}Standalone-Modus:${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_OK}standalone${COLOR_RESET}" "Standalone-Menü" #printf "\t%-30b # %s\n" "${COLOR_OK}standalonestart${COLOR_RESET}" "Standalone starten" #printf "\t%-30b # %s\n" "${COLOR_OK}standalonestop${COLOR_RESET}" "Standalone stoppen" #printf "\t%-30b # %s\n" "${COLOR_OK}standalonerestart${COLOR_RESET}" "Standalone neustarten" #echo " " # Bereinigung printf "%b\n" "${COLOR_SERVER}OpenSim Grid Bereinigen:${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_WARNING}dataclean${COLOR_RESET}" "Alte Dateien löschen ${COLOR_BAD}(⚡ Neuinstallation)${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_WARNING}pathclean${COLOR_RESET}" "Alte Verzeichnisse löschen ${COLOR_BAD}(⚡ Neuinstallation)${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_OK}cacheclean${COLOR_RESET}" "Cache bereinigen" printf "\t%-30b # %s\n" "${COLOR_OK}logclean${COLOR_RESET}" "Logs löschen" printf "\t%-30b # %s\n" "${COLOR_OK}mapclean${COLOR_RESET}" "Maptiles löschen" #printf "\t%-30b # %s\n" "${COLOR_WARNING}autoallclean${COLOR_RESET}" "Komplettbereinigung ${COLOR_BAD}(⚡ Neuinstallation)${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_WARNING}regionsclean${COLOR_RESET}" "Regionen löschen" #printf "\t%-30b # %s\n" "${COLOR_WARNING}cleanall${COLOR_RESET}" "Alles bereinigen ${COLOR_BAD}(⚡ Gefährlich)${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_OK}renamefiles${COLOR_RESET}" "Umbenennung aller *.example Dateien" echo " " # System printf "%b\n" "${COLOR_SERVER}Systembefehle:${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_OK}reboot${COLOR_RESET}" "Server neustarten ${COLOR_RESET}" #printf "\t%-30b # %s\n" "${COLOR_OK}colortest${COLOR_RESET}" "Farbtest anzeigen" echo " " # Hilfe printf "%b\n" "${COLOR_SERVER}Hilfen:${COLOR_RESET}" printf "\t%-30b # %s\n" "${COLOR_OK}help${COLOR_RESET}" "Diese Hilfeseite" echo " " } #?────────────────────────────────────────────────────────────────────────────────────────── #* Eingabeauswertung #?────────────────────────────────────────────────────────────────────────────────────────── case $KOMMANDO in # SYSTEM-CHECKS & SETUP # servercheck) servercheck ;; createdirectory) createdirectory ;; setcrontab) setcrontab ;; check_screens) check_screens ;; # DATENBANK-MANAGEMENT # database_setup) database_setup ;; # GIT-OPERATIONEN # opensimgitcopy|opensimgit) opensimgitcopy ;; moneygitcopy|moneygit) moneygitcopy ;; ruthrothgit) ruthrothgit ;; avatarassetsgit) avatarassetsgit ;; osslscriptsgit) osslscriptsgit ;; pbrtexturesgit) pbrtexturesgit ;; downloadallgit) downloadallgit ;; versionrevision) versionrevision ;; # OPENSIM BUILD & DEPLOY # opensimbuild) opensimbuild ;; opensimcopy) opensimcopy ;; opensimupgrade) opensimupgrade ;; # KONFIGURATIONS-MGMT # cleandoublecomments) cleandoublecomments ;; configclean|clean_comments_and_empty_lines) clean_comments_and_empty_lines ;; regionsconfig) regionsconfig ;; generatename|generate_name) generate_name ;; cleanconfig) clean_config "$2" ;; # AUTOKONFIGURATION # setrobusthg) setrobusthg ;; setopensim) setopensim ;; setgridcommon) setgridcommon ;; setflotsamcache) setflotsamcache ;; setosslenable) setosslenable ;; setwelcome) setwelcome ;; configall) configall ;; autosetinstall) autosetinstall ;; # Experimental # configure_pbr_textures) configure_pbr_textures ;; configure_example_ini) configure_example_ini ;; # INI-OPERATIONEN # verify_ini_section) verify_ini_section "$2" "$3" "$4" ;; verify_ini_key) verify_ini_key "$2" "$3" "$4" ;; add_ini_section) add_ini_section "$2" "$3" ;; set_ini_key) set_ini_key "$2" "$3" "$4" "$5" ;; del_ini_section) del_ini_section "$2" "$3" ;; uncomment_ini_line) uncomment_ini_line "$2" "$3" ;; # XML-OPERATIONEN # verify_xml_section) verify_xml_section "$2" "$3" ;; add_xml_section) add_xml_section "$2" "$3" "$4" ;; del_xml_section) del_xml_section "$2" "$3" ;; # OPENSIM-STEUERUNG # start|opensimstart) opensimstart ;; stop|opensimstop) opensimstop ;; osrestart|autorestart|restart|opensimrestart) opensimrestart ;; # STANDALONE-MODUS # standalone) standalone ;; standalonestart) standalonestart ;; standalonestop) standalonestop ;; standalonerestart) standalonerestart ;; # SYSTEM-BEREINIGUNG # reboot) reboot ;; dataclean) dataclean ;; pathclean) pathclean ;; cacheclean) cacheclean ;; logclean) logclean ;; mapclean) mapclean ;; autoallclean) autoallclean ;; regionsclean) regionsclean ;; cleanall) cleanall ;; renamefiles) renamefiles ;; colortest) colortest ;; # HILFE & SONSTIGES # h|help|hilfe|*) help ;; esac # Programm Ende mit Zeitstempel blankline echo -e "\e[36m${SCRIPTNAME}\e[0m ${VERSION} wurde beendet $(date +'%Y-%m-%d %H:%M:%S')" >&2 exit 0