private static void FindPimgResources(List <ResourceMetadata> list, IPsbValue obj, bool deDuplication = true) { if (obj is PsbCollection c) { foreach (var o in c) { if (!(o is PsbDictionary dic)) { continue; } if (dic["layer_id"] is PsbString layerId) { var res = list.FirstOrDefault(k => k.Name.StartsWith(layerId.Value, true, null)); if (res == null) { continue; } if (uint.TryParse(layerId.Value, out var id)) { res.Index = id; } if (dic["width"] is PsbNumber nw) { res.Width = deDuplication ? Math.Max((int)nw, res.Width) : (int)nw; } if (dic["height"] is PsbNumber nh) { res.Height = deDuplication ? Math.Max((int)nh, res.Height) : (int)nh; } } } } }
private static void FindMotionResources <T>(List <T> list, IPsbValue obj, bool deDuplication = true) where T : IResourceMetadata { switch (obj) { case PsbList c: c.ForEach(o => FindMotionResources(list, o, deDuplication)); break; case PsbDictionary d: if (d[Consts.ResourceKey] is PsbResource r) { if (!deDuplication) { list.Add((T)(IResourceMetadata)GenerateImageMetadata(d, r)); } else if (r.Index == null || list.FirstOrDefault(md => md.Index == r.Index.Value) == null) { list.Add((T)(IResourceMetadata)GenerateImageMetadata(d, r)); } } foreach (var o in d.Values) { FindMotionResources(list, o, deDuplication); } break; } }
private static void FindMotionResources(List <ResourceMetadata> list, IPsbValue obj, bool deDuplication = true) { switch (obj) { case PsbCollection c: c.ForEach(o => FindMotionResources(list, o, deDuplication)); break; case PsbDictionary d: if (d[ResourceKey] is PsbResource r) { if (!deDuplication) { list.Add(GenerateMotionResMetadata(d, r)); } else if (r.Index == null || list.FirstOrDefault(md => md.Index == r.Index.Value) == null) { list.Add(GenerateMotionResMetadata(d, r)); } } foreach (var o in d.Values) { FindMotionResources(list, o, deDuplication); } break; } }
private static void FindTachieResources(List <ResourceMetadata> list, IPsbValue obj, string currentLabel = "") { switch (obj) { case PsbCollection c: c.ForEach(o => FindTachieResources(list, o)); break; case PsbDictionary d: if (d["label"] is PsbString label) { if (string.IsNullOrWhiteSpace(currentLabel)) { currentLabel = label; } else { currentLabel = string.Join("-", currentLabel, label); } } if (d[ResourceKey] is PsbResource r) { list.Add(GenerateTachieResMetadata(d, r, currentLabel)); } foreach (var o in d.Values) { FindTachieResources(list, o, currentLabel); } break; } }
/// <summary> /// Find object by MMO style path (based on label) /// <example>e.g. "all_parts/全体構造/■全体レイアウト"</example> /// </summary> /// <param name="psbObj"></param> /// <param name="path"></param> /// <returns></returns> public static IPsbValue FindByMmoPath(this IPsbCollection psbObj, string path) { if (psbObj == null) { return(null); } if (path.StartsWith("/")) { path = new string(path.SkipWhile(c => c == '/').ToArray()); } string current = null; int pos = -1; if (path.Contains("/")) { pos = path.IndexOf('/'); current = path.Substring(0, pos); } else { current = path; } IPsbValue currentObj = null; if (psbObj is PsbCollection col) { currentObj = col.FirstOrDefault(c => c is PsbDictionary d && d.ContainsKey("label") && d["label"] is PsbString s && s.Value == current); } else if (psbObj is PsbDictionary dic) { //var dd = dic.Value.FirstOrDefault(); var children = (PsbCollection)(dic.ContainsKey("layerChildren") ? dic["layerChildren"] : dic["children"]); currentObj = children.FirstOrDefault(c => c is PsbDictionary d && d.ContainsKey("label") && d["label"] is PsbString s && s.Value == current); } if (pos == path.Length - 1 || pos < 0) { return(currentObj); } if (currentObj is IPsbCollection psbCol) { path = path.Substring(pos); return(psbCol.FindByMmoPath(path)); } return(psbObj[path]); }
/// <summary> /// Quickly fetch children (use at your own risk) /// </summary> /// <param name="col"></param> /// <param name="index"></param> /// <returns></returns> public static IPsbValue Children(this IPsbValue col, int index) { switch (col) { case PsbDictionary dictionary: return(dictionary.Values.ElementAt(index)); case PsbList collection: return(collection[index]); } throw new ArgumentException($"{col} doesn't have children."); }
public static IPsbValue Children(this IPsbValue col, string name) { while (true) { switch (col) { case PsbDictionary dictionary: return(dictionary[name]); case PsbCollection collection: col = collection.FirstOrDefault(c => c is PsbDictionary); continue; } throw new ArgumentException($"{col} doesn't have children."); } }
/// <inheritdoc cref="FindByPath(FreeMote.Psb.PsbDictionary,string)"/> public static IPsbValue FindByPath(this PsbCollection psbObj, string path) { if (psbObj == null) { return(null); } if (path.StartsWith("/")) { path = new string(path.SkipWhile(c => c == '/').ToArray()); } if (path.Contains("/")) { var pos = path.IndexOf('/'); var current = path.Substring(0, pos); IPsbValue currentObj = null; if (current == "*") { currentObj = psbObj.FirstOrDefault(); } if (current.StartsWith("[") && current.EndsWith("]") && Int32.TryParse(current.Substring(1, current.Length - 2), out var id)) { currentObj = psbObj[id]; } if (pos == path.Length - 1) { return(currentObj); } if (currentObj is PsbDictionary dictionary) { path = path.Substring(pos); return(dictionary.FindByPath(path)); } if (currentObj is PsbCollection collection) { path = path.Substring(pos); return(collection.FindByPath(path)); } } return(null); }
/// <summary> /// Quickly fetch number (use at your own risk) /// </summary> /// <param name="col"></param> /// <param name="name"></param> /// <returns></returns> public static float GetFloat(this IPsbValue col) { return(((PsbNumber)col).AsFloat); }
/// <summary> /// Quickly fetch number (use at your own risk) /// </summary> /// <param name="col"></param> /// <param name="name"></param> /// <returns></returns> public static double GetDouble(this IPsbValue col) { return(((PsbNumber)col).AsDouble); }
/// <summary> /// Set archData value to archData object /// </summary> /// <param name="archData"></param> /// <param name="val"></param> public static void SetPsbArchData(this IArchData archData, IPsbValue val) { archData.PsbArchData["archData"] = val; }
/// <summary> /// Quickly fetch number (use at your own risk) /// </summary> /// <param name="col"></param> /// <param name="name"></param> /// <returns></returns> public static int GetInt(this IPsbValue col) { return(((PsbNumber)col).AsInt); }
public static bool CompareValue(IPsbValue p1, IPsbValue p2) { //if (p1.Type != p2.Type && !(p1 is PsbString)) //{ // Console.WriteLine($"Strict Type diff: {p1}({p1.Type}) vs {p2}({p2.Type})"); //} if (p1 != null && p2 == null) { Console.WriteLine($"p1 == {p1.ToString()} && p2 == null"); return(false); } if (p1 == null && p2 != null) { Console.WriteLine($"p1 == null && p2 == {p2.ToString()}"); return(false); } if (p1 == null && p2 == null) { return(true); } if (p1.GetType() != p2.GetType()) { Console.WriteLine($"Type diff: {p1}({p1.GetType()}) vs {p2}({p2.GetType()})"); return(false); } switch (p1) { case PsbResource r1: var r2 = (PsbResource)p2; if (r1.Data.SequenceEqual(r2.Data)) { return(true); } Console.WriteLine($"Res Diff: {r1} vs {r2}"); return(false); case PsbNull _: return(true); case PsbNumber n1: var n2 = (PsbNumber)p2; if (n1.Type != n2.Type) { Console.WriteLine($"Wrong Number Type: {n1}({n1.Type}) vs {n2}({n2.Type})"); return(false); } switch (n1.NumberType) { case PsbNumberType.Int: if ((int)n1 != (int)n2) { Console.WriteLine($"{n1} != {n2}"); return(false); } break; case PsbNumberType.Float: if (Math.Abs((float)n1 - (float)n2) > float.Epsilon) { Console.WriteLine($"{n1} != {n2}"); return(false); } break; case PsbNumberType.Double: if (Math.Abs((double)n1 - (double)n2) > double.Epsilon) { Console.WriteLine($"{n1} != {n2}"); return(false); } break; default: throw new ArgumentOutOfRangeException(); } return(true); case PsbString s1: var s2 = (PsbString)p2; if (s1.Value == s2.Value) { return(true); } Console.WriteLine($"{s1} != {s2}"); return(false); case PsbBool b1: var b2 = (PsbBool)p2; if (b1.Value == b2.Value) { return(true); } Console.WriteLine($"{b1} != {b2}"); return(false); case PsbArray a1: var a2 = (PsbArray)p2; if (a1.Value.SequenceEqual(a2.Value)) { return(true); } Console.WriteLine($"{a1} != {a2}"); return(false); case PsbCollection c1: var c2 = (PsbCollection)p2; for (var i = 0; i < c1.Count; i++) { if (CompareValue(c1[i], c2[i])) { continue; } Console.WriteLine(c1.Path); //Console.WriteLine($"{c1.Value[i]} != {c2.Value[i]}"); } return(true); case PsbDictionary d1: var d2 = (PsbDictionary)p2; foreach (var pair1 in d1) { if (!d2.ContainsKey(pair1.Key)) { Console.WriteLine($"Missing {pair1.Key}"); } else { CompareValue(pair1.Value, d2[pair1.Key]); } } return(true); } return(true); }
private static void FindMmoResources <T>(List <T> list, IPsbValue obj, in string defaultPartname = "",
private static void FindMmoResources(List <ResourceMetadata> list, IPsbValue obj, in string defaultPartname = "",
private static void FindPimgResources <T>(List <T> list, IPsbValue obj, bool deDuplication = true) where T : IResourceMetadata { if (obj is PsbList c) { foreach (var o in c) { if (!(o is PsbDictionary dic)) { continue; } if (dic.ContainsKey("layer_id")) { int layerId = 0; if (dic["layer_id"] is PsbString sLayerId && int.TryParse(sLayerId.Value, out var id)) { layerId = id; } else if (dic["layer_id"] is PsbNumber nLayerId) { layerId = nLayerId.IntValue; } else { Console.WriteLine($"[WARN] layer_id {dic["layer_id"]} is wrong."); continue; } var res = (ImageMetadata)(IResourceMetadata)list.FirstOrDefault(k => k.Name.StartsWith(layerId.ToString(), true, null)); if (res == null) { continue; } res.Index = (uint)layerId; //res.Part = layerId.ToString(); if (dic["width"] is PsbNumber nw) { res.Width = GetIntValue(nw, res.Width); } if (dic["height"] is PsbNumber nh) { res.Height = GetIntValue(nh, res.Height); } if (dic["top"] is PsbNumber nt) { res.Top = GetIntValue(nt, res.Top); } if (dic["left"] is PsbNumber nl) { res.Left = GetIntValue(nl, res.Left); } if (dic["opacity"] is PsbNumber no) { res.Opacity = GetIntValue(no, res.Opacity); } if (dic["group_layer_id"] is PsbNumber gLayerId) { res.Part = gLayerId.IntValue.ToString(); } if (dic["visible"] is PsbNumber nv) { res.Visible = nv.IntValue != 0; } if (dic["name"] is PsbString nn) { res.Label = nn.Value; } } } }
/// <summary> /// Add stubs (<see cref="PsbResource"/> with null Data) into a Motion PSB. A stub must be linked with a texture, or it will be null after <see cref="PSB.Build"/> /// </summary> /// <param name="resources"></param> /// <param name="obj"></param> private static void GenerateMotionResourceStubs(List <PsbResource> resources, IPsbValue obj) { switch (obj) { case PsbList c: c.ForEach(o => GenerateMotionResourceStubs(resources, o)); break; case PsbDictionary d: if (d.ContainsKey(Consts.ResourceKey) && (d[Consts.ResourceKey] == null || d[Consts.ResourceKey] is PsbNull)) { if (d.ContainsKey("width") && d.ContainsKey("height")) { //confirmed, add stub PsbResource res = new PsbResource(); resources.Add(res); res.Index = (uint)resources.IndexOf(res); d[Consts.ResourceKey] = res; } } foreach (var o in d.Values) { GenerateMotionResourceStubs(resources, o); } break; } }