775 lines
21 KiB
C#
775 lines
21 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using Steamworks;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
public class UI_Player : MonoBehaviour
|
|
{
|
|
private const string FirstLaunchDatePrefKey = "player.first_launch_date";
|
|
private const string SongResourcesPath = "song_songIndex";
|
|
private const string VersionLabel = "\u5185\u90e8\u6d4b\u8bd5v207b35";
|
|
private const string ChannelLabel = "Steam";
|
|
private const float MaxDisplayedRksForSlider = 100f;
|
|
private static readonly Color SteamOnlineColor = new Color32(20, 120, 45, 255);
|
|
|
|
[Header("prefab")]
|
|
public GameObject pInfoPrefab;
|
|
public Transform pInfoParent;
|
|
|
|
[Header("so")]
|
|
[SerializeField] private Player_SO pSO;
|
|
|
|
[Header("uData")]
|
|
public Image userProfileImage;
|
|
public Text userNameText;
|
|
public Text userIDText;
|
|
public Text user_registDate;
|
|
|
|
[Header("uSource")]
|
|
public Text userSource;
|
|
|
|
[Header("uRecord")]
|
|
public Text fcAmount;
|
|
public Text firstFCsong;
|
|
public Text totalPlayTime;
|
|
|
|
[Header("uLevel")]
|
|
[SerializeField] private userLevel_skills_SO userLevelConfig;
|
|
public Slider userLevelSlider;
|
|
public Text userCurrentLevelText;
|
|
public Text userNextLevelText;
|
|
public Text userCurrentExpText;
|
|
|
|
[Header("uRks")]
|
|
public Slider uRksSlider;
|
|
public Text uRksText;
|
|
|
|
[Header("buttons")]
|
|
public Button quitButton;
|
|
|
|
private readonly List<GameObject> spawnedInfoEntries = new List<GameObject>();
|
|
private Color defaultInfoColor = Color.black;
|
|
private Coroutine forceRefreshUiRoutine;
|
|
|
|
private void Start()
|
|
{
|
|
BindQuitButton();
|
|
PlayerRksService.OnRksChanged += HandleRksChanged;
|
|
PlayerExperienceLedger.EnsureInstance().OnExperienceChanged += HandlePlayerExperienceChanged;
|
|
StartCoroutine(InitializeAsync());
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
BindQuitButton();
|
|
DisableBlockingBackgroundRaycasts();
|
|
RefreshRksUi();
|
|
RefreshLevelUi();
|
|
RestartForceRefreshUiRoutine();
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
PlayerRksService.OnRksChanged -= HandleRksChanged;
|
|
if (PlayerExperienceLedger.Instance != null)
|
|
{
|
|
PlayerExperienceLedger.Instance.OnExperienceChanged -= HandlePlayerExperienceChanged;
|
|
}
|
|
if (forceRefreshUiRoutine != null)
|
|
{
|
|
StopCoroutine(forceRefreshUiRoutine);
|
|
forceRefreshUiRoutine = null;
|
|
}
|
|
if (quitButton != null)
|
|
{
|
|
quitButton.onClick.RemoveListener(ClosePanel);
|
|
}
|
|
}
|
|
|
|
private void BindQuitButton()
|
|
{
|
|
if (quitButton == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
quitButton.onClick.RemoveListener(ClosePanel);
|
|
quitButton.onClick.AddListener(ClosePanel);
|
|
}
|
|
|
|
private void DisableBlockingBackgroundRaycasts()
|
|
{
|
|
Image[] images = GetComponentsInChildren<Image>(true);
|
|
for (int i = 0; i < images.Length; i++)
|
|
{
|
|
Image image = images[i];
|
|
if (image == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string name = image.gameObject.name;
|
|
if (string.Equals(name, "btmImg (1)", StringComparison.OrdinalIgnoreCase)
|
|
|| string.Equals(name, "btmImg (2)", StringComparison.OrdinalIgnoreCase)
|
|
|| string.Equals(name, "btmImg", StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
image.raycastTarget = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void ClosePanel()
|
|
{
|
|
gameObject.SetActive(false);
|
|
}
|
|
|
|
private void RestartForceRefreshUiRoutine()
|
|
{
|
|
if (!isActiveAndEnabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (forceRefreshUiRoutine != null)
|
|
{
|
|
StopCoroutine(forceRefreshUiRoutine);
|
|
}
|
|
|
|
forceRefreshUiRoutine = StartCoroutine(ForceRefreshUiDeferred());
|
|
}
|
|
|
|
private IEnumerator ForceRefreshUiDeferred()
|
|
{
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
yield return null;
|
|
ForceRefreshUiLayoutNow();
|
|
}
|
|
|
|
forceRefreshUiRoutine = null;
|
|
}
|
|
|
|
private void ForceRefreshUiLayoutNow()
|
|
{
|
|
Canvas.ForceUpdateCanvases();
|
|
|
|
Transform current = transform;
|
|
int safety = 0;
|
|
while (current != null && safety++ < 12)
|
|
{
|
|
RectTransform rect = current as RectTransform;
|
|
if (rect != null)
|
|
{
|
|
LayoutRebuilder.ForceRebuildLayoutImmediate(rect);
|
|
}
|
|
|
|
current = current.parent;
|
|
}
|
|
|
|
Canvas.ForceUpdateCanvases();
|
|
}
|
|
|
|
private IEnumerator InitializeAsync()
|
|
{
|
|
StoreOwnershipLedger.EnsureInstance().InitializeIfNeeded();
|
|
StoreOwnershipLedger.EnsureInstance().ForceSyncMirrorFlags();
|
|
PlayerRksService.EnsureLoaded(pSO);
|
|
PlayerExperienceLedger.EnsureInstance().AttachPlayerData(pSO);
|
|
|
|
string registerDate = EnsureFirstLaunchDate();
|
|
UserInfoSnapshot snapshot = BuildUserInfoSnapshot(registerDate);
|
|
|
|
ApplyLegacyTextMirrors(snapshot);
|
|
RebuildInfoEntries(snapshot);
|
|
RefreshRksUi();
|
|
RefreshLevelUi();
|
|
|
|
yield return null;
|
|
yield return StartCoroutine(LoadSteamProfileAsync(snapshot.isSteamOnline));
|
|
}
|
|
|
|
private void HandleRksChanged(float _)
|
|
{
|
|
RefreshRksUi();
|
|
}
|
|
|
|
private void HandlePlayerExperienceChanged(int _)
|
|
{
|
|
RefreshLevelUi();
|
|
}
|
|
|
|
private void RefreshRksUi()
|
|
{
|
|
float currentRks = PlayerRksService.RefreshAndPersist(pSO);
|
|
|
|
if (uRksText != null)
|
|
{
|
|
uRksText.text = currentRks.ToString("F2");
|
|
}
|
|
|
|
if (uRksSlider != null)
|
|
{
|
|
uRksSlider.minValue = 0f;
|
|
uRksSlider.maxValue = MaxDisplayedRksForSlider;
|
|
uRksSlider.value = Mathf.Clamp(currentRks, 0f, MaxDisplayedRksForSlider);
|
|
}
|
|
}
|
|
|
|
private void RefreshLevelUi()
|
|
{
|
|
if (userLevelSlider == null
|
|
&& userCurrentLevelText == null
|
|
&& userNextLevelText == null
|
|
&& userCurrentExpText == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
userLevel_skills_SO levelConfig = ResolveUserLevelConfig();
|
|
LevelUiState state = BuildLevelUiState(levelConfig, GetCurrentPlayerExperience());
|
|
|
|
if (userCurrentLevelText != null)
|
|
{
|
|
userCurrentLevelText.text = state.currentLevelText;
|
|
}
|
|
|
|
if (userNextLevelText != null)
|
|
{
|
|
userNextLevelText.text = state.nextLevelText;
|
|
}
|
|
|
|
if (userCurrentExpText != null)
|
|
{
|
|
userCurrentExpText.text = state.expText;
|
|
}
|
|
|
|
if (userLevelSlider != null)
|
|
{
|
|
userLevelSlider.minValue = 0f;
|
|
userLevelSlider.maxValue = 1f;
|
|
userLevelSlider.value = state.progress01;
|
|
}
|
|
}
|
|
|
|
private int GetCurrentPlayerExperience()
|
|
{
|
|
if (Application.isPlaying)
|
|
{
|
|
return Mathf.Max(0, PlayerExperienceLedger.EnsureInstance().GetExperience());
|
|
}
|
|
|
|
return pSO != null ? Mathf.Max(0, pSO.player_currentEXP) : 0;
|
|
}
|
|
|
|
private userLevel_skills_SO ResolveUserLevelConfig()
|
|
{
|
|
if (userLevelConfig != null)
|
|
{
|
|
return userLevelConfig;
|
|
}
|
|
|
|
uLevel_skills[] skillPanels = Resources.FindObjectsOfTypeAll<uLevel_skills>();
|
|
for (int i = 0; i < skillPanels.Length; i++)
|
|
{
|
|
if (skillPanels[i] != null && skillPanels[i].ulsSO != null)
|
|
{
|
|
userLevelConfig = skillPanels[i].ulsSO;
|
|
return userLevelConfig;
|
|
}
|
|
}
|
|
|
|
userLevel_skills_SO[] loadedConfigs = Resources.FindObjectsOfTypeAll<userLevel_skills_SO>();
|
|
for (int i = 0; i < loadedConfigs.Length; i++)
|
|
{
|
|
if (loadedConfigs[i] != null)
|
|
{
|
|
userLevelConfig = loadedConfigs[i];
|
|
return userLevelConfig;
|
|
}
|
|
}
|
|
|
|
#if UNITY_EDITOR
|
|
if (userLevelConfig == null)
|
|
{
|
|
userLevelConfig = UnityEditor.AssetDatabase.LoadAssetAtPath<userLevel_skills_SO>(
|
|
"Assets/playerInfoDisplay/uls/ulsSO.asset");
|
|
}
|
|
#endif
|
|
|
|
return userLevelConfig;
|
|
}
|
|
|
|
private static LevelUiState BuildLevelUiState(userLevel_skills_SO config, int currentExp)
|
|
{
|
|
currentExp = Mathf.Max(0, currentExp);
|
|
|
|
if (config == null || config.skills == null || config.skills.Count == 0)
|
|
{
|
|
return new LevelUiState
|
|
{
|
|
currentLevelText = "0",
|
|
nextLevelText = string.Empty,
|
|
expText = "MAX",
|
|
progress01 = 1f
|
|
};
|
|
}
|
|
|
|
List<userLevel_skills_SO.UserLevelSkillEntry> validLevels = new List<userLevel_skills_SO.UserLevelSkillEntry>();
|
|
for (int i = 0; i < config.skills.Count; i++)
|
|
{
|
|
if (config.skills[i] != null)
|
|
{
|
|
validLevels.Add(config.skills[i]);
|
|
}
|
|
}
|
|
|
|
if (validLevels.Count == 0)
|
|
{
|
|
return new LevelUiState
|
|
{
|
|
currentLevelText = "0",
|
|
nextLevelText = string.Empty,
|
|
expText = "MAX",
|
|
progress01 = 1f
|
|
};
|
|
}
|
|
|
|
validLevels.Sort((left, right) =>
|
|
{
|
|
int expCompare = Mathf.Max(0, left.thisLevelNeedExps).CompareTo(Mathf.Max(0, right.thisLevelNeedExps));
|
|
if (expCompare != 0)
|
|
{
|
|
return expCompare;
|
|
}
|
|
|
|
return left.userLevel.CompareTo(right.userLevel);
|
|
});
|
|
|
|
int currentIndex = 0;
|
|
for (int i = 0; i < validLevels.Count; i++)
|
|
{
|
|
if (currentExp >= Mathf.Max(0, validLevels[i].thisLevelNeedExps))
|
|
{
|
|
currentIndex = i;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
userLevel_skills_SO.UserLevelSkillEntry currentLevel = validLevels[currentIndex];
|
|
bool isMaxLevel = currentIndex >= validLevels.Count - 1;
|
|
int nextRequiredExp = isMaxLevel
|
|
? Mathf.Max(0, currentLevel.thisLevelNeedExps)
|
|
: Mathf.Max(0, validLevels[currentIndex + 1].thisLevelNeedExps);
|
|
|
|
float progress = isMaxLevel || nextRequiredExp <= 0
|
|
? 1f
|
|
: Mathf.Clamp01((float)currentExp / nextRequiredExp);
|
|
|
|
return new LevelUiState
|
|
{
|
|
currentLevelText = Mathf.Max(0, currentLevel.userLevel).ToString(),
|
|
nextLevelText = isMaxLevel ? string.Empty : Mathf.Max(0, validLevels[currentIndex + 1].userLevel).ToString(),
|
|
expText = isMaxLevel ? "MAX" : $"{currentExp}/{nextRequiredExp}",
|
|
progress01 = progress
|
|
};
|
|
}
|
|
|
|
private string EnsureFirstLaunchDate()
|
|
{
|
|
string playerPrefsDate = PlayerPrefs.GetString(FirstLaunchDatePrefKey, string.Empty);
|
|
string finalDate = !string.IsNullOrWhiteSpace(playerPrefsDate)
|
|
? playerPrefsDate
|
|
: DateTime.Now.ToString("yyyy-MM-dd");
|
|
|
|
if (playerPrefsDate != finalDate)
|
|
{
|
|
PlayerPrefs.SetString(FirstLaunchDatePrefKey, finalDate);
|
|
PlayerPrefs.Save();
|
|
}
|
|
|
|
if (pSO != null && pSO.firstLaunchDate != finalDate)
|
|
{
|
|
pSO.firstLaunchDate = finalDate;
|
|
#if UNITY_EDITOR
|
|
if (!Application.isPlaying)
|
|
{
|
|
UnityEditor.EditorUtility.SetDirty(pSO);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
return finalDate;
|
|
}
|
|
|
|
private UserInfoSnapshot BuildUserInfoSnapshot(string registerDate)
|
|
{
|
|
SongStats songStats = CollectSongStats();
|
|
return new UserInfoSnapshot
|
|
{
|
|
registerDate = registerDate,
|
|
ownedHeroCount = CountOwnedHeroes(),
|
|
ownedSongCount = songStats.ownedSongCount,
|
|
totalGameEnterCount = songStats.totalGameEnterCount,
|
|
totalPlaySeconds = songStats.totalPlaySeconds,
|
|
isSteamOnline = IsSteamOnline()
|
|
};
|
|
}
|
|
|
|
private void ApplyLegacyTextMirrors(UserInfoSnapshot snapshot)
|
|
{
|
|
if (user_registDate != null)
|
|
{
|
|
user_registDate.text = snapshot.registerDate;
|
|
}
|
|
|
|
if (userSource != null)
|
|
{
|
|
userSource.text = ChannelLabel;
|
|
userSource.color = snapshot.isSteamOnline ? SteamOnlineColor : Color.black;
|
|
}
|
|
|
|
if (totalPlayTime != null)
|
|
{
|
|
totalPlayTime.text = FormatPlayTime(snapshot.totalPlaySeconds);
|
|
}
|
|
|
|
if (fcAmount != null && string.IsNullOrWhiteSpace(fcAmount.text))
|
|
{
|
|
fcAmount.text = "-";
|
|
}
|
|
|
|
if (firstFCsong != null && string.IsNullOrWhiteSpace(firstFCsong.text))
|
|
{
|
|
firstFCsong.text = "-";
|
|
}
|
|
}
|
|
|
|
private void RebuildInfoEntries(UserInfoSnapshot snapshot)
|
|
{
|
|
ClearInfoEntries();
|
|
CacheDefaultInfoColor();
|
|
|
|
SpawnInfoEntry("\u6ce8\u518c\u65e5\u671f", snapshot.registerDate);
|
|
SpawnInfoEntry("\u62e5\u6709\u89d2\u8272\u6570\u91cf", snapshot.ownedHeroCount.ToString());
|
|
SpawnInfoEntry("\u62e5\u6709\u6b4c\u66f2\u6570\u91cf", snapshot.ownedSongCount.ToString());
|
|
SpawnInfoEntry("\u603b\u6e38\u620f\u6b21\u6570", snapshot.totalGameEnterCount.ToString());
|
|
SpawnInfoEntry("\u6e38\u73a9\u603b\u65f6\u957f", FormatPlayTime(snapshot.totalPlaySeconds));
|
|
SpawnInfoEntry("\u6e20\u9053", ChannelLabel, snapshot.isSteamOnline ? SteamOnlineColor : defaultInfoColor);
|
|
SpawnInfoEntry("\u7248\u672c", VersionLabel);
|
|
}
|
|
|
|
private void ClearInfoEntries()
|
|
{
|
|
for (int i = 0; i < spawnedInfoEntries.Count; i++)
|
|
{
|
|
if (spawnedInfoEntries[i] != null)
|
|
{
|
|
Destroy(spawnedInfoEntries[i]);
|
|
}
|
|
}
|
|
|
|
spawnedInfoEntries.Clear();
|
|
}
|
|
|
|
private void CacheDefaultInfoColor()
|
|
{
|
|
if (pInfoPrefab == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pInfoPrefab sample = pInfoPrefab.GetComponent<pInfoPrefab>();
|
|
if (sample != null && sample.this_iDetail != null)
|
|
{
|
|
defaultInfoColor = sample.this_iDetail.color;
|
|
}
|
|
}
|
|
|
|
private void SpawnInfoEntry(string title, string detail, Color? detailColor = null)
|
|
{
|
|
if (pInfoPrefab == null || pInfoParent == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GameObject entryObject = Instantiate(pInfoPrefab, pInfoParent);
|
|
spawnedInfoEntries.Add(entryObject);
|
|
|
|
pInfoPrefab entry = entryObject.GetComponent<pInfoPrefab>();
|
|
if (entry == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (entry.this_iTitle != null)
|
|
{
|
|
entry.this_iTitle.text = title;
|
|
}
|
|
|
|
if (entry.this_iDetail != null)
|
|
{
|
|
entry.this_iDetail.text = detail;
|
|
entry.this_iDetail.color = detailColor ?? defaultInfoColor;
|
|
}
|
|
}
|
|
|
|
private static int CountOwnedHeroes()
|
|
{
|
|
AllyHero_SO[] loadedHeroes = RuntimeResourcesCache.LoadAllAllyHeroes();
|
|
HashSet<int> uniqueHeroIds = new HashSet<int>();
|
|
int ownedCount = 0;
|
|
|
|
AllyHeroDeployLedger ledger = AllyHeroDeployLedger.EnsureInstance();
|
|
ledger.InitializeIfNeeded();
|
|
|
|
for (int i = 0; i < loadedHeroes.Length; i++)
|
|
{
|
|
AllyHero_SO hero = loadedHeroes[i];
|
|
if (hero == null || !uniqueHeroIds.Add(hero.ally_heroID))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
hero.ally_battleDeployCount = ledger.GetDeployCount(hero.ally_heroID);
|
|
if (hero.isUnlocked)
|
|
{
|
|
ownedCount++;
|
|
}
|
|
}
|
|
|
|
return ownedCount;
|
|
}
|
|
|
|
private static SongStats CollectSongStats()
|
|
{
|
|
SongData[] songs = RuntimeResourcesCache.LoadSongsFromPath(SongResourcesPath);
|
|
HashSet<int> uniqueSongIds = new HashSet<int>();
|
|
SongStats stats = new SongStats();
|
|
|
|
for (int i = 0; i < songs.Length; i++)
|
|
{
|
|
SongData song = songs[i];
|
|
if (song == null || !uniqueSongIds.Add(song.songID))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
song.EnsurePersistentDataLoaded();
|
|
|
|
if (song.isUnlocked)
|
|
{
|
|
stats.ownedSongCount++;
|
|
}
|
|
|
|
stats.totalGameEnterCount += Mathf.Max(0, song.game_enterTimes);
|
|
stats.totalPlaySeconds += Math.Max(0f, song.time_totalPlayingTime);
|
|
}
|
|
|
|
return stats;
|
|
}
|
|
|
|
private static string FormatPlayTime(double totalSeconds)
|
|
{
|
|
TimeSpan span = TimeSpan.FromSeconds(Math.Max(0d, totalSeconds));
|
|
if (span.TotalHours >= 1d)
|
|
{
|
|
return string.Format("{0:D2}\u5c0f\u65f6{1:D2}\u5206\u949f", (int)span.TotalHours, span.Minutes);
|
|
}
|
|
|
|
if (span.TotalMinutes >= 1d)
|
|
{
|
|
return string.Format("{0:D2}\u5206\u949f{1:D2}\u79d2", (int)span.TotalMinutes, span.Seconds);
|
|
}
|
|
|
|
return string.Format("{0:D2}\u79d2", Math.Max(0, span.Seconds));
|
|
}
|
|
|
|
private IEnumerator LoadSteamProfileAsync(bool isSteamOnline)
|
|
{
|
|
int initRetry = 0;
|
|
while (initRetry < 25 && !SteamManager.Initialized)
|
|
{
|
|
initRetry++;
|
|
yield return new WaitForSecondsRealtime(0.2f);
|
|
}
|
|
|
|
if (!SteamManager.Initialized)
|
|
{
|
|
ApplySteamUnavailable();
|
|
yield break;
|
|
}
|
|
|
|
int retryCount = 0;
|
|
while (retryCount < 20)
|
|
{
|
|
if (TryPopulateSteamProfile(isSteamOnline))
|
|
{
|
|
yield break;
|
|
}
|
|
|
|
retryCount++;
|
|
yield return new WaitForSecondsRealtime(0.25f);
|
|
}
|
|
|
|
ApplySteamUnavailable();
|
|
}
|
|
|
|
private void ApplySteamUnavailable()
|
|
{
|
|
if (userNameText != null)
|
|
{
|
|
userNameText.text = "Steam Unavailable";
|
|
}
|
|
|
|
if (userIDText != null)
|
|
{
|
|
userIDText.text = "-";
|
|
}
|
|
|
|
if (userSource != null)
|
|
{
|
|
userSource.text = ChannelLabel;
|
|
userSource.color = Color.black;
|
|
}
|
|
}
|
|
|
|
private static bool IsSteamOnline()
|
|
{
|
|
if (!SteamManager.Initialized)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
return SteamFriends.GetPersonaState() != EPersonaState.k_EPersonaStateOffline;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private bool TryPopulateSteamProfile(bool isSteamOnline)
|
|
{
|
|
try
|
|
{
|
|
CSteamID steamId = SteamUser.GetSteamID();
|
|
string personaName = SteamFriends.GetPersonaName();
|
|
|
|
if (!steamId.IsValid() || string.IsNullOrWhiteSpace(personaName))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (userNameText != null)
|
|
{
|
|
userNameText.text = personaName;
|
|
}
|
|
|
|
if (userIDText != null)
|
|
{
|
|
userIDText.text = steamId.m_SteamID.ToString();
|
|
}
|
|
|
|
if (userSource != null)
|
|
{
|
|
userSource.text = ChannelLabel;
|
|
userSource.color = isSteamOnline ? SteamOnlineColor : Color.black;
|
|
}
|
|
|
|
return TryApplySteamAvatar(steamId) || userProfileImage == null;
|
|
}
|
|
catch
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private bool TryApplySteamAvatar(CSteamID steamId)
|
|
{
|
|
if (userProfileImage == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
int imageId = SteamFriends.GetLargeFriendAvatar(steamId);
|
|
if (imageId == -1)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (imageId == 0)
|
|
{
|
|
imageId = SteamFriends.GetMediumFriendAvatar(steamId);
|
|
}
|
|
|
|
if (imageId < 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
uint width;
|
|
uint height;
|
|
if (!SteamUtils.GetImageSize(imageId, out width, out height) || width == 0 || height == 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
byte[] imageBuffer = new byte[width * height * 4];
|
|
if (!SteamUtils.GetImageRGBA(imageId, imageBuffer, imageBuffer.Length))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Texture2D sourceTexture = new Texture2D((int)width, (int)height, TextureFormat.RGBA32, false);
|
|
sourceTexture.LoadRawTextureData(imageBuffer);
|
|
sourceTexture.Apply();
|
|
|
|
Texture2D flippedTexture = new Texture2D((int)width, (int)height, TextureFormat.RGBA32, false);
|
|
for (int y = 0; y < (int)height; y++)
|
|
{
|
|
Color[] rowPixels = sourceTexture.GetPixels(0, y, (int)width, 1);
|
|
flippedTexture.SetPixels(0, (int)height - 1 - y, (int)width, 1, rowPixels);
|
|
}
|
|
|
|
flippedTexture.Apply();
|
|
userProfileImage.sprite = Sprite.Create(
|
|
flippedTexture,
|
|
new Rect(0, 0, flippedTexture.width, flippedTexture.height),
|
|
new Vector2(0.5f, 0.5f));
|
|
|
|
return true;
|
|
}
|
|
|
|
private struct UserInfoSnapshot
|
|
{
|
|
public string registerDate;
|
|
public int ownedHeroCount;
|
|
public int ownedSongCount;
|
|
public int totalGameEnterCount;
|
|
public double totalPlaySeconds;
|
|
public bool isSteamOnline;
|
|
}
|
|
|
|
private struct SongStats
|
|
{
|
|
public int ownedSongCount;
|
|
public int totalGameEnterCount;
|
|
public double totalPlaySeconds;
|
|
}
|
|
|
|
private struct LevelUiState
|
|
{
|
|
public string currentLevelText;
|
|
public string nextLevelText;
|
|
public string expText;
|
|
public float progress01;
|
|
}
|
|
}
|