UniversalViewer/Assets/KF3/Scripts/KF3AssetLibrary.cs

340 lines
11 KiB
C#
Raw Normal View History

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using UnityEngine;
public class KF3AssetLibrary : AssetLibrary
{
public List<CharaData> CharaData = new List<CharaData>();
public List<KF3AssetBundle> AssetBundles = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Characters = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Animations = new List<KF3AssetBundle>();
public List<KF3AssetBundle> AnimationSets = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Ceruleans = new List<KF3AssetBundle>();
public Dictionary<string, List<KF3AssetBundle>> CeruleansD = new Dictionary<string, List<KF3AssetBundle>>();
public List<KF3AssetBundle> CeruleanAnimationSets = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Effects = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Furniture = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Icons = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Miracles = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Skies = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Stages = new List<KF3AssetBundle>();
public List<KF3AssetBundle> Misc = new List<KF3AssetBundle>();
public static KF3AssetLibrary Instance => GetInstance<KF3AssetLibrary>();
public IEnumerator Init()
{
_mainInstance = this;
string charaData = LoadGzipFile("CHARA_DATA");
if (charaData != "error")
{
Error.Log(Color.green, "Loaded Chara_Data from KF3 cache");
CharaData = JsonHelper.getJsonArray<CharaData>(charaData).ToList();
}
KF3Names.LoadCeruleanNames();
if (GetComponent<KF3ModelViewerMain>().IsOnline)
{
yield return GetAbList();
}
if (AssetBundles.Count <= 0)
{
Error.Log(Color.red, "Failed to load ab_list.txt");
}
yield break;
}
public string LoadGzipFile(string fileName)
{
string openFile = Path.Combine(Settings.CacheDirectory, "CHARA_DATA.d");
if (!File.Exists(openFile)) { Error.Log(Color.blue, "CHARA_DATA cache file not found, character names may be outdated"); return "error"; }
using (Stream decompress = new GZipStream(File.OpenRead(openFile), CompressionMode.Decompress))
using (StreamReader stringWriter = new StreamReader(decompress))
{
return stringWriter.ReadToEnd();
}
}
private IEnumerator GetAbList()
{
//LOAD GAME VERSION
Error.Log(Color.green, $"Game Version is {Settings.GameVersion}");
//LOAD ASSETS URL
Error.Log(Color.green, $"Assets server address is: {Settings.AssetsUrl}");
//LOAD AB_LIST
string filePath = Path.Combine(Settings.AssetListDirectory, "ab_list.txt");
if (File.Exists(filePath))
{
LoadText(File.ReadAllText(filePath));
Error.Log(Color.green, $"Loaded ab file from {filePath}");
}
else if (KF3ModelViewerMain.Instance.IsOnline)
{
WWW www = new WWW(Settings.AssetsUrl + "/Windows/1.0.0/ja/ab_list.txt");
yield return www;
string response = www.text;
if (!string.IsNullOrEmpty(response))
{
LoadText(response);
Error.Log(Color.green, $"ab file downloaded");
File.WriteAllText(filePath, response);
}
else
{
Error.Log(Color.red, $"Failed to load ab file");
}
}
else
{
Error.Log(Color.red, $"Failed to load ab file");
}
//Load loose assets
foreach(var fileName in Directory.GetFiles(Settings.LooseAssetsDirectory))
{
string name = Path.GetFullPath(fileName);
KF3AssetBundle bundle = new KF3AssetBundle(Path.GetFileName(name));
bundle.FullPath = name;
AddToCategory(bundle, bundle.DisplayName);
}
}
public KF3AssetBundle Find(string fileName)
{
return AssetBundles.FirstOrDefault(ab => ab.FileName == fileName);
}
public IEnumerator LoadAsset(KF3AssetBundle bundle, Action<AssetBundle> callback)
{
if(bundle == null)
{
callback?.Invoke(null);
yield break;
}
if (File.Exists(bundle.FullPath))
{
callback?.Invoke(AssetBundle.LoadFromFile(bundle.FullPath));
yield break;
}
else if (KF3ModelViewerMain.Instance.IsOnline)
{
AssetBundle assetBundle = null;
yield return DownloadAssetBundle(bundle, (ab) =>
{
assetBundle = ab;
});
if(assetBundle != null)
{
callback?.Invoke(assetBundle);
yield break;
}
else
{
callback?.Invoke(null);
yield break;
}
}
else
{
Error.Log(Color.yellow, $"{bundle.FileName} Does not exist");
callback?.Invoke(null);
}
}
public IEnumerator DownloadAssetBundle(KF3AssetBundle bundle, System.Action<AssetBundle> callback)
{
string saveTo = bundle.FullPath;
string url = Settings.AssetsUrl + "/Windows/1.0.0/ja/assets/" + bundle.FileName;
Error.Log($"Downloading\n{url}\nto\n{saveTo}", Color.blue);
WWW www = new WWW(url);
yield return www;
if (!string.IsNullOrEmpty(www.error))
{
Error.Log(Color.red, www.error);
www.Dispose();
callback(null);
yield break;
}
byte[] bytes = www.bytes;
Directory.CreateDirectory(Path.GetDirectoryName(saveTo));
File.WriteAllBytes(saveTo, bytes);
www.Dispose();
Error.Log(Color.green, $"Download Successful");
callback(AssetBundle.LoadFromFile(saveTo));
}
/// <summary>
/// Load AssetBundle list
/// </summary>
private void LoadText(string abListTxt)
{
int loaded = 0;
int total = 0;
using (StringReader reader = new StringReader(abListTxt))
{
while (reader.Peek() >= 0)
{
total++;
string line = reader.ReadLine();
if (string.IsNullOrEmpty(line))
{
continue;
}
loaded++;
string[] temp = line.Split(new string[] { " ", "\t" }, StringSplitOptions.RemoveEmptyEntries);
string bundleName = temp[0];
KF3AssetBundle bundle = new KF3AssetBundle(bundleName);
AddToCategory(bundle, bundleName);
}
}
Error.Log(Color.green, $"Loaded {loaded}/{total} AB lines");
}
private void AddToCategory(KF3AssetBundle bundle, string bundleName)
{
//add to global list
AssetBundles.Add(bundle);
//add to characters list
if (bundleName.StartsWith("ch_") && bundleName.EndsWith("_a.prefab"))
{
bundle.IdStr = bundleName.Split('_', '.')[1];
bundle.IdNum = int.Parse(bundle.IdStr);
if (bundle.IdNum < 10000)
{
Characters.Add(bundle);
}
else
{
bundle.DisplayName = KF3Names.GetEnemyName(bundle.IdNum);
Ceruleans.Add(bundle);
if (CeruleansD.ContainsKey(bundle.DisplayName))
{
CeruleansD[bundle.DisplayName].Add(bundle);
}
else
{
CeruleansD.Add(bundle.DisplayName, new List<KF3AssetBundle>() { bundle });
}
}
}
else if (bundleName.StartsWith("icon_"))
{
Icons.Add(bundle);
}
else if (bundleName.StartsWith("captainroom_"))
{
bundle.DisplayName = bundle.DisplayName.Replace("captainroom_obj_", "").Replace("_mdl.prefab", "");
Furniture.Add(bundle);
}
else if (bundleName.StartsWith("ch_") && bundleName.EndsWith("_mot.prefab"))
{
bundle.IdStr = bundleName.Split('_', '.')[1];
bundle.IdNum = int.Parse(bundle.IdStr);
Animations.Add(bundle);
if (bundleName.EndsWith("a_mot.prefab"))
{
if (bundle.IdNum < 10000)
{
bundle.DisplayName = bundle.IdStr + "_" + KF3Names.GetCharaName(bundle.IdNum);
AnimationSets.Add(bundle);
}
else
{
bundle.DisplayName = KF3Names.GetEnemyName(bundle.IdNum);
CeruleanAnimationSets.Add(bundle);
}
}
}
else if (bundleName.StartsWith("st_"))
{
Stages.Add(bundle);
}
else if (bundleName.StartsWith("sky_"))
{
Skies.Add(bundle);
}
else if (bundleName.StartsWith("ef_auth"))
{
bundle.DisplayName = bundleName.Replace("ef_auth", "");
Miracles.Add(bundle);
}
else if (bundleName.StartsWith("ef_"))
{
Effects.Add(bundle);
Misc.Add(bundle);
}
}
/// <summary>
/// Get a list of costumes from selected character id
/// </summary>
public List<KF3AssetBundle> GetCostumesFromId(int id)
{
if (id > 9999)
{
id = id / 10;
return AssetBundles.Where(k => k.FileName.StartsWith($"ch_{id.ToString().PadLeft(4, '0')}") && !k.FileName.Contains("mot") && k.FileName.Split(new char[] { '.', '_' }).Length == 4)
.ToList().ConvertAll(o=>(KF3AssetBundle)o);
}
else
{
return AssetBundles.Where(k => k.FileName.StartsWith($"ch_{id.ToString().PadLeft(4, '0')}") && !k.FileName.Contains("mot") && k.FileName.Split(new char[] { '.', '_' }).Length == 4)
.ToList().ConvertAll(o => (KF3AssetBundle)o);
}
}
public KF3AssetBundle GetAnimationSet(string name)
{
if(int.TryParse(name.Split('_','.')[1], out int id)){
return GetAnimationSet(id);
}
return (KF3AssetBundle)AnimationSets.FirstOrDefault(a => a.DisplayName == name || a.FileName == name);
}
public KF3AssetBundle GetAnimationSet(int id)
{
return (KF3AssetBundle)AnimationSets.FirstOrDefault(a => int.Parse(a.FileName.Split('_', '.')[1]) == id);
}
public List<KF3AssetBundle> GetMisc()
{
return Misc.ConvertAll(k=>(KF3AssetBundle)k);
}
public List<KF3AssetBundle> GetMiracles()
{
return Miracles.ConvertAll(k => (KF3AssetBundle)k);
}
public List<KF3AssetBundle> GetCeruleans(string name)
{
return CeruleansD[name];
}
public KF3AssetBundle GetFurnitureBundle(string bundleName)
{
return (KF3AssetBundle)Furniture.FirstOrDefault(a => a.DisplayName == bundleName || a.FileName == bundleName);
}
public KF3AssetBundle GetMiscBundle(string bundleName)
{
return (KF3AssetBundle)Misc.FirstOrDefault(a => a.DisplayName == bundleName || a.FileName == bundleName);
}
public KF3AssetBundle GetMiracleBundle(string bundleName)
{
return (KF3AssetBundle)Miracles.FirstOrDefault(a => a.DisplayName == bundleName || a.FileName == bundleName);
}
}