using UnityEngine; using System; using System.Collections.Generic; using Mono.Data.Sqlite; using System.Data; using Assets.Scripts; using System.IO; public class UmaDatabaseController { private static UmaDatabaseController instance; /// /// Database Loader instance /// public static UmaDatabaseController Instance { get { if (instance == null) { instance = new UmaDatabaseController(); } return instance; } } /// /// https://prd-storage-umamusume.akamaized.net/dl/resources/ /// public static string ServerUrl = "https://prd-storage-umamusume.akamaized.net/dl/resources/"; /// Android/assetbundles/ public static string AssetUrl = "Windows/assetbundles/"; /// 3d/chara/body/ public static string BodyPath = "3d/chara/body/"; /// 3d/chara/head/ public static string HeadPath = "3d/chara/head/"; /// 3d/motion/ public static string MotionPath = "3d/motion/"; /// 3d/chara/ public static string CharaPath = "3d/chara/"; /// 3d/effect/ public static string EffectPath = "3d/effect/"; /// outgame/dress/ public static string CostumePath = "outgame/dress/"; public Dictionary MetaEntries; public List CharaData; public List MobCharaData; public List FaceTypeData; public List LiveData; public List DressData; /// Meta Database Connection private SqliteConnection metaDb; /// Master Database Connection private SqliteConnection masterDb; /// Loads the file database public UmaDatabaseController() { try { if(Config.Instance.WorkMode == WorkMode.Standalone) { if(!File.Exists($@"{Config.Instance.MainPath}\meta_umaviewer")) throw new Exception(); metaDb = new SqliteConnection($@"Data Source={Config.Instance.MainPath}\meta_umaviewer;"); masterDb = new SqliteConnection($@"Data Source={Config.Instance.MainPath}\master\master_umaviewer.mdb;"); } else { if (!File.Exists($@"{Config.Instance.MainPath}\meta")) throw new Exception(); metaDb = new SqliteConnection($@"Data Source={Config.Instance.MainPath}\meta;"); masterDb = new SqliteConnection($@"Data Source={Config.Instance.MainPath}\master\master.mdb;"); } metaDb.Open(); MetaEntries = ReadMeta(metaDb); masterDb.Open(); CharaData = ReadCharaMaster(masterDb); MobCharaData = ReadMobCharaMaster(masterDb); FaceTypeData = ReadFaceTypeData(masterDb); LiveData = ReadAllLiveData(masterDb); DressData = ReadAllDressData(masterDb); } catch { CloseAllConnection(); var msg = $"Database not found at: {Config.Instance.MainPath}"; if(Config.Instance.WorkMode == WorkMode.Standalone) { msg += "\nPlease update the database in the settings panel"; } else { msg += "\nPlease install the dmm game client"; } UmaViewerUI.Instance.ShowMessage(msg, UIMessageType.Error); } } static Dictionary ReadMeta(SqliteConnection conn) { SqliteCommand sqlite_cmd = conn.CreateCommand(); sqlite_cmd.CommandText = "SELECT m,n,h,c,d FROM a"; SqliteDataReader sqlite_datareader = sqlite_cmd.ExecuteReader(); Dictionary meta = new Dictionary(); while (sqlite_datareader.Read()) { UmaDatabaseEntry entry = null; try { entry = new UmaDatabaseEntry() { Type = (UmaFileType)Enum.Parse(typeof(UmaFileType), sqlite_datareader["m"] as string), Name = sqlite_datareader["n"] as string, Url = sqlite_datareader["h"] as string, Checksum = sqlite_datareader["c"].ToString(), Prerequisites = sqlite_datareader["d"] as string }; } catch(Exception e) { Debug.LogError("Error caught: " + e); } if (entry != null) meta.Add(entry.Name, entry); } return meta; } static List ReadCharaMaster(SqliteConnection conn) { return ReadMaster(conn, "SELECT * FROM chara_data C,(SELECT D.'index' charaid,D.'text' charaname FROM text_data D WHERE id like 6) T WHERE C.id like T.charaid"); } static List ReadMobCharaMaster(SqliteConnection conn) { return ReadMaster(conn, "SELECT * FROM mob_data"); } static List ReadMaster(SqliteConnection conn,string sql) { List dr = new List(); SqliteCommand sqlite_cmd = conn.CreateCommand(); sqlite_cmd.CommandText = sql; SqliteDataReader sqlite_datareader = sqlite_cmd.ExecuteReader(); var result = new DataTable(); result.Load(sqlite_datareader); var temp = result.Rows.GetEnumerator(); while (temp.MoveNext()) { dr.Add((DataRow)temp.Current); } sqlite_cmd.Dispose(); return dr; } static List ReadFaceTypeData(SqliteConnection conn) { List data = new List(); SqliteCommand sqlite_cmd = conn.CreateCommand(); sqlite_cmd.CommandText = "SELECT * FROM face_type_data"; SqliteDataReader sqlite_datareader = sqlite_cmd.ExecuteReader(); while (sqlite_datareader.Read()) { FaceTypeData entry = new FaceTypeData() { label = sqlite_datareader.GetString(0), eyebrow_l = sqlite_datareader.GetString(1), eyebrow_r = sqlite_datareader.GetString(2), eye_l = sqlite_datareader.GetString(3), eye_r = sqlite_datareader.GetString(4), mouth = sqlite_datareader.GetString(5), mouth_shape_type = sqlite_datareader.GetInt32(6), inverce_face_type = sqlite_datareader.GetString(7), set_face_group = sqlite_datareader.GetInt32(8), }; data.Add(entry); } return data; } static List ReadAllLiveData(SqliteConnection conn) { return ReadMaster(conn, $"SELECT * FROM live_data L,(SELECT D.'index' songid,D.'text' songname FROM text_data D WHERE id like 16) T WHERE L.music_id like T.songid"); } static List ReadAllDressData(SqliteConnection conn) { return ReadMaster(conn, $"SELECT * FROM dress_data C,(SELECT D.'index' dressid,D.'text' dressname FROM text_data D WHERE id like 14) T WHERE C.id like T.dressid"); } public static DataRow ReadCharaData(CharaEntry chara) { if (chara.IsMob) { return instance.MobCharaData.Find(e => { return Convert.ToInt32(e["mob_id"]) == chara.Id; }); } return instance.CharaData.Find(e => { return Convert.ToInt32(e["id"]) == chara.Id; }); } public static DataRow ReadMobDressColor(string mobid) { var results= ReadMaster(instance.masterDb, $"SELECT * FROM mob_dress_color_set WHERE id LIKE {mobid}"); foreach(var data in results) { return data; } return null; } public static DataRow ReadMobHairColor(string colorid) { var results= ReadMaster(instance.masterDb, $"SELECT * FROM mob_hair_color_set WHERE id LIKE {colorid}"); foreach(var data in results) { return data; } return null; } public void CloseAllConnection() { masterDb?.Close(); metaDb?.Close(); masterDb?.Dispose(); metaDb?.Dispose(); SqliteConnection.ClearAllPools(); GC.Collect(); GC.WaitForPendingFinalizers(); } }