232 lines
7.4 KiB
C#
232 lines
7.4 KiB
C#
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
using UnityEngine.UI;
|
|
using GameServer.Client;
|
|
|
|
#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 class friendCardPrefab : MonoBehaviour
|
|
{
|
|
[SerializeField] private Image profileBorder;
|
|
[SerializeField] private Image friendProfile;
|
|
[SerializeField] private Text friendName;
|
|
[SerializeField] private Text friendStatus;
|
|
[SerializeField] private Button friendDetails;
|
|
[SerializeField] private Button startPersonalConversation;
|
|
[SerializeField] private Toggle isStarFriend;
|
|
[SerializeField] private Image friendOffline_blackMask;
|
|
|
|
[Header("offline heibai")]
|
|
[SerializeField] private Material offline_material;
|
|
|
|
private Material _profileBorderMaterial;
|
|
private Material _friendProfileMaterial;
|
|
private Coroutine _avatarLoadRoutine;
|
|
private string _steamId;
|
|
private Action<string, bool> _starChanged;
|
|
private Action<string> _openDetails;
|
|
private Action<string> _openPrivateConversation;
|
|
private bool _bindingToggle;
|
|
|
|
private void Awake()
|
|
{
|
|
_profileBorderMaterial = profileBorder != null ? profileBorder.material : null;
|
|
_friendProfileMaterial = friendProfile != null ? friendProfile.material : null;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_avatarLoadRoutine != null)
|
|
{
|
|
StopCoroutine(_avatarLoadRoutine);
|
|
_avatarLoadRoutine = null;
|
|
}
|
|
}
|
|
|
|
public void Bind(FriendCardViewData data, Action<string, bool> onStarChanged, Action<string> onOpenDetails, Action<string> onOpenPrivateConversation)
|
|
{
|
|
_steamId = data != null ? data.SteamId : string.Empty;
|
|
_starChanged = onStarChanged;
|
|
_openDetails = onOpenDetails;
|
|
_openPrivateConversation = onOpenPrivateConversation;
|
|
|
|
if (friendName != null)
|
|
{
|
|
friendName.text = data != null ? data.DisplayName ?? string.Empty : string.Empty;
|
|
}
|
|
|
|
if (friendStatus != null)
|
|
{
|
|
friendStatus.text = data != null ? data.StatusText ?? string.Empty : string.Empty;
|
|
}
|
|
|
|
ApplyOnlineVisualState(data != null && data.IsOnline);
|
|
|
|
if (isStarFriend != null)
|
|
{
|
|
isStarFriend.onValueChanged.RemoveAllListeners();
|
|
_bindingToggle = true;
|
|
isStarFriend.isOn = data != null && data.IsStarred;
|
|
_bindingToggle = false;
|
|
isStarFriend.onValueChanged.AddListener(HandleStarToggleChanged);
|
|
}
|
|
|
|
if (friendDetails != null)
|
|
{
|
|
friendDetails.onClick.RemoveAllListeners();
|
|
friendDetails.onClick.AddListener(HandleOpenDetails);
|
|
}
|
|
|
|
if (startPersonalConversation != null)
|
|
{
|
|
startPersonalConversation.onClick.RemoveAllListeners();
|
|
startPersonalConversation.onClick.AddListener(HandleStartPrivateConversation);
|
|
}
|
|
|
|
if (_avatarLoadRoutine != null)
|
|
{
|
|
StopCoroutine(_avatarLoadRoutine);
|
|
}
|
|
_avatarLoadRoutine = StartCoroutine(LoadAvatarRoutine(data));
|
|
}
|
|
|
|
private void HandleStarToggleChanged(bool isOn)
|
|
{
|
|
if (_bindingToggle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_starChanged?.Invoke(_steamId, isOn);
|
|
}
|
|
|
|
private void HandleOpenDetails()
|
|
{
|
|
_openDetails?.Invoke(_steamId);
|
|
}
|
|
|
|
private void HandleStartPrivateConversation()
|
|
{
|
|
_openPrivateConversation?.Invoke(_steamId);
|
|
}
|
|
|
|
private void ApplyOnlineVisualState(bool isOnline)
|
|
{
|
|
if (friendOffline_blackMask != null)
|
|
{
|
|
friendOffline_blackMask.gameObject.SetActive(!isOnline);
|
|
}
|
|
|
|
Material borderMaterial = isOnline ? _profileBorderMaterial : offline_material;
|
|
Material profileMaterial = isOnline ? _friendProfileMaterial : offline_material;
|
|
|
|
if (profileBorder != null)
|
|
{
|
|
profileBorder.material = borderMaterial;
|
|
}
|
|
|
|
if (friendProfile != null)
|
|
{
|
|
friendProfile.material = profileMaterial;
|
|
}
|
|
}
|
|
|
|
private IEnumerator LoadAvatarRoutine(FriendCardViewData data)
|
|
{
|
|
if (friendProfile == null || data == null)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
string resolvedAvatarUrl = NetworkManager.ResolveAvatarUrl(data.AvatarUrl, data.SteamId);
|
|
bool loaded = false;
|
|
|
|
if (NetworkManager.IsUsableAvatarUrl(resolvedAvatarUrl)
|
|
&& !resolvedAvatarUrl.StartsWith(NetworkManager.SteamAvatarUrlPrefix, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(resolvedAvatarUrl))
|
|
{
|
|
yield return request.SendWebRequest();
|
|
if (request.result == UnityWebRequest.Result.Success)
|
|
{
|
|
Texture2D texture = DownloadHandlerTexture.GetContent(request);
|
|
if (texture != null)
|
|
{
|
|
friendProfile.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
|
|
loaded = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!loaded)
|
|
{
|
|
yield return LoadSteamAvatarRoutine(data.SteamId);
|
|
}
|
|
|
|
_avatarLoadRoutine = null;
|
|
}
|
|
|
|
private IEnumerator LoadSteamAvatarRoutine(string steamId)
|
|
{
|
|
#if FRIEND_DISABLE_STEAMWORKS
|
|
yield break;
|
|
#else
|
|
if (!SteamManager.Initialized || string.IsNullOrWhiteSpace(steamId) || friendProfile == null || !ulong.TryParse(steamId, out ulong rawSteamId))
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
var targetSteamId = new CSteamID(rawSteamId);
|
|
SteamFriends.RequestUserInformation(targetSteamId, false);
|
|
|
|
const float timeout = 5f;
|
|
float deadline = Time.realtimeSinceStartup + timeout;
|
|
while (Time.realtimeSinceStartup < deadline)
|
|
{
|
|
int imageId = SteamFriends.GetLargeFriendAvatar(targetSteamId);
|
|
if (imageId <= 0)
|
|
{
|
|
imageId = SteamFriends.GetMediumFriendAvatar(targetSteamId);
|
|
}
|
|
|
|
if (imageId > 0 && SteamUtils.GetImageSize(imageId, out uint width, out uint height) && width > 0 && height > 0)
|
|
{
|
|
byte[] buffer = new byte[width * height * 4];
|
|
if (SteamUtils.GetImageRGBA(imageId, buffer, buffer.Length))
|
|
{
|
|
friendProfile.sprite = CreateFlippedSteamAvatarSprite(buffer, (int)width, (int)height);
|
|
yield break;
|
|
}
|
|
}
|
|
|
|
yield return new WaitForSecondsRealtime(0.25f);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private static Sprite CreateFlippedSteamAvatarSprite(byte[] rgbaBuffer, int width, int height)
|
|
{
|
|
Texture2D texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
|
|
texture.LoadRawTextureData(rgbaBuffer);
|
|
texture.Apply();
|
|
|
|
Texture2D flipped = new Texture2D(width, height, TextureFormat.RGBA32, false);
|
|
for (int y = 0; y < height; y++)
|
|
{
|
|
Color[] pixels = texture.GetPixels(0, y, width, 1);
|
|
flipped.SetPixels(0, height - 1 - y, width, 1, pixels);
|
|
}
|
|
flipped.Apply();
|
|
return Sprite.Create(flipped, new Rect(0, 0, width, height), new Vector2(0.5f, 0.5f));
|
|
}
|
|
}
|