feat : update backend
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
extends Control
|
||||
## Leaderboard panel — full-scene layout.
|
||||
## Leaderboard panel — reads from Nakama native leaderboard (global_high_score).
|
||||
## Left: sortable leaderboard list.
|
||||
## Right: 3D SubViewport character preview of the selected/top-ranked player.
|
||||
|
||||
@@ -10,6 +10,7 @@ signal closed
|
||||
# -------------------------------------------------------------------------
|
||||
@onready var back_btn := %BackBtn as Button
|
||||
@onready var refresh_btn := %RefreshBtn as Button
|
||||
@onready var sync_btn := %SyncBtn as Button
|
||||
@onready var sort_score_btn := %SortScoreBtn as Button
|
||||
@onready var sort_win_rate_btn := %SortWinRateBtn as Button
|
||||
@onready var sort_games_btn := %SortGamesBtn as Button
|
||||
@@ -41,6 +42,7 @@ const AVATAR_TO_CHAR: Array[String] = ["Pip", "Gatot", "Dabro", "Copper"]
|
||||
func _ready() -> void:
|
||||
back_btn.pressed.connect(_on_close_pressed)
|
||||
refresh_btn.pressed.connect(_fetch_leaderboard_data)
|
||||
sync_btn.pressed.connect(_on_sync_pressed)
|
||||
sort_score_btn.pressed.connect(func(): _sort_by("high_score"))
|
||||
sort_win_rate_btn.pressed.connect(func(): _sort_by("win_rate"))
|
||||
sort_games_btn.pressed.connect(func(): _sort_by("games_played"))
|
||||
@@ -52,12 +54,31 @@ func _ready() -> void:
|
||||
# -------------------------------------------------------------------------
|
||||
func show_panel() -> void:
|
||||
show()
|
||||
status_label.text = "Syncing scores..."
|
||||
# Bulk-sync all users' storage stats to native leaderboard (server-side operation)
|
||||
if NakamaManager.session:
|
||||
var sync_result = await NakamaManager.client.rpc_async(NakamaManager.session, "sync_leaderboard", "{}")
|
||||
if sync_result.is_exception():
|
||||
push_error("[Leaderboard] sync_leaderboard RPC failed: ", sync_result.get_exception().message)
|
||||
else:
|
||||
print("[Leaderboard] Server sync finished: ", sync_result.payload)
|
||||
_fetch_leaderboard_data()
|
||||
|
||||
func _on_close_pressed() -> void:
|
||||
hide()
|
||||
emit_signal("closed")
|
||||
|
||||
func _on_sync_pressed() -> void:
|
||||
"""Push the current player's stored stats up to the native Nakama leaderboard."""
|
||||
if not NakamaManager.session or AuthManager.is_guest:
|
||||
status_label.text = "Must be logged in to sync"
|
||||
return
|
||||
status_label.text = "Syncing your score..."
|
||||
await UserProfileManager._submit_to_leaderboard()
|
||||
status_label.text = "Synced! Refreshing..."
|
||||
await get_tree().create_timer(0.5).timeout
|
||||
_fetch_leaderboard_data()
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Data
|
||||
# -------------------------------------------------------------------------
|
||||
@@ -66,11 +87,59 @@ func _fetch_leaderboard_data() -> void:
|
||||
status_label.text = "Not connected to Nakama"
|
||||
return
|
||||
|
||||
status_label.text = "Fetching Global Records..."
|
||||
status_label.text = "Fetching Leaderboard..."
|
||||
for child in leaderboard_list.get_children():
|
||||
child.queue_free()
|
||||
|
||||
# Calls the updated RPC that returns ONLY native global_high_score records
|
||||
# Try native Nakama leaderboard first (fastest, ranked already)
|
||||
var native_data = await _fetch_native_leaderboard()
|
||||
|
||||
if native_data.size() > 0:
|
||||
leaderboard_data = native_data
|
||||
_calculate_win_rates()
|
||||
status_label.text = ""
|
||||
_sort_by(current_sort_key)
|
||||
if leaderboard_data.size() > 0:
|
||||
_show_entry_preview(0)
|
||||
else:
|
||||
# Fallback: try the server RPC (reads same native leaderboard)
|
||||
await _fetch_via_rpc()
|
||||
|
||||
func _fetch_native_leaderboard() -> Array:
|
||||
"""Use the Nakama client API to list native leaderboard records directly."""
|
||||
var result = await NakamaManager.client.list_leaderboard_records_async(
|
||||
NakamaManager.session,
|
||||
"global_high_score",
|
||||
[], # no specific owner filter
|
||||
null, # expiry = null (no filter)
|
||||
100 # limit
|
||||
)
|
||||
|
||||
if result.is_exception():
|
||||
push_warning("[Leaderboard] Native API failed: ", result.get_exception().message)
|
||||
return []
|
||||
|
||||
var data: Array = []
|
||||
for record in result.records:
|
||||
var meta: Dictionary = {}
|
||||
if record.metadata and not record.metadata.is_empty():
|
||||
var parsed = JSON.parse_string(record.metadata)
|
||||
if parsed is Dictionary:
|
||||
meta = parsed
|
||||
|
||||
data.append({
|
||||
"user_id": record.owner_id,
|
||||
"display_name": record.username if (record.username and not record.username.is_empty()) else "Unknown",
|
||||
"avatar_url": meta.get("avatar_url", ""),
|
||||
"high_score": int(record.score),
|
||||
"games_played": int(meta.get("games_played", 0)),
|
||||
"games_won": int(meta.get("games_won", 0)),
|
||||
"rank": int(record.rank)
|
||||
})
|
||||
return data
|
||||
|
||||
func _fetch_via_rpc() -> void:
|
||||
"""Fallback: call server RPC which reads the same native leaderboard."""
|
||||
var result = await NakamaManager.client.rpc_async(NakamaManager.session, "get_leaderboard_stats", "{}")
|
||||
|
||||
if result.is_exception():
|
||||
@@ -78,20 +147,19 @@ func _fetch_leaderboard_data() -> void:
|
||||
push_error("[Leaderboard] RPC failed: ", result.get_exception().message)
|
||||
return
|
||||
|
||||
var json = JSON.new()
|
||||
var error = json.parse(result.payload)
|
||||
if error == OK:
|
||||
var json := JSON.new()
|
||||
if json.parse(result.payload) == OK:
|
||||
var data = json.get_data()
|
||||
if data.has("leaderboard"):
|
||||
if data.has("leaderboard") and data.leaderboard.size() > 0:
|
||||
leaderboard_data = data.leaderboard
|
||||
_calculate_win_rates()
|
||||
status_label.text = ""
|
||||
_sort_by(current_sort_key)
|
||||
# Show top player's character in 3D preview
|
||||
if leaderboard_data.size() > 0:
|
||||
_show_entry_preview(0)
|
||||
else:
|
||||
status_label.text = "No records found"
|
||||
# No records exist yet — show a helpful hint
|
||||
status_label.text = "No scores recorded yet.\nPlay a match to appear here!"
|
||||
else:
|
||||
status_label.text = "Error parsing server data"
|
||||
|
||||
@@ -122,7 +190,7 @@ func _populate_list() -> void:
|
||||
child.queue_free()
|
||||
|
||||
if leaderboard_data.size() == 0:
|
||||
status_label.text = "No players found"
|
||||
status_label.text = "No players found.\nPlay a match to appear here!"
|
||||
return
|
||||
|
||||
for i in range(leaderboard_data.size()):
|
||||
@@ -143,7 +211,7 @@ func _create_leaderboard_item(rank: int, entry: Dictionary, index: int) -> void:
|
||||
item.add_theme_stylebox_override("panel", style)
|
||||
|
||||
var hbox = HBoxContainer.new()
|
||||
hbox.theme_override_constants.separation = 16
|
||||
hbox.add_theme_constant_override("separation", 16)
|
||||
item.add_child(hbox)
|
||||
|
||||
# Rank
|
||||
|
||||
+36
-134
@@ -7,7 +7,6 @@ extends Control
|
||||
@onready var password_input := %PasswordInput as LineEdit
|
||||
@onready var remember_me := %RememberMe as CheckBox
|
||||
@onready var login_button := %LoginButton as Button
|
||||
@onready var register_link := %RegisterLink as LinkButton
|
||||
@onready var google_button := %GoogleButton as Button
|
||||
@onready var apple_button := %AppleButton as Button
|
||||
@onready var facebook_button := %FacebookButton as Button
|
||||
@@ -15,7 +14,7 @@ extends Control
|
||||
@onready var loading_spinner := %LoadingSpinner as TextureProgressBar
|
||||
|
||||
# Registration panel elements
|
||||
@onready var registration_panel := %RegistrationPanel as PanelContainer
|
||||
@onready var tab_container := %TabContainer as TabContainer
|
||||
@onready var reg_email_input := %RegEmailInput as LineEdit
|
||||
@onready var reg_username_input := %RegUsernameInput as LineEdit
|
||||
@onready var reg_password_input := %RegPasswordInput as LineEdit
|
||||
@@ -25,25 +24,33 @@ extends Control
|
||||
@onready var reg_captcha_question := %RegCaptchaQuestion as Label
|
||||
@onready var reg_captcha_input := %RegCaptchaInput as LineEdit
|
||||
@onready var register_button := %RegisterButton as Button
|
||||
@onready var back_to_login_link := %BackToLoginLink as LinkButton
|
||||
@onready var reg_status_label := %RegStatusLabel as Label
|
||||
|
||||
var current_captcha_answer: int = 0
|
||||
|
||||
# Main panel reference
|
||||
@onready var main_panel := $CenterContainer/MainPanel as PanelContainer
|
||||
|
||||
var is_loading: bool = false
|
||||
|
||||
# Server Selection Controls
|
||||
var server_option: OptionButton
|
||||
var server_ip_input: LineEdit
|
||||
var lan_section: VBoxContainer # LAN-specific controls
|
||||
@onready var server_option := %ServerOption as OptionButton
|
||||
@onready var server_ip_input := %ServerIPInput as LineEdit
|
||||
@onready var lan_section := %LANSection as VBoxContainer
|
||||
@onready var lan_host_btn := %LANHostBtn as Button
|
||||
@onready var lan_ip := %LANIPInput as LineEdit
|
||||
@onready var lan_join_btn := %LANJoinBtn as Button
|
||||
|
||||
func _ready() -> void:
|
||||
_connect_signals()
|
||||
_setup_ui()
|
||||
_setup_server_config_ui()
|
||||
|
||||
# Initialize connection mode view
|
||||
if NakamaManager.nakama_host == "localhost":
|
||||
server_option.selected = 0
|
||||
elif NakamaManager.nakama_host == "tektondash.vps.webdock.cloud":
|
||||
server_option.selected = 3
|
||||
else:
|
||||
server_option.selected = 1
|
||||
server_ip_input.text = NakamaManager.nakama_host if NakamaManager.nakama_host != "localhost" else "127.0.0.1"
|
||||
_on_server_option_selected(server_option.selected)
|
||||
|
||||
# Check if already authenticated
|
||||
if AuthManager.is_logged_in():
|
||||
@@ -53,7 +60,6 @@ func _connect_signals() -> void:
|
||||
# Login buttons
|
||||
guest_button.pressed.connect(_on_guest_pressed)
|
||||
login_button.pressed.connect(_on_login_pressed)
|
||||
register_link.pressed.connect(_show_registration)
|
||||
|
||||
# Social buttons
|
||||
google_button.pressed.connect(_on_google_pressed)
|
||||
@@ -62,7 +68,6 @@ func _connect_signals() -> void:
|
||||
|
||||
# Registration buttons
|
||||
register_button.pressed.connect(_on_register_pressed)
|
||||
back_to_login_link.pressed.connect(_show_login)
|
||||
|
||||
# Password strength checker
|
||||
reg_password_input.text_changed.connect(_check_password_strength)
|
||||
@@ -73,6 +78,13 @@ func _connect_signals() -> void:
|
||||
AuthManager.auth_failed.connect(_on_auth_failed)
|
||||
AuthManager.session_restored.connect(_on_session_restored)
|
||||
|
||||
tab_container.tab_changed.connect(_on_tab_changed)
|
||||
server_option.item_selected.connect(_on_server_option_selected)
|
||||
server_ip_input.text_submitted.connect(_on_server_ip_submitted)
|
||||
server_ip_input.focus_exited.connect(func(): _on_server_ip_submitted(server_ip_input.text))
|
||||
lan_host_btn.pressed.connect(_on_lan_host_pressed)
|
||||
lan_join_btn.pressed.connect(func(): _on_lan_join_pressed(lan_ip.text))
|
||||
|
||||
# Enter key to submit
|
||||
password_input.text_submitted.connect(func(_t): _on_login_pressed())
|
||||
reg_confirm_password_input.text_submitted.connect(func(_t): _on_register_pressed())
|
||||
@@ -81,8 +93,7 @@ func _setup_ui() -> void:
|
||||
status_label.text = ""
|
||||
reg_status_label.text = ""
|
||||
loading_spinner.visible = false
|
||||
registration_panel.visible = false
|
||||
main_panel.visible = true
|
||||
tab_container.current_tab = 0
|
||||
|
||||
# Hide social buttons on platforms where they're not supported
|
||||
_configure_social_buttons()
|
||||
@@ -102,12 +113,14 @@ func _configure_social_buttons() -> void:
|
||||
# Panel Switching
|
||||
# =============================================================================
|
||||
|
||||
func _show_registration() -> void:
|
||||
main_panel.visible = false
|
||||
registration_panel.visible = true
|
||||
reg_status_label.text = ""
|
||||
_generate_captcha()
|
||||
reg_email_input.grab_focus()
|
||||
func _on_tab_changed(tab: int) -> void:
|
||||
if tab == 0:
|
||||
status_label.text = ""
|
||||
email_input.grab_focus()
|
||||
elif tab == 1:
|
||||
reg_status_label.text = ""
|
||||
_generate_captcha()
|
||||
reg_email_input.grab_focus()
|
||||
|
||||
func _generate_captcha() -> void:
|
||||
var num1 := randi_range(1, 10)
|
||||
@@ -116,12 +129,6 @@ func _generate_captcha() -> void:
|
||||
reg_captcha_question.text = "Security Check: %d + %d = ?" % [num1, num2]
|
||||
reg_captcha_input.text = ""
|
||||
|
||||
func _show_login() -> void:
|
||||
registration_panel.visible = false
|
||||
main_panel.visible = true
|
||||
status_label.text = ""
|
||||
email_input.grab_focus()
|
||||
|
||||
# =============================================================================
|
||||
# Login Handlers
|
||||
# =============================================================================
|
||||
@@ -183,112 +190,7 @@ func _on_facebook_pressed() -> void:
|
||||
# When you have the access token from Facebook SDK:
|
||||
# AuthManager.login_with_facebook(access_token)
|
||||
|
||||
func _setup_server_config_ui() -> void:
|
||||
"""Inject server configuration controls into MainPanel."""
|
||||
if not main_panel: return
|
||||
|
||||
var vbox = main_panel.get_node_or_null("VBox")
|
||||
if not vbox: return
|
||||
|
||||
# Find where to insert (before GuestButton)
|
||||
var insert_pos = 3 # Default position
|
||||
if guest_button:
|
||||
insert_pos = guest_button.get_index()
|
||||
|
||||
# Create Server Section
|
||||
var server_section = VBoxContainer.new()
|
||||
server_section.name = "ServerSelectionSection"
|
||||
server_section.add_theme_constant_override("separation", 10)
|
||||
vbox.add_child(server_section)
|
||||
vbox.move_child(server_section, insert_pos)
|
||||
|
||||
# Server Label
|
||||
var label = Label.new()
|
||||
label.text = "CONNECTION MODE"
|
||||
label.add_theme_color_override("font_color", Color(0.69, 0.529, 0.357, 1))
|
||||
label.add_theme_font_size_override("font_size", 13)
|
||||
server_section.add_child(label)
|
||||
|
||||
# Server OptionButton
|
||||
server_option = OptionButton.new()
|
||||
server_option.name = "ServerOption"
|
||||
server_option.custom_minimum_size = Vector2(0, 44)
|
||||
server_option.add_item("Nakama - Localhost (Testing)")
|
||||
server_option.add_item("Nakama - Remote Server (Host IP)")
|
||||
server_option.add_item("LAN Direct (No Server)")
|
||||
server_option.add_item("Nakama - Tekton Dash EU")
|
||||
|
||||
# Set initial state based on NakamaManager
|
||||
if NakamaManager.nakama_host == "localhost":
|
||||
server_option.selected = 0
|
||||
elif NakamaManager.nakama_host == "tektondash.vps.webdock.cloud":
|
||||
server_option.selected = 3
|
||||
else:
|
||||
server_option.selected = 1
|
||||
|
||||
server_option.item_selected.connect(_on_server_option_selected)
|
||||
server_section.add_child(server_option)
|
||||
|
||||
# Nakama Server IP Input
|
||||
server_ip_input = LineEdit.new()
|
||||
server_ip_input.name = "ServerIPInput"
|
||||
server_ip_input.custom_minimum_size = Vector2(0, 44)
|
||||
server_ip_input.placeholder_text = "Enter Nakama Server IP..."
|
||||
server_ip_input.text = NakamaManager.nakama_host if NakamaManager.nakama_host != "localhost" else "127.0.0.1"
|
||||
server_ip_input.visible = server_option.selected == 1
|
||||
server_ip_input.text_submitted.connect(_on_server_ip_submitted)
|
||||
server_ip_input.focus_exited.connect(func(): _on_server_ip_submitted(server_ip_input.text))
|
||||
server_section.add_child(server_ip_input)
|
||||
|
||||
# --- LAN Section ---
|
||||
lan_section = VBoxContainer.new()
|
||||
lan_section.name = "LANSection"
|
||||
lan_section.add_theme_constant_override("separation", 8)
|
||||
lan_section.visible = false
|
||||
server_section.add_child(lan_section)
|
||||
|
||||
var lan_info = Label.new()
|
||||
lan_info.text = "Play over LAN without any server.\nFirewall may need to allow port 7777."
|
||||
lan_info.add_theme_color_override("font_color", Color(0.7, 0.7, 0.7, 1))
|
||||
lan_info.add_theme_font_size_override("font_size", 12)
|
||||
lan_info.autowrap_mode = TextServer.AUTOWRAP_WORD
|
||||
lan_section.add_child(lan_info)
|
||||
|
||||
# Host LAN button
|
||||
var lan_host_btn = Button.new()
|
||||
lan_host_btn.name = "LANHostBtn"
|
||||
lan_host_btn.text = "HOST LAN GAME"
|
||||
lan_host_btn.custom_minimum_size = Vector2(0, 44)
|
||||
lan_host_btn.pressed.connect(_on_lan_host_pressed)
|
||||
lan_section.add_child(lan_host_btn)
|
||||
|
||||
var lan_sep = Label.new()
|
||||
lan_sep.text = "── or join a friend ──"
|
||||
lan_sep.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||
lan_sep.add_theme_color_override("font_color", Color(0.5, 0.5, 0.5, 1))
|
||||
lan_sep.add_theme_font_size_override("font_size", 11)
|
||||
lan_section.add_child(lan_sep)
|
||||
|
||||
# LAN Host IP input
|
||||
var lan_ip = LineEdit.new()
|
||||
lan_ip.name = "LANIPInput"
|
||||
lan_ip.custom_minimum_size = Vector2(0, 44)
|
||||
lan_ip.placeholder_text = "Host IP (e.g. 192.168.1.10)"
|
||||
lan_ip.text = "127.0.0.1"
|
||||
lan_section.add_child(lan_ip)
|
||||
|
||||
# Join LAN button
|
||||
var lan_join_btn = Button.new()
|
||||
lan_join_btn.name = "LANJoinBtn"
|
||||
lan_join_btn.text = "JOIN LAN GAME"
|
||||
lan_join_btn.custom_minimum_size = Vector2(0, 44)
|
||||
lan_join_btn.pressed.connect(func(): _on_lan_join_pressed(lan_ip.text))
|
||||
lan_section.add_child(lan_join_btn)
|
||||
|
||||
# Add a separator after the section
|
||||
var separator = HSeparator.new()
|
||||
vbox.add_child(separator)
|
||||
vbox.move_child(separator, insert_pos + 1)
|
||||
|
||||
|
||||
func _on_server_option_selected(index: int) -> void:
|
||||
if index == 0:
|
||||
@@ -322,7 +224,7 @@ func _on_lan_host_pressed() -> void:
|
||||
player_name = "Host"
|
||||
LobbyManager.local_player_name = player_name
|
||||
|
||||
var ok = await LobbyManager.create_room_lan()
|
||||
var ok = LobbyManager.create_room_lan()
|
||||
if ok:
|
||||
_go_to_lobby()
|
||||
else:
|
||||
@@ -490,7 +392,7 @@ func _on_auth_failed(error: String) -> void:
|
||||
loading_spinner.visible = false
|
||||
_set_inputs_enabled(true)
|
||||
|
||||
if registration_panel.visible:
|
||||
if tab_container.current_tab == 1:
|
||||
_show_reg_error(error)
|
||||
else:
|
||||
_show_error(error)
|
||||
|
||||
@@ -25,6 +25,16 @@ signal profile_updated
|
||||
@onready var avatar_popup := %AvatarSelectionPopup as PopupPanel
|
||||
@onready var avatar_grid := %GridContainer as GridContainer
|
||||
|
||||
# Account Settings refs
|
||||
@onready var acc_settings_dialog := %AccountSettingsDialog as AcceptDialog
|
||||
@onready var old_pass_input := %OldPassInput as LineEdit
|
||||
@onready var new_email_input := %NewEmailInput as LineEdit
|
||||
@onready var new_pass_input := %NewPassInput as LineEdit
|
||||
@onready var submit_cred_btn := %SubmitCredBtn as Button
|
||||
@onready var tz_dropdown := %TzDropdown as OptionButton
|
||||
@onready var save_tz_btn := %SaveTzBtn as Button
|
||||
@onready var reset_stats_btn := %ResetStatsBtn as Button
|
||||
|
||||
# Loadout refs
|
||||
@onready var char_left_btn := %CharLeftBtn as Button
|
||||
@onready var char_right_btn := %CharRightBtn as Button
|
||||
@@ -55,6 +65,7 @@ func _ready() -> void:
|
||||
_connect_signals()
|
||||
_load_profile_data()
|
||||
_setup_avatar_grid()
|
||||
_setup_account_settings_ui()
|
||||
_load_loadout()
|
||||
_setup_3d_preview()
|
||||
|
||||
@@ -71,6 +82,17 @@ func _connect_signals() -> void:
|
||||
|
||||
UserProfileManager.profile_updated.connect(_on_profile_updated)
|
||||
UserProfileManager.profile_update_failed.connect(_on_profile_update_failed)
|
||||
|
||||
# Dynamically inject Account Settings button
|
||||
var acc_settings_btn = Button.new()
|
||||
acc_settings_btn.text = "Account Settings"
|
||||
acc_settings_btn.custom_minimum_size = Vector2(0, 44)
|
||||
acc_settings_btn.add_theme_font_override("font", load("res://assets/fonts/Nougat-ExtraBlack.ttf"))
|
||||
acc_settings_btn.pressed.connect(_open_account_settings)
|
||||
# Insert it before Logout button
|
||||
var logout_idx = logout_btn.get_index()
|
||||
logout_btn.get_parent().add_child(acc_settings_btn)
|
||||
logout_btn.get_parent().move_child(acc_settings_btn, logout_idx)
|
||||
|
||||
# -------------------------------------------------------------------------
|
||||
# Profile
|
||||
@@ -279,6 +301,63 @@ func _on_link_account_pressed() -> void:
|
||||
dialog.queue_free()
|
||||
)
|
||||
|
||||
func _setup_account_settings_ui() -> void:
|
||||
# Populate Timezone dropdown
|
||||
tz_dropdown.clear()
|
||||
for i in range(-12, 15):
|
||||
var prefix = "+" if i >= 0 else ""
|
||||
tz_dropdown.add_item("GMT " + prefix + str(i))
|
||||
|
||||
# Connect buttons
|
||||
submit_cred_btn.pressed.connect(func():
|
||||
status_label.text = "Updating credentials..."
|
||||
var payload = {
|
||||
"current_password": old_pass_input.text,
|
||||
"new_email": new_email_input.text,
|
||||
"new_password": new_pass_input.text
|
||||
}
|
||||
var result = await NakamaManager.client.rpc_async(NakamaManager.session, "change_credentials", JSON.stringify(payload))
|
||||
if result.is_exception():
|
||||
status_label.text = "Failed: " + result.get_exception().message
|
||||
else:
|
||||
status_label.text = "Credentials updated successfully!"
|
||||
acc_settings_dialog.hide()
|
||||
)
|
||||
|
||||
save_tz_btn.pressed.connect(func():
|
||||
var selected_text = tz_dropdown.get_item_text(tz_dropdown.selected)
|
||||
var res = await NakamaManager.client.update_account_async(NakamaManager.session, null, null, null, null, null, selected_text)
|
||||
if res.is_exception():
|
||||
status_label.text = "TZ Failed: " + res.get_exception().message
|
||||
else:
|
||||
status_label.text = "Timezone saved!"
|
||||
)
|
||||
|
||||
reset_stats_btn.pressed.connect(func():
|
||||
var conf = ConfirmationDialog.new()
|
||||
conf.dialog_text = "Are you SURE you want to irreversibly wipe all your stats to 0?"
|
||||
add_child(conf)
|
||||
conf.popup_centered()
|
||||
conf.confirmed.connect(func():
|
||||
var r = await NakamaManager.client.rpc_async(NakamaManager.session, "reset_stats", "{}")
|
||||
if not r.is_exception():
|
||||
UserProfileManager.stats = {
|
||||
"games_played": 0, "games_won": 0, "games_lost": 0, "total_score": 0, "high_score": 0, "play_time_minutes": 0
|
||||
}
|
||||
_load_profile_data()
|
||||
status_label.text = "Stats wiped completely."
|
||||
conf.queue_free()
|
||||
acc_settings_dialog.hide()
|
||||
)
|
||||
)
|
||||
|
||||
func _open_account_settings() -> void:
|
||||
old_pass_input.visible = not AuthManager.is_guest
|
||||
old_pass_input.text = ""
|
||||
new_email_input.text = ""
|
||||
new_pass_input.text = ""
|
||||
acc_settings_dialog.popup_centered()
|
||||
|
||||
func _on_logout_pressed() -> void:
|
||||
AuthManager.logout()
|
||||
get_tree().change_scene_to_file("res://scenes/ui/login_screen.tscn")
|
||||
@@ -301,6 +380,10 @@ func show_panel() -> void:
|
||||
_load_loadout()
|
||||
_check_admin_visibility()
|
||||
show()
|
||||
|
||||
if AuthManager.is_guest:
|
||||
_on_link_account_pressed()
|
||||
status_label.text = "Please link an email to save your progress permanently!"
|
||||
|
||||
func _check_admin_visibility() -> void:
|
||||
admin_panel_btn.hide()
|
||||
|
||||
Reference in New Issue
Block a user