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) #define FRIEND_DISABLE_STEAMWORKS #endif #if !FRIEND_DISABLE_STEAMWORKS using Steamworks; #endif public class friendRequestPrefab : MonoBehaviour { [SerializeField] private Image profileImage; [SerializeField] private Text friendName; [SerializeField] private Text friendSourceInfomation; [SerializeField] private Button acceptButton; [SerializeField] private Button rejectButton; private Coroutine _avatarLoadRoutine; private Coroutine _buttonCooldownRoutine; private void OnDestroy() { if (_avatarLoadRoutine != null) { StopCoroutine(_avatarLoadRoutine); _avatarLoadRoutine = null; } if (_buttonCooldownRoutine != null) { StopCoroutine(_buttonCooldownRoutine); _buttonCooldownRoutine = null; } } public void Bind(SocialFriendRequestEntry request, Func onAccept, Func onReject, float cooldownSeconds) { string steamId = request != null ? request.from_steam_id : string.Empty; if (friendName != null) { friendName.text = request != null ? NetworkManager.ResolveDisplayName(request.from_name, steamId, false) : string.Empty; } if (acceptButton != null) { acceptButton.onClick.RemoveAllListeners(); if (onAccept != null) { acceptButton.onClick.AddListener(() => { if (_buttonCooldownRoutine != null) { return; } _ = HandleDecisionClickedAsync(onAccept, cooldownSeconds); }); } } if (rejectButton != null) { rejectButton.onClick.RemoveAllListeners(); if (onReject != null) { rejectButton.onClick.AddListener(() => { if (_buttonCooldownRoutine != null) { return; } _ = HandleDecisionClickedAsync(onReject, cooldownSeconds); }); } } if (_avatarLoadRoutine != null) { StopCoroutine(_avatarLoadRoutine); } if (profileImage != null && request != null) { profileImage.sprite = null; string avatarUrl = NetworkManager.ResolveAvatarUrl(request.from_avatar, steamId); _avatarLoadRoutine = StartCoroutine(LoadAvatarRoutine(steamId, avatarUrl)); } } private async Task HandleDecisionClickedAsync(Func action, float cooldownSeconds) { SetDecisionButtonsInteractable(false); _buttonCooldownRoutine = StartCoroutine(ButtonCooldownRoutine(cooldownSeconds)); await action(); } private IEnumerator ButtonCooldownRoutine(float cooldownSeconds) { yield return new WaitForSecondsRealtime(cooldownSeconds); SetDecisionButtonsInteractable(true); _buttonCooldownRoutine = null; } private void SetDecisionButtonsInteractable(bool interactable) { if (acceptButton != null) { acceptButton.interactable = interactable; } if (rejectButton != null) { rejectButton.interactable = interactable; } } private IEnumerator LoadAvatarRoutine(string steamId, string avatarUrl) { if (profileImage == null) { yield break; } bool loaded = false; if (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 FRIEND_DISABLE_STEAMWORKS 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 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)); } }