commit initial

This commit is contained in:
deed 2024-06-29 23:47:38 +02:00
parent 3f6868d5f7
commit 9d05045af5
15 changed files with 4184 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 592 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://umey1bnaop31"
path="res://.godot/imported/Login-Khanat-background.png-f30cde6f0e3928967b81dc2d0ec14f34.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/background/Login-Khanat-background.png"
dest_files=["res://.godot/imported/Login-Khanat-background.png-f30cde6f0e3928967b81dc2d0ec14f34.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 KiB

View file

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ckukbjjvm54c5"
path="res://.godot/imported/settings-Khanat-background.png-8bd61fffc5f2eda0c5cfad78523e3b9d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/background/settings-Khanat-background.png"
dest_files=["res://.godot/imported/settings-Khanat-background.png-8bd61fffc5f2eda0c5cfad78523e3b9d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

1566
assets/tres/khaganat.tres Normal file

File diff suppressed because one or more lines are too long

112
export_presets.cfg Normal file
View file

@ -0,0 +1,112 @@
[preset.0]
name="Linux/X11"
platform="Linux"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="./khastore.x86_64"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=0
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
binary_format/architecture="x86_64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
export DISPLAY=:0
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
\"{temp_dir}/{exe_name}\" {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""
texture_format/bptc=true
texture_format/s3tc=true
texture_format/etc=false
texture_format/etc2=false
[preset.1]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="./khastore.exe"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.1.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=true
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
application/export_d3d12=0
application/d3d12_agility_sdk_multiarch=true
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"
texture_format/bptc=true
texture_format/s3tc=true
texture_format/etc=false
texture_format/etc2=false

1
icon.svg Normal file
View file

@ -0,0 +1 @@
<svg height="128" width="128" xmlns="http://www.w3.org/2000/svg"><rect x="2" y="2" width="124" height="124" rx="14" fill="#363d52" stroke="#212532" stroke-width="4"/><g transform="scale(.101) translate(122 122)"><g fill="#fff"><path d="M105 673v33q407 354 814 0v-33z"/><path d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z" fill="#478cbf"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></g></svg>

After

Width:  |  Height:  |  Size: 949 B

37
icon.svg.import Normal file
View file

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://d33xqawxdrwpt"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

20
project.godot Normal file
View file

@ -0,0 +1,20 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="khastore"
run/main_scene="res://scenes/main.tscn"
config/features=PackedStringArray("4.3", "Forward Plus")
config/icon="res://icon.svg"
[filesystem]
import/blender/enabled=false

View file

@ -0,0 +1,146 @@
[gd_scene load_steps=4 format=3 uid="uid://h4sygmnwvcvf"]
[ext_resource type="Script" path="res://scripts/interface/page_game.gd" id="1_f1igk"]
[ext_resource type="Texture2D" uid="uid://ckukbjjvm54c5" path="res://assets/background/settings-Khanat-background.png" id="2_gqbla"]
[ext_resource type="Theme" uid="uid://qdstcmrdbjar" path="res://assets/tres/khaganat.tres" id="3_xc68h"]
[node name="page_choice_game" type="Control"]
layout_mode = 3
anchor_right = 1.111
anchor_bottom = 1.11
offset_right = -1279.87
offset_bottom = -719.28
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_f1igk")
[node name="background" type="TextureRect" parent="."]
layout_mode = 0
offset_right = 1280.0
offset_bottom = 720.0
texture = ExtResource("2_gqbla")
[node name="label_titre" type="Label" parent="."]
layout_mode = 0
offset_left = 321.0
offset_top = 11.0
offset_right = 1017.0
offset_bottom = 122.0
theme = ExtResource("3_xc68h")
theme_override_font_sizes/font_size = 76
text = "The games catalog"
[node name="label_description" type="Label" parent="."]
layout_mode = 0
offset_left = 287.0
offset_top = 213.0
offset_right = 1098.0
offset_bottom = 481.0
theme = ExtResource("3_xc68h")
[node name="label_size" type="Label" parent="."]
layout_mode = 0
offset_left = 635.0
offset_top = 147.0
offset_right = 1062.0
offset_bottom = 185.0
theme = ExtResource("3_xc68h")
[node name="OptionButton" type="OptionButton" parent="."]
layout_mode = 0
offset_left = 318.0
offset_top = 137.0
offset_right = 587.0
offset_bottom = 193.0
tooltip_text = "Select Games"
theme = ExtResource("3_xc68h")
action_mode = 1
alignment = 1
selected = 0
fit_to_longest_item = false
allow_reselect = true
item_count = 1
popup/item_0/text = "Select Games"
popup/item_0/disabled = true
[node name="DownloadButton" type="Button" parent="."]
layout_mode = 0
offset_left = 285.0
offset_top = 504.0
offset_right = 495.0
offset_bottom = 547.0
theme = ExtResource("3_xc68h")
text = "Donwload Game"
[node name="PatchButton" type="Button" parent="."]
layout_mode = 0
offset_left = 539.0
offset_top = 508.0
offset_right = 826.0
offset_bottom = 542.0
theme = ExtResource("3_xc68h")
text = "Patch Game"
[node name="PatchButtonQuit" type="Button" parent="."]
visible = false
layout_mode = 0
offset_left = 532.0
offset_top = 294.0
offset_right = 761.0
offset_bottom = 359.0
theme = ExtResource("3_xc68h")
text = "Reboot after Maj"
[node name="LaunchGameButton" type="Button" parent="."]
custom_minimum_size = Vector2(200, 40)
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_left = 888.0
offset_top = 511.0
offset_right = 1088.0
offset_bottom = 562.0
grow_vertical = 0
theme = ExtResource("3_xc68h")
text = "Lauch Game"
[node name="DownloadProgressBar" type="ProgressBar" parent="."]
layout_mode = 0
offset_left = 278.0
offset_top = 561.0
offset_right = 850.0
offset_bottom = 588.0
theme = ExtResource("3_xc68h")
[node name="UpdateProgressBar" type="ProgressBar" parent="."]
layout_mode = 0
offset_left = 277.0
offset_top = 595.0
offset_right = 849.0
offset_bottom = 622.0
theme = ExtResource("3_xc68h")
[node name="button_quit" type="Button" parent="."]
layout_mode = 0
offset_left = 936.0
offset_top = 594.0
offset_right = 1096.0
offset_bottom = 625.0
theme = ExtResource("3_xc68h")
text = "QUIT"
[node name="DownloadProgressTimer" type="Timer" parent="."]
[node name="UpdateProgressTimer" type="Timer" parent="."]
[node name="HTTPRequest" type="HTTPRequest" parent="."]
[connection signal="item_selected" from="OptionButton" to="." method="_on_option_button_item_selected"]
[connection signal="pressed" from="DownloadButton" to="." method="_on_download_button_pressed"]
[connection signal="pressed" from="PatchButton" to="." method="_on_update_game_button_pressed"]
[connection signal="pressed" from="PatchButtonQuit" to="." method="_on_patch_button_quit_pressed"]
[connection signal="pressed" from="LaunchGameButton" to="." method="_on_launch_game_button_pressed"]
[connection signal="changed" from="DownloadProgressBar" to="." method="_check_download_progress"]
[connection signal="changed" from="UpdateProgressBar" to="." method="_on_file_downloaded_update_progress"]
[connection signal="pressed" from="button_quit" to="." method="_on_quit_button_down"]

View file

@ -0,0 +1,116 @@
[gd_scene load_steps=4 format=3 uid="uid://kkwgk2l7gu4n"]
[ext_resource type="Texture2D" uid="uid://umey1bnaop31" path="res://assets/background/Login-Khanat-background.png" id="1_den6m"]
[ext_resource type="Script" path="res://scripts/interface/page_login.gd" id="1_dotvb"]
[ext_resource type="Theme" uid="uid://qdstcmrdbjar" path="res://assets/tres/khaganat.tres" id="1_vdkuo"]
[node name="page_login" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_right = 127.0
offset_bottom = 68.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme = ExtResource("1_vdkuo")
script = ExtResource("1_dotvb")
[node name="background" type="TextureRect" parent="."]
layout_mode = 0
offset_right = 1280.0
offset_bottom = 720.0
texture = ExtResource("1_den6m")
[node name="boxContainer_login" type="BoxContainer" parent="."]
layout_mode = 1
anchors_preset = -1
anchor_left = 0.5
anchor_right = 0.5
offset_left = -19.5
offset_top = 311.0
offset_right = 477.5
offset_bottom = 513.0
grow_horizontal = 2
[node name="vBoxContainer_login" type="VBoxContainer" parent="boxContainer_login"]
layout_direction = 1
layout_mode = 2
size_flags_horizontal = 3
[node name="text_username" type="TextEdit" parent="boxContainer_login/vBoxContainer_login"]
custom_minimum_size = Vector2(0, 40)
layout_mode = 2
theme = ExtResource("1_vdkuo")
theme_override_font_sizes/font_size = 20
placeholder_text = "#todo Username"
[node name="text_password" type="TextEdit" parent="boxContainer_login/vBoxContainer_login"]
custom_minimum_size = Vector2(0, 40)
layout_mode = 2
theme = ExtResource("1_vdkuo")
theme_override_font_sizes/font_size = 20
placeholder_text = "#todo Password"
[node name="button_creationcompte" type="Button" parent="boxContainer_login/vBoxContainer_login"]
custom_minimum_size = Vector2(200, 50)
layout_mode = 2
theme = ExtResource("1_vdkuo")
text = "#todo Creation ou gestion
de compte"
[node name="button_forgetpass" type="Button" parent="boxContainer_login/vBoxContainer_login"]
custom_minimum_size = Vector2(200, 50)
layout_mode = 2
theme = ExtResource("1_vdkuo")
text = "#todo J'ai oubliez mon mot de passe"
[node name="VBoxContainer" type="VBoxContainer" parent="boxContainer_login"]
layout_mode = 2
[node name="button_login" type="Button" parent="boxContainer_login/VBoxContainer"]
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("1_vdkuo")
text = "#todo LOGIN"
[node name="button_quit" type="Button" parent="boxContainer_login/VBoxContainer"]
custom_minimum_size = Vector2(150, 40)
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("1_vdkuo")
text = "QUIT"
[node name="button_login_sc" type="Button" parent="boxContainer_login/VBoxContainer"]
custom_minimum_size = Vector2(150, 50)
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("1_vdkuo")
text = "LOGIN
sans compte"
[node name="button_help" type="Button" parent="boxContainer_login/VBoxContainer"]
custom_minimum_size = Vector2(150, 50)
layout_mode = 2
size_flags_horizontal = 4
theme = ExtResource("1_vdkuo")
text = "HELP"
[node name="label_titre" type="Label" parent="."]
layout_mode = 0
offset_left = 343.0
offset_top = 57.0
offset_right = 880.0
offset_bottom = 194.0
theme = ExtResource("1_vdkuo")
theme_override_font_sizes/font_size = 100
text = "KHASTORE"
[connection signal="pressed" from="boxContainer_login/vBoxContainer_login/button_forgetpass" to="." method="_on_button_forgetPass_pressed"]
[connection signal="pressed" from="boxContainer_login/VBoxContainer/button_login" to="." method="_on_login_pressed"]
[connection signal="button_down" from="boxContainer_login/VBoxContainer/button_quit" to="." method="_on_quit_button_down"]
[connection signal="pressed" from="boxContainer_login/VBoxContainer/button_login_sc" to="." method="_on_login_pressed"]
[connection signal="pressed" from="boxContainer_login/VBoxContainer/button_help" to="." method="_on_button_help_pressed"]

1554
scenes/main.tscn Normal file

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,524 @@
extends Control
const GAMES_CATALOG_URL := "https://khixi.kagouille.fr/games_list.json"
const GAMES_INSTALLATION_DIRECTORY := "user://games/"
const UPDATE_TEMP_DIRECTORY := "res://temp/"
const LOGS_DIRECTORY := "user://logs/"
@onready var games_dropdown_menu: OptionButton = $OptionButton
@onready var game_description_label: Label = $label_description
@onready var game_size_label: Label = $label_size
@onready var download_game_button: Button = $DownloadButton
@onready var update_game_button: Button = $PatchButton
@onready var update_button_quit: Button = $PatchButtonQuit
@onready var launch_game_button: Button = $LaunchGameButton
@onready var download_progress_bar: ProgressBar = $DownloadProgressBar
@onready var download_progress_timer: Timer = $DownloadProgressTimer
@onready var update_progress_bar: ProgressBar = $UpdateProgressBar
@onready var update_progress_timer: Timer = $UpdateProgressTimer
var available_games_catalog: Array = []
var selected_game_info: Dictionary = {}
var active_http_request: HTTPRequest = null
var current_download_size: int = 0
var total_download_size: int = 0
var current_update_size: int = 0
var total_update_size: int = 0
func _ready() -> void:
initialize_ui()
var base_path = "user://"
var directories_to_create = ["games", "logs", "temp", "user"]
ensure_directory_exists(base_path, directories_to_create)
ensure_temp_directory_exists()
download_games_catalog()
func initialize_ui() -> void:
download_game_button.disabled = true
update_game_button.disabled = true
launch_game_button.disabled = true
game_description_label.text = ""
game_size_label.text = ""
download_game_button.text = "Nothing to download"
update_game_button.text = "No update available"
launch_game_button.text = "Launch Game"
download_progress_bar.visible = false
update_progress_bar.visible = false
func ensure_directory_exists(base_path, directories_to_create: Array) -> void:
var directory_access = DirAccess.open(base_path)
if not directory_access:
push_error("Failed to access base directory: " + base_path)
return
for dir_name in directories_to_create:
var full_path = base_path.path_join(dir_name)
if not directory_access.dir_exists(full_path):
var creation_result = directory_access.make_dir_recursive(full_path)
if creation_result != OK:
push_error("Failed to create games directory: " + full_path)
else:
print("Games directory created: " + full_path)
else:
print("Games directory already exists: " + full_path)
func ensure_temp_directory_exists() -> void:
var user_dir = OS.get_executable_path().get_base_dir()
var temp_dir = user_dir.path_join("temp")
var directory_access = DirAccess.open(user_dir)
if not directory_access:
push_error("Failed to access base directory: " + user_dir)
return
if not directory_access.dir_exists("games"):
var creation_result = directory_access.make_dir_recursive("temp")
if creation_result != OK:
push_error("Failed to create games directory: " + temp_dir)
else:
print("Games directory created: " + temp_dir)
else:
print("Games directory already exists: " + temp_dir)
func download_games_catalog() -> void:
active_http_request = HTTPRequest.new()
add_child(active_http_request)
active_http_request.request_completed.connect(_on_games_catalog_downloaded)
var request_error := active_http_request.request(GAMES_CATALOG_URL)
if request_error != OK:
push_error("HTTP request error while fetching games catalog.")
@warning_ignore("unused_parameter")
func _on_games_catalog_downloaded(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
if active_http_request:
if response_code == HTTPClient.RESPONSE_OK:
var json_parser := JSON.new()
var parse_result := json_parser.parse(body.get_string_from_utf8())
if parse_result == OK:
available_games_catalog = json_parser.get_data()
check_app_update() # Vérifier les mises à jour de l'application
populate_games_dropdown()
else:
push_error("Failed to parse games catalog JSON.")
else:
push_error("Failed to download games catalog.")
active_http_request.queue_free()
active_http_request = null
else:
push_error("HTTP request instance not found")
func check_app_update() -> void:
if not available_games_catalog.is_empty():
var app_update_info = available_games_catalog[0] # Le premier jeu est la mise à jour de l'application
var files_to_update = []
for file_name in app_update_info["file_hashes"].keys():
var expected_hash = app_update_info["file_hashes"][file_name]
var file_path = "res://" + file_name # Chemin à la racine du projet
if FileAccess.file_exists(file_path):
var current_hash = calculate_file_sha256(file_path)
if current_hash != expected_hash:
files_to_update.append(file_name)
else:
files_to_update.append(file_name)
if not files_to_update.is_empty():
print("Application files to update: ", files_to_update)
update_application_files(app_update_info, files_to_update)
else:
print("Application is up to date")
func update_application_files(app_update_info: Dictionary, files_to_update: Array) -> void:
update_progress_bar.value = 0
update_progress_bar.visible = true
total_update_size = 0
current_update_size = 0
# Créer un dossier temporaire pour les nouveaux fichiers
#var dir = DirAccess.open("res://")
#dir.make_dir(UPDATE_TEMP_DIRECTORY)
# Calculer la taille totale des fichiers à mettre à jour
for file_name in files_to_update:
if "file_sizes" in app_update_info and file_name in app_update_info["file_sizes"]:
total_update_size += app_update_info["file_sizes"][file_name]
for file_name in files_to_update:
var temp_file_path = UPDATE_TEMP_DIRECTORY.path_join(file_name)
await download_file_coroutine(app_update_info["patch_url"] + "/" + file_name, temp_file_path)
print("All files downloaded to temporary directory")
update_progress_bar.visible = false
# Exécuter le script bash pour effectuer la mise à jour
var output = []
var exit_code = OS.execute("sh", ["./update_script.sh", UPDATE_TEMP_DIRECTORY], output, true)
if exit_code != 0:
push_error("Failed to execute update script. Output: " + str(output))
else:
print("Update script executed successfully")
# Nettoyer le dossier temporaire
#dir.remove(GAMES_TEMP_DIRECTORY)
print("Application update completed")
update_progress_bar.visible = false
# Redémarrer l'application
update_button_quit.visible = true
func download_file_coroutine(url: String, file_path: String) -> void:
var download_request := HTTPRequest.new()
add_child(download_request)
download_request.request(url)
update_progress_bar.value = 0
update_progress_bar.visible = true
update_progress_timer.connect("timeout", _on_file_downloaded_update_progress.bind(download_request))
update_progress_timer.start(0.1)
current_update_size = 0
while download_request.get_http_client_status() == HTTPClient.STATUS_REQUESTING:
await get_tree().create_timer(0.1).timeout
var result = await download_request.request_completed
if result[0] == OK and result[1] == 200:
var file = FileAccess.open(file_path, FileAccess.WRITE)
file.store_buffer(result[3])
file.close()
current_update_size += result[3].size()
else:
push_error("Failed to download file: " + url)
update_progress_timer.stop()
update_progress_timer.disconnect("timeout", _on_file_downloaded_update_progress)
download_request.queue_free()
func populate_games_dropdown() -> void:
if not available_games_catalog.is_empty():
for i in range(1, available_games_catalog.size()): # Commencez à partir de 1 pour exclure le premier élément
var game = available_games_catalog[i]
games_dropdown_menu.add_item(game["name"])
func _on_game_selected(index: int) -> void:
var selected_game_name := games_dropdown_menu.get_item_text(index)
for i in range(1, available_games_catalog.size()): # Commencez à partir de 1 pour exclure le premier élément
var game = available_games_catalog[i]
if game["name"] == selected_game_name:
selected_game_info = game
break
if not selected_game_info.is_empty():
update_game_info_display()
enable_download_button()
check_game_status()
else:
clear_game_info_display()
func update_game_info_display() -> void:
game_description_label.text = selected_game_info["description"]
game_size_label.text = "Size: " + str(selected_game_info["size"]) + " bytes"
func enable_download_button() -> void:
download_game_button.disabled = false
download_game_button.text = "Download: " + selected_game_info["name"]
func clear_game_info_display() -> void:
game_description_label.text = ""
game_size_label.text = ""
download_game_button.disabled = true
update_game_button.disabled = true
download_game_button.text = "Nothing to download"
update_game_button.text = "No update available"
func _on_download_button_pressed() -> void:
if not selected_game_info.is_empty():
var download_url: String = selected_game_info["download_url"]
var download_request := HTTPRequest.new()
add_child(download_request)
download_request.request_completed.connect(_on_game_downloaded)
# Réinitialisez et affichez la barre de progression
download_progress_bar.value = 0
download_progress_bar.visible = true
# Configurez le timer pour vérifier la progression
download_progress_timer.connect("timeout", _check_download_progress.bind(download_request))
download_progress_timer.start(0.1) # Vérifiez toutes les 0.1 secondes
current_download_size = 0
total_download_size = selected_game_info.get("size", 0)
var request_error := download_request.request(download_url)
if request_error != OK:
push_error("HTTP request error while downloading game.")
func _check_download_progress(download_request: HTTPRequest) -> void:
current_download_size = download_request.get_downloaded_bytes()
if total_download_size > 0:
var progress = float(current_download_size) / float(total_download_size)
download_progress_bar.value = progress * 100 # Convertir en pourcentage
@warning_ignore("unused_parameter")
func _on_game_downloaded(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray) -> void:
if response_code == HTTPClient.RESPONSE_OK:
var game_name := games_dropdown_menu.get_item_text(games_dropdown_menu.selected)
var game_zip_path := GAMES_INSTALLATION_DIRECTORY.path_join(game_name + ".zip")
var file := FileAccess.open(game_zip_path, FileAccess.WRITE)
file.store_buffer(body)
file.close()
print("Game downloaded successfully: ", game_name)
unzip_game(game_zip_path)
check_game_status()
else:
push_error("Failed to download game.")
# Arrêtez le timer et cachez la barre de progression
download_progress_timer.stop()
download_progress_timer.disconnect("timeout", _check_download_progress)
download_progress_bar.visible = false
$HTTPRequest.queue_free()
static func unzip_game(zip_file_path: String) -> void:
var zip_reader : ZIPReader = ZIPReader.new()
if zip_reader.open(zip_file_path) == OK:
var zip_directory : String = zip_file_path.get_base_dir()
var extraction_path : String = zip_file_path.trim_suffix(".zip")
var directory_access : DirAccess = DirAccess.open(zip_directory)
if directory_access:
if not directory_access.dir_exists(extraction_path):
var dir_create_result = directory_access.make_dir(extraction_path)
if dir_create_result != OK:
push_error("Failed to create extraction directory: " + extraction_path)
return
for file_path in zip_reader.get_files():
var full_extraction_path : String = extraction_path.path_join(file_path)
var file_dir : String = full_extraction_path.get_base_dir()
# Créer les répertoires parents si nécessaire
if not directory_access.dir_exists(file_dir):
var make_dir_result = directory_access.make_dir_recursive(file_dir)
if make_dir_result != OK:
push_error("Failed to create directory: " + file_dir)
continue
var file_access : FileAccess = FileAccess.open(full_extraction_path, FileAccess.WRITE)
if file_access:
file_access.store_buffer(zip_reader.read_file(file_path))
file_access.close()
else:
push_error("Failed to create file: " + full_extraction_path)
else:
push_error("Failed to access directory: " + zip_directory)
else:
push_error("Failed to open ZIP file: " + zip_file_path)
zip_reader.close()
func update_game_files(game_name: String) -> void:
var game_directory := GAMES_INSTALLATION_DIRECTORY.path_join(game_name)
var game_info = selected_game_info
var files_to_update = []
var files_to_delete = []
var existing_files = []
# Vérifier les fichiers existants et les comparer avec le catalogue
var dir = DirAccess.open(game_directory)
if dir:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if not dir.current_is_dir():
existing_files.append(file_name)
file_name = dir.get_next()
dir.list_dir_end()
# Vérifier les fichiers dans le catalogue
for file_name in game_info["file_hashes"].keys():
var expected_hash = game_info["file_hashes"][file_name]
var file_path = game_directory.path_join(file_name)
if FileAccess.file_exists(file_path):
var current_hash = calculate_file_sha256(file_path)
if current_hash != expected_hash:
files_to_update.append(file_name)
existing_files.erase(file_name)
else:
files_to_update.append(file_name)
# Les fichiers restants dans existing_files doivent être supprimés
files_to_delete = existing_files
for file_name in files_to_update:
if "file_sizes" in game_info and file_name in game_info["file_sizes"]:
total_update_size += game_info["file_sizes"][file_name]
else:
push_error("Size information not available for file: " + file_name)
# Mettre à jour les fichiers
if files_to_update.is_empty():
print("All files are up to date for game: ", game_name)
else:
print("Files to update: ", files_to_update)
for file_name in files_to_update:
var file_path = game_directory.path_join(file_name)
download_file(game_info["patch_url"] + "/" + file_name, file_path)
# Supprimer les fichiers obsolètes
if not files_to_delete.is_empty():
print("Files to delete: ", files_to_delete)
for file_name in files_to_delete:
var file_path = game_directory.path_join(file_name)
var dir_access = DirAccess.open(game_directory)
if dir_access:
dir_access.remove(file_name)
print("Deleted file: ", file_path)
else:
push_error("Failed to access game directory for deletion: " + game_directory)
print("Game files update process completed for: ", game_name)
check_game_status()
func calculate_file_sha256(file_path: String) -> String:
var file = FileAccess.open(file_path, FileAccess.READ)
if file:
var hash_ctx = HashingContext.new()
hash_ctx.start(HashingContext.HASH_SHA256)
const chunk_size = 16384 # 16 KB chunks
while not file.eof_reached():
var chunk = file.get_buffer(chunk_size)
hash_ctx.update(chunk)
file.close()
var hash_file = hash_ctx.finish()
return hash_file.hex_encode()
return ""
func download_file(url: String, file_path: String) -> void:
var download_request := HTTPRequest.new()
add_child(download_request)
download_request.request_completed.connect(_on_file_downloaded.bind(file_path))
# Déconnectez d'abord le signal s'il est déjà connecté
if update_progress_timer.timeout.is_connected(_on_file_downloaded_update_progress):
update_progress_timer.timeout.disconnect(_on_file_downloaded_update_progress)
update_progress_bar.value = 0
update_progress_bar.visible = true
update_progress_timer.connect("timeout", _on_file_downloaded_update_progress.bind(download_request))
update_progress_timer.start(0.1)
current_update_size = 0
var request_error := download_request.request(url)
if request_error != OK:
push_error("HTTP request error while downloading file: " + file_path)
@warning_ignore("unused_parameter")
func _on_file_downloaded(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray, file_path: String) -> void:
if response_code == HTTPClient.RESPONSE_OK:
var file := FileAccess.open(file_path, FileAccess.WRITE)
file.store_buffer(body)
file.close()
print("File downloaded successfully: ", file_path)
else:
push_error("Failed to download file: " + file_path)
update_progress_timer.stop()
update_progress_timer.disconnect("timeout", _on_file_downloaded_update_progress)
if current_update_size >= total_update_size:
update_progress_bar.visible = false
print("Update process completed")
$HTTPRequest.queue_free()
func check_game_status() -> void:
if not selected_game_info.is_empty():
var game_name := games_dropdown_menu.get_item_text(games_dropdown_menu.selected)
var game_directory := GAMES_INSTALLATION_DIRECTORY.path_join(game_name)
var directory_access := DirAccess.open(GAMES_INSTALLATION_DIRECTORY)
if directory_access:
if directory_access.dir_exists(game_directory):
download_game_button.disabled = true
update_game_button.disabled = false
update_game_button.text = "Update available"
launch_game_button.disabled = false
else:
download_game_button.disabled = false
update_game_button.disabled = true
update_game_button.text = "Game not installed"
launch_game_button.disabled = true
else:
download_game_button.disabled = false
update_game_button.disabled = true
update_game_button.text = "Error checking game status"
launch_game_button.disabled = true
func _on_launch_game_button_pressed() -> void:
if not selected_game_info.is_empty():
var game_name: String = games_dropdown_menu.get_item_text(games_dropdown_menu.selected)
var game_directory: String = GAMES_INSTALLATION_DIRECTORY.path_join(game_name)
var executable_name: String = ""
if selected_game_info.has("executable"):
if selected_game_info["executable"] is Dictionary:
executable_name = selected_game_info["executable"].get(OS.get_name().to_lower(), "")
elif selected_game_info["executable"] is String:
executable_name = selected_game_info["executable"]
if executable_name.is_empty():
push_error("No executable specified for this game.")
return
var executable_path: String = game_directory.path_join(executable_name)
if FileAccess.file_exists(executable_path):
var output: Array = []
var exit_code: int
if OS.get_name() == "Windows":
exit_code = OS.execute(executable_name, [], output, false, true)
elif OS.get_name() == "Linux":
var file = FileAccess.open(executable_path, FileAccess.READ)
if file:
@warning_ignore("static_called_on_instance")
var permissions = FileAccess.get_unix_permissions(executable_name)
file.close()
if permissions & 64 == 0:
push_error("Executable lacks execution permissions: " + executable_name)
OS.execute("sh", ["-c", "chmod", "+x", executable_name], [], true)
exit_code = OS.execute("sh", ["-c", "./" + executable_name], output, false, true)
else:
push_error("Unsupported operating system")
return
if exit_code != OK:
push_error("Failed to launch game: " + "./" + executable_name)
print("Output: ", output)
else:
print("Game launched successfully: " + game_name)
else:
push_error("Game executable not found: " + executable_path)
func _on_option_button_item_selected(index: int) -> void:
_on_game_selected(index)
func _on_update_game_button_pressed() -> void:
if not selected_game_info.is_empty():
var game_name := games_dropdown_menu.get_item_text(games_dropdown_menu.selected)
update_game_files(game_name)
func _on_file_downloaded_update_progress(download_request) -> void:
current_update_size = download_request.get_downloaded_bytes()
if total_update_size > 0:
var progress = float(current_update_size) / float(total_update_size)
update_progress_bar.value = progress * 100 # Convertir en pourcentage
print("Update process completed")
func _on_quit_button_down():
get_tree().quit()
func _on_patch_button_quit_pressed() -> void:
var pid = OS.create_process(OS.get_executable_path(), [])
if pid == -1:
push_error("Failed to start new process")
else:
print("New process started with PID: ", pid)
# Attendre un court instant avant de quitter
await get_tree().create_timer(0.5).timeout
get_tree().quit()

View file

@ -0,0 +1,19 @@
extends Control
const scene_game_path : String = "res://scenes/interface/page_game.tscn"
#@onready var description: Label = $label_titre
func _ready():
ResourceLoader.load_threaded_request(scene_game_path)
func _on_login_pressed():
get_tree().change_scene_to_file(scene_game_path)
func _on_quit_button_down():
get_tree().quit()
func _on_button_help_pressed():
OS.shell_open("https://khaganat.net")
func _on_button_forgetPass_pressed():
OS.shell_open("https://chat.jabberfr.org/converse.js/khaganat@chat.khaganat.net")

21
update_script.sh Normal file
View file

@ -0,0 +1,21 @@
#!/bin/bash
# Le premier argument est le chemin du dossier temporaire
#TEMP_DIR=$1
# Parcourir tous les fichiers dans le dossier temporaire
#for file in "$TEMP_DIR"/*; do
# Obtenir le nom du fichier sans le chemin
#filename=$(basename "$file")
# Supprimer l'ancien fichier s'il existe
#if [ -f "$filename" ]; then
# rm "$filename"
#fi
# Déplacer le nouveau fichier à sa place
mv temp/* .
#done
echo "Update completed successfully"