feat: update 2.1.9

This commit is contained in:
2026-04-29 01:36:49 +08:00
parent 1585b91509
commit 8a2f865ad8
76 changed files with 2628 additions and 39 deletions
+133
View File
@@ -0,0 +1,133 @@
extends Node
## Unified interface for backend services
## All platforms use Nakama for achievements, leaderboards, and shop
## Steam is only used for authentication (auth session ticket for Nakama login)
enum Platform {
DESKTOP_STEAM,
DESKTOP_NAKAMA,
MOBILE_NAKAMA
}
var current_platform: Platform = Platform.DESKTOP_STEAM
var steamworks_manager: Node # Only for auth ticket retrieval
var nakama_backend: Node
func _ready() -> void:
_detect_platform()
_initialize_backend()
func _detect_platform() -> void:
# Detect if running on mobile or desktop
if OS.has_feature("android") or OS.has_feature("ios"):
current_platform = Platform.MOBILE_NAKAMA
else:
# Desktop: detect Steam by checking if GodotSteam class exists
# OS.has_feature("steam") is only true when launched through Steam client,
# but ClassDB.class_exists("Steam") is true whenever the GDExtension is enabled
if ClassDB.class_exists("Steam"):
current_platform = Platform.DESKTOP_STEAM
else:
current_platform = Platform.DESKTOP_NAKAMA
func _initialize_backend() -> void:
# All platforms use Nakama for backend features
# Steamworks is only initialized for auth ticket retrieval when GodotSteam is available
if current_platform == Platform.DESKTOP_STEAM:
_initialize_steamworks_for_auth()
_initialize_nakama()
func _initialize_steamworks_for_auth() -> void:
var steamworks_script = load("res://scripts/services/steamworks_manager.gd")
if steamworks_script:
steamworks_manager = steamworks_script.new()
add_child(steamworks_manager)
print("BackendService: Initialized Steamworks for auth only")
else:
push_error("BackendService: Failed to load Steamworks manager")
func _initialize_nakama() -> void:
nakama_backend = NakamaManager
if nakama_backend:
_connect_nakama_signals()
print("BackendService: Initialized Nakama backend")
else:
push_error("BackendService: NakamaManager not found")
func _connect_nakama_signals() -> void:
# Nakama signals are handled directly by NakamaManager
# No need to connect through BackendService
pass
## Achievement Methods
# All platforms use Nakama for achievements
func unlock_achievement(achievement_id: String) -> void:
if nakama_backend:
# Nakama achievement implementation
pass
func set_achievement_progress(achievement_id: String, current: int, max: int) -> void:
if nakama_backend:
# Nakama progress implementation
pass
func get_achievement_progress(achievement_id: String) -> Dictionary:
if nakama_backend:
# Nakama get progress implementation
pass
return {}
func get_all_achievements() -> Array:
if nakama_backend:
# Nakama get all achievements implementation
pass
return []
## Leaderboard Methods
# All platforms use Nakama for leaderboards
func submit_leaderboard_score(leaderboard_id: String, score: int) -> void:
if nakama_backend:
# Nakama leaderboard submission - use UserProfileManager.submit_to_leaderboard()
await UserProfileManager.submit_to_leaderboard()
func get_leaderboard_entries(leaderboard_id: String, range_start: int = 1, range_end: int = 10) -> void:
if nakama_backend:
# Nakama get leaderboard entries - use LeaderboardPanel._fetch_leaderboard_data()
# This is handled by the UI panel directly
pass
## Shop Methods
# All platforms use Nakama for shop
func purchase_shop_item(item_id: String) -> void:
if nakama_backend:
# Nakama shop purchase - use UserProfileManager.purchase_item()
# This is handled by the UI panel directly via ShopPanel
pass
func get_shop_items() -> void:
if nakama_backend:
# Nakama get shop items - use UserProfileManager.fetch_shop_catalog()
# This is handled by the UI panel directly via ShopPanel
pass
## Utility Methods
func is_initialized() -> bool:
# Nakama is the primary backend for all features
if nakama_backend != null:
return true
# Steamworks is optional (only for auth)
return false
func get_platform_name() -> String:
return Platform.keys()[current_platform]
func get_steamworks_manager() -> Node:
# Returns SteamworksManager for auth ticket retrieval (Steam login)
return steamworks_manager
+1
View File
@@ -0,0 +1 @@
uid://dnpp80dw4ve8l
+72
View File
@@ -0,0 +1,72 @@
class_name SteamworksManager
extends Node
## Steamworks integration for Nakama authentication only
## Used to get Steam auth session tickets for Nakama login/registration
## Steam singleton is provided by GodotSteam GDExtension
var is_steam_initialized: bool = false
var steam_app_id: int = ProjectSettings.get_setting("steam/initialization/app_id", 480)
func _ready() -> void:
_initialize_steam()
func _initialize_steam() -> void:
# Check if GodotSteam GDExtension is loaded
if not ClassDB.class_exists("Steam"):
push_error("SteamworksManager: GodotSteam GDExtension not found. Enable it in Project Settings > Plugins.")
return
# Use steamInitEx for proper initialization with status reporting
var init_result: Dictionary = Steam.steamInitEx()
var status: int = init_result.get("status", -1)
var verbal: String = init_result.get("verbal", "Unknown error")
if status == 0:
is_steam_initialized = true
print("SteamworksManager: Steam initialized (App ID: %s)" % steam_app_id)
else:
push_warning("SteamworksManager: Steam init failed [%d] - %s" % [status, verbal])
print("SteamworksManager: Make sure Steam is running and App ID %s is valid" % steam_app_id)
func is_initialized() -> bool:
return is_steam_initialized
## Auth Methods
func get_auth_session_ticket() -> String:
if not is_steam_initialized:
push_warning("SteamworksManager: Steam not initialized, cannot get auth ticket")
return ""
# getAuthSessionTicket returns a Dictionary in GodotSteam {"id": int, "buffer": PackedByteArray}
var ticket_data = Steam.getAuthSessionTicket()
if typeof(ticket_data) == TYPE_DICTIONARY:
var buffer: PackedByteArray = ticket_data.get("buffer", PackedByteArray())
if buffer.size() > 0:
var ticket_hex = buffer.hex_encode()
print("SteamworksManager: Got Steam auth session ticket")
return ticket_hex
push_error("SteamworksManager: Auth ticket buffer is empty")
return ""
elif typeof(ticket_data) == TYPE_STRING and not ticket_data.is_empty():
print("SteamworksManager: Got Steam auth session ticket")
return ticket_data
else:
push_error("SteamworksManager: Failed to get auth session ticket")
return ""
func get_steam_user_name() -> String:
if not is_steam_initialized:
return ""
return Steam.getPersonaName()
func get_steam_user_id() -> int:
if not is_steam_initialized:
return 0
return Steam.getSteamID()
func _notification(what: int) -> void:
if what == NOTIFICATION_WM_CLOSE_REQUEST:
if is_steam_initialized:
Steam.steamShutdown()
@@ -0,0 +1 @@
uid://3k02bu0c2ast