770 lines
24 KiB
C#
770 lines
24 KiB
C#
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;
|
|
}
|
|
}
|