using System; using System.Collections.Generic; using UnityEngine; public sealed class DlcRuntimePackage { public string packageId; public string dlcKey; public string version; public string sourceCatalogPath; public dlcData[] dlcs = Array.Empty(); public SongData[] songs = Array.Empty(); public SongDlcContentSO[] songContents = Array.Empty(); public HeroSkinSO[] heroSkins = Array.Empty(); public AllyHero_SO[] heroes = Array.Empty(); } public static class DlcRuntimeRegistry { private static readonly List Packages = new List(); private static readonly Dictionary DlcsByKey = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary SongsById = new Dictionary(); private static readonly Dictionary SongContentsById = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary HeroSkinsById = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly Dictionary HeroesById = new Dictionary(); private static dlcData[] cachedDlcs = Array.Empty(); private static SongData[] cachedSongs = Array.Empty(); private static SongDlcContentSO[] cachedSongContents = Array.Empty(); private static HeroSkinSO[] cachedHeroSkins = Array.Empty(); private static AllyHero_SO[] cachedHeroes = Array.Empty(); public static event Action RuntimeContentChanged; [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] private static void ResetState() { ClearSilently(); } public static bool HasRuntimeContent { get { return Packages.Count > 0; } } public static IReadOnlyList GetPackages() { return Packages; } public static dlcData[] GetAllDlcs() { return cachedDlcs; } public static SongData[] GetAllSongs() { return cachedSongs; } public static SongDlcContentSO[] GetAllSongContents() { return cachedSongContents; } public static HeroSkinSO[] GetAllHeroSkins() { return cachedHeroSkins; } public static AllyHero_SO[] GetAllHeroes() { return cachedHeroes; } public static void ReplaceAll(IList packages) { ClearSilently(); if (packages != null) { for (int i = 0; i < packages.Count; i++) { RegisterPackageInternal(packages[i]); } } RebuildSnapshots(); RuntimeContentChanged?.Invoke(); } public static void ClearAll() { ClearSilently(); RuntimeContentChanged?.Invoke(); } private static void ClearSilently() { Packages.Clear(); DlcsByKey.Clear(); SongsById.Clear(); SongContentsById.Clear(); HeroSkinsById.Clear(); HeroesById.Clear(); cachedDlcs = Array.Empty(); cachedSongs = Array.Empty(); cachedSongContents = Array.Empty(); cachedHeroSkins = Array.Empty(); cachedHeroes = Array.Empty(); } private static void RegisterPackageInternal(DlcRuntimePackage package) { if (package == null) { return; } Packages.Add(package); if (package.dlcs != null) { for (int i = 0; i < package.dlcs.Length; i++) { dlcData dlc = package.dlcs[i]; if (dlc == null) { continue; } string key = dlc.GetResolvedDlcKey(); if (string.IsNullOrWhiteSpace(key)) { continue; } DlcsByKey[key] = dlc; } } if (package.songs != null) { for (int i = 0; i < package.songs.Length; i++) { SongData song = package.songs[i]; if (song == null || song.songID <= 0) { continue; } SongsById[song.songID] = song; } } if (package.songContents != null) { for (int i = 0; i < package.songContents.Length; i++) { SongDlcContentSO content = package.songContents[i]; if (content == null) { continue; } string contentId = content.GetResolvedContentId(); if (string.IsNullOrWhiteSpace(contentId)) { continue; } SongContentsById[contentId] = content; } } if (package.heroSkins != null) { for (int i = 0; i < package.heroSkins.Length; i++) { HeroSkinSO skin = package.heroSkins[i]; if (skin == null) { continue; } string skinId = skin.GetResolvedSkinId(); if (string.IsNullOrWhiteSpace(skinId)) { continue; } HeroSkinsById[skinId] = skin; } } if (package.heroes != null) { for (int i = 0; i < package.heroes.Length; i++) { AllyHero_SO hero = package.heroes[i]; if (hero == null || hero.ally_heroID <= 0) { continue; } HeroesById[hero.ally_heroID] = hero; } } } private static void RebuildSnapshots() { cachedDlcs = new dlcData[DlcsByKey.Count]; DlcsByKey.Values.CopyTo(cachedDlcs, 0); cachedSongs = new SongData[SongsById.Count]; SongsById.Values.CopyTo(cachedSongs, 0); cachedSongContents = new SongDlcContentSO[SongContentsById.Count]; SongContentsById.Values.CopyTo(cachedSongContents, 0); cachedHeroSkins = new HeroSkinSO[HeroSkinsById.Count]; HeroSkinsById.Values.CopyTo(cachedHeroSkins, 0); cachedHeroes = new AllyHero_SO[HeroesById.Count]; HeroesById.Values.CopyTo(cachedHeroes, 0); } }