mirror of
https://github.com/JHDev2006/Super-Mario-Bros.-Remastered-Public.git
synced 2025-10-22 23:48:11 +00:00
added the game
This commit is contained in:
143
addons/mod_tool/global/store.gd
Normal file
143
addons/mod_tool/global/store.gd
Normal file
@@ -0,0 +1,143 @@
|
||||
@tool
|
||||
class_name ModToolStore
|
||||
extends Node
|
||||
|
||||
|
||||
# Global store for all Data the ModTool requires.
|
||||
|
||||
|
||||
const PATH_SAVE_FILE := "user://mod-tool-plugin-save.json"
|
||||
const PATH_TEMPLATES_DIR := "res://addons/mod_tool/templates/"
|
||||
|
||||
var editor_plugin: EditorPlugin
|
||||
var editor_file_system: EditorFileSystem
|
||||
var editor_base_control: Control
|
||||
|
||||
var name_mod_dir := "":
|
||||
set = set_name_mod_dir
|
||||
var path_mod_dir := ""
|
||||
var path_current_template_dir := "res://addons/mod_tool/templates/default/"
|
||||
var path_export_dir := "":
|
||||
set = set_path_export_dir
|
||||
var path_temp_dir := ""
|
||||
var path_manifest := ""
|
||||
var path_global_export_dir := ""
|
||||
var path_global_project_dir := ""
|
||||
var path_global_temp_dir := ""
|
||||
var path_addon_dir := "res://addons/mod_tool/"
|
||||
var path_global_addon_dir := ""
|
||||
var path_global_seven_zip := ""
|
||||
var path_global_seven_zip_base_dir := ""
|
||||
var path_global_final_zip := ""
|
||||
var excluded_file_extensions: PackedStringArray = [".csv.import"]
|
||||
var path_mod_files := []
|
||||
var path_script_backup_dir := "res://addons/mod_tool/.script_backup"
|
||||
var current_os := ""
|
||||
var is_seven_zip_installed := true
|
||||
var pending_reloads: Array[String] = []
|
||||
var is_hook_generation_done := false
|
||||
var hooked_scripts := {}
|
||||
|
||||
# ModManifest instance
|
||||
var manifest_data : ModManifest
|
||||
|
||||
var mod_hook_preprocessor := _ModLoaderModHookPreProcessor.new()
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
load_store()
|
||||
|
||||
if not DirAccess.dir_exists_absolute(path_script_backup_dir):
|
||||
create_script_backup_dir()
|
||||
|
||||
|
||||
func _exit_tree() -> void:
|
||||
save_store()
|
||||
|
||||
|
||||
func set_name_mod_dir(new_name_mod_dir: String) -> void:
|
||||
name_mod_dir = new_name_mod_dir
|
||||
update_paths(new_name_mod_dir)
|
||||
|
||||
|
||||
func set_path_export_dir(new_path_export_dir: String) -> void:
|
||||
path_export_dir = new_path_export_dir
|
||||
path_global_export_dir = ProjectSettings.globalize_path(path_export_dir)
|
||||
path_global_final_zip = "%s/%s.zip" % [path_global_export_dir, name_mod_dir]
|
||||
|
||||
|
||||
func init(store: Dictionary) -> void:
|
||||
path_global_project_dir = ProjectSettings.globalize_path(_ModLoaderPath.get_local_folder_dir())
|
||||
path_global_addon_dir = path_global_project_dir + "addons/mod_tool/"
|
||||
if OS.has_feature("windows"):
|
||||
current_os = "windows"
|
||||
elif OS.has_feature("macos"):
|
||||
current_os = "osx"
|
||||
elif OS.has_feature("linux"):
|
||||
current_os = "x11"
|
||||
else:
|
||||
ModToolUtils.output_error("OS currently not supported. Please open an issue on GitHub")
|
||||
|
||||
name_mod_dir = store.name_mod_dir
|
||||
path_mod_dir = "res://mods-unpacked/" + store.name_mod_dir
|
||||
path_current_template_dir = store.path_current_template_dir
|
||||
path_export_dir = store.path_export_dir
|
||||
path_global_export_dir = ProjectSettings.globalize_path(path_export_dir)
|
||||
path_temp_dir = "user://temp/" + store.name_mod_dir
|
||||
path_manifest = path_mod_dir + "/manifest.json"
|
||||
path_global_temp_dir = ProjectSettings.globalize_path(path_temp_dir)
|
||||
|
||||
path_global_final_zip = "%s/%s.zip" % [path_global_export_dir, name_mod_dir]
|
||||
excluded_file_extensions = []
|
||||
is_hook_generation_done = store.is_hook_generation_done
|
||||
hooked_scripts = JSON.parse_string(store.hooked_scripts)
|
||||
mod_hook_preprocessor.hashmap = JSON.parse_string(store.mod_hook_preprocessor_hashmap)
|
||||
|
||||
|
||||
func update_paths(new_name_mod_dir: String) -> void:
|
||||
path_mod_dir = "res://mods-unpacked/" + new_name_mod_dir
|
||||
path_temp_dir = "user://temp/" + new_name_mod_dir
|
||||
path_global_temp_dir = ProjectSettings.globalize_path(path_temp_dir)
|
||||
path_manifest = path_mod_dir + "/manifest.json"
|
||||
path_global_final_zip = "%s/%s.zip" % [path_global_export_dir, name_mod_dir]
|
||||
|
||||
|
||||
func create_script_backup_dir() -> void:
|
||||
DirAccess.make_dir_recursive_absolute(path_script_backup_dir)
|
||||
FileAccess.open("%s/.gdignore" % path_script_backup_dir, FileAccess.WRITE)
|
||||
|
||||
|
||||
func save_store() -> void:
|
||||
var save_data := {
|
||||
"name_mod_dir": name_mod_dir,
|
||||
"path_mod_dir": path_mod_dir,
|
||||
"path_current_template_dir": path_current_template_dir,
|
||||
"path_export_dir": path_export_dir,
|
||||
"path_global_project_dir": path_global_project_dir,
|
||||
"path_temp_dir": path_temp_dir,
|
||||
"excluded_file_extensions": excluded_file_extensions,
|
||||
"is_hook_generation_done": is_hook_generation_done,
|
||||
"hooked_scripts": JSON.stringify(hooked_scripts),
|
||||
"mod_hook_preprocessor_hashmap": JSON.stringify(mod_hook_preprocessor.hashmap)
|
||||
}
|
||||
|
||||
var file := FileAccess.open(PATH_SAVE_FILE, FileAccess.WRITE)
|
||||
if not file:
|
||||
ModToolUtils.output_error(str(FileAccess.get_open_error()))
|
||||
file.store_string(JSON.stringify(save_data))
|
||||
file.close()
|
||||
|
||||
|
||||
# NOTE: Check if mod_dir still exists when loading
|
||||
func load_store() -> void:
|
||||
if not FileAccess.file_exists(PATH_SAVE_FILE):
|
||||
return
|
||||
|
||||
var file := FileAccess.open(PATH_SAVE_FILE, FileAccess.READ)
|
||||
if not file:
|
||||
ModToolUtils.output_error(str(FileAccess.get_open_error()))
|
||||
var content := file.get_as_text()
|
||||
|
||||
var test_json_conv = JSON.new()
|
||||
test_json_conv.parse(content)
|
||||
init(test_json_conv.data)
|
1
addons/mod_tool/global/store.gd.uid
Normal file
1
addons/mod_tool/global/store.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cdwo5pqojoumm
|
243
addons/mod_tool/global/utils.gd
Normal file
243
addons/mod_tool/global/utils.gd
Normal file
@@ -0,0 +1,243 @@
|
||||
@tool
|
||||
extends Node
|
||||
class_name ModToolUtils
|
||||
|
||||
|
||||
# Utility functions used across the ModTool.
|
||||
|
||||
|
||||
# ! Not used currently. This can overwrite existing text very easily if the wrong script is shown in the text editor.
|
||||
static func reload_script(script: Script, mod_tool_store: ModToolStore) -> void:
|
||||
var pending_reloads := mod_tool_store.pending_reloads
|
||||
|
||||
if script.resource_path in pending_reloads:
|
||||
var source_code_from_disc := FileAccess.open(script.resource_path, FileAccess.READ).get_as_text()
|
||||
|
||||
var script_editor := EditorInterface.get_script_editor()
|
||||
var text_edit: CodeEdit = script_editor.get_current_editor().get_base_editor()
|
||||
|
||||
var column := text_edit.get_caret_column()
|
||||
var row := text_edit.get_caret_line()
|
||||
var scroll_position_h := text_edit.get_h_scroll_bar().value
|
||||
var scroll_position_v := text_edit.get_v_scroll_bar().value
|
||||
|
||||
text_edit.text = source_code_from_disc
|
||||
text_edit.set_caret_column(column)
|
||||
text_edit.set_caret_line(row)
|
||||
text_edit.scroll_horizontal = scroll_position_h
|
||||
text_edit.scroll_vertical = scroll_position_v
|
||||
|
||||
text_edit.tag_saved_version()
|
||||
|
||||
pending_reloads.erase(script.resource_path)
|
||||
|
||||
|
||||
# Takes a file path and an array of file extensions [.txt, .tscn, ..]
|
||||
static func is_file_extension(path: String, excluded_extensions: PackedStringArray) -> bool:
|
||||
var is_extension := false
|
||||
|
||||
for extension in excluded_extensions:
|
||||
var file_name := path.get_file()
|
||||
if(extension in file_name):
|
||||
is_extension = true
|
||||
break
|
||||
else:
|
||||
is_extension = false
|
||||
|
||||
return is_extension
|
||||
|
||||
|
||||
# Returns the content of the file from the given path as a string.
|
||||
static func file_get_as_text(path: String) -> String:
|
||||
var file_access := FileAccess.open(path, FileAccess.READ)
|
||||
var content := file_access.get_as_text()
|
||||
file_access.close()
|
||||
return content
|
||||
|
||||
|
||||
# Copies a file from a given src to the specified dst path.
|
||||
# src = path/to/file.extension
|
||||
# dst = other/path/to/file.extension
|
||||
static func file_copy(src: String, dst: String) -> void:
|
||||
var dst_dir := dst.get_base_dir()
|
||||
|
||||
if not DirAccess.dir_exists_absolute(dst_dir):
|
||||
DirAccess.make_dir_recursive_absolute(dst_dir)
|
||||
|
||||
DirAccess.copy_absolute(src, dst)
|
||||
|
||||
|
||||
# Log error messages
|
||||
static func output_error(message) -> void:
|
||||
printerr("ModTool Error: " + str(message))
|
||||
|
||||
|
||||
static func output_info(message) -> void:
|
||||
print("ModTool: " + str(message))
|
||||
|
||||
|
||||
static func save_to_manifest_json(manifest_data: ModManifest, path_manifest: String) -> bool:
|
||||
var is_success := _ModLoaderFile._save_string_to_file(
|
||||
manifest_data.to_json(),
|
||||
path_manifest
|
||||
)
|
||||
|
||||
if is_success:
|
||||
output_info("Successfully saved manifest.json file!")
|
||||
|
||||
return is_success
|
||||
|
||||
|
||||
static func make_dir_recursive(dst_dir: String) -> bool:
|
||||
var error := DirAccess.make_dir_recursive_absolute(dst_dir)
|
||||
if not error == OK:
|
||||
output_error("Failed creating directory at %s with error \"%s\"" % [dst_dir, error_string(error)])
|
||||
return false
|
||||
return true
|
||||
|
||||
|
||||
# Takes a directory path to get removed.
|
||||
# https://www.davidepesce.com/2019/11/04/essential-guide-to-godot-filesystem-api/
|
||||
static func remove_recursive(path: String) -> void:
|
||||
var directory := DirAccess.open(path)
|
||||
|
||||
if not directory:
|
||||
print("Error removing " + path)
|
||||
return
|
||||
|
||||
# List directory content
|
||||
directory.list_dir_begin()
|
||||
var file_name := directory.get_next()
|
||||
while file_name != "":
|
||||
if directory.current_is_dir():
|
||||
remove_recursive(path + "/" + file_name)
|
||||
else:
|
||||
directory.remove(file_name)
|
||||
file_name = directory.get_next()
|
||||
|
||||
# Remove current path
|
||||
directory.remove(path)
|
||||
|
||||
|
||||
static func check_for_hooked_script(script_paths: Array[String], mod_tool_store: ModToolStore) -> int:
|
||||
var count := 0
|
||||
|
||||
for script_path in script_paths:
|
||||
if mod_tool_store.hooked_scripts.has(script_path):
|
||||
count += 1
|
||||
|
||||
return count
|
||||
|
||||
|
||||
static func quote_string(string: String) -> String:
|
||||
var settings: EditorSettings = EditorInterface.get_editor_settings()
|
||||
if settings.get_setting("text_editor/completion/use_single_quotes"):
|
||||
return "'%s'" % string
|
||||
return "\"%s\"" % string
|
||||
|
||||
|
||||
static func script_has_method(script_path: String, method: String) -> bool:
|
||||
var script: Script = load(script_path)
|
||||
|
||||
for script_method in script.get_script_method_list():
|
||||
if script_method.name == method:
|
||||
return true
|
||||
|
||||
if method in script.source_code:
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
|
||||
static func get_index_at_method_end(method_name: String, text: String) -> int:
|
||||
var starting_index := text.rfind(method_name)
|
||||
|
||||
# Find the end of the method
|
||||
var next_method_line_index := text.find("func ", starting_index)
|
||||
var method_end := -1
|
||||
|
||||
if next_method_line_index == -1:
|
||||
# Backtrack empty lines from the end of the file
|
||||
method_end = text.length() -1
|
||||
else:
|
||||
# Get the line before the next function line
|
||||
method_end = text.rfind("\n", next_method_line_index)
|
||||
|
||||
# Backtrack to the last non-empty line
|
||||
var last_non_empty_line_index := method_end
|
||||
while last_non_empty_line_index > starting_index:
|
||||
last_non_empty_line_index -= 1
|
||||
# Remove spaces, tabs and newlines (whitespace) to check if the line really is empty
|
||||
if text[last_non_empty_line_index].rstrip("\t\n "):
|
||||
break # encountered a filled line
|
||||
|
||||
return last_non_empty_line_index +1
|
||||
|
||||
# Slightly modified version of:
|
||||
# https://gist.github.com/willnationsdev/00d97aa8339138fd7ef0d6bd42748f6e
|
||||
# Removed .import from the extension filter.
|
||||
# p_match is a string that filters the list of files.
|
||||
# If p_match_is_regex is false, p_match is directly string-searched against the FILENAME.
|
||||
# If it is true, a regex object compiles p_match and runs it against the FILEPATH.
|
||||
static func get_flat_view_dict(
|
||||
p_dir := "res://",
|
||||
p_match := "",
|
||||
p_match_file_extensions: Array[StringName] = [],
|
||||
p_match_is_regex := false,
|
||||
include_empty_dirs := false,
|
||||
ignored_dirs: Array[StringName] = []
|
||||
) -> PackedStringArray:
|
||||
var data: PackedStringArray = []
|
||||
var regex: RegEx
|
||||
|
||||
if p_match_is_regex:
|
||||
regex = RegEx.new()
|
||||
var _compile_error: int = regex.compile(p_match)
|
||||
if not regex.is_valid():
|
||||
return data
|
||||
|
||||
var dirs := [p_dir]
|
||||
var first := true
|
||||
while not dirs.is_empty():
|
||||
var dir_name : String = dirs.back()
|
||||
var dir := DirAccess.open(dir_name)
|
||||
dirs.pop_back()
|
||||
|
||||
if dir_name.lstrip("res://").get_slice("/", 0) in ignored_dirs:
|
||||
continue
|
||||
|
||||
if dir:
|
||||
var _dirlist_error: int = dir.list_dir_begin()
|
||||
var file_name := dir.get_next()
|
||||
if include_empty_dirs and not dir_name == p_dir:
|
||||
data.append(dir_name)
|
||||
while file_name != "":
|
||||
if not dir_name == "res://":
|
||||
first = false
|
||||
# ignore hidden, temporary, or system content
|
||||
if not file_name.begins_with(".") and not file_name.get_extension() == "tmp":
|
||||
# If a directory, then add to list of directories to visit
|
||||
if dir.current_is_dir():
|
||||
dirs.push_back(dir.get_current_dir() + "/" + file_name)
|
||||
# If a file, check if we already have a record for the same name
|
||||
else:
|
||||
var path := dir.get_current_dir() + ("/" if not first else "") + file_name
|
||||
# grab all
|
||||
if not p_match and not p_match_file_extensions:
|
||||
data.append(path)
|
||||
# grab matching strings
|
||||
elif not p_match_is_regex and p_match and file_name.contains(p_match):
|
||||
data.append(path)
|
||||
# garb matching file extension
|
||||
elif p_match_file_extensions and file_name.get_extension() in p_match_file_extensions:
|
||||
data.append(path)
|
||||
# grab matching regex
|
||||
elif p_match_is_regex:
|
||||
var regex_match := regex.search(path)
|
||||
if regex_match != null:
|
||||
data.append(path)
|
||||
# Move on to the next file in this directory
|
||||
file_name = dir.get_next()
|
||||
# We've exhausted all files in this directory. Close the iterator.
|
||||
dir.list_dir_end()
|
||||
return data
|
1
addons/mod_tool/global/utils.gd.uid
Normal file
1
addons/mod_tool/global/utils.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bssconjrhi4i8
|
Reference in New Issue
Block a user