def download_index(self, asset_id): ''' Downloads the JSON asset index specified by 'asset_id' ''' asset_url_object = URL("indexes/" + asset_id + ".json", URL.DOWNLOAD).url_object() asset_index_path = str(self.BASE_PATH.joinpath("indexes/" + asset_id + ".json")) FileTools.write_object(asset_index_path, asset_url_object)
def download_missing(self, asset_id, progress_function=None): ''' Downloads assets specified in 'asset_id' that are not already downloaded ''' asset_info = FileTools.read_json(str(self.get_paths(asset_id)["index"])) asset_list = asset_info["objects"] if not (progress_function == None): progress_function("Finding missing assets", 0) asset_dict = dict() if (self._is_virtual(asset_info)): assets_base_path = self.BASE_PATH.joinpath("virtual/" + asset_id) if not assets_base_path.exists(): for asset_name in asset_list.keys(): asset_url = URL([asset_list[asset_name]["hash"][:2], asset_list[asset_name]["hash"]], URL.RESOURCES) asset_dict[asset_url] = str(assets_base_path.joinpath(asset_name)) else: for asset in asset_list.values(): asset_relative_path = [asset["hash"][:2], asset["hash"]] asset_url = URL(asset_relative_path, URL.RESOURCES) asset_path = self.BASE_PATH.joinpath(*(["objects"] + asset_relative_path)) if not asset_path.exists(): asset_dict[asset_url] = str(asset_path) asset_count = 0 asset_total_count = len(asset_dict) for asset_url in asset_dict.keys(): asset_url_object = asset_url.url_object() FileTools.write_object(asset_dict[asset_url], asset_url_object) asset_count += 1 if not (progress_function == None): progress_function("Downloading assets", asset_count/asset_total_count)
def _file_exists(self, name, file_path): if FileTools.exists(file_path): if FileTools.is_file(file_path): return True else: QtGui.QMessageBox.critical(self, "YAMCL: " + name + " Path Error", name + " path '" + file_path + "' is not a regular file.") return False else: QtGui.QMessageBox.critical(self, "YAMCL: " + name + " Path Error", name + " path '" + file_path + "' does not exist.")
def delete(self, profile_name): ''' Deletes profile 'profile_name' ''' if not profile_name in self.index: raise Exception("Profile " + str(profile_name) + " does not exist") # TODO: More appropriate exception FileTools.delete_and_clean(str(self.BASE_PATH.joinpath(*self.index[profile_name]["directory"]))) del self.index[profile_name] self._flush_index()
def _dir_exists(self, name, dir_path): if FileTools.exists(dir_path): if FileTools.is_dir(dir_path): return True else: QtGui.QMessageBox.critical(self, "YAMCL: " + name + " Path Error", name + " path '" + dir_path + "' is not a directory.") return False else: QtGui.QMessageBox.critical(self, "YAMCL: " + name + " Path Error", name + " path '" + dir_path + "' does not exist.")
def new(self, profile_name): ''' Creates a new profile with name 'profile_name' ''' if not profile_name in self.index: self.index[profile_name] = dict() self.index[profile_name]["directory"] = [FileTools.create_valid_name(profile_name)] profile_metadata = dict() FileTools.write_json(str(self.BASE_PATH.joinpath(profile_name + "/yamcl_metadata.json")), profile_metadata) self._flush_index()
def delete(self, version_id, version_type): if not self.version_exists(version_id, version_type): raise Exception("Version does not exist") # TODO: More appropriate exception index_count = 0 for current_version in self.index: if current_version["type"] == version_type and current_version["name"] == version_id: break else: index_count += 1 del self.index[index_count] self._flush_index() FileTools.delete_and_clean(str(self.get_paths(version_id, version_type)["directory"]))
def _clone_version(self, orig_id, orig_type, clone_id, clone_type): orig_paths = self.get_paths(orig_id, orig_type) clone_paths = self.get_paths(clone_id, clone_type) FileTools.copy(orig_paths["jar"], clone_paths["jar"]) FileTools.copy(orig_paths["json"], clone_paths["json"]) current_listing = dict() current_listing["type"] = clone_type current_listing["name"] = clone_id self.index.append(current_listing) self._flush_index()
def rename(self, current_profile_name, new_profile_name): ''' Renames a profile 'current_profile_name' to a new name 'new_profile_name' ''' if not current_profile_name in self.index: raise Exception("Cannot rename: " + current_profile_name + " does not exist") if new_profile_name in self.index: raise Exception("Cannot rename: " + new_profile_name + " already exists") FileTools.rename(str(self.BASE_PATH.joinpath(*self.index[current_profile_name]["directory"])), str(self.BASE_PATH.joinpath(FileTools.create_valid_name(new_profile_name)))) del self.index[current_profile_name] self.index[new_profile_name] = dict() self.index[new_profile_name]["directory"] = [FileTools.create_valid_name(new_profile_name)] self._flush_index()
def install_custom(self, version_id, version_jar, version_json): if self.version_exists(version_id, "custom"): raise Exception("Version already exists") # TODO: More appropriate exception paths_dict = self.get_paths(version_id, "custom") FileTools.copy(version_jar, paths_dict["jar"]) FileTools.copy(version_json, paths_dict["json"]) current_listing = dict() current_listing["type"] = "custom" current_listing["name"] = version_id self.index.append(current_listing) self._flush_index()
def download_official(self, version_id): if self.version_exists(version_id, "vanilla"): raise Exception("Version " + version_id + " already exists") # TODO: More appropriate exception paths_dict = self.get_paths(version_id, "vanilla") FileTools.write_object(paths_dict["jar"], URL(["versions", version_id, version_id + ".jar"], URL.DOWNLOAD).url_object()) FileTools.write_object(paths_dict["json"], URL(["versions", version_id, version_id + ".json"], URL.DOWNLOAD).url_object()) current_listing = dict() current_listing["type"] = "vanilla" current_listing["name"] = version_id self.index.append(current_listing) self._flush_index()
def _remove_unused_objects(self, asset_id_list): ''' Removes assets from the 'objects' folder that are not present in the indexes 'asset_id_list' This does not include virtual assets ''' used_hash_list = list() for asset_id in asset_id_list: current_assets = FileTools.read_json(str(self.get_paths(asset_id)["index"]))["objects"] for resource in current_assets.keys(): current_hash = current_assets[resource]["hash"] if not current_hash in used_hash_list: used_hash_list.append(current_hash) for prefix_hash_dir in self.BASE_PATH.joinpath("objects").iterdir(): for hash_file in prefix_hash_dir.iterdir(): if not hash_file.name in used_hash_list: FileTools.delete_and_clean(str(hash_file))
def __init__(self, launcher_obj): self.Launcher = launcher_obj self.download_exclusive = True self.BASE_PATH = self.Launcher.ROOT_PATH.joinpath("lib") self.index_path = str(self.BASE_PATH.joinpath("index.json")) self.index = FileTools.read_json(self.index_path)
def __init__(self, launcher_obj, name, profile_path): self.Launcher = launcher_obj self.profile_name = name self.data_path = profile_path self.metadata = FileTools.read_json(str(self.data_path.joinpath("yamcl_metadata.json"))) self.game_process = None
def _add_native_path(self): new_directory = self._get_filebrowser_dir_path("YAMCL: Select Natives Directory") if self._native_exists(new_directory): QtGui.QMessageBox.critical(self, "YAMCL: Native Path Exists", "Natives directory '" + new_directory + "' is already added.", QtGui.QMessageBox.Ok) else: self.last_filebrowser_dir = FileTools.dir_name(new_directory) self.natives_dir_list.model().appendRow(QtGui.QStandardItem(new_directory))
def _get_filebrowser_file_path(self, dialog_title, file_filter=None): all_filters = "All Files(*)" if not file_filter == None: all_filters = file_filter + ";;" + all_filters file_name, current_filter = QtGui.QFileDialog.getOpenFileName(self, dialog_title, dir=self.last_filebrowser_dir, filter=all_filters) if file_name: self.last_filebrowser_dir = FileTools.dir_name(file_name) return file_name else: return None
def delete(self, asset_id): ''' Deletes assets 'asset_id' ''' asset_paths = self.get_paths(asset_id) if self._is_virtual(FileTools.read_json(str(asset_paths["index"]))): FileTools.delete_and_clean(str(asset_paths["directory"])) FileTools.delete_and_clean(str(asset_paths["index"])) else: FileTools.delete_and_clean(str(asset_paths["index"])) self._remove_unused_objects(self._get_indexes())
def get_paths(self, asset_id): ''' Returns a dictionary containing the path to the index and directory for assets ID 'asset_id' ''' asset_index_path = self.BASE_PATH.joinpath("indexes/" + asset_id + ".json") if not asset_index_path.exists(): raise Exception("Assets ID " + asset_id + " does not exist") asset_paths = dict() asset_paths["index"] = asset_index_path if self._is_virtual(FileTools.read_json(str(asset_index_path))): asset_paths["directory"] = str(self.BASE_PATH.joinpath("virtual/" + asset_id)) return asset_paths asset_paths["directory"] = self.BASE_PATH.joinpath("objects") return asset_paths
def add_local(self, library_id, is_natives, source_paths, destination_path): ''' source_paths is a list if regular library, then it should contain one string to a jar if natives, then it should contain paths to all natives directories Destination path is a path to a jar or directory (for regular or natives, respectively) ''' if library_id in self.index: raise Exception("Library already exists") # TODO: More appropriate exception if isinstance(destination_path, list): final_path = self.BASE_PATH.joinpath(*destination_path) else: final_path = pathlib.Path(destination_path) # Assuming absolute if is_natives: for current_source in source_paths: try: FileTools.copy(current_source, str(final_path.joinpath(FileTools.get_file_name(current_source)))) except FileExistsError: pass else: FileTools.copy(source_paths[0], str(final_path)) self.index[library_id] = dict() self.index[library_id]["path"] = list(final_path.relative_to(self.BASE_PATH).parts) self._flush_index()
def _download_library(self, library_metadata): if self.download_exclusive and not library_metadata.current_system_supported(): return if library_metadata.is_natives(): if self.download_exclusive: all_extensions = [library_metadata.get_current_system_natives_extension()] else: all_extensions = library_metadata.get_all_natives_extensions() natives_list = all_extensions if self.is_library_existant(library_metadata): if library_metadata.is_natives(): natives_list = list() for current_extension in all_extensions: if not self.is_natives_existant(library_metadata, current_extension): natives_list.append(current_extension) if natives_list == list(): return # Natives already exists else: return # Library already exists if library_metadata.is_natives(): download_list = library_metadata.get_download_list(natives_list) else: download_list = library_metadata.get_download_list() for current_library in download_list: current_tries = 1 while current_tries <= 3: correct_hash = current_library["hash"].url_object().read().decode("UTF-8") FileTools.write_object(str(self.BASE_PATH.joinpath(current_library["path"])), current_library["url"].url_object()) hasher = hashlib.sha1() hasher.update(open(str(self.BASE_PATH.joinpath(current_library["path"])), mode="rb").read()) if hasher.hexdigest() == correct_hash: if library_metadata.is_natives(): natives_directory = self.BASE_PATH.joinpath(current_library["path"].parent.joinpath(current_library["natives_extension"])) jar_path = str(self.BASE_PATH.joinpath(current_library["path"])) FileTools.extract_jar_files(FileTools.get_jar_object(jar_path), str(natives_directory), library_metadata.get_natives_exclude()) FileTools.delete_and_clean(jar_path) break else: current_tries += 1 if current_tries == 3: raise Exception("Failed to download library " + library_metadata.get_id()) # TODO: More appropriate exception self.index[library_metadata.get_id()] = dict() if library_metadata.is_natives(): self.index[library_metadata.get_id()]["path"] = download_list[0]["path"].parent.parts else: self.index[library_metadata.get_id()]["path"] = download_list[0]["path"].parts
def rename(self, current_version_id, new_version_id): if not self.version_exists(current_version_id, "custom"): raise Exception("Cannot rename: " + current_version_id + " does not exist") if self.version_exists(new_version_id, "custom"): raise Exception("Cannot rename: " + new_version_id + " already exists") old_id_paths = self.get_paths(current_version_id, "custom") new_id_paths = self.get_paths(new_version_id, "custom") FileTools.add_missing_dirs(new_id_paths["jar"]) for file_type in ["jar", "json"]: FileTools.move(old_id_paths[file_type], new_id_paths[file_type]) FileTools.delete_and_clean(str(old_id_paths["directory"])) index_listing = self.index[self._get_version_index(current_version_id, "custom")] index_listing["name"] = new_version_id self._flush_index()
def flush_metadata(self): ''' Writes current library index in memory to the YAMCL data directory ''' FileTools.write_json(str(self.data_path.joinpath("yamcl_metadata.json")), self.metadata)
def __init__(self, launcher_obj): self.Launcher = launcher_obj self.BASE_PATH = self.Launcher.ROOT_PATH.joinpath("profile") self.index = FileTools.read_json(str(self.BASE_PATH.joinpath("index.json"))) self.profile_instances = dict()
def _flush_index(self): ''' Writes current profile index in memory to the YAMCL data directory ''' FileTools.write_json(str(self.BASE_PATH.joinpath("index.json")), self.index)
def delete(self, library_id): if not library_id in self.index: raise Exception("Library is not existant") # TODO: More appropriate exception FileTools.delete_and_clean(str(self.BASE_PATH.joinpath(self.get_library_path(library_id)))) del self.index[library_id] self._flush_index()
def _flush_index(self): FileTools.write_json(self.index_path, self.index)
def __init__(self, launcher_obj): self.Launcher = launcher_obj self.BASE_PATH = self.Launcher.ROOT_PATH.joinpath("bin") self.index_path = str(self.BASE_PATH.joinpath("index.json")) self.index = FileTools.read_json(self.index_path)
def flush_info(self): FileTools.write_json(self.info_path, self.json_info)
def __init__(self, launcher_obj, json_path, custom_bool): self.Launcher = launcher_obj self.is_custom = custom_bool self.info_path = json_path self.json_info = FileTools.read_json(json_path)