Skip to content

Commit

Permalink
Updated version 0.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
CaraMob323 committed Feb 25, 2024
1 parent 825bdd3 commit bdb1745
Show file tree
Hide file tree
Showing 70 changed files with 9,583 additions and 103 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# TobiMods

TobiMods is a "Lethal company" mod updater and installer that aims to make all your friends have the same mods.

## Usage

Just run the .exe, select the folder where the lethal executable is and let the magic happen.

## Contributing

Any help is welcome.

-Sorry for the spagetti code, it's my first project.

## License

[MIT](https://choosealicense.com/licenses/mit/)
3 changes: 2 additions & 1 deletion TobiMods/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from .core import *
from .core import *
from .helpers import *
Binary file added TobiMods/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Binary file added TobiMods/__pycache__/core.cpython-312.pyc
Binary file not shown.
Binary file added TobiMods/__pycache__/helpers.cpython-312.pyc
Binary file not shown.
208 changes: 106 additions & 102 deletions TobiMods/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,100 @@
import requests
import zipfile
import shutil
from .helpers import *
from helpers import *
from easygui import diropenbox
from concurrent.futures import ThreadPoolExecutor

class GetFilesRules:
def __init__(self) -> None:
self.files_rules = {}

def get_file_rules(self, path: str):
for dirpath, dirnames, filenames in os.walk(os.path.join(path)):
for item in filenames + dirnames:
full_path = os.path.join(dirpath, item)
dirlist = full_path.split(os.sep)
mod_name = path.split("\\")[-1]
if os.path.isfile(full_path) and item.endswith(".dll"):
self.files_rules[mod_name] = {
"path_.dll": full_path,
"path_bepinex": self.get_rule_path(dirlist, "bepinex"),
"path_plugins": self.get_rule_path(dirlist, "plugins"),
"path_manifest": None
}
elif os.path.isdir(full_path) and full_path.split("\\")[-1].lower() == "plugins":
self.files_rules[mod_name] = {
"path_.dll": None,
"path_bepinex": self.get_rule_path(dirlist, "bepinex"),
"path_plugins": self.get_rule_path(dirlist, "plugins"),
"path_manifest": None
}

for dirpath, dirnames, filenames in os.walk(os.path.join(path)):
for filename in filenames:
if filename == "manifest.json":
dirlist = dirpath.split(os.sep)
if mod_name in self.files_rules:
self.files_rules[mod_name]["path_manifest"] = os.path.join(dirpath, filename)
else:
self.files_rules[mod_name] = {
"path_.dll": None,
"path_bepinex": None,
"path_plugins": None,
"path_manifest": os.path.join(dirpath, filename)
}

def get_rule_path(self, dirname: list, folder: str):
lower_dirnames = [lower_dirname.lower() for lower_dirname in dirname]
if folder in lower_dirnames:
for i in range(len(dirname)):
if lower_dirnames[i] == folder:
return os.path.join(*dirname[:i+1])
else:
return None

class ManageFolders:
def __init__(self) -> None:
self.lethal_path = None
self.search_folder()
self.yml = self.get_mods_list()

def search_folder(self):
folder = diropenbox(title="Seleccione la carpeta de Lethal Company")
if folder == "" or folder == None:
raise FileNotFoundError("Seleccione una carpeta")
self.lethal_path = folder

def get_mods_list(self):
url = "https://raw.githubusercontent.com/CaraMob323/Tobimods/main/mods.yml"
request = requests.get(url)
if request.status_code == 200:
file = yaml.safe_load(request.text)
return file
raise request

class ManageCases: # I don't know as this works but works
def __init__(self) -> None:
pass
self.manage_folders = ManageFolders()
self.lethal_path = self.manage_folders.lethal_path
self.rules = GetFilesRules()

def choose_case(self, name: str, author: str):
self.rules.get_file_rules(self.lethal_path+"\\"+name)
manifest = self.rules.files_rules[name]["path_manifest"]
pathlist = manifest.split("\\")
full_name = author+"-"+pathlist[-2]
pathlist = [x + "\\" for x in pathlist]
pathlist = pathlist[:-1]
path = os.path.join(*pathlist)
if self.rules.files_rules[name]["path_bepinex"] == None:
self.case_folder_dll(path, full_name)
elif self.rules.files_rules[name]["path_bepinex"] != None and self.rules.files_rules[name]["path_plugins"] != None:
self.case_bepinex_plugins_dll(path, full_name)
else:
self.case_bepinex_dll(path, full_name)
shutil.rmtree(path)
print(name, "se descargo bien xd")

def case_bepinex_plugins_dll(self, path_folder: str, full_name: str):
plugins_folder = path_folder+"BepInEx"+"\\"+"plugins"
Expand All @@ -33,6 +119,7 @@ def case_bepinex_plugins_dll(self, path_folder: str, full_name: str):
def case_folder_dll(self, path_folder: str, full_name: str):
plugins_folder = path_folder+"plugins"

os.makedirs(plugins_folder, exist_ok=True)
file_destination = plugins_folder+"\\"+full_name
content_mod = os.listdir(path_folder)
content_plugins = os.listdir(plugins_folder)
Expand Down Expand Up @@ -108,79 +195,10 @@ def case_bepinex_dll(self, path_folder: str, full_name: str):

shutil.copytree(path_folder, self.lethal_path, dirs_exist_ok=True)

class GetFilesRules:
class IdentifyMods:
def __init__(self) -> None:
self.files_rules = {}

def get_file_rules(self, path: str):
for dirpath, dirnames, filenames in os.walk(os.path.join(path)):
for item in filenames + dirnames:
full_path = os.path.join(dirpath, item)
dirlist = full_path.split(os.sep)
mod_name = path.split("\\")[-1]
if os.path.isfile(full_path) and item.endswith(".dll"):
self.files_rules[mod_name] = {
"path_.dll": full_path,
"path_bepinex": self.get_rule_path(dirlist, "bepinex"),
"path_plugins": self.get_rule_path(dirlist, "plugins"),
"path_manifest": None
}
elif os.path.isdir(full_path) and full_path.split("\\")[-1].lower() == "plugins":
self.files_rules[mod_name] = {
"path_.dll": None,
"path_bepinex": self.get_rule_path(dirlist, "bepinex"),
"path_plugins": self.get_rule_path(dirlist, "plugins"),
"path_manifest": None
}

for dirpath, dirnames, filenames in os.walk(os.path.join(path)):
for filename in filenames:
if filename == "manifest.json":
dirlist = dirpath.split(os.sep)
if mod_name in self.files_rules:
self.files_rules[mod_name]["path_manifest"] = os.path.join(dirpath, filename)
else:
self.files_rules[mod_name] = {
"path_.dll": None,
"path_bepinex": None,
"path_plugins": None,
"path_manifest": os.path.join(dirpath, filename)
}


def get_rule_path(self, dirname: list, folder: str):
lower_dirnames = [lower_dirname.lower() for lower_dirname in dirname]
if folder in lower_dirnames:
for i in range(len(dirname)):
if lower_dirnames[i] == folder:
return os.path.join(*dirname[:i])
else:
return None


class ManageFolders:
def __init__(self) -> None:
self.lethal_path = self.search_folder()
self.yml = self.get_mods_list()

def search_folder(self):
folder = diropenbox(title="Seleccione la carpeta de Lethal Company")
if folder == "" or folder == None:
raise FileNotFoundError("Seleccione una carpeta")
return folder

def get_mods_list(self):
url = "https://raw.githubusercontent.com/CaraMob323/Tobimods/main/mods.yml"
request = requests.get(url)
if request.status_code == 200:
file = yaml.safe_load(request.text)
return file
raise request

class IdentifyMods(ManageFolders):
def __init__(self) -> None:
ManageFolders.__init__(self)
self.rules = GetFilesRules()
self.manage_cases = ManageCases()
self.lethal_path = self.manage_cases.lethal_path

self.missing_mods = []
self.extra_mods = []
Expand All @@ -206,28 +224,31 @@ def process_mod(mod_name):
self.information_mods[mod_name]["latest_version"] = json_mod["latest"]["version_number"]
self.information_mods[mod_name]["download_url"] = json_mod["latest"]["download_url"]
self.identify_outdated_mods(mod_name)
self.identify_missing_mods(mod_name)

if response.status_code != 200:
print("INTENTA DE NUEVO, FALLO CATASTROFICO")

with ThreadPoolExecutor(2) as executor:
executor.map(process_mod, self.information_mods.keys())


def identify_author_mods(self):
mods: list = self.yml
mods: list = self.manage_cases.manage_folders.yml
for mod_name in self.information_mods:
for mod in mods:
if mod["displayName"] == mod_name:
mods.remove(mod)
self.information_mods[mod_name]["author"] = mod["authorName"]
else:
self.extra_mods.append(mod_name)
self.identify_missing_mods()
for mod in self.manage_cases.manage_folders.yml:
self.missing_mods.append(mod["displayName"])
for mod_name in self.missing_mods:
for mod in mods:
if mod["displayName"] == mod_name:
self.information_mods.setdefault(mod_name, {}).update({"author": mod["authorName"], "local_version": "", "latest_version": ""})
self.yml = self.get_yml()
self.manage_cases.manage_folders.yml = self.manage_cases.manage_folders.get_mods_list()

def identify_outdated_mods(self, mod_name):
if self.information_mods[mod_name]["latest_version"] != self.information_mods[mod_name]["local_version"] and self.information_mods[mod_name]["local_version"] != "":
Expand All @@ -236,41 +257,24 @@ def identify_outdated_mods(self, mod_name):
elif self.information_mods[mod_name]["local_version"] != "":
print(mod_name, "ACTUALIZADO")

def identify_missing_mods(self):
for mod in self.yml:
self.missing_mods.append(mod["displayName"])
def identify_missing_mods(self, mod_name: str):
if self.information_mods[mod_name]["local_version"] == "":
print(mod_name, "NO ESTA")

def identify_extra_mods(self, mod_name):
mod_exits: bool = False
for mod in self.yml:
for mod in self.manage_cases.manage_folders.yml:
if mod.get("displayName") == mod_name:
mod_exits = True
return False
if mod_exits == False:
print(mod_name, "ELIMINA ESTE MOD QUE YO NO QUIERO JAJA XD")
return True

def identify_one_case(self, name: str):
self.rules.get_file_rules(self.lethal_path+"\\"+name)
manifest = self.rules.files_rules[name]["path_manifest"]
pathlist = manifest.split("\\")
author = self.information_mods[pathlist[-2]]["author"]
full_name = author+"-"+pathlist[-2]
pathlist = [x + "\\" for x in pathlist]
pathlist = pathlist[:-1]
path = os.path.join(*pathlist)
if self.rules.files_rules[name]["path_bepinex"] == None:
self.case_folder_dll(path, full_name)
elif self.rules.files_rules[name]["path_bepinex"] != None and self.rules.files_rules[name]["path_plugins"] != None:
self.case_bepinex_plugins_dll(path, full_name)
else:
self.case_bepinex_dll(path, full_name)
shutil.rmtree(path)
print(name, "se descargo bien xd")

class ManageMods:
def __init__(self) -> None:
self.identify = IdentifyMods()
self.cases = self.identify.manage_cases

def download_mod(self, url: str, name: str, path: str):
while True:
Expand All @@ -289,17 +293,17 @@ def extract_mod(self, name: str, path: str):
extract.extractall(path+"\\"+name)

def install_all(self):
print("\r\nInstalando...")
for mod_name in self.identify.outdated_mods + self.identify.missing_mods:
print("Instalando...")
self.download_mod(self.identify.information_mods[mod_name]["download_url"], mod_name, self.identify.lethal_path)
self.extract_mod(mod_name, self.identify.lethal_path)
os.remove(f"{self.identify.lethal_path}\\{mod_name}.zip")
self.identify.identify_one_case(mod_name)
self.cases.choose_case(mod_name, self.identify.information_mods[mod_name]["author"])

if "__main__" == __name__:
test = ManageMods()
print("Verificando mods...")
test.identify.identify_versions_local()
test.identify.identify_local_version()
test.identify.identify_author_mods()
test.identify.identify_latest_version()
test.install_all()
Expand Down
Binary file added Versions/app.exe
Binary file not shown.
Empty file added tests/__init__.py
Empty file.
Binary file added tests/__pycache__/TobiMods.cpython-312.pyc
Binary file not shown.
Binary file added tests/__pycache__/context.cpython-312.pyc
Binary file not shown.
5 changes: 5 additions & 0 deletions tests/context.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

import TobiMods
Loading

0 comments on commit bdb1745

Please sign in to comment.