340 lines
11 KiB
C#
340 lines
11 KiB
C#
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);
|
|
}
|
|
}
|