Files
2026-06-30 21:21:30 +08:00

233 lines
6.6 KiB
C#

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<dlcData>();
public SongData[] songs = Array.Empty<SongData>();
public SongDlcContentSO[] songContents = Array.Empty<SongDlcContentSO>();
public HeroSkinSO[] heroSkins = Array.Empty<HeroSkinSO>();
public AllyHero_SO[] heroes = Array.Empty<AllyHero_SO>();
}
public static class DlcRuntimeRegistry
{
private static readonly List<DlcRuntimePackage> Packages = new List<DlcRuntimePackage>();
private static readonly Dictionary<string, dlcData> DlcsByKey =
new Dictionary<string, dlcData>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<int, SongData> SongsById =
new Dictionary<int, SongData>();
private static readonly Dictionary<string, SongDlcContentSO> SongContentsById =
new Dictionary<string, SongDlcContentSO>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<string, HeroSkinSO> HeroSkinsById =
new Dictionary<string, HeroSkinSO>(StringComparer.OrdinalIgnoreCase);
private static readonly Dictionary<int, AllyHero_SO> HeroesById =
new Dictionary<int, AllyHero_SO>();
private static dlcData[] cachedDlcs = Array.Empty<dlcData>();
private static SongData[] cachedSongs = Array.Empty<SongData>();
private static SongDlcContentSO[] cachedSongContents = Array.Empty<SongDlcContentSO>();
private static HeroSkinSO[] cachedHeroSkins = Array.Empty<HeroSkinSO>();
private static AllyHero_SO[] cachedHeroes = Array.Empty<AllyHero_SO>();
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<DlcRuntimePackage> 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<DlcRuntimePackage> 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<dlcData>();
cachedSongs = Array.Empty<SongData>();
cachedSongContents = Array.Empty<SongDlcContentSO>();
cachedHeroSkins = Array.Empty<HeroSkinSO>();
cachedHeroes = Array.Empty<AllyHero_SO>();
}
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);
}
}