Files
LCE-Qt-Launcher/src/lce_qt_launcher/managers/mod_manager.py

245 lines
7.3 KiB
Python
Executable File

#!/usr/bin/env python
"""
LCE Mods Manager
Copyright (C) 2026 Xgui4
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import sys
import os
import argparse
from enum import StrEnum
from zipfile import ZipFile, BadZipFile
DLC_LOCATION: str = os.path.join("Windows64Media", "DLC")
WORLD_LOCATION: str = os.path.join("Windows64", "GameHDD")
MOD_LOCATION: str = os.path.join("Windows64", "Media")
CUSTOM_SKIN_LOCATION: str = os.path.join("Common", "res", "mob")
class ContentType(StrEnum):
DLC = DLC_LOCATION
WORLD = WORLD_LOCATION
MOD = MOD_LOCATION
CUSTOM_SKIN = CUSTOM_SKIN_LOCATION
NONE = "0"
def from_str_to_enum(string: str) -> ContentType:
print(string)
match string:
case "DLC":
return ContentType.DLC
case "World":
return ContentType.WORLD
case "Mod":
return ContentType.MOD
case "Default Skin":
return ContentType.CUSTOM_SKIN
case "None":
return ContentType.NONE
case _:
raise RuntimeError("Invalid Argument")
LEGAL_TEXT = """
LCE Mods Managers Copyright (C) 2026 Xgui4
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
"""
def extract_zip(data: ZipFile, extraction_path: str) -> None:
"""
_summary_ :
extract the zipfile of the content to the desired path
Args:
data : the zip file itself
extraction_path : the specified extraction path
#FIXME Make Async"""
data.extractall(extraction_path)
def install_content(instance_path: str, contentType: ContentType, archive_file: str) -> None:
"""_summary_
install the content of the mode
Args:
instance_path (str): _description_ : the instance path
contentType (ContentType): _description_ : the content type
archive_file (str): _description_ the archive file that have the content
"""
try:
zipFile = ZipFile(archive_file)
content_path: str = os.path.join(instance_path, contentType.value)
extract_zip(zipFile, content_path)
except BadZipFile as e:
print(
f"Could not extract content to destination, zipfile was bad. More Info : {e}"
)
except FileNotFoundError as e:
print(
f"Could not extract content to destination, archive do not exist. More Info : {e.filename} : {e}"
)
except FileExistsError as e:
print(
f"Could not extract content to destination, file(s) already exist. More Info : {e.filename} : {e}"
)
except RuntimeError as e:
print(f"An unexpected error occured. More info {e.args}")
else:
print(
f"Successully extracted the {contentType.name} ({archive_file}) at instance : {instance_path}"
)
def main():
if len(sys.argv) > 1:
if sys.argv[1] == "--gui":
from PySide6.QtWidgets import QApplication
from PySide6.QtGui import QFontDatabase
from lce_qt_launcher.views.content_installer_dialog import ContentInstallerView
app = QApplication()
app.setStyle("Fusion")
ContentInstallerView()
font_id = QFontDatabase.addApplicationFont(":/fonts/monocraft.ttc")
if font_id == -1:
print("Error: Font could not be loaded.")
else:
family = QFontDatabase.applicationFontFamilies(font_id)[0]
app.setFont(family)
sys.exit(app.exec())
parser = argparse.ArgumentParser(
prog="LCE Mods Manager",
description="Manage DLC, World and Mods for Minecraft LCE",
)
file: str = ""
contentType: str = ""
instance_path: str = ""
contentTypeEnum: ContentType = ContentType.NONE
if len(sys.argv) > 1:
parser.add_help = True
parser.epilog = LEGAL_TEXT
parser.add_argument(
"--instance_path",
type=str,
help="Path of the instance to install the content on",
)
parser.add_argument(
"--content_type",
type=str,
help="Content Type, possible valie : DLC, World and Mod",
)
parser.add_argument("--file", type=str, help="The Archive file to install")
parsed_cmd_args = parser.parse_known_intermixed_args()
contentType = parsed_cmd_args[0].content_type
contentTypeEnum = ContentType.NONE
if parsed_cmd_args[0].content_type == "None":
print(r"""
1. Install Maps/World
2. Install DLC
3. Install Mods
4. Install Custom Skin
5. Cancel
""")
user_input = input("Choose a option")
if user_input == "1":
contentTypeEnum = ContentType.WORLD
if user_input == "2":
contentTypeEnum = ContentType.DLC
if user_input == "3":
contentTypeEnum = ContentType.MOD
if user_input == "4":
contentTypeEnum = ContentType.CUSTOM_SKIN
else:
exit("Operation Canceled")
if contentType == "DLC":
contentTypeEnum = ContentType.DLC
if contentType == "World":
contentTypeEnum = ContentType.WORLD
if contentType == "Mod":
contentTypeEnum = ContentType.MOD
if contentType == "Custom Skin":
contentTypeEnum = ContentType.CUSTOM_SKIN
else:
pass
instance_path = parsed_cmd_args[0].instance_path
if instance_path == "None":
instance_path = input("Enter the Instance path.")
file = parsed_cmd_args[0].file
if file == "None":
file = input(f"Enter the archive of the {contentTypeEnum.name}")
else:
print(r"""
1. Install Maps/World
2. Install DLC
3. Install Mods
4. Install Custom Skin
5. Cancel
""")
user_input = input("Choose a option")
if user_input == "1":
contentTypeEnum = ContentType.WORLD
if user_input == "2":
contentTypeEnum = ContentType.DLC
if user_input == "3":
contentTypeEnum = ContentType.MOD
if user_input == "4":
contentTypeEnum = ContentType.CUSTOM_SKIN
else:
exit("Operation Canceled")
instance_path = input("Enter the Instance path.")
file = input(f"Enter the archive of the {contentTypeEnum.name}")
print(LEGAL_TEXT)
print(f"""File : {file}
Content Type : {contentTypeEnum.value}
Instance_Path : {instance_path}""")
install_content(instance_path, contentTypeEnum, file)
if __name__ == "__main__":
main()