功能批量实现 优化 服务端 新浮动小游戏框架 新界面UI
This commit is contained in:
@@ -0,0 +1,769 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Bansonic;
|
||||
using GameServer.Client;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX)
|
||||
#define FRIEND_DISABLE_STEAMWORKS
|
||||
#endif
|
||||
|
||||
#if !FRIEND_DISABLE_STEAMWORKS
|
||||
using Steamworks;
|
||||
#endif
|
||||
|
||||
public enum FriendFilterType
|
||||
{
|
||||
All,
|
||||
Online,
|
||||
Starred,
|
||||
Offline,
|
||||
GameFriends,
|
||||
SteamFriends
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public sealed class FriendCardViewData
|
||||
{
|
||||
public string SteamId;
|
||||
public string DisplayName;
|
||||
public string AvatarUrl;
|
||||
public string StatusText;
|
||||
public bool IsOnline;
|
||||
public bool IsStarred;
|
||||
public bool IsGameFriend;
|
||||
public bool IsSteamFriend;
|
||||
}
|
||||
|
||||
public class friendSystem : MonoBehaviour
|
||||
{
|
||||
private const string LabelAllFriends = "全部好友";
|
||||
private const string LabelOnlineFriends = "在线好友";
|
||||
private const string LabelStarredFriends = "星标好友";
|
||||
private const string LabelOfflineFriends = "离线好友";
|
||||
private const string LabelGameFriends = "游戏好友";
|
||||
private const string LabelSteamFriends = "Steam好友";
|
||||
private const string StatusOnline = "在线";
|
||||
private const string StatusOffline = "离线";
|
||||
private const string StatusPlaying = "游戏中";
|
||||
private const string StatusInRoom = "房间中";
|
||||
private const string NoticeFriendDetailsNotReady = "好友详情面板尚未接入";
|
||||
private const string NoticePrivateChatNotReady = "私聊面板尚未接入";
|
||||
private const string DefaultStatusLoading = "正在拉取好友信息...";
|
||||
private const string DefaultStatusEmpty = "你当前没有好友";
|
||||
private const string DefaultStatusServiceUnavailable = "无法访问服务";
|
||||
|
||||
public GameObject friendCardPrefab;
|
||||
public Transform friendsDisplayContent;
|
||||
|
||||
[Header("filter")]
|
||||
public Dropdown friendsDisplayDropdown;
|
||||
|
||||
[Header("text")]
|
||||
public Text defaultText;
|
||||
|
||||
[Header("sync")]
|
||||
[SerializeField] private float steamFriendResyncIntervalSeconds = 8f;
|
||||
|
||||
private readonly Dictionary<string, FriendCardViewData> _mergedFriends =
|
||||
new Dictionary<string, FriendCardViewData>(StringComparer.Ordinal);
|
||||
private readonly Dictionary<string, FriendCardViewData> _steamFriendCache =
|
||||
new Dictionary<string, FriendCardViewData>(StringComparer.Ordinal);
|
||||
private readonly Dictionary<string, GameObject> _spawnedCards =
|
||||
new Dictionary<string, GameObject>(StringComparer.Ordinal);
|
||||
private readonly List<(FriendFilterType filter, string label)> _filters =
|
||||
new List<(FriendFilterType filter, string label)>
|
||||
{
|
||||
(FriendFilterType.All, LabelAllFriends),
|
||||
(FriendFilterType.Online, LabelOnlineFriends),
|
||||
(FriendFilterType.Starred, LabelStarredFriends),
|
||||
(FriendFilterType.Offline, LabelOfflineFriends),
|
||||
(FriendFilterType.GameFriends, LabelGameFriends),
|
||||
(FriendFilterType.SteamFriends, LabelSteamFriends)
|
||||
};
|
||||
|
||||
private bool _dropdownInitialized;
|
||||
private bool _isRefreshing;
|
||||
private bool _lastRefreshFailed;
|
||||
private Coroutine _resyncCoroutine;
|
||||
private static List<string> _startupSteamFriendIds = new List<string>();
|
||||
|
||||
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
|
||||
private static void WarmSteamFriendIdsOnStartup()
|
||||
{
|
||||
_startupSteamFriendIds = ReadSteamFriendIdsOnly();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
ClearDisplayedFriends();
|
||||
SetDefaultText(DefaultStatusLoading);
|
||||
InitializeDropdown();
|
||||
|
||||
if (ArenaRoomService.Instance != null)
|
||||
{
|
||||
ArenaRoomService.Instance.OnFriendsListChanged += HandleFriendsListChanged;
|
||||
}
|
||||
|
||||
StartCoroutine(InitializeFriendsRoutine());
|
||||
if (_resyncCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_resyncCoroutine);
|
||||
}
|
||||
_resyncCoroutine = StartCoroutine(SteamFriendResyncLoop());
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (ArenaRoomService.Instance != null)
|
||||
{
|
||||
ArenaRoomService.Instance.OnFriendsListChanged -= HandleFriendsListChanged;
|
||||
}
|
||||
|
||||
if (_resyncCoroutine != null)
|
||||
{
|
||||
StopCoroutine(_resyncCoroutine);
|
||||
_resyncCoroutine = null;
|
||||
}
|
||||
|
||||
if (friendsDisplayDropdown != null)
|
||||
{
|
||||
friendsDisplayDropdown.onValueChanged.RemoveListener(HandleFilterChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearDisplayedFriends()
|
||||
{
|
||||
_spawnedCards.Clear();
|
||||
if (friendsDisplayContent == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int index = friendsDisplayContent.childCount - 1; index >= 0; index--)
|
||||
{
|
||||
Transform child = friendsDisplayContent.GetChild(index);
|
||||
if (child != null)
|
||||
{
|
||||
Destroy(child.gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator InitializeFriendsRoutine()
|
||||
{
|
||||
if (_isRefreshing)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
_isRefreshing = true;
|
||||
_lastRefreshFailed = false;
|
||||
SetDefaultText(DefaultStatusLoading);
|
||||
RefreshSteamFriendCache();
|
||||
|
||||
float waitDeadline = Time.realtimeSinceStartup + 3f;
|
||||
while (NetworkManager.Instance == null && Time.realtimeSinceStartup < waitDeadline)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
NetworkManager network = NetworkManager.Instance;
|
||||
List<string> steamFriendIds = _steamFriendCache.Keys
|
||||
.Where(id => !string.IsNullOrWhiteSpace(id))
|
||||
.Distinct(StringComparer.Ordinal)
|
||||
.ToList();
|
||||
|
||||
if (network != null)
|
||||
{
|
||||
var friendsTask = network.GetFriendsList(steamFriendIds);
|
||||
float timeoutAt = Time.realtimeSinceStartup + 20f;
|
||||
while (!friendsTask.IsCompleted && Time.realtimeSinceStartup < timeoutAt)
|
||||
{
|
||||
yield return null;
|
||||
}
|
||||
|
||||
if (!friendsTask.IsCompleted)
|
||||
{
|
||||
_lastRefreshFailed = true;
|
||||
Debug.LogWarning("[friendSystem] GetFriendsList timed out.");
|
||||
}
|
||||
else if (friendsTask.Status == System.Threading.Tasks.TaskStatus.RanToCompletion
|
||||
&& friendsTask.Result != null
|
||||
&& friendsTask.Result.success)
|
||||
{
|
||||
ReplaceGameFriends(friendsTask.Result.friends);
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastRefreshFailed = true;
|
||||
string error = friendsTask.IsFaulted ? friendsTask.Exception?.GetBaseException().Message : "friend list request failed";
|
||||
Debug.LogWarning($"[friendSystem] Initialize friends failed: {error}");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_lastRefreshFailed = true;
|
||||
Debug.LogWarning("[friendSystem] NetworkManager is unavailable when initializing friends.");
|
||||
}
|
||||
|
||||
Render();
|
||||
_isRefreshing = false;
|
||||
}
|
||||
|
||||
private IEnumerator SteamFriendResyncLoop()
|
||||
{
|
||||
float interval = Mathf.Max(3f, steamFriendResyncIntervalSeconds);
|
||||
var wait = new WaitForSecondsRealtime(interval);
|
||||
while (isActiveAndEnabled)
|
||||
{
|
||||
yield return wait;
|
||||
if (_isRefreshing)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
RefreshSteamFriendCache();
|
||||
if (!ShouldRetrySteamImport())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return InitializeFriendsRoutine();
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeDropdown()
|
||||
{
|
||||
if (friendsDisplayDropdown == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
friendsDisplayDropdown.onValueChanged.RemoveListener(HandleFilterChanged);
|
||||
if (!_dropdownInitialized)
|
||||
{
|
||||
friendsDisplayDropdown.ClearOptions();
|
||||
friendsDisplayDropdown.AddOptions(_filters.Select(item => item.label).ToList());
|
||||
friendsDisplayDropdown.value = 0;
|
||||
_dropdownInitialized = true;
|
||||
}
|
||||
|
||||
friendsDisplayDropdown.onValueChanged.AddListener(HandleFilterChanged);
|
||||
friendsDisplayDropdown.RefreshShownValue();
|
||||
}
|
||||
|
||||
private void HandleFilterChanged(int _)
|
||||
{
|
||||
Render();
|
||||
}
|
||||
|
||||
private void HandleFriendsListChanged(IReadOnlyList<SocialFriendEntry> friends)
|
||||
{
|
||||
_lastRefreshFailed = false;
|
||||
RefreshSteamFriendCache();
|
||||
ReplaceGameFriends(friends);
|
||||
Render();
|
||||
}
|
||||
|
||||
private void RefreshSteamFriendCache()
|
||||
{
|
||||
CacheSteamFriends(ReadSteamFriends().Concat(BuildStartupSteamFriendCards()));
|
||||
}
|
||||
|
||||
private bool ShouldRetrySteamImport()
|
||||
{
|
||||
if (_steamFriendCache.Count == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, FriendCardViewData> pair in _steamFriendCache)
|
||||
{
|
||||
FriendCardViewData steamFriend = pair.Value;
|
||||
if (steamFriend == null || string.IsNullOrWhiteSpace(steamFriend.SteamId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_mergedFriends.ContainsKey(steamFriend.SteamId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (steamFriend.IsOnline || string.Equals(steamFriend.StatusText, StatusPlaying, StringComparison.Ordinal))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CacheSteamFriends(IEnumerable<FriendCardViewData> steamFriends)
|
||||
{
|
||||
_steamFriendCache.Clear();
|
||||
if (steamFriends == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (FriendCardViewData steamFriend in steamFriends)
|
||||
{
|
||||
if (steamFriend == null || string.IsNullOrWhiteSpace(steamFriend.SteamId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
steamFriend.IsStarred = LoadStarredState(steamFriend.SteamId);
|
||||
_steamFriendCache[steamFriend.SteamId] = steamFriend;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReplaceGameFriends(IEnumerable<SocialFriendEntry> gameFriends)
|
||||
{
|
||||
_mergedFriends.Clear();
|
||||
if (gameFriends == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (SocialFriendEntry gameFriend in gameFriends)
|
||||
{
|
||||
if (gameFriend == null || string.IsNullOrWhiteSpace(gameFriend.friend_steam_id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string steamId = gameFriend.friend_steam_id.Trim();
|
||||
_steamFriendCache.TryGetValue(steamId, out FriendCardViewData steamFriend);
|
||||
bool steamSaysPlaying = steamFriend != null && string.Equals(steamFriend.StatusText, StatusPlaying, StringComparison.Ordinal);
|
||||
bool mergedOnline = gameFriend.online || (steamFriend != null && steamFriend.IsOnline) || steamSaysPlaying;
|
||||
string mergedStatus = MapServerPresenceToStatusText(gameFriend.status, steamFriend, mergedOnline);
|
||||
|
||||
FriendCardViewData merged = new FriendCardViewData
|
||||
{
|
||||
SteamId = steamId,
|
||||
DisplayName = ResolvePreferredDisplayName(
|
||||
steamFriend != null ? steamFriend.DisplayName : string.Empty,
|
||||
NetworkManager.ResolveDisplayName(gameFriend.friend_name, steamId, false),
|
||||
steamId),
|
||||
AvatarUrl = ResolvePreferredAvatarUrl(
|
||||
steamFriend != null ? steamFriend.AvatarUrl : string.Empty,
|
||||
NetworkManager.ResolveAvatarUrl(gameFriend.friend_avatar, steamId),
|
||||
steamId),
|
||||
StatusText = mergedStatus,
|
||||
IsOnline = mergedOnline,
|
||||
IsStarred = LoadStarredState(steamId),
|
||||
IsGameFriend = true,
|
||||
IsSteamFriend = steamFriend != null
|
||||
};
|
||||
|
||||
_mergedFriends[steamId] = merged;
|
||||
}
|
||||
}
|
||||
|
||||
private async System.Threading.Tasks.Task HydrateRegisteredSteamFriendsAsync(NetworkManager network)
|
||||
{
|
||||
if (network == null || _steamFriendCache.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (KeyValuePair<string, FriendCardViewData> pair in _steamFriendCache)
|
||||
{
|
||||
string steamId = pair.Key;
|
||||
FriendCardViewData steamFriend = pair.Value;
|
||||
if (string.IsNullOrWhiteSpace(steamId) || _mergedFriends.ContainsKey(steamId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ProfileData profile;
|
||||
try
|
||||
{
|
||||
profile = await network.GetProfile(steamId);
|
||||
}
|
||||
catch
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (profile == null || string.IsNullOrWhiteSpace(profile.steam_id))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool steamSaysPlaying = steamFriend != null && string.Equals(steamFriend.StatusText, StatusPlaying, StringComparison.Ordinal);
|
||||
bool mergedOnline = steamFriend != null && steamFriend.IsOnline;
|
||||
string mergedStatus = steamSaysPlaying ? StatusPlaying : (mergedOnline ? StatusOnline : StatusOffline);
|
||||
|
||||
_mergedFriends[steamId] = new FriendCardViewData
|
||||
{
|
||||
SteamId = steamId,
|
||||
DisplayName = ResolvePreferredDisplayName(
|
||||
steamFriend != null ? steamFriend.DisplayName : string.Empty,
|
||||
NetworkManager.ResolveDisplayName(profile.display_name, steamId, false),
|
||||
steamId),
|
||||
AvatarUrl = ResolvePreferredAvatarUrl(
|
||||
steamFriend != null ? steamFriend.AvatarUrl : string.Empty,
|
||||
NetworkManager.ResolveAvatarUrl(profile.avatar_url, steamId),
|
||||
steamId),
|
||||
StatusText = mergedStatus,
|
||||
IsOnline = mergedOnline,
|
||||
IsStarred = LoadStarredState(steamId),
|
||||
IsGameFriend = true,
|
||||
IsSteamFriend = true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void Render()
|
||||
{
|
||||
if (friendsDisplayContent == null || friendCardPrefab == null)
|
||||
{
|
||||
SetDefaultText(DefaultStatusServiceUnavailable);
|
||||
return;
|
||||
}
|
||||
|
||||
List<FriendCardViewData> target = ApplyFilter(_mergedFriends.Values)
|
||||
.OrderBy(friend => GetSortBucket(friend))
|
||||
.ThenBy(friend => friend.DisplayName ?? string.Empty, StringComparer.OrdinalIgnoreCase)
|
||||
.ThenBy(friend => friend.SteamId ?? string.Empty, StringComparer.OrdinalIgnoreCase)
|
||||
.ToList();
|
||||
|
||||
HashSet<string> targetIds = new HashSet<string>(target.Select(friend => friend.SteamId), StringComparer.Ordinal);
|
||||
foreach (KeyValuePair<string, GameObject> pair in _spawnedCards.ToList())
|
||||
{
|
||||
if (targetIds.Contains(pair.Key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Destroy(pair.Value);
|
||||
_spawnedCards.Remove(pair.Key);
|
||||
}
|
||||
|
||||
for (int index = 0; index < target.Count; index++)
|
||||
{
|
||||
FriendCardViewData friend = target[index];
|
||||
if (!_spawnedCards.TryGetValue(friend.SteamId, out GameObject cardObject) || cardObject == null)
|
||||
{
|
||||
cardObject = Instantiate(friendCardPrefab, friendsDisplayContent);
|
||||
_spawnedCards[friend.SteamId] = cardObject;
|
||||
}
|
||||
|
||||
cardObject.transform.SetSiblingIndex(index);
|
||||
friendCardPrefab card = cardObject.GetComponent<friendCardPrefab>();
|
||||
if (card != null)
|
||||
{
|
||||
card.Bind(friend, HandleStarChanged, HandleOpenDetails, HandleOpenPrivateConversation);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateDefaultTextState(target.Count);
|
||||
}
|
||||
|
||||
private void UpdateDefaultTextState(int visibleCount)
|
||||
{
|
||||
if (_lastRefreshFailed)
|
||||
{
|
||||
SetDefaultText(DefaultStatusServiceUnavailable);
|
||||
return;
|
||||
}
|
||||
|
||||
if (visibleCount > 0)
|
||||
{
|
||||
SetDefaultText(string.Empty);
|
||||
return;
|
||||
}
|
||||
|
||||
SetDefaultText(DefaultStatusEmpty);
|
||||
}
|
||||
|
||||
private void SetDefaultText(string message)
|
||||
{
|
||||
if (defaultText == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
defaultText.text = message ?? string.Empty;
|
||||
}
|
||||
|
||||
private IEnumerable<FriendCardViewData> ApplyFilter(IEnumerable<FriendCardViewData> source)
|
||||
{
|
||||
FriendFilterType filter = GetSelectedFilter();
|
||||
switch (filter)
|
||||
{
|
||||
case FriendFilterType.All:
|
||||
return source;
|
||||
case FriendFilterType.Online:
|
||||
return source.Where(friend => friend.IsOnline);
|
||||
case FriendFilterType.Starred:
|
||||
return source.Where(friend => friend.IsStarred);
|
||||
case FriendFilterType.Offline:
|
||||
return source.Where(friend => !friend.IsOnline);
|
||||
case FriendFilterType.GameFriends:
|
||||
return source.Where(friend => friend.IsGameFriend);
|
||||
case FriendFilterType.SteamFriends:
|
||||
return source.Where(friend => friend.IsSteamFriend);
|
||||
default:
|
||||
return source;
|
||||
}
|
||||
}
|
||||
|
||||
private FriendFilterType GetSelectedFilter()
|
||||
{
|
||||
if (friendsDisplayDropdown == null || friendsDisplayDropdown.value < 0 || friendsDisplayDropdown.value >= _filters.Count)
|
||||
{
|
||||
return FriendFilterType.All;
|
||||
}
|
||||
|
||||
return _filters[friendsDisplayDropdown.value].filter;
|
||||
}
|
||||
|
||||
private void HandleStarChanged(string steamId, bool isOn)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(steamId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerPrefs.SetInt(BuildStarKey(steamId), isOn ? 1 : 0);
|
||||
PlayerPrefs.Save();
|
||||
|
||||
if (_mergedFriends.TryGetValue(steamId, out FriendCardViewData friend) && friend != null)
|
||||
{
|
||||
friend.IsStarred = isOn;
|
||||
}
|
||||
|
||||
if (_steamFriendCache.TryGetValue(steamId, out FriendCardViewData steamFriend) && steamFriend != null)
|
||||
{
|
||||
steamFriend.IsStarred = isOn;
|
||||
}
|
||||
|
||||
Render();
|
||||
}
|
||||
|
||||
private void HandleOpenDetails(string steamId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(steamId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gNotice.warning.display(NoticeFriendDetailsNotReady);
|
||||
}
|
||||
|
||||
private void HandleOpenPrivateConversation(string steamId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(steamId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
globalChatSystem.OpenPrivateConversation(steamId);
|
||||
}
|
||||
|
||||
private static int GetSortBucket(FriendCardViewData friend)
|
||||
{
|
||||
if (friend == null)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
if (friend.IsStarred && friend.IsOnline)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (friend.IsStarred && !friend.IsOnline)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!friend.IsStarred && friend.IsOnline)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 3;
|
||||
}
|
||||
|
||||
private static string ResolvePreferredDisplayName(string currentDisplayName, string newDisplayName, string steamId)
|
||||
{
|
||||
if (NetworkManager.IsUsableDisplayName(newDisplayName, steamId))
|
||||
{
|
||||
return newDisplayName;
|
||||
}
|
||||
|
||||
if (NetworkManager.IsUsableDisplayName(currentDisplayName, steamId))
|
||||
{
|
||||
return currentDisplayName;
|
||||
}
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
private static string ResolvePreferredAvatarUrl(string currentAvatarUrl, string newAvatarUrl, string steamId)
|
||||
{
|
||||
if (NetworkManager.IsUsableAvatarUrl(newAvatarUrl))
|
||||
{
|
||||
return newAvatarUrl;
|
||||
}
|
||||
|
||||
if (NetworkManager.IsUsableAvatarUrl(currentAvatarUrl))
|
||||
{
|
||||
return currentAvatarUrl;
|
||||
}
|
||||
|
||||
return NetworkManager.ResolveAvatarUrl(string.Empty, steamId);
|
||||
}
|
||||
|
||||
private static string BuildStarKey(string steamId)
|
||||
{
|
||||
return $"friend_star_{steamId}";
|
||||
}
|
||||
|
||||
private static bool LoadStarredState(string steamId)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(steamId))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return PlayerPrefs.GetInt(BuildStarKey(steamId), 0) == 1;
|
||||
}
|
||||
|
||||
private static List<FriendCardViewData> ReadSteamFriends()
|
||||
{
|
||||
var result = new List<FriendCardViewData>();
|
||||
#if FRIEND_DISABLE_STEAMWORKS
|
||||
return result;
|
||||
#else
|
||||
if (!SteamManager.Initialized)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
int count = SteamFriends.GetFriendCount(EFriendFlags.k_EFriendFlagImmediate);
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
CSteamID friendSteamId = SteamFriends.GetFriendByIndex(index, EFriendFlags.k_EFriendFlagImmediate);
|
||||
string steamId = friendSteamId.m_SteamID.ToString();
|
||||
SteamFriends.RequestUserInformation(friendSteamId, false);
|
||||
|
||||
string displayName = SteamFriends.GetFriendPersonaName(friendSteamId);
|
||||
EPersonaState personaState = SteamFriends.GetFriendPersonaState(friendSteamId);
|
||||
FriendGameInfo_t gameInfo;
|
||||
bool isPlaying = SteamFriends.GetFriendGamePlayed(friendSteamId, out gameInfo);
|
||||
bool isOnline = personaState != EPersonaState.k_EPersonaStateOffline;
|
||||
string statusText = isPlaying ? StatusPlaying : (isOnline ? StatusOnline : StatusOffline);
|
||||
|
||||
result.Add(
|
||||
new FriendCardViewData
|
||||
{
|
||||
SteamId = steamId,
|
||||
DisplayName = NetworkManager.ResolveDisplayName(displayName, steamId, false),
|
||||
AvatarUrl = NetworkManager.ResolveAvatarUrl(string.Empty, steamId),
|
||||
StatusText = statusText,
|
||||
IsOnline = isOnline,
|
||||
IsSteamFriend = true,
|
||||
IsGameFriend = false,
|
||||
IsStarred = LoadStarredState(steamId)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
private static IEnumerable<FriendCardViewData> BuildStartupSteamFriendCards()
|
||||
{
|
||||
if (_startupSteamFriendIds == null || _startupSteamFriendIds.Count == 0)
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
|
||||
foreach (string steamId in _startupSteamFriendIds)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(steamId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
yield return new FriendCardViewData
|
||||
{
|
||||
SteamId = steamId,
|
||||
DisplayName = NetworkManager.ResolveDisplayName(string.Empty, steamId, false),
|
||||
AvatarUrl = NetworkManager.ResolveAvatarUrl(string.Empty, steamId),
|
||||
StatusText = string.Empty,
|
||||
IsOnline = false,
|
||||
IsSteamFriend = true,
|
||||
IsGameFriend = false,
|
||||
IsStarred = LoadStarredState(steamId)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private static List<string> ReadSteamFriendIdsOnly()
|
||||
{
|
||||
var result = new List<string>();
|
||||
#if FRIEND_DISABLE_STEAMWORKS
|
||||
return result;
|
||||
#else
|
||||
if (!SteamManager.Initialized)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
int count = SteamFriends.GetFriendCount(EFriendFlags.k_EFriendFlagImmediate);
|
||||
for (int index = 0; index < count; index++)
|
||||
{
|
||||
CSteamID friendSteamId = SteamFriends.GetFriendByIndex(index, EFriendFlags.k_EFriendFlagImmediate);
|
||||
string steamId = friendSteamId.m_SteamID.ToString();
|
||||
if (!string.IsNullOrWhiteSpace(steamId))
|
||||
{
|
||||
result.Add(steamId);
|
||||
}
|
||||
}
|
||||
|
||||
return result.Distinct(StringComparer.Ordinal).ToList();
|
||||
#endif
|
||||
}
|
||||
|
||||
private static string MapServerPresenceToStatusText(string status, FriendCardViewData steamFriend, bool mergedOnline)
|
||||
{
|
||||
if (string.Equals(status, "IN_GAME", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return StatusPlaying;
|
||||
}
|
||||
|
||||
if (string.Equals(status, "IN_ROOM", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return StatusInRoom;
|
||||
}
|
||||
|
||||
if (string.Equals(status, "ONLINE", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return StatusOnline;
|
||||
}
|
||||
|
||||
if (string.Equals(status, "OFFLINE", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return StatusOffline;
|
||||
}
|
||||
|
||||
if (steamFriend != null && string.Equals(steamFriend.StatusText, StatusPlaying, StringComparison.Ordinal))
|
||||
{
|
||||
return StatusPlaying;
|
||||
}
|
||||
|
||||
return mergedOnline ? StatusOnline : StatusOffline;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user