Fix NOMODS flag clearing the load order

Mods that don't have loadable scripts are forced on
This commit is contained in:
Map 2024-10-06 20:30:04 -05:00
parent b1719c4b21
commit a266c9508c

View file

@ -190,380 +190,387 @@ init -999 python:
# Contains the mod_name's of previous mods that have successfully loaded, mirroring mod_menu_metadata while in this loop. Only used for ID checking.
mod_name_list = []
for file in loadable_mod_metadata:
mod_data_final = {}
mod_jsonfail_list = [] # List of languages that has an associated metadata language file that failed to load.
mod_preferred_modname = []
mod_exception = False
mod_in_root_folder = file.count("/", len(mods_dir)) is 0
mod_folder_name = file.split("/")[-2]
# mod_name is used only to display debugging information via mod_menu_errorcodes. Contains the mod folder name and whatever translations of
# the mod's name that exist. Kind of a cursed implemnetation but with how early error reporting this is before solidifying the mod name
# this is just what I came up with.
# Other than what's directly defined here, it will contain mod names by their language code if they exist. The "None" key will be the fallback if a name of user's
# current language is not there.
mod_name = {}
if mod_in_root_folder:
mod_name["Folder"] = None # 'None' will make it default to 'in root of mods folder' when used in the errorcode conversion.
else:
mod_name["Folder"] = mod_folder_name
# Quickly get the names of mods for debugging information, and in the process get raw values from each metadata file that exists.
# Make the base metadata file (presumably english) organized like a lang_data object, moving the ID to the mod_data_final object.
try:
mod_data = json.load(renpy.open_file(file))
except Exception as e:
if load_metadata:
for file in loadable_mod_metadata:
mod_data_final = {}
mod_jsonfail_list = [] # List of languages that has an associated metadata language file that failed to load.
mod_preferred_modname = []
mod_exception = False
mod_in_root_folder = file.count("/", len(mods_dir)) is 0
mod_folder_name = file.split("/")[-2]
# mod_name is used only to display debugging information via mod_menu_errorcodes. Contains the mod folder name and whatever translations of
# the mod's name that exist. Kind of a cursed implemnetation but with how early error reporting this is before solidifying the mod name
# this is just what I came up with.
# Other than what's directly defined here, it will contain mod names by their language code if they exist. The "None" key will be the fallback if a name of user's
# current language is not there.
mod_name = {}
if mod_in_root_folder:
print("//////////// ERROR IN ROOT FOLDER MOD:")
mod_name["Folder"] = None # 'None' will make it default to 'in root of mods folder' when used in the errorcode conversion.
else:
print(f"//////////// ERROR IN MOD '{mod_folder_name}':")
print(" "+str(e))
print("//////////// END OF ERROR")
mod_exception = True
mod_jsonfail_list.append("None")
mod_name["Folder"] = mod_folder_name
if not mod_jsonfail_list:
if _preferences.language == None and isinstance(mod_data.get("Name"), str):
mod_name["None"] = mod_data["Name"]
# Move these non-language specific pairs out of mod_data, into the base of the final mod dict.
move_key_to_dict(mod_data, mod_data_final, "ID")
move_key_to_dict(mod_data, mod_data_final, "Label")
# Then store the rest like any other language, just our default one.
mod_data_final['None'] = mod_data
# Quickly get the names of mods for debugging information, and in the process get raw values from each metadata file that exists.
# Find language metadata files in the same place as our original metadata file, and then get values from it.
for lang in renpy.known_languages():
lang_file = file[:-5] + "_" + lang + ".json" # Finds the metadata file. ex: metadata_es.json
if renpy.loadable(lang_file):
try:
lang_data = (json.load(renpy.open_file(lang_file)))
except Exception as e:
if mod_in_root_folder:
print(f"//////////// ERROR FOR {lang} METADATA IN ROOT FOLDER MOD:")
else:
print(f"//////////// ERROR FOR {lang} METADATA IN MOD '{mod_folder_name}':")
print(" "+str(e))
print("//////////// END OF ERROR")
mod_jsonfail_list.append(lang)
# Attempt to use this mod's translation of it's name if it matches the user's language preference.
if not lang in mod_jsonfail_list:
if _preferences.language == lang and isinstance(lang_data.get("Name"), str):
mod_name[lang] = lang_data["Name"]
mod_data_final[lang] = lang_data
# Finally report if any of the jsons failed to load, now that we have the definitive list of mod names we could display.
for lang_code in mod_jsonfail_list:
mod_menu_errorcodes.append([ ModError.Metadata_Fail, { "mod_name": mod_name, "lang_code": lang_code }])
#
# Sanitize/Clean metadata values
#
# Make sure our main metadata loaded
if not "None" in mod_jsonfail_list:
if mod_data_final.get("Label") != None and not isinstance(mod_data_final.get("Label"), str):
mod_menu_errorcodes.append([ ModError.Label_Not_String, { "mod_name": mod_name }])
mod_data_final["Label"] = None
# If we don't have an ID, don't put it in the mod loader
if mod_data_final.get("ID") == None:
mod_menu_errorcodes.append([ ModError.No_ID, { "mod_name": mod_name }])
# Make the base metadata file (presumably english) organized like a lang_data object, moving the ID to the mod_data_final object.
try:
mod_data = json.load(renpy.open_file(file))
except Exception as e:
if mod_in_root_folder:
print("//////////// ERROR IN ROOT FOLDER MOD:")
else:
print(f"//////////// ERROR IN MOD '{mod_folder_name}':")
print(" "+str(e))
print("//////////// END OF ERROR")
mod_exception = True
elif not isinstance(mod_data_final["ID"], str):
mod_menu_errorcodes.append([ ModError.ID_Not_String, { "mod_name": mod_name }])
mod_exception = True
else:
# Detect already loaded metadata that has the same ID as our current one, and if so, don't load them
# We'll never get a match for the first mod loaded, so this is fine.
for i, x in enumerate(mod_menu_metadata):
if x["ID"] == mod_data_final["ID"]:
mod_menu_errorcodes.append([ ModError.Similar_IDs_Found, { "mod_name": mod_name, "mod_name2": mod_name_list[i] }])
mod_exception = True
break
mod_jsonfail_list.append("None")
# Since lang keys will only be added to the mod data dict if their respective metadata successfully loaded, no need to check if they can.
for lang_key in mod_data_final.keys():
if lang_key is "None" or lang_key in renpy.known_languages():
lang_data = mod_data_final[lang_key]
if not mod_jsonfail_list:
if _preferences.language == None and isinstance(mod_data.get("Name"), str):
mod_name["None"] = mod_data["Name"]
# The JSON object returns an actual python list, but renpy only works with it's own list object and the automation for this fails with JSON.
# So we gotta make all lists revertable
for x in lang_data.keys():
if type(lang_data[x]) == python_list:
lang_data[x] = renpy.revertable.RevertableList(lang_data[x])
# Move these non-language specific pairs out of mod_data, into the base of the final mod dict.
move_key_to_dict(mod_data, mod_data_final, "ID")
move_key_to_dict(mod_data, mod_data_final, "Label")
# Then store the rest like any other language, just our default one.
mod_data_final['None'] = mod_data
# Automatically give the name of the mod from the folder it's using if there's no defined name, but report an error if one is defined but not a string
if value_isnt_valid_string(lang_data, "Name"):
if lang_data.get("Name") != None:
mod_menu_errorcodes.append([ ModError.Name_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Name"] = mod_folder_name
# Default "Display" to 'both' mode
if lang_data.get("Display") != None:
if not isinstance(lang_data.get("Display"), str):
if lang_data.get("Display") != None:
mod_menu_errorcodes.append([ ModError.Display_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Display"] = "both"
elif lang_data["Display"] not in ["both","icon","name"]:
mod_menu_errorcodes.append([ ModError.Display_Invalid_Mode, { "mod_name": mod_name, "display_mode": lang_data["Display"], "lang_code": lang_key }])
lang_data["Display"] = "both"
if value_isnt_valid_string(lang_data, "Version"):
mod_menu_errorcodes.append([ ModError.Version_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Version"] = None
# See if "Authors" is a list or string, and if it's a list search through the contents of the list to check if they're valid strings
if value_isnt_valid_string(lang_data, "Authors") and value_isnt_valid_list(lang_data, "Authors"):
mod_menu_errorcodes.append([ ModError.Authors_Not_String_Or_List, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Authors"] = None
elif isinstance(lang_data.get("Authors"), list):
# Search through and call out entries that aren't strings
for i, s in enumerate(lang_data["Authors"]):
if not isinstance(s, str):
mod_menu_errorcodes.append([ ModError.Authors_Contents_Not_String, { "mod_name": mod_name, "author_number": i + 1, "lang_code": lang_key }])
# And then mutate the list to only include strings
lang_data["Authors"][:] = [x for x in lang_data["Authors"] if isinstance(x, str)]
if lang_data["Authors"] == []:
lang_data["Authors"] = None
# Do the same as 'Authors' to 'Links'
if value_isnt_valid_string(lang_data, "Links") and value_isnt_valid_list(lang_data, "Links"):
mod_menu_errorcodes.append([ ModError.Links_Not_String_Or_List, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Links"] = None
elif isinstance(lang_data.get("Links"), list):
for i, s in enumerate(lang_data["Links"]):
if not isinstance(s, str):
mod_menu_errorcodes.append([ ModError.Links_Contents_Not_String, { "mod_name": mod_name, "link_number": i + 1, "lang_code": lang_key }])
lang_data["Links"][:] = [x for x in lang_data["Links"] if isinstance(x, str)]
if lang_data["Links"] == []:
lang_data["Links"] = None
if value_isnt_valid_string(lang_data, "Description"):
mod_menu_errorcodes.append([ ModError.Description_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Description"] = None
if value_isnt_valid_string(lang_data, "Mobile Description"):
mod_menu_errorcodes.append([ ModError.Mobile_Description_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Mobile Description"] = None
if lang_data.get("Screenshot Displayables") != None:
if not isinstance(lang_data.get("Screenshot Displayables"), list):
mod_menu_errorcodes.append([ ModError.Screenshot_Displayables_Not_List, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Screenshot Displayables"] = None
else:
# Instead of remaking the list to only include strings, replace the non-strings with empty strings ("") so subsequent strings will still be in the right
# place when eventually showing displayable screenshots over non-displayable ones
for i, s in enumerate(lang_data["Screenshot Displayables"]):
if not isinstance(s, str):
mod_menu_errorcodes.append([ ModError.Screenshot_Displayables_Contents_Not_String, { "mod_name": mod_name, "screenshot_number": i + 1, "lang_code": lang_key }])
s = ""
if lang_data["Screenshot Displayables"] == []:
lang_data["Screenshot Displayables"] = None
if value_isnt_valid_string(lang_data, "Icon Displayable"):
mod_menu_errorcodes.append([ ModError.Icon_Displayable_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Icon Displayable"] = None
if value_isnt_valid_string(lang_data, "Thumbnail Displayable"):
mod_menu_errorcodes.append([ ModError.Thumbnail_Displayable_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Thumbnail Displayable"] = None
# If our mod does not follow the structure of 'mods/Mod Name/metadata.json', don't load them
this_mod_dir = file[len(mods_dir):-len("metadata.json")] # If the metadata file is in another place, this will connect the filepath between it and the mods folder.
if file.count("/", len(mods_dir)) > 1:
good_folder = "'{color=#ffbdbd}" + mods_dir + mod_folder_name + "/{/color}'"
curr_folder = "'{color=#ffbdbd}" + mods_dir + this_mod_dir + "{/color}'"
mod_menu_errorcodes.append([ ModError.Installed_Incorrectly, { "mod_name": mod_name, "good_dir": good_folder, "curr_dir": curr_folder }])
mod_exception = True
elif mod_in_root_folder:
mod_menu_errorcodes.append([ ModError.Installed_Incorrectly, { "mod_name": mod_name, "good_dir": mods_dir + "My Mod/", "curr_dir": mods_dir }])
mod_exception = True
#
# Collect mod scripts and metadata images
#
mod_scripts = []
mod_screenshots = {}
this_mod_dir_length = len(mods_dir + this_mod_dir)
for i in all_mod_files:
if i.startswith(mods_dir + this_mod_dir):
# Collect mod scripts
if not mod_exception and i.endswith(".rpym"):
mod_scripts.append(i[:-5])
continue
# This will only allow files that are at the root of the mod folder and have one period.
elif i.count("/", this_mod_dir_length) == 0 and i.count(".", this_mod_dir_length) == 1:
this_file = i[this_mod_dir_length:]
if this_file.startswith("thumbnail."):
if is_valid_metadata_image(this_file, mod_name):
mod_data_final["None"]["Thumbnail"] = i
elif this_file.startswith("thumbnail_"):
trimmed_string = this_file[len("thumbnail_"):this_file.find(".")]
for lang in renpy.known_languages():
if lang == trimmed_string:
if is_valid_metadata_image(this_file, mod_name):
mod_data_final[lang]["Thumbnail"] = i
elif this_file.startswith("icon."):
if is_valid_metadata_image(this_file, mod_name):
if mod_data_final.get("None") == None:
mod_data_final["None"] = {}
mod_data_final["None"]["Icon"] = i
elif this_file.startswith("icon_"):
trimmed_string = this_file[len("icon_"):this_file.find(".")]
for lang in renpy.known_languages():
if lang == trimmed_string:
if is_valid_metadata_image(this_file, mod_name):
if mod_data_final.get(lang) == None:
mod_data_final["None"] = {}
mod_data_final[lang]["Icon"] = i
elif this_file.startswith("screenshot"):
# Disect the string after "screenshot" for the number and possible lang code
trimmed_string = this_file[len("screenshot"):this_file.find(".")]
number = ""
lang_code = ""
seperator = trimmed_string.find("_")
if seperator != -1:
number = trimmed_string[:seperator]
lang_code = trimmed_string[seperator + 1:]
# Find language metadata files in the same place as our original metadata file, and then get values from it.
for lang in renpy.known_languages():
lang_file = file[:-5] + "_" + lang + ".json" # Finds the metadata file. ex: metadata_es.json
if renpy.loadable(lang_file):
try:
lang_data = (json.load(renpy.open_file(lang_file)))
except Exception as e:
if mod_in_root_folder:
print(f"//////////// ERROR FOR {lang} METADATA IN ROOT FOLDER MOD:")
else:
number = trimmed_string
print(f"//////////// ERROR FOR {lang} METADATA IN MOD '{mod_folder_name}':")
print(" "+str(e))
print("//////////// END OF ERROR")
mod_jsonfail_list.append(lang)
# See if we can extract the number
try:
converted_number = int(number)
except:
continue
# Attempt to use this mod's translation of it's name if it matches the user's language preference.
if not lang in mod_jsonfail_list:
if _preferences.language == lang and isinstance(lang_data.get("Name"), str):
mod_name[lang] = lang_data["Name"]
mod_data_final[lang] = lang_data
if not is_valid_metadata_image(this_file, mod_name):
continue
# Finally report if any of the jsons failed to load, now that we have the definitive list of mod names we could display.
for lang_code in mod_jsonfail_list:
mod_menu_errorcodes.append([ ModError.Metadata_Fail, { "mod_name": mod_name, "lang_code": lang_code }])
if seperator == -1:
if mod_screenshots.get("None") == None:
mod_screenshots["None"] = []
mod_screenshots["None"].append((i, converted_number))
elif lang_code in renpy.known_languages():
if mod_screenshots.get(lang_code) == None:
mod_screenshots[lang_code] = []
mod_screenshots[lang_code].append((i, converted_number))
#
# Sanitize/Clean metadata values
#
# Make sure our main metadata loaded
if not "None" in mod_jsonfail_list:
if mod_data_final.get("Label") != None and not isinstance(mod_data_final.get("Label"), str):
mod_menu_errorcodes.append([ ModError.Label_Not_String, { "mod_name": mod_name }])
mod_data_final["Label"] = None
# If we don't have an ID, don't put it in the mod loader
if mod_data_final.get("ID") == None:
mod_menu_errorcodes.append([ ModError.No_ID, { "mod_name": mod_name }])
mod_exception = True
elif not isinstance(mod_data_final["ID"], str):
mod_menu_errorcodes.append([ ModError.ID_Not_String, { "mod_name": mod_name }])
mod_exception = True
else:
# Detect already loaded metadata that has the same ID as our current one, and if so, don't load them
# We'll never get a match for the first mod loaded, so this is fine.
for i, x in enumerate(mod_menu_metadata):
if x["ID"] == mod_data_final["ID"]:
mod_menu_errorcodes.append([ ModError.Similar_IDs_Found, { "mod_name": mod_name, "mod_name2": mod_name_list[i] }])
mod_exception = True
break
# Since lang keys will only be added to the mod data dict if their respective metadata successfully loaded, no need to check if they can.
for lang_key in mod_data_final.keys():
if lang_key is "None" or lang_key in renpy.known_languages():
lang_data = mod_data_final[lang_key]
# The JSON object returns an actual python list, but renpy only works with it's own list object and the automation for this fails with JSON.
# So we gotta make all lists revertable
for x in lang_data.keys():
if type(lang_data[x]) == python_list:
lang_data[x] = renpy.revertable.RevertableList(lang_data[x])
# Automatically give the name of the mod from the folder it's using if there's no defined name, but report an error if one is defined but not a string
if value_isnt_valid_string(lang_data, "Name"):
if lang_data.get("Name") != None:
mod_menu_errorcodes.append([ ModError.Name_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Name"] = mod_folder_name
# Default "Display" to 'both' mode
if lang_data.get("Display") != None:
if not isinstance(lang_data.get("Display"), str):
if lang_data.get("Display") != None:
mod_menu_errorcodes.append([ ModError.Display_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Display"] = "both"
elif lang_data["Display"] not in ["both","icon","name"]:
mod_menu_errorcodes.append([ ModError.Display_Invalid_Mode, { "mod_name": mod_name, "display_mode": lang_data["Display"], "lang_code": lang_key }])
lang_data["Display"] = "both"
if value_isnt_valid_string(lang_data, "Version"):
mod_menu_errorcodes.append([ ModError.Version_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Version"] = None
# See if "Authors" is a list or string, and if it's a list search through the contents of the list to check if they're valid strings
if value_isnt_valid_string(lang_data, "Authors") and value_isnt_valid_list(lang_data, "Authors"):
mod_menu_errorcodes.append([ ModError.Authors_Not_String_Or_List, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Authors"] = None
elif isinstance(lang_data.get("Authors"), list):
# Search through and call out entries that aren't strings
for i, s in enumerate(lang_data["Authors"]):
if not isinstance(s, str):
mod_menu_errorcodes.append([ ModError.Authors_Contents_Not_String, { "mod_name": mod_name, "author_number": i + 1, "lang_code": lang_key }])
# And then mutate the list to only include strings
lang_data["Authors"][:] = [x for x in lang_data["Authors"] if isinstance(x, str)]
if lang_data["Authors"] == []:
lang_data["Authors"] = None
# Do the same as 'Authors' to 'Links'
if value_isnt_valid_string(lang_data, "Links") and value_isnt_valid_list(lang_data, "Links"):
mod_menu_errorcodes.append([ ModError.Links_Not_String_Or_List, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Links"] = None
elif isinstance(lang_data.get("Links"), list):
for i, s in enumerate(lang_data["Links"]):
if not isinstance(s, str):
mod_menu_errorcodes.append([ ModError.Links_Contents_Not_String, { "mod_name": mod_name, "link_number": i + 1, "lang_code": lang_key }])
lang_data["Links"][:] = [x for x in lang_data["Links"] if isinstance(x, str)]
if lang_data["Links"] == []:
lang_data["Links"] = None
if value_isnt_valid_string(lang_data, "Description"):
mod_menu_errorcodes.append([ ModError.Description_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Description"] = None
if value_isnt_valid_string(lang_data, "Mobile Description"):
mod_menu_errorcodes.append([ ModError.Mobile_Description_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Mobile Description"] = None
if lang_data.get("Screenshot Displayables") != None:
if not isinstance(lang_data.get("Screenshot Displayables"), list):
mod_menu_errorcodes.append([ ModError.Screenshot_Displayables_Not_List, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Screenshot Displayables"] = None
else:
# Instead of remaking the list to only include strings, replace the non-strings with empty strings ("") so subsequent strings will still be in the right
# place when eventually showing displayable screenshots over non-displayable ones
for i, s in enumerate(lang_data["Screenshot Displayables"]):
if not isinstance(s, str):
mod_menu_errorcodes.append([ ModError.Screenshot_Displayables_Contents_Not_String, { "mod_name": mod_name, "screenshot_number": i + 1, "lang_code": lang_key }])
s = ""
if lang_data["Screenshot Displayables"] == []:
lang_data["Screenshot Displayables"] = None
if value_isnt_valid_string(lang_data, "Icon Displayable"):
mod_menu_errorcodes.append([ ModError.Icon_Displayable_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Icon Displayable"] = None
if value_isnt_valid_string(lang_data, "Thumbnail Displayable"):
mod_menu_errorcodes.append([ ModError.Thumbnail_Displayable_Not_String, { "mod_name": mod_name, "lang_code": lang_key }])
lang_data["Thumbnail Displayable"] = None
# If our mod does not follow the structure of 'mods/Mod Name/metadata.json', don't load them
this_mod_dir = file[len(mods_dir):-len("metadata.json")] # If the metadata file is in another place, this will connect the filepath between it and the mods folder.
if file.count("/", len(mods_dir)) > 1:
good_folder = "'{color=#ffbdbd}" + mods_dir + mod_folder_name + "/{/color}'"
curr_folder = "'{color=#ffbdbd}" + mods_dir + this_mod_dir + "{/color}'"
mod_menu_errorcodes.append([ ModError.Installed_Incorrectly, { "mod_name": mod_name, "good_dir": good_folder, "curr_dir": curr_folder }])
mod_exception = True
elif mod_in_root_folder:
mod_menu_errorcodes.append([ ModError.Installed_Incorrectly, { "mod_name": mod_name, "good_dir": mods_dir + "My Mod/", "curr_dir": mods_dir }])
mod_exception = True
#
# Collect mod scripts and metadata images
#
mod_scripts = []
mod_screenshots = {}
this_mod_dir_length = len(mods_dir + this_mod_dir)
for i in all_mod_files:
if i.startswith(mods_dir + this_mod_dir):
# Collect mod scripts
if not mod_exception and i.endswith(".rpym"):
mod_scripts.append(i[:-5])
continue
# This will only allow files that are at the root of the mod folder and have one period.
elif i.count("/", this_mod_dir_length) == 0 and i.count(".", this_mod_dir_length) == 1:
this_file = i[this_mod_dir_length:]
if this_file.startswith("thumbnail."):
if is_valid_metadata_image(this_file, mod_name):
mod_data_final["None"]["Thumbnail"] = i
elif this_file.startswith("thumbnail_"):
trimmed_string = this_file[len("thumbnail_"):this_file.find(".")]
for lang in renpy.known_languages():
if lang == trimmed_string:
if is_valid_metadata_image(this_file, mod_name):
mod_data_final[lang]["Thumbnail"] = i
# Don't load the mod if there's mod breaking errors
if mod_exception:
continue
elif this_file.startswith("icon."):
if is_valid_metadata_image(this_file, mod_name):
if mod_data_final.get("None") == None:
mod_data_final["None"] = {}
mod_data_final["None"]["Icon"] = i
elif this_file.startswith("icon_"):
trimmed_string = this_file[len("icon_"):this_file.find(".")]
for lang in renpy.known_languages():
if lang == trimmed_string:
if is_valid_metadata_image(this_file, mod_name):
if mod_data_final.get(lang) == None:
mod_data_final["None"] = {}
mod_data_final[lang]["Icon"] = i
# We're now gonna clean up the screenshots to be more usable as-is.
# Refine collected screenshots so that translated screenshots use the 'None' screenshots (the ones without a lang code)
# as a base, and then either replacing or adding the translated screenshots according to their order/number.
for lang_key in mod_screenshots.keys():
if lang_key != "None":
if mod_screenshots.get("None") == None:
temp_list_with_indexes = mod_screenshots[lang_key]
elif this_file.startswith("screenshot"):
# Disect the string after "screenshot" for the number and possible lang code
trimmed_string = this_file[len("screenshot"):this_file.find(".")]
number = ""
lang_code = ""
seperator = trimmed_string.find("_")
if seperator != -1:
number = trimmed_string[:seperator]
lang_code = trimmed_string[seperator + 1:]
else:
number = trimmed_string
# See if we can extract the number
try:
converted_number = int(number)
except:
continue
if not is_valid_metadata_image(this_file, mod_name):
continue
if seperator == -1:
if mod_screenshots.get("None") == None:
mod_screenshots["None"] = []
mod_screenshots["None"].append((i, converted_number))
elif lang_code in renpy.known_languages():
if mod_screenshots.get(lang_code) == None:
mod_screenshots[lang_code] = []
mod_screenshots[lang_code].append((i, converted_number))
# Don't load the mod if there's mod breaking errors
if mod_exception:
continue
# We're now gonna clean up the screenshots to be more usable as-is.
# Refine collected screenshots so that translated screenshots use the 'None' screenshots (the ones without a lang code)
# as a base, and then either replacing or adding the translated screenshots according to their order/number.
for lang_key in mod_screenshots.keys():
if lang_key != "None":
if mod_screenshots.get("None") == None:
temp_list_with_indexes = mod_screenshots[lang_key]
else:
temp_list_with_indexes = mod_screenshots["None"]
for i, lang_images in enumerate(mod_screenshots[lang_key]):
u = 0
while u < len(temp_list_with_indexes):
if lang_images[1] > temp_list_with_indexes[u][1] and u == len(temp_list_with_indexes) - 1:
temp_list_with_indexes.append(lang_images)
break
elif lang_images[1] == temp_list_with_indexes[u][1]:
temp_list_with_indexes[u] = lang_images
break
elif lang_images[1] < temp_list_with_indexes[u][1]:
temp_list_with_indexes.insert(u, lang_images)
break
u += 1
else:
temp_list_with_indexes = mod_screenshots["None"]
for i, lang_images in enumerate(mod_screenshots[lang_key]):
u = 0
while u < len(temp_list_with_indexes):
if lang_images[1] > temp_list_with_indexes[u][1] and u == len(temp_list_with_indexes) - 1:
temp_list_with_indexes.append(lang_images)
break
elif lang_images[1] == temp_list_with_indexes[u][1]:
temp_list_with_indexes[u] = lang_images
break
elif lang_images[1] < temp_list_with_indexes[u][1]:
temp_list_with_indexes.insert(u, lang_images)
break
u += 1
else:
temp_list_with_indexes = mod_screenshots["None"]
# Get rid of the tuples and just leave the screenshot files
mod_data_final[lang_key]["Screenshots"] = []
for i in temp_list_with_indexes:
mod_data_final[lang_key]["Screenshots"].append(i[0])
# Get rid of the tuples and just leave the screenshot files
mod_data_final[lang_key]["Screenshots"] = []
for i in temp_list_with_indexes:
mod_data_final[lang_key]["Screenshots"].append(i[0])
# Make a copy of the current screenshots list, then put displayable screenshots wherever the values of "Screenshot Displayables" correspond in this list
# mod_screenshots will return an empty list if there were no screenshot files to begin with, so this works fine.
for lang_key in mod_data_final.keys():
if lang_key is "None" or lang_key in renpy.known_languages():
if mod_data_final[lang_key].get("Screenshots") == None:
mod_screenshots = []
else:
mod_screenshots = mod_data_final[lang_key]["Screenshots"]
if mod_data_final[lang_key].get("Screenshot Displayables") != None:
mod_displayable_list = mod_screenshots.copy()
for i, x in enumerate(mod_data_final[lang_key]["Screenshot Displayables"]):
if i < len(mod_screenshots):
if x != "":
mod_displayable_list[i] = x
else:
mod_displayable_list.append(x)
if mod_displayable_list != []:
mod_data_final[lang_key]["Screenshot Displayables"] = mod_displayable_list
# Make a copy of the current screenshots list, then put displayable screenshots wherever the values of "Screenshot Displayables" correspond in this list
# mod_screenshots will return an empty list if there were no screenshot files to begin with, so this works fine.
for lang_key in mod_data_final.keys():
if lang_key is "None" or lang_key in renpy.known_languages():
if mod_data_final[lang_key].get("Screenshots") == None:
mod_screenshots = []
else:
mod_data_final[lang_key]["Screenshot Displayables"] = None
mod_screenshots = mod_data_final[lang_key]["Screenshots"]
# Store the collected scripts and screenshots
mod_data_final["Scripts"] = mod_scripts
if mod_data_final[lang_key].get("Screenshot Displayables") != None:
mod_displayable_list = mod_screenshots.copy()
# Make our mod loadable
mod_menu_metadata.append(mod_data_final)
mod_name_list.append(mod_name) # This will mirror mod_menu_metadata
for i, x in enumerate(mod_data_final[lang_key]["Screenshot Displayables"]):
if i < len(mod_screenshots):
if x != "":
mod_displayable_list[i] = x
else:
mod_displayable_list.append(x)
if mod_displayable_list != []:
mod_data_final[lang_key]["Screenshot Displayables"] = mod_displayable_list
else:
mod_data_final[lang_key]["Screenshot Displayables"] = None
# Store the collected scripts and screenshots
mod_data_final["Scripts"] = mod_scripts
# Make our mod loadable
mod_menu_metadata.append(mod_data_final)
mod_name_list.append(mod_name) # This will mirror mod_menu_metadata
# Sort mod metadata list according to enabled_mods, while dropping mods from enabled_mods if they aren't installed
# This will also apply the state of a mod if it's supposed to be enabled/disabled
# The effect will be that mod_menu_metadata is sorted from first to last to be loaded
temp_list = []
for saved_mod_id, saved_mod_state in persistent.enabled_mods:
# Sort mod metadata list according to enabled_mods, while dropping mods from enabled_mods if they aren't installed
# This will also apply the state of a mod if it's supposed to be enabled/disabled
# The effect will be that mod_menu_metadata is sorted from first to last to be loaded
temp_list = []
for saved_mod_id, saved_mod_state in persistent.enabled_mods:
for mod in mod_menu_metadata:
if mod["ID"] == saved_mod_id:
mod["Enabled"] = saved_mod_state
temp_list.append(mod)
break
# Now inverse search to find new mods and append them to metadata list. New mods are by default enabled, and are the last to be loaded
for mod in mod_menu_metadata:
if mod["ID"] == saved_mod_id:
mod["Enabled"] = saved_mod_state
mod_not_found = True
for saved_mod_id in persistent.enabled_mods:
if mod["ID"] == saved_mod_id[0]:
mod_not_found = False
if mod_not_found:
# If this mod doesn't have any loadable scripts, treat it as on (Say, if a mod changed something in the base game and the label points there)
if not mod["Scripts"]:
mod["Enabled"] = True
# Otherwise set mods to the default state
else:
mod["Enabled"] = persistent.newmods_default_state
temp_list.append(mod)
break
# Now inverse search to find new mods and append them to metadata list. New mods are by default enabled, and are the last to be loaded
for mod in mod_menu_metadata:
mod_not_found = True
for saved_mod_id in persistent.enabled_mods:
if mod["ID"] == saved_mod_id[0]:
mod_not_found = False
if mod_not_found:
mod["Enabled"] = persistent.newmods_default_state
temp_list.append(mod)
mod_menu_metadata = temp_list
mod_menu_metadata = temp_list
# Rewrite enabled_mods to reflect the new mod order, and load all the mods
persistent.enabled_mods.clear()
# Rewrite enabled_mods to reflect the new mod order, and load all the mods
persistent.enabled_mods.clear()
for mod in mod_menu_metadata:
persistent.enabled_mods.append( [ mod["ID"], mod["Enabled"] ] )
for mod in mod_menu_metadata:
persistent.enabled_mods.append( [ mod["ID"], mod["Enabled"] ] )
# Making the load_mods check here makes it so the NOLOAD flag doesn't overwrite the previously saved load order
if load_mods and mod["Enabled"]:
for script in mod["Scripts"]:
renpy.include_module(script)
else:
mod["Enabled"] = False
# Making the load_mods check here makes it so the NOLOAD flag doesn't overwrite the previously saved load order
if load_mods and mod["Enabled"]:
for script in mod["Scripts"]:
renpy.include_module(script)
else:
mod["Enabled"] = False
# Now convert our errorcodes to errorstrings
init python: