222 lines
7.2 KiB
C#
222 lines
7.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Threading.Tasks;
|
|
using GameServer.Client;
|
|
using UnityEngine;
|
|
using UnityEngine.Networking;
|
|
using UnityEngine.UI;
|
|
|
|
#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX
|
|
using Steamworks;
|
|
#endif
|
|
|
|
public class friendSearchPrefab : MonoBehaviour
|
|
{
|
|
[SerializeField] private Image profileImage;
|
|
[SerializeField] private Text friendName;
|
|
[SerializeField] private Text friendSourceInfomation;
|
|
[SerializeField] private Button addFriendButton;
|
|
[SerializeField] private Text addFriendButtonText;
|
|
|
|
private Coroutine _avatarLoadRoutine;
|
|
private Coroutine _buttonCooldownRoutine;
|
|
private string _defaultAddButtonText;
|
|
|
|
private void Awake()
|
|
{
|
|
Text buttonText = ResolveAddButtonText();
|
|
_defaultAddButtonText = buttonText != null ? buttonText.text : string.Empty;
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (_avatarLoadRoutine != null)
|
|
{
|
|
StopCoroutine(_avatarLoadRoutine);
|
|
_avatarLoadRoutine = null;
|
|
}
|
|
|
|
if (_buttonCooldownRoutine != null)
|
|
{
|
|
StopCoroutine(_buttonCooldownRoutine);
|
|
_buttonCooldownRoutine = null;
|
|
}
|
|
}
|
|
|
|
public void Bind(ProfileData profile, bool canAdd, string disabledButtonText, Func<Task> onAddClicked, float cooldownSeconds)
|
|
{
|
|
if (friendName != null)
|
|
{
|
|
friendName.text = profile != null
|
|
? NetworkManager.ResolveDisplayName(profile.display_name, profile.steam_id, false)
|
|
: string.Empty;
|
|
}
|
|
|
|
if (addFriendButton != null)
|
|
{
|
|
addFriendButton.onClick.RemoveAllListeners();
|
|
addFriendButton.interactable = canAdd;
|
|
Text buttonText = ResolveAddButtonText();
|
|
if (buttonText != null)
|
|
{
|
|
buttonText.text = !canAdd && !string.IsNullOrWhiteSpace(disabledButtonText)
|
|
? disabledButtonText
|
|
: _defaultAddButtonText;
|
|
}
|
|
if (canAdd && onAddClicked != null)
|
|
{
|
|
addFriendButton.onClick.AddListener(() =>
|
|
{
|
|
if (_buttonCooldownRoutine != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
_ = HandleAddClickedAsync(onAddClicked, cooldownSeconds);
|
|
});
|
|
}
|
|
}
|
|
|
|
if (_avatarLoadRoutine != null)
|
|
{
|
|
StopCoroutine(_avatarLoadRoutine);
|
|
}
|
|
|
|
if (profileImage != null && profile != null)
|
|
{
|
|
profileImage.sprite = null;
|
|
string avatarUrl = NetworkManager.ResolveAvatarUrl(profile.avatar_url, profile.steam_id);
|
|
_avatarLoadRoutine = StartCoroutine(LoadAvatarRoutine(profile.steam_id, avatarUrl));
|
|
}
|
|
}
|
|
|
|
private async Task HandleAddClickedAsync(Func<Task> onAddClicked, float cooldownSeconds)
|
|
{
|
|
if (addFriendButton != null)
|
|
{
|
|
addFriendButton.interactable = false;
|
|
}
|
|
|
|
_buttonCooldownRoutine = StartCoroutine(ButtonCooldownRoutine(cooldownSeconds));
|
|
await onAddClicked();
|
|
}
|
|
|
|
private IEnumerator ButtonCooldownRoutine(float cooldownSeconds)
|
|
{
|
|
yield return new WaitForSecondsRealtime(cooldownSeconds);
|
|
if (addFriendButton != null)
|
|
{
|
|
addFriendButton.interactable = true;
|
|
}
|
|
|
|
_buttonCooldownRoutine = null;
|
|
}
|
|
|
|
private IEnumerator LoadAvatarRoutine(string steamId, string avatarUrl)
|
|
{
|
|
if (profileImage == null)
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
bool loaded = false;
|
|
if (playerMessagePrefab.TryGetCachedAvatarSprite(steamId, avatarUrl, out Sprite cachedSprite) && cachedSprite != null)
|
|
{
|
|
profileImage.sprite = cachedSprite;
|
|
loaded = true;
|
|
}
|
|
|
|
if (!loaded
|
|
&& NetworkManager.IsUsableAvatarUrl(avatarUrl)
|
|
&& !avatarUrl.StartsWith(NetworkManager.SteamAvatarUrlPrefix, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(avatarUrl))
|
|
{
|
|
yield return request.SendWebRequest();
|
|
if (request.result == UnityWebRequest.Result.Success)
|
|
{
|
|
Texture2D texture = DownloadHandlerTexture.GetContent(request);
|
|
if (texture != null)
|
|
{
|
|
profileImage.sprite = Sprite.Create(
|
|
texture,
|
|
new Rect(0f, 0f, texture.width, texture.height),
|
|
new Vector2(0.5f, 0.5f));
|
|
loaded = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!loaded)
|
|
{
|
|
yield return LoadSteamAvatarRoutine(steamId);
|
|
}
|
|
|
|
_avatarLoadRoutine = null;
|
|
}
|
|
|
|
private IEnumerator LoadSteamAvatarRoutine(string steamId)
|
|
{
|
|
#if !(UNITY_STANDALONE_WIN || UNITY_STANDALONE_LINUX || UNITY_STANDALONE_OSX || STEAMWORKS_WIN || STEAMWORKS_LIN_OSX)
|
|
yield break;
|
|
#else
|
|
if (!SteamManager.Initialized || string.IsNullOrWhiteSpace(steamId) || profileImage == null || !ulong.TryParse(steamId, out ulong rawSteamId))
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
CSteamID targetSteamId = new CSteamID(rawSteamId);
|
|
SteamFriends.RequestUserInformation(targetSteamId, false);
|
|
|
|
float deadline = Time.realtimeSinceStartup + 5f;
|
|
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))
|
|
{
|
|
profileImage.sprite = CreateFlippedSteamAvatarSprite(buffer, (int)width, (int)height);
|
|
yield break;
|
|
}
|
|
}
|
|
|
|
yield return new WaitForSecondsRealtime(0.25f);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private Text ResolveAddButtonText()
|
|
{
|
|
if (addFriendButtonText != null)
|
|
{
|
|
return addFriendButtonText;
|
|
}
|
|
|
|
return addFriendButton != null ? addFriendButton.GetComponentInChildren<Text>(true) : null;
|
|
}
|
|
|
|
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));
|
|
}
|
|
}
|