284 lines
8.1 KiB
C#
284 lines
8.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
#if UNITY_EDITOR
|
|
using UnityEditor;
|
|
#endif
|
|
|
|
public static class SongDlcContentResolver
|
|
{
|
|
private const string RuntimeResourcesFolder = "so/songDlcContents";
|
|
private const string EditorSearchFolder = "Assets/Resources/so/songDlcContents";
|
|
|
|
private static SongDlcContentSO[] cachedAllContents;
|
|
private static readonly Dictionary<int, List<SongDlcContentSO>> CachedBySongId = new Dictionary<int, List<SongDlcContentSO>>();
|
|
|
|
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
|
|
private static void ResetStaticState()
|
|
{
|
|
cachedAllContents = null;
|
|
CachedBySongId.Clear();
|
|
}
|
|
|
|
public static void InvalidateCache()
|
|
{
|
|
cachedAllContents = null;
|
|
CachedBySongId.Clear();
|
|
}
|
|
|
|
public static SongDlcContentSO GetContent(SongData song)
|
|
{
|
|
if (song == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
EnsureCacheBuilt();
|
|
if (!CachedBySongId.TryGetValue(song.songID, out List<SongDlcContentSO> list) || list == null || list.Count == 0)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
string preferredDlcKey = song.belongsTo_whichDLC ?? string.Empty;
|
|
for (int i = 0; i < list.Count; i++)
|
|
{
|
|
SongDlcContentSO item = list[i];
|
|
if (item == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (IsMatchingDlc(item, preferredDlcKey))
|
|
{
|
|
return item;
|
|
}
|
|
}
|
|
|
|
return list[0];
|
|
}
|
|
|
|
public static TextAsset GetChartFile(SongData song, int difficulty)
|
|
{
|
|
SongDlcContentSO content = GetContent(song);
|
|
if (content == null || content.chartOverrides == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
for (int i = 0; i < content.chartOverrides.Count; i++)
|
|
{
|
|
SongDlcChartOverrideEntry entry = content.chartOverrides[i];
|
|
if (entry == null || entry.difficulty != difficulty || entry.chartFile == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
return entry.chartFile;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public static AudioClip GetSettlementMusic(SongData song)
|
|
{
|
|
SongDlcContentSO content = GetContent(song);
|
|
if (content != null && content.settlementMusic != null)
|
|
{
|
|
return content.settlementMusic;
|
|
}
|
|
|
|
dlcData owningDlc = GetOwningDlc(song);
|
|
return owningDlc != null ? owningDlc.settlementMusic : null;
|
|
}
|
|
|
|
public static dlcData GetOwningDlc(SongData song)
|
|
{
|
|
if (song == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
SongDlcContentSO content = GetContent(song);
|
|
if (content != null && content.ownerDlc != null)
|
|
{
|
|
return content.ownerDlc;
|
|
}
|
|
|
|
dlcData[] allDlcs = RuntimeResourcesCache.LoadAllDlcs();
|
|
string preferredDlcKey = song.belongsTo_whichDLC ?? string.Empty;
|
|
dlcData fallback = null;
|
|
|
|
for (int i = 0; i < allDlcs.Length; i++)
|
|
{
|
|
dlcData dlc = allDlcs[i];
|
|
if (dlc == null)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (dlc.songList != null && dlc.songList.Contains(song))
|
|
{
|
|
if (IsMatchingDlc(dlc, preferredDlcKey))
|
|
{
|
|
return dlc;
|
|
}
|
|
|
|
fallback = fallback ?? dlc;
|
|
}
|
|
}
|
|
|
|
return fallback;
|
|
}
|
|
|
|
public static SongDlcContentSO[] LoadAllSongDlcContents()
|
|
{
|
|
EnsureCacheBuilt();
|
|
return cachedAllContents ?? Array.Empty<SongDlcContentSO>();
|
|
}
|
|
|
|
private static bool IsMatchingDlc(SongDlcContentSO content, string preferredDlcKey)
|
|
{
|
|
if (content == null)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(preferredDlcKey))
|
|
{
|
|
if (!string.IsNullOrWhiteSpace(content.sourceDlcId) &&
|
|
string.Equals(content.sourceDlcId.Trim(), preferredDlcKey.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (content.ownerDlc != null)
|
|
{
|
|
if (string.Equals(content.ownerDlc.dlcName ?? string.Empty, preferredDlcKey.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (string.Equals(content.ownerDlc.dlcID.ToString(), preferredDlcKey.Trim(), StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static bool IsMatchingDlc(dlcData dlc, string preferredDlcKey)
|
|
{
|
|
if (dlc == null || string.IsNullOrWhiteSpace(preferredDlcKey))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
string safeKey = preferredDlcKey.Trim();
|
|
return string.Equals(dlc.dlcName ?? string.Empty, safeKey, StringComparison.OrdinalIgnoreCase)
|
|
|| string.Equals(dlc.dlcID.ToString(), safeKey, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
private static void EnsureCacheBuilt()
|
|
{
|
|
if (cachedAllContents != null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
cachedAllContents = LoadAllContentsInternal();
|
|
CachedBySongId.Clear();
|
|
|
|
for (int i = 0; i < cachedAllContents.Length; i++)
|
|
{
|
|
SongDlcContentSO content = cachedAllContents[i];
|
|
if (content == null || content.songId <= 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!CachedBySongId.TryGetValue(content.songId, out List<SongDlcContentSO> list) || list == null)
|
|
{
|
|
list = new List<SongDlcContentSO>();
|
|
CachedBySongId[content.songId] = list;
|
|
}
|
|
|
|
list.Add(content);
|
|
}
|
|
|
|
foreach (KeyValuePair<int, List<SongDlcContentSO>> pair in CachedBySongId)
|
|
{
|
|
pair.Value.Sort(CompareContent);
|
|
}
|
|
}
|
|
|
|
private static int CompareContent(SongDlcContentSO left, SongDlcContentSO right)
|
|
{
|
|
if (ReferenceEquals(left, right))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (left == null)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (right == null)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
int ownerCompare = string.CompareOrdinal(left.sourceDlcId ?? string.Empty, right.sourceDlcId ?? string.Empty);
|
|
if (ownerCompare != 0)
|
|
{
|
|
return ownerCompare;
|
|
}
|
|
|
|
return string.CompareOrdinal(left.GetResolvedContentId(), right.GetResolvedContentId());
|
|
}
|
|
|
|
private static SongDlcContentSO[] LoadAllContentsInternal()
|
|
{
|
|
#if UNITY_EDITOR
|
|
if (!Application.isPlaying)
|
|
{
|
|
string[] searchFolders = { EditorSearchFolder };
|
|
string[] guids = AssetDatabase.FindAssets("t:SongDlcContentSO", searchFolders);
|
|
if (guids != null && guids.Length > 0)
|
|
{
|
|
List<SongDlcContentSO> result = new List<SongDlcContentSO>(guids.Length);
|
|
for (int i = 0; i < guids.Length; i++)
|
|
{
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
|
|
SongDlcContentSO content = AssetDatabase.LoadAssetAtPath<SongDlcContentSO>(assetPath);
|
|
if (content != null)
|
|
{
|
|
result.Add(content);
|
|
}
|
|
}
|
|
|
|
return result.ToArray();
|
|
}
|
|
|
|
string[] fallbackGuids = AssetDatabase.FindAssets("t:SongDlcContentSO");
|
|
List<SongDlcContentSO> fallback = new List<SongDlcContentSO>(fallbackGuids.Length);
|
|
for (int i = 0; i < fallbackGuids.Length; i++)
|
|
{
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(fallbackGuids[i]);
|
|
SongDlcContentSO content = AssetDatabase.LoadAssetAtPath<SongDlcContentSO>(assetPath);
|
|
if (content != null)
|
|
{
|
|
fallback.Add(content);
|
|
}
|
|
}
|
|
|
|
return fallback.ToArray();
|
|
}
|
|
#endif
|
|
|
|
return RuntimeResourcesCache.LoadAllSongDlcContents() ?? Array.Empty<SongDlcContentSO>();
|
|
}
|
|
}
|