public static void Postfix(CharFile __instance, BinaryReader reader, Boolean noSetPNG, Boolean noLoadStatus) { Debug.Log(HSExtSave._logPrefix + "Loading extended data for character..."); long cachedPosition = reader.BaseStream.Position; try { XmlDocument doc = new XmlDocument(); doc.Load(reader.BaseStream); HashSet <HSExtSave.HandlerGroup> calledHandlers = new HashSet <HSExtSave.HandlerGroup>(); foreach (XmlNode node in doc.ChildNodes) { switch (node.Name) { case "charExtData": foreach (XmlNode child in node.ChildNodes) { try { HSExtSave.HandlerGroup group; if (HSExtSave._handlers.TryGetValue(child.Name, out group) && group.onCharRead != null) { group.onCharRead(__instance, child); calledHandlers.Add(group); } } catch (Exception e) { Debug.LogError(HSExtSave._logPrefix + "Exception happened in handler \"" + child.Name + "\" during character loading. The exception was: " + e); } } break; } } foreach (KeyValuePair <string, HSExtSave.HandlerGroup> handler in HSExtSave._handlers) { if (handler.Value.onCharRead != null && calledHandlers.Contains(handler.Value) == false) { handler.Value.onCharRead(__instance, null); } } } catch (XmlException) { Debug.Log(HSExtSave._logPrefix + "No ext data in reader."); foreach (KeyValuePair <string, HSExtSave.HandlerGroup> kvp in HSExtSave._handlers) { if (kvp.Value.onCharRead != null) { kvp.Value.onCharRead(__instance, null); } } reader.BaseStream.Seek(cachedPosition, SeekOrigin.Begin); } }
public static void Postfix(CharFile __instance, BinaryWriter writer) { Debug.Log(HSExtSave._logPrefix + "Saving extended data for character..."); using (XmlTextWriter xmlWriter = new XmlTextWriter(writer.BaseStream, Encoding.UTF8)) { xmlWriter.Formatting = Formatting.None; xmlWriter.WriteStartElement("charExtData"); foreach (KeyValuePair <string, HSExtSave.HandlerGroup> kvp in HSExtSave._handlers) { if (kvp.Value.onCharWrite == null) { continue; } using (StringWriter stringWriter = new StringWriter()) { using (XmlTextWriter xmlWriter2 = new XmlTextWriter(stringWriter)) { try { xmlWriter2.WriteStartElement(kvp.Key); kvp.Value.onCharWrite(__instance, xmlWriter2); xmlWriter2.WriteEndElement(); // Checking if xml is well formed XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(stringWriter.ToString()); xmlWriter.WriteRaw(stringWriter.ToString()); } catch (Exception e) { Debug.LogError(HSExtSave._logPrefix + "Exception happened in handler \"" + kvp.Key + "\" during character saving. The exception was: " + e); } } } } xmlWriter.WriteEndElement(); } Debug.Log(HSExtSave._logPrefix + "Saving done."); }
/// <summary> /// TODO: Finish ConvertCharacters. Still not fully implemented, but it was 75% or so. /// </summary> /// <param name="outputFileName"></param> /// <param name="zone"></param> public void ConvertCharacters(string outputFileName, Zone zone) { // Delete if it's already there. if (File.Exists(outputFileName)) { File.Delete(outputFileName); } using (var fsOut = File.Create(outputFileName)) { using (var zipArchive = new ZipArchive(fsOut, ZipArchiveMode.Create)) { foreach (ModelRef modelRef in byType[20]) { var charfile = new CharFile(modelRef._name); if (1 != modelRef.skeleton.Length) { throw new Exception("ModelRef.Skeleton had more than 1 element."); } var skeleton = (SkelPierceTrackSet)modelRef.skeleton[0].Value[0].Value; var roottrackname = skeleton.Tracks[0].pierceTrack[0].Value.Name; var aniTrees = new Dictionary <string, AniTree>(); aniTrees.Add("", null);// not sure if I need this. foreach (SkelPierceTrack x in byType[19]) { var name = x.Name; if (name != roottrackname && name.EndsWith(roottrackname)) { aniTrees.Add(name.Replace(roottrackname, ""), null); } } foreach (var prefix in aniTrees.Keys.ToList()) { //aniTrees[prefix] = InvertTree(BuildAniTree(skeleton, prefix, 0)); } var meshes = skeleton.Meshes; var voff = 0; foreach (FragRef fr in meshes[0].Value) { var off = 0; var mesh = (FragMesh)fr.Value; foreach (var poly in mesh.Polytex) { var count = poly[0]; var index = poly[1]; var texnames = ((FragRef[])mesh.Textures[0].Value)[index].Resolve().OfType <string>().ToList(); var texFlags = ((TexRef)mesh.Textures[0].Value[index].Value).SaneFlags; var tmpS3DData = texnames.Select(t => s3d[t.ToLower()]).ToList(); var material = new Material(texFlags, tmpS3DData); var outpolys = new List <int>(); for (var i = off; i < off + count; i++) { outpolys.Add(voff + (int)mesh.Polys[i].Item2.x); outpolys.Add(voff + (int)mesh.Polys[i].Item2.y); outpolys.Add(voff + (int)mesh.Polys[i].Item2.z); } charfile.AddMaterial(material, outpolys); off += count; } voff += mesh.Vertices.Length; } foreach (var aniTree in aniTrees.Values) { foreach (var frame in aniTree.Frames) { BuildBoneMatrices(frame, Matrix4x4.Identity); } } var aa = 1; //for modelref in self.byType[0x14]: // for name, frames in aniTrees.items(): // for i, frame in enumerate(frames): // mats = { } // buildBoneMatrices(frame, Matrix44.identity()) // outbuffer = [] // for mesh in meshes: // inverts = mesh['vertices'] // innorms = mesh['normals'] // texcoords = mesh['texcoords'] // vertices = [] // normals = [] // off = 0 // for count, matid in mesh['bonevertices']: // vertices += transform(inverts[off: off + count], mats[matid]) // normals += transform(innorms[off: off + count], mats[matid]) // off += count // temp = flatten(interleave(vertices, normals, texcoords)) // outbuffer += temp // charfile.addFrame(name, outbuffer) // charfile.out(zip) } } } // def convertCharacters(self, zip): // def invertTree(atree): // def getMaxFrames(elem): // return max([len(elem['frames'])] + map(getMaxFrames, elem['children'])) // framecount = getMaxFrames(atree) // def sub(elem, i): // return dict(bone = elem['bone'], transform = elem['frames'][i if len(elem['frames']) > 1 else 0], children =[sub(x, i) for x in elem['children']]) // frames = [] // for i in xrange(framecount): // frames.append(sub(atree, i)) // return frames //def transform(elems, mat): // return [tuple(mat * Vector3(elem)) for elem in elems] }