feat: 2.3.1
This commit is contained in:
@@ -213,7 +213,7 @@ func get_dm_history(user_id: String, limit: int = 50) -> Array:
|
||||
var channel = await open_dm(user_id)
|
||||
if not channel:
|
||||
return []
|
||||
var result = await NakamaManager.client.list_channel_messages_async(NakamaManager.session, channel.id, limit, true)
|
||||
var result = await NakamaManager.client.list_channel_messages_async(NakamaManager.session, channel.id, limit, false)
|
||||
if result.is_exception():
|
||||
push_warning("[FriendManager] Failed to fetch DM history: " + result.get_exception().message)
|
||||
return []
|
||||
@@ -226,9 +226,9 @@ func get_dm_history(user_id: String, limit: int = 50) -> Array:
|
||||
text = parsed.get("msg", msg.content)
|
||||
else:
|
||||
text = msg.content
|
||||
history.append({"from": msg.sender_id, "msg": text, "username": msg.username})
|
||||
history.append({"from": msg.sender_id, "msg": text, "username": msg.username, "create_time": msg.create_time})
|
||||
|
||||
history.reverse() # Oldest to newest
|
||||
history.reverse() # API returns newest-first; flip to oldest-first so display is top=old, bottom=new
|
||||
return history
|
||||
|
||||
func send_dm(user_id: String, message: String) -> bool:
|
||||
@@ -249,6 +249,10 @@ func _on_channel_message(message) -> void:
|
||||
# Ignore global chat
|
||||
if "social_global" in message.channel_id:
|
||||
return
|
||||
|
||||
# Ignore messages sent by ourselves (we already add them locally instantly)
|
||||
if NakamaManager.session and message.sender_id == NakamaManager.session.user_id:
|
||||
return
|
||||
|
||||
var text: String = ""
|
||||
var parsed = JSON.parse_string(message.content)
|
||||
|
||||
@@ -157,7 +157,8 @@ func create_room(room_name: String) -> void:
|
||||
current_room = {
|
||||
"room_name": room_name,
|
||||
"host_name": local_player_name,
|
||||
"max_players": GameStateManager.max_players
|
||||
"max_players": GameStateManager.max_players,
|
||||
"game_mode": game_mode
|
||||
}
|
||||
|
||||
# Connect to Nakama and create match
|
||||
@@ -166,7 +167,11 @@ func create_room(room_name: String) -> void:
|
||||
push_error("Failed to connect to Nakama")
|
||||
return
|
||||
|
||||
NakamaManager.host_game()
|
||||
NakamaManager.host_game({
|
||||
"host_name": local_player_name,
|
||||
"game_mode": game_mode,
|
||||
"max_players": GameStateManager.max_players
|
||||
})
|
||||
|
||||
func join_room(match_id: String) -> void:
|
||||
"""Client joins an existing room by match ID (Nakama)."""
|
||||
@@ -201,7 +206,8 @@ func create_room_lan(room_name: String = "LAN Game") -> bool:
|
||||
"room_name": room_name,
|
||||
"host_name": local_player_name,
|
||||
"max_players": GameStateManager.max_players,
|
||||
"match_id": "LAN"
|
||||
"match_id": "LAN",
|
||||
"game_mode": game_mode
|
||||
}
|
||||
|
||||
# Add host to player list
|
||||
@@ -239,7 +245,8 @@ func _broadcast_lan_room(room_name: String):
|
||||
"host_name": local_player_name,
|
||||
"player_count": players_in_room.size(),
|
||||
"max_players": GameStateManager.max_players,
|
||||
"match_id": "LAN"
|
||||
"match_id": "LAN",
|
||||
"game_mode": game_mode
|
||||
}
|
||||
var msg = "TEKTON_HOST:" + JSON.stringify(room_data)
|
||||
_udp_peer.set_dest_address("255.255.255.255", LAN_DISCOVERY_PORT)
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
extends Node
|
||||
|
||||
signal mail_updated
|
||||
signal unread_count_changed(count: int)
|
||||
|
||||
var mails: Array = []
|
||||
var claimed_ids: Array = []
|
||||
var read_ids: Array = []
|
||||
|
||||
var _is_fetching: bool = false
|
||||
|
||||
func _ready() -> void:
|
||||
if UserProfileManager:
|
||||
UserProfileManager.profile_loaded.connect(_on_profile_loaded)
|
||||
|
||||
func _on_profile_loaded(_profile: Dictionary) -> void:
|
||||
fetch_mails()
|
||||
|
||||
func fetch_mails() -> void:
|
||||
if _is_fetching or not NakamaManager.session: return
|
||||
_is_fetching = true
|
||||
|
||||
var r = await NakamaManager.client.rpc_async(NakamaManager.session, "get_mail", "{}")
|
||||
_is_fetching = false
|
||||
|
||||
if r.is_exception():
|
||||
push_error("[MailManager] Failed to fetch mails: " + r.get_exception().message)
|
||||
return
|
||||
|
||||
var payload = JSON.parse_string(r.payload)
|
||||
if payload and payload is Dictionary:
|
||||
mails = payload.get("mails", [])
|
||||
var state = payload.get("state", {})
|
||||
claimed_ids = state.get("claimed_ids", [])
|
||||
read_ids = state.get("read_ids", [])
|
||||
|
||||
# Sort by date descending
|
||||
mails.sort_custom(func(a, b):
|
||||
return a.get("date", "") > b.get("date", "")
|
||||
)
|
||||
|
||||
mail_updated.emit()
|
||||
_update_unread_count()
|
||||
|
||||
func _update_unread_count() -> void:
|
||||
var count = 0
|
||||
for m in mails:
|
||||
if m.id not in read_ids:
|
||||
count += 1
|
||||
unread_count_changed.emit(count)
|
||||
|
||||
func claim_reward(mail_id: String) -> bool:
|
||||
var r = await NakamaManager.client.rpc_async(NakamaManager.session, "claim_mail_reward", JSON.stringify({"mail_id": mail_id}))
|
||||
if r.is_exception():
|
||||
push_error("[MailManager] Claim failed: " + r.get_exception().message)
|
||||
return false
|
||||
|
||||
var payload = JSON.parse_string(r.payload)
|
||||
if payload and payload.get("success"):
|
||||
claimed_ids = payload.get("claimed_ids", claimed_ids)
|
||||
if mail_id not in read_ids:
|
||||
read_ids.append(mail_id)
|
||||
mail_updated.emit()
|
||||
_update_unread_count()
|
||||
|
||||
# Refresh wallet
|
||||
UserProfileManager.load_profile()
|
||||
return true
|
||||
return false
|
||||
|
||||
func delete_mail(mail_id: String) -> bool:
|
||||
var r = await NakamaManager.client.rpc_async(NakamaManager.session, "delete_mail", JSON.stringify({"mail_id": mail_id}))
|
||||
if r.is_exception():
|
||||
push_error("[MailManager] Delete failed: " + r.get_exception().message)
|
||||
return false
|
||||
|
||||
var payload = JSON.parse_string(r.payload)
|
||||
if payload and payload.get("success"):
|
||||
var deleted_ids = payload.get("deleted_ids", [])
|
||||
# Remove from local array
|
||||
for i in range(mails.size() - 1, -1, -1):
|
||||
if mails[i].id in deleted_ids:
|
||||
mails.remove_at(i)
|
||||
if mail_id not in read_ids:
|
||||
read_ids.append(mail_id)
|
||||
mail_updated.emit()
|
||||
_update_unread_count()
|
||||
return true
|
||||
return false
|
||||
|
||||
func mark_as_read(mail_id: String) -> void:
|
||||
if mail_id in read_ids: return
|
||||
# Since there's no specific RPC for just marking as read, we can just do a claim with 0 rewards if needed,
|
||||
# or add an RPC for it. For now we just let claim or delete handle the server-side state.
|
||||
# Let's add an empty claim or just handle it purely local until claimed/deleted if it has no rewards.
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
uid://dx0lbsmcid72r
|
||||
Reference in New Issue
Block a user