Files
bansonic_beta_main/Assets/scripts/friendSystem/friendRequestPrefab.cs
T

217 lines
6.8 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)
#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<Task> onAccept, Func<Task> 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<Task> 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));
}
}