1 Commits

240
mc_addon_loader.py Normal file
View File

@@ -0,0 +1,240 @@
import paramiko
import os
import json
# Server-Details und Pfade
SSH_HOST = "XXX.XXX.XXX.XXX"
SSH_USER = "root"
SSH_PASSWORD = "XXXXXXXXXX"
DOCKER_VOLUME_PATH = "/media/usb0/docker-data/volumes/minecraft_mc/_data2"
BEHAVIOR_PACKS_PATH = f"{DOCKER_VOLUME_PATH}/behavior_packs"
RESOURCE_PACKS_PATH = f"{DOCKER_VOLUME_PATH}/resource_packs"
WORLDS_PATH = f"{DOCKER_VOLUME_PATH}/worlds"
WORLD_NAME = "Bedrock level"
def ssh_connect():
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(SSH_HOST, username=SSH_USER, password=SSH_PASSWORD)
return client
def get_mods(ssh, behavior_packs_path, resource_packs_path):
# Befehl zum Auflisten der Verzeichnisse im Behavior Packs Pfad
command_behavior = f'find {behavior_packs_path} -maxdepth 1 -type d'
stdin, stdout, stderr = ssh.exec_command(command_behavior)
behavior_packs = stdout.read().decode().strip().split('\n')
# Filtere den Basispfad, leere Zeilen und unerwünschte Ordner heraus
behavior_packs = [pack for pack in behavior_packs if pack and pack != behavior_packs_path and not os.path.basename(pack).startswith(("vanilla", "chemistry", "experimental"))]
# Befehl zum Auflisten der Verzeichnisse im Resource Packs Pfad
command_resource = f'find {resource_packs_path} -maxdepth 1 -type d'
stdin, stdout, stderr = ssh.exec_command(command_resource)
resource_packs = stdout.read().decode().strip().split('\n')
# Filtere den Basispfad, leere Zeilen und unerwünschte Ordner heraus
resource_packs = [pack for pack in resource_packs if pack and pack != resource_packs_path and not os.path.basename(pack).startswith(("vanilla", "chemistry", "experimental"))]
# Bereinige die Pfade, um nur die Verzeichnisnamen zu erhalten
behavior_packs = [os.path.basename(pack) for pack in behavior_packs]
resource_packs = [os.path.basename(pack) for pack in resource_packs]
print("Behavior Packs:")
for pack in behavior_packs:
print(pack)
print("\nResource Packs:")
for pack in resource_packs:
print(pack)
def mod_install_dialog(sftp):
AUSWAHL = input("\nWas soll installiert werden?\n1 - Behavior Pack\n2 - Ressource Pack\n -> ")
install_path = None # Initialisiere install_path mit None
if AUSWAHL == "1":
print("Behavior Pack wird installiert...")
install_path = mod_install(sftp, "behavior")
elif AUSWAHL == "2":
print("Ressource Pack wird installiert...")
install_path = mod_install(sftp, "ressource")
if install_path:
print(f"Mod wurde installiert unter: {install_path}")
else:
print("Installation fehlgeschlagen oder abgebrochen.")
def mod_install(sftp, Pack_Type):
world_name = WORLD_NAME
local_dir_input = input("\nPfad zum Mod: ")
local_dir = local_dir_input.strip('"').strip()
local_dir_name = os.path.basename(local_dir)
if Pack_Type == "behavior":
remote_base_dir = BEHAVIOR_PACKS_PATH
pack_type = "behavior"
elif Pack_Type == "ressource":
remote_base_dir = RESOURCE_PACKS_PATH
pack_type = "ressource"
else:
print("Unbekannter Pack-Typ:", Pack_Type)
return
remote_dir = os.path.join(remote_base_dir, local_dir_name).replace('\\', '/')
upload_directory(sftp, local_dir, remote_dir)
# Extrahiere die UUID und Version aus der manifest.json
uuid, version = extract_manifest_data(sftp, remote_dir)
# Füge die Daten in die Welt-JSON-Datei ein
world_path = os.path.join(WORLDS_PATH, world_name).replace('\\', '/')
json_add(sftp, world_path, pack_type, uuid, version)
return remote_dir
def upload_directory(sftp, local_dir, remote_dir):
"""Hilfsfunktion zum rekursiven Hochladen des Inhalts eines Verzeichnisses."""
if not os.path.isdir(local_dir):
print("Der angegebene Pfad ist kein Verzeichnis:", local_dir)
return
for item in os.listdir(local_dir):
local_path = os.path.join(local_dir, item)
# Konvertiere Windows-Pfade in Unix-Pfade für den Remote-Server
remote_path = os.path.join(remote_dir, item).replace('\\', '/')
if os.path.isdir(local_path):
# Es ist ein Verzeichnis, rekursiv weitermachen
try:
sftp.listdir(remote_path)
except IOError:
sftp.mkdir(remote_path)
upload_directory(sftp, local_path, remote_path) # Rekursiver Aufruf mit korrekten Pfaden
else:
# Es ist eine Datei, hochladen
sftp.put(local_path, remote_path)
def extract_manifest_data(sftp, mod_path):
manifest_path = os.path.join(mod_path, "manifest.json").replace('\\', '/')
try:
with sftp.open(manifest_path, "r") as manifest_file:
manifest_data = json.load(manifest_file)
uuid = manifest_data['header']['uuid']
version = ".".join(str(v) for v in manifest_data['header']['version'])
return uuid, version
except Exception as e:
print(f"Fehler beim Lesen der manifest.json: {e}")
return None, None
def json_add(sftp, world_path, pack_type, uuid, version):
if pack_type == "behavior":
json_file_path = os.path.join(world_path, "world_behavior_packs.json").replace('\\', '/')
elif pack_type == "ressource":
json_file_path = os.path.join(world_path, "world_resource_packs.json").replace('\\', '/')
else:
print("Unbekannter Pack-Typ")
return
# Stelle sicher, dass das Verzeichnis existiert
try:
sftp.chdir(world_path) # Versuche, in das Verzeichnis zu wechseln
except IOError:
print(f"Das Verzeichnis {world_path} existiert nicht auf dem Server.")
return
data = [] # Initialisiere eine leere Liste für den Fall, dass die Datei nicht existiert
try:
# Versuche, die existierende JSON-Datei zu lesen
with sftp.open(json_file_path, "r") as json_file:
data = json.load(json_file)
except IOError:
print(f"Die Datei {json_file_path} existiert nicht. Eine neue Datei wird erstellt.")
# Füge das neue Pack hinzu
new_pack = {"pack_id": uuid, "version": version}
if new_pack not in data:
data.append(new_pack)
# Schreibe die aktualisierte Liste zurück in die Datei
with sftp.open(json_file_path, "w") as json_file:
json.dump(data, json_file, indent=4)
print(f"Die Informationen wurden erfolgreich zu {json_file_path} hinzugefügt.")
def remove_mod_from_json(sftp, world_path, pack_type, uuid):
if pack_type == "behavior":
json_file_path = os.path.join(world_path, "world_behavior_packs.json").replace('\\', '/')
elif pack_type == "ressource":
json_file_path = os.path.join(world_path, "world_resource_packs.json").replace('\\', '/')
else:
print("Unbekannter Pack-Typ")
return False
try:
with sftp.open(json_file_path, "r") as json_file:
data = json.load(json_file)
except IOError:
print(f"Die Datei {json_file_path} existiert nicht.")
return False
# Entferne den Eintrag mit der entsprechenden UUID
data = [pack for pack in data if pack.get("pack_id") != uuid]
# Schreibe die aktualisierte Liste zurück in die Datei
with sftp.open(json_file_path, "w") as json_file:
json.dump(data, json_file, indent=4)
print(f"Mod mit UUID {uuid} wurde aus {json_file_path} entfernt.")
return True
def delete_mod_folder(sftp, mod_path):
try:
# Liste alle Dateien/Ordner im Mod-Ordner auf und lösche sie
for item in sftp.listdir(mod_path):
item_path = os.path.join(mod_path, item).replace('\\', '/')
try:
sftp.remove(item_path) # Versuche, die Datei zu löschen
except IOError:
delete_mod_folder(sftp, item_path) # Falls es ein Ordner ist, rekursiv löschen
sftp.rmdir(mod_path) # Lösche den nun leeren Mod-Ordner
print(f"Mod-Ordner {mod_path} wurde gelöscht.")
return True
except Exception as e:
print(f"Fehler beim Löschen des Mod-Ordners {mod_path}: {e}")
return False
def mod_uninstall_dialog(sftp):
pack_type_input = input("\nWelcher Typ von Mod soll deinstalliert werden?\n1 - Behavior Pack\n2 - Ressource Pack\n -> ")
pack_type = "behavior" if pack_type_input == "1" else "ressource"
mod_name = input("Gib den Namen des Mods ein: ").strip()
# Pfade für den Mod und die JSON-Datei
remote_base_dir = BEHAVIOR_PACKS_PATH if pack_type == "behavior" else RESOURCE_PACKS_PATH
mod_path = os.path.join(remote_base_dir, mod_name).replace('\\', '/')
world_path = os.path.join(WORLDS_PATH, WORLD_NAME).replace('\\', '/')
# Extrahiere die UUID aus der manifest.json des Mods
uuid, _ = extract_manifest_data(sftp, mod_path)
if uuid:
# Entferne den Mod aus der JSON-Datei und lösche den Mod-Ordner
if remove_mod_from_json(sftp, world_path, pack_type, uuid) and delete_mod_folder(sftp, mod_path):
print(f"Mod {mod_name} wurde erfolgreich deinstalliert.")
else:
print("Fehler beim Deinstallieren des Mods.")
else:
print("Mod konnte nicht gefunden oder UUID konnte nicht extrahiert werden.")
if __name__ == "__main__":
ssh = ssh_connect()
run = True
while run:
AUSWAHL = input("\nBefehl eingeben:\n1 - Mods auflisten\n2 - Mod installieren\n3 - Mod deinstallieren\nq - Beenden\n -> ").strip()
if(AUSWAHL == "1"):
get_mods(ssh, BEHAVIOR_PACKS_PATH, RESOURCE_PACKS_PATH)
elif(AUSWAHL == "2"):
sftp = ssh.open_sftp()
mod_install_dialog(sftp)
elif(AUSWAHL == "3"):
sftp = ssh.open_sftp()
mod_uninstall_dialog(sftp)
elif(AUSWAHL == "q"):
ssh.close()
run = False