Multi project launcher/updater

Godot Version

Godot 4.2.2

Question

I have a game called Wordy which has it’s own hardcoded auto version checker and I wanted to make a multi updater/launcher of my main three projects so far. the guessing game, the music player and idle plants.

This is all the code from the launcher so far. At first it would always let you update, then it would let you update once , then see it shouldnt update. Though each retest would lead to being updateable and then being told there is no update.

extends Node

var projects = {
	"Wordy": {
		"local_version": "1.0",
		"current_version": "",
		"remote_version": " snip - wordy_updates/main/version.txt",
		"url": " snip - wordy_updates/main/wordy_update.zip",
		"file_name": "Wordy.zip",
		"EXE_name": "Wordy.exe",
		"folder_name": "Wordy"
	},
	"Idle Plants": {
		"local_version": "1.0",
		"current+version": "",
		"remote_version": "",
		"url": "",
		"file_name": "idle_plants.zip",
		"EXE_name": "Idle Plants.exe",
		"folder_name": "Idle Plants"
	},
	"Music Player": {
		"local_version": "1.0",
		"current_version": "",
		"remote_version": "",
		"url": "",
		"file_name": "music_player.zip",
		"EXE_name": "Music Player.exe",
		"folder_name": "Music Player"
	}
}


func _ready():
	var desktop = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)
	var kinda_wrks_folder = desktop + "/KindaWrks"
	
	for project in projects:
		var project_folder = kinda_wrks_folder + "/" + projects[project]["folder_name"]
		projects[project]["current_version"] = project_folder + "/version.txt"
		
	create_directories()
	create_gui()

func create_directories():
	var desktop = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)
	var kinda_wrks_folder = desktop + "/KindaWrks"
	var dir = DirAccess.open(desktop)

	if dir != null:
		if !dir.dir_exists(kinda_wrks_folder):
			dir.make_dir(kinda_wrks_folder)

	for project in projects:
		var project_folder = kinda_wrks_folder + "/" + projects[project]["folder_name"]
		var local_version_file = FileAccess.open(project_folder + "/version.txt", FileAccess.WRITE)
		if local_version_file != null:
			local_version_file.store_string(projects[project]["local_version"] + "\n")
			local_version_file.close()
		if !dir.dir_exists(project_folder):
			dir.make_dir(project_folder)

		##Update the projects dictionary with the local version file path
		projects[project]["local_version_file"] = project_folder + "/version.txt"

func create_gui():
	var container = VBoxContainer.new()
	add_child(container)

	for project in projects:
		var project_container = HBoxContainer.new()
		container.add_child(project_container)

		var label = Label.new()
		label.text = project
		project_container.add_child(label)

		var update_button = Button.new()
		update_button.text = "Update"
		update_button.connect("pressed", check_update.bind(project))
		project_container.add_child(update_button)

		var launch_button = Button.new()
		launch_button.text = "Launch"
		launch_button.connect("pressed", launch_project.bind(project))
		project_container.add_child(launch_button)

func check_update(project_name):
	var local_version = projects[project_name]["local_version"]
	get_remote_version(project_name)

func get_remote_version(project_name):
	var http_request = HTTPRequest.new()
	add_child(http_request)
	http_request.connect("request_completed", _on_remote_version_received.bind(project_name))
	http_request.request(projects[project_name]["remote_version"])

func _on_remote_version_received(_result, _response_code, _headers, body, project_name):
	var remote_version = body.get_string_from_utf8().strip_edges()
	var local_version = get_local_version(project_name)
	if local_version != remote_version:
		print("Update available for " + project_name)
		download_update(project_name)
		update_local_version(project_name, remote_version)
	else:
		print("No update available for " + project_name)

func download_update(project_name):
	var http_request = HTTPRequest.new()
	add_child(http_request)
	http_request.connect("request_completed", _on_update_downloaded.bind(project_name))
	http_request.request(projects[project_name]["url"])

func _on_update_downloaded(_result, _response_code, _headers, body, project_name):
	var desktop = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)
	var project_folder = desktop + "/KindaWrks/" + projects[project_name]["folder_name"]
	var file = FileAccess.open(project_folder + "/" + projects[project_name]["file_name"], FileAccess.WRITE)
	file.store_buffer(body)
	file.close()
	
func get_local_version(project_name):
	var file_path = projects[project_name]["local_version_file"]
	var file = FileAccess.open(file_path, FileAccess.READ)
	if file != null:
		var local_version = file.get_as_text()
		file.close()
		return local_version.strip_edges()
	else:
		return ""

func update_local_version(project_name, new_version):
	var file_path = projects[project_name]["current_version"]
	var file = FileAccess.open(file_path, FileAccess.WRITE)
	file.store_string(new_version)
	file.close()
	projects[project_name]["local_version"] = new_version

func launch_project(project_name):
	var executable_path = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP) + "/KindaWrks/" + projects[project_name]["folder_name"] + "/" + projects[project_name]["EXE_name"]
	var error = OS.execute(executable_path, [])
	if error != OK:
		print("Error launching executable:", error)

I think I solved my problem so small adding to this post. I removed current_version and now it all uses local_version which is different from my Wordy which has both.

var projects = {
	"Wordy": {
		"local_version": "1.0",
		"remote_version": "snip - KindaWrks/wordy_updates/main/version.txt",
		"url": " snip - /KindaWrks/wordy_updates/main/wordy_update.zip",
		"file_name": "Wordy.zip",
		"EXE_name": "Wordy.exe",
		"folder_name": "Wordy"

and this is the fix I have that seems to work as far as I have seen this evening.

func _ready():
	var desktop = OS.get_system_dir(OS.SYSTEM_DIR_DESKTOP)
	var kinda_wrks_folder = desktop + "/KindaWrks"
	
	for project in projects:
		var project_folder = kinda_wrks_folder + "/" + projects[project]["folder_name"]
		var local_version_path = project_folder + "/version.txt"
		
		# Read local version from version.txt
		projects[project]["local_version"] = read_local_version(local_version_path)
		
	create_directories()
	create_gui()

func read_local_version(file_path):
	var file = FileAccess.open(file_path, FileAccess.READ)
	if file != null:
		var local_version = file.get_as_text().strip_edges()
		file.close()
		return local_version
	else:
		return ""
1 Like