feat: 2.3.1
This commit is contained in:
@@ -116,7 +116,12 @@ func connect_to_nakama_async(email: String = "", password: String = "") -> bool:
|
||||
socket = Nakama.create_socket_from(client)
|
||||
var socket_result = await socket.connect_async(session)
|
||||
|
||||
if socket_result.is_exception():
|
||||
if typeof(socket_result) == TYPE_INT:
|
||||
if socket_result != OK:
|
||||
printerr("[NakamaManager] Socket Error (Code: %s)" % socket_result)
|
||||
emit_signal("connection_failed", "Socket connect failed with code " + str(socket_result))
|
||||
return false
|
||||
elif socket_result.is_exception():
|
||||
var err = socket_result.get_exception()
|
||||
printerr("[NakamaManager] Socket Error: %s (Code: %s)" % [err.message, err.status_code])
|
||||
emit_signal("connection_failed", err.message)
|
||||
@@ -154,6 +159,12 @@ func cleanup():
|
||||
socket.close()
|
||||
socket = null
|
||||
|
||||
# Delete match metadata from storage (best-effort, don't block cleanup)
|
||||
if session and client and not current_match_id.is_empty():
|
||||
client.delete_storage_objects_async(session, [
|
||||
NakamaStorageObjectId.new("match_meta", current_match_id, session.user_id)
|
||||
])
|
||||
|
||||
current_match_id = ""
|
||||
|
||||
# Reset Godot's multiplayer peer
|
||||
@@ -164,7 +175,7 @@ func cleanup():
|
||||
|
||||
# --- Match Management ---
|
||||
|
||||
func host_game():
|
||||
func host_game(room_meta: Dictionary = {}):
|
||||
if not bridge:
|
||||
printerr("Cannot host: Bridge not initialized")
|
||||
return
|
||||
@@ -172,6 +183,19 @@ func host_game():
|
||||
var result = await bridge.create_match()
|
||||
if result and result.is_exception():
|
||||
emit_signal("match_join_error", result.get_exception().message)
|
||||
return
|
||||
# Store room metadata in Nakama storage so other players can see it in listings
|
||||
if session and current_match_id and room_meta.size() > 0:
|
||||
var meta_json = JSON.stringify(room_meta)
|
||||
var write_obj = NakamaWriteStorageObject.new(
|
||||
"match_meta", current_match_id,
|
||||
2, 1, meta_json, ""
|
||||
)
|
||||
var wr = await client.write_storage_objects_async(session, [write_obj])
|
||||
if wr.is_exception():
|
||||
push_warning("[NakamaManager] Failed to write match metadata: ", wr.get_exception().message)
|
||||
else:
|
||||
print("[NakamaManager] Match metadata stored for: ", current_match_id)
|
||||
|
||||
func join_game(match_id: String):
|
||||
if not bridge:
|
||||
@@ -206,8 +230,10 @@ func is_connected_to_nakama() -> bool:
|
||||
|
||||
# --- Match Listing ---
|
||||
|
||||
func list_matches_async() -> Array:
|
||||
"""Query available matches from Nakama server."""
|
||||
func list_matches_async(mode_filter: String = "") -> Array:
|
||||
"""Query available matches from Nakama server.
|
||||
mode_filter: optional game mode string — used as label query for authoritative matches.
|
||||
For relayed matches this has no server-side effect; filtering is client-side."""
|
||||
if not client:
|
||||
push_error("Cannot list matches: Client not initialized")
|
||||
return []
|
||||
@@ -216,9 +242,10 @@ func list_matches_async() -> Array:
|
||||
push_error("Cannot list matches: No valid session")
|
||||
return []
|
||||
|
||||
print("Querying matches from Nakama server...")
|
||||
print("Querying matches from Nakama server... (filter: '%s')" % mode_filter)
|
||||
|
||||
# Query matches - min 0, max 8 players, limit 20, authoritative=false for relayed matches
|
||||
# Query matches — label filter works for authoritative matches only.
|
||||
# For relayed matches all rooms are returned; game_mode is parsed from label field if present.
|
||||
var result = await client.list_matches_async(session, 0, 8, 20, false, "", "")
|
||||
|
||||
if result.is_exception():
|
||||
@@ -228,16 +255,53 @@ func list_matches_async() -> Array:
|
||||
var rooms: Array = []
|
||||
if result.matches:
|
||||
print("Found %d matches" % result.matches.size())
|
||||
# Build storage read requests for all matches
|
||||
var read_ids: Array = []
|
||||
for match_data in result.matches:
|
||||
# Try to read metadata stored by each host
|
||||
read_ids.append(match_data.match_id)
|
||||
|
||||
# Batch-read room metadata from Nakama storage
|
||||
var meta_map: Dictionary = {} # match_id -> {host_name, game_mode, ...}
|
||||
if read_ids.size() > 0:
|
||||
var storage_reads: Array = []
|
||||
for mid in read_ids:
|
||||
# We don't know the owner_id, so list objects by collection+key
|
||||
# Use list_storage_objects per match or batch read
|
||||
pass
|
||||
# Read all match metas from our own storage (other users' objects are public read)
|
||||
for mid in read_ids:
|
||||
var list_result = await client.list_storage_objects_async(session, "match_meta", "", 100)
|
||||
if not list_result.is_exception() and list_result.objects:
|
||||
for obj in list_result.objects:
|
||||
var parsed = JSON.parse_string(obj.value)
|
||||
if parsed is Dictionary:
|
||||
meta_map[obj.key] = parsed
|
||||
break # Only need one call — lists all match_meta objects
|
||||
|
||||
for match_data in result.matches:
|
||||
print(" Match: ", match_data.match_id, " - Size: ", match_data.size)
|
||||
# Use first 8 chars of match ID as room identifier since Nakama doesn't store custom names
|
||||
var short_id = match_data.match_id.substr(0, 8) if match_data.match_id.length() > 8 else match_data.match_id
|
||||
|
||||
# Get metadata from storage (host_name, game_mode)
|
||||
var meta = meta_map.get(match_data.match_id, {})
|
||||
var host_name = meta.get("host_name", "Unknown")
|
||||
var game_mode = meta.get("game_mode", "")
|
||||
var max_players = int(meta.get("max_players", 8))
|
||||
|
||||
# Fallback: parse game_mode from label if available
|
||||
if game_mode.is_empty():
|
||||
var label: String = match_data.label if match_data.label != null else ""
|
||||
if label.begins_with("[") and "]" in label:
|
||||
game_mode = label.substr(1, label.find("]") - 1)
|
||||
|
||||
rooms.append({
|
||||
"match_id": match_data.match_id,
|
||||
"room_name": short_id,
|
||||
"host_name": "Host",
|
||||
"host_name": host_name,
|
||||
"player_count": match_data.size if match_data.size else 1,
|
||||
"max_players": 4
|
||||
"max_players": max_players,
|
||||
"game_mode": game_mode
|
||||
})
|
||||
else:
|
||||
print("No matches found")
|
||||
|
||||
Reference in New Issue
Block a user