/// <summary> /// Starts the external Plugin /// </summary> /// <param name="pfd">File Descriptor of the Selected File</param> /// <param name="package">The package the File is stored in</param> public void Execute(SimPe.Interfaces.Scenegraph.IScenegraphFileIndexItem item) { if (item == null) { return; } if (item.FileDescriptor == null) { return; } if (item.Package == null) { return; } string extfile = System.IO.Path.Combine(System.IO.Path.GetTempPath(), "simpe"); uint ct = 0; while (System.IO.File.Exists(extfile + Helper.HexString(ct) + ".tmp")) { ct++; } extfile = extfile + Helper.HexString(ct) + ".tmp"; try { SavePackedFile(extfile, false, (SimPe.Packages.PackedFileDescriptor)item.FileDescriptor, (SimPe.Packages.GeneratableFile)item.Package); Process p = new Process(); p.StartInfo.FileName = RealFileName; p.StartInfo.Arguments = Attributes.Replace("{tempname}", "\"" + extfile + "\"").Replace("{tempfile}", "\"" + extfile + "\""); p.Start(); p.WaitForExit(); p.Close(); SimPe.Packages.PackedFileDescriptor pfd = (SimPe.Packages.PackedFileDescriptor)item.FileDescriptor; OpenPackedFile(extfile, ref pfd); pfd.Filename = null; pfd.Path = null; } finally { try { System.IO.File.Delete(extfile); } catch (Exception) {} } }
/// <summary> /// Saves Metainformations about a PackedFile as xml output /// </summary> /// <param name="flname">The Filename</param> /// <param name="pfd">The description of the File</param> protected void SaveMetaInfo(string flname, PackedFileDescriptor pfd) { System.IO.TextWriter fs = System.IO.File.CreateText(flname); try { fs.WriteLine("<?xml version=\"1.0\" encoding=\"" + fs.Encoding.HeaderName + "\" ?>"); fs.WriteLine("<package type=\"" + ((uint)Header.IndexType).ToString() + "\">"); fs.Write(pfd.GenerateXmlMetaInfo()); fs.WriteLine("</package>"); } finally { fs.Close(); fs.Dispose(); fs = null; } }
/// <summary> /// saves the packed File /// </summary> /// <param name="filename"></param> /// <param name="dscfile"></param> public static void SavePackedFile(string filename, bool dscfile, SimPe.Packages.PackedFileDescriptor pfd, SimPe.Packages.GeneratableFile package) { #if !DEBUG try #endif { pfd.Path = System.IO.Path.GetDirectoryName(filename); pfd.Path = ".\\"; pfd.Filename = System.IO.Path.GetFileName(filename); package.SavePackedFile(filename, null, pfd, dscfile); } #if !DEBUG catch (Exception ex) { Helper.ExceptionMessage(Localization.Manager.GetString("errwritingfile") + filename, ex); } #endif }
/// <summary> /// Creates a clone of this Object /// </summary> /// <returns>The Cloned Object</returns> public IPackedFileDescriptor Clone() { PackedFileDescriptor pfd = new PackedFileDescriptor(); pfd.filename = filename; pfd.group = group; pfd.instance = instance; pfd.offset = offset; pfd.size = size; pfd.subtype = subtype; pfd.type = type; pfd.changed = changed; pfd.wascomp = this.wascomp; pfd.markcompress = this.markcompress; pfd.markdeleted = this.markdeleted; return((IPackedFileDescriptor)pfd); }
/// <summary> /// Stores a MemoryStream to a File /// </summary> /// <param name="flname">The Filename</param> /// <param name="pf"> /// The Memorystream representing the PackedFile. If null and pfd is not null, the Packedfile /// will be loaded with Extract(). /// </param> /// <param name="pfd"> /// The description of the File, or null. If not null an additional XML File will be created /// representing the Information like TypeId, SubId, Instance and Group. /// </param> /// <param name="meta">set false if you do not want to create the Meta Xml File</param> /// public void SavePackedFile(string flname, MemoryStream pf, PackedFileDescriptor pfd, bool meta) { if (pfd != null) { if (pf == null) { pf = Extract(pfd); } if (meta) { SaveMetaInfo(flname + ".xml", pfd); } } if (pf != null) { SavePackedFile(flname, pf); } }
bool CouldBeIndexItem(BinaryReader br, long pos, int step, bool strict) { if (pos < 0) { return(false); } for (int i = 0; i < 4; i++) { br.BaseStream.Seek(pos + i * step, SeekOrigin.Begin); SimPe.Packages.PackedFileDescriptor pfd = new PackedFileDescriptor(); pfd.LoadFromStream(pkg.Header, br); if (!types.Contains(pfd.Type)) { return(false); } if (pfd.Size <= 0) { return(false); } if (pfd.Offset <= 0 || pfd.Offset >= br.BaseStream.Length) { return(false); } if (strict) { if (pfd.Type == 0x00000000) { return(false); } if (pfd.Type == 0xffffffff) { return(false); } } } return(true); }
/// <summary> /// This is used to enable SimPe to add compressed Resources /// </summary> void PrepareCompression() { if (fileindex == null) { return; } if (filelistfile != null) { return; } filelistfile = new SimPe.PackedFiles.Wrapper.CompressedFileList(this.Header.IndexType); filelist = new PackedFileDescriptor(); filelist.Type = Data.MetaData.DIRECTORY_FILE; filelist.LongInstance = 0x286B1F03; filelist.Group = Data.MetaData.DIRECTORY_FILE; filelistfile.FileDescriptor = filelist; filelistfile.SynchronizeUserData(); this.Add(filelist); }
/// <summary> /// Open a Packed File and add it to the package /// </summary> /// <param name="filename">Name of the File</param> /// <param name="pfd">Descriptor of the Target File</param> /// <param name="package">The package the Fille sould be added to</param> /// <returns>true if succesfull</returns> public static bool OpenPackedFile(string filename, ref Packages.PackedFileDescriptor pfd) { try { try { if (filename.ToLower().EndsWith(".xml")) { pfd = XmlPackageReader.OpenExtractedPackedFile(filename); filename = System.IO.Path.Combine(pfd.Path, pfd.Filename); } else { string[] part = System.IO.Path.GetFileNameWithoutExtension(filename).Split("-".ToCharArray(), 4); try { pfd.Type = Convert.ToUInt32(part[0].Trim(), 16); pfd.SubType = Convert.ToUInt32(part[1].Trim(), 16); pfd.Group = Convert.ToUInt32(part[2].Trim(), 16); pfd.Instance = Convert.ToUInt32(part[3].Trim(), 16); } catch (Exception) { part = System.IO.Path.GetFileNameWithoutExtension(filename).Split("-".ToCharArray(), 5); try { pfd.Type = Convert.ToUInt32(part[0].Trim(), 16); pfd.SubType = Convert.ToUInt32(part[2].Trim(), 16); pfd.Group = Convert.ToUInt32(part[3].Trim(), 16); pfd.Instance = Convert.ToUInt32(part[4].Trim(), 16); } catch (Exception) {} } try { part = System.IO.Path.GetDirectoryName(filename).Split("\\".ToCharArray()); if (part.Length > 0) { string last = part[part.Length - 1]; part = last.Split("-".ToCharArray(), 2); pfd.Type = Convert.ToUInt32(part[0].Trim(), 16); } } catch (Exception) {} } } catch (Exception) { } System.IO.FileStream fs = System.IO.File.OpenRead(filename); try { System.IO.BinaryReader mbr = new System.IO.BinaryReader(fs); byte[] data = new byte[mbr.BaseStream.Length]; for (int i = 0; i < data.Length; i++) { data[i] = mbr.ReadByte(); } pfd.UserData = data; } catch (Exception ex) { Helper.ExceptionMessage(Localization.Manager.GetString("err003").Replace("{0}", filename), ex); return(false); } finally { fs.Close(); fs.Dispose(); fs = null; } } catch (Exception ex) { Helper.ExceptionMessage(Localization.Manager.GetString("erropenfile") + " " + filename, ex); return(false); } return(true); }
/// <summary> /// Writes the Index to the Package File /// </summary> /// <param name="writer">The BinaryWriter to use</param> /// <param name="tmpcmp">the index you want to write</param> /// <param name="tmpindex">listing of the compressin state for each packed File</param> protected void WriteFileList(BinaryWriter writer, ref PackedFileDescriptors tmpindex, ArrayList tmpcmp) { if (this.filelist == null) { filelist = new PackedFileDescriptor(); filelist.instance = 0x286B1F03; filelist.Group = Data.MetaData.DIRECTORY_FILE; filelist.Type = Data.MetaData.DIRECTORY_FILE; } //we use the fact, taht packed files that were altered by SimPe will not be compressed, //so we only need to delete entries in the Filelist that do not exist any longer. The Size //won't change! byte[] b = this.Read(filelist).UncompressedData; SimPe.PackedFiles.Wrapper.CompressedFileList fl = new SimPe.PackedFiles.Wrapper.CompressedFileList(filelist, this); if (filelist.MarkForDelete) { fl.Clear(); } SimPe.PackedFiles.Wrapper.CompressedFileList newfl = new SimPe.PackedFiles.Wrapper.CompressedFileList(this.Header.IndexType); newfl.FileDescriptor = filelist; for (int i = 0; i < tmpcmp.Count; i++) { if ((bool)tmpcmp[i]) { int pos = fl.FindFile((IPackedFileDescriptor)tmpindex[i]); if (pos != -1) //the file did already exist, so the size did not change! { SimPe.PackedFiles.Wrapper.ClstItem fi = fl.Items[pos]; newfl.Add(fi); } else //the file is new but compressed { //IPackedFile pf = this.Read((IPackedFileDescriptor)tmpindex[i]); SimPe.PackedFiles.Wrapper.ClstItem fi = new SimPe.PackedFiles.Wrapper.ClstItem(newfl.IndexType); PackedFileDescriptor pfd = (PackedFileDescriptor)tmpindex[i]; fi.Type = pfd.Type; fi.Group = pfd.Group; fi.Instance = pfd.Instance; fi.SubType = pfd.SubType; fi.UncompressedSize = (uint)pfd.fldata.UncompressedSize; newfl.Add(fi); } } } //no compressed Files, so remove the (empty) Filelist if (newfl.Items.Length != 0) { //tmpindex[tmpindex.Length-1] = filelist; tmpindex.Add(filelist); newfl.SynchronizeUserData(); filelist.offset = (uint)writer.BaseStream.Position; filelist.size = filelist.UserData.Length; writer.Write(filelist.UserData); filelist.Changed = false; } this.filelistfile = newfl; }
/// <summary> /// Compiles a new Package File from the currently stored Information /// </summary> /// <returns>The MemoryStream representing the new Package File</returns> public MemoryStream Build() { this.LockStream(); OpenReader(); System.IO.MemoryStream ms = new MemoryStream(10000); System.IO.BinaryWriter writer = new BinaryWriter(ms); //make sure we write the correct Version! if ((header.majorversion == 1) && (header.minorversion == 0)) { header.minorversion = 1; header.majorversion = 1; filelist = null; } int oldcount = 0; if (this.Index != null) { oldcount = this.Index.Length; } //now save the stuff header.Save(writer); //now save the files PackedFileDescriptors tmpindex = new PackedFileDescriptors(); ArrayList tmpcmp = new ArrayList(); if (this.fileindex == null) { fileindex = new SimPe.Interfaces.Files.IPackedFileDescriptor[0]; } PrepareCompression(); foreach (PackedFileDescriptor pfd in this.fileindex) { pfd.Changed = false; //we write the filelist as last File if (pfd == this.filelist) { continue; } if (pfd.Type == Data.MetaData.DIRECTORY_FILE) { continue; } if (pfd.MarkForDelete) { continue; } //PackedFileDescriptor newpfd = (PackedFileDescriptor)pfd.Clone(); PackedFileDescriptor newpfd = (PackedFileDescriptor)pfd; PackedFile pf = null; if (pfd.MarkForReCompress) { try { if (pfd.HasUserdata) { pf = new PackedFile(PackedFile.Compress(pfd.UserData)); pf.uncsize = (uint)pfd.UserData.Length; } else { byte[] data = ((PackedFile)this.Read(pfd)).UncompressedData; pf = new PackedFile(PackedFile.Compress(data)); pf.uncsize = (uint)data.Length; } pf.size = pf.data.Length; pf.signature = Data.MetaData.COMPRESS_SIGNATURE; pf.headersize = 9; newpfd.size = pf.data.Length; newpfd.SetUserData(null, false); //recreate the FileList filelist = null; } catch (Exception ex) { pf = (PackedFile)this.Read(pfd); newpfd.size = pf.data.Length; newpfd.SetUserData(pfd.UserData, false); if (Helper.DebugMode) { Helper.ExceptionMessage(ex); } } } else { pf = (PackedFile)this.Read(pfd); newpfd.size = pf.data.Length; newpfd.SetUserData(pfd.UserData, false); } newpfd.offset = (uint)writer.BaseStream.Position; newpfd.Changed = false; newpfd.MarkForReCompress = false; newpfd.fldata = pf; newpfd.WasCompressed = pf.IsCompressed; tmpcmp.Add(pf.IsCompressed); tmpindex.Add(newpfd); writer.Write(pf.data); } //Last Entry should be the Filelist WriteFileList(writer, ref tmpindex, tmpcmp); //create a new Index IPackedFileDescriptor[] myindex = new PackedFileDescriptor[tmpindex.Count]; tmpindex.CopyTo(myindex); //write the hole index header.HoleIndex.Offset = 0; header.HoleIndex.Size = (int)(header.HoleIndex.ItemSize * 0); header.HoleIndex.Count = 0; holeindex = new HoleIndexItem[0]; //write the packed Fileindex header.Index.Offset = (uint)writer.BaseStream.Position; header.Index.Size = (int)(header.Index.ItemSize * myindex.Length); header.Index.Count = myindex.Length; SaveIndex(writer, myindex); Index = myindex; //rewrite Header ms.Seek(0, SeekOrigin.Begin); header.Save(writer); ms.Seek(0, SeekOrigin.Begin); this.UnLockStream(); CloseReader(); FireIndexEvent(); if (Index.Length < oldcount) { this.FireRemoveEvent(); } else if (Index.Length > oldcount) { this.FireAddEvent(); } return(ms); }
/// <summary> /// Add a MMAT to the package /// </summary> protected SimPe.PackedFiles.Wrapper.Cpf AddMMAT(SimPe.Plugin.Rcol matd, string subset, string cresname, uint instance, bool substate) { //now add the default MMAT System.IO.BinaryReader br = new System.IO.BinaryReader(this.GetType().Assembly.GetManifestResourceStream("SimPe.Plugin.mmat.simpe")); SimPe.Packages.PackedFileDescriptor pfd1 = new SimPe.Packages.PackedFileDescriptor(); pfd1.Group = 0xffffffff; pfd1.SubType = 0x00000000; pfd1.Instance = instance; pfd1.Type = 0x4C697E5A; //MMAT pfd1.UserData = br.ReadBytes((int)br.BaseStream.Length); package.Add(pfd1); SimPe.PackedFiles.Wrapper.Cpf mmat = new SimPe.PackedFiles.Wrapper.Cpf(); mmat.ProcessData(pfd1, package); if (!substate) { mmat.GetSaveItem("family").StringValue = System.Guid.NewGuid().ToString(); } mmat.GetSaveItem("name").StringValue = matd.FileName.Substring(0, matd.FileName.Length - 5); mmat.GetSaveItem("subsetName").StringValue = subset; mmat.GetSaveItem("modelName").StringValue = cresname; //Get the GUID Interfaces.Files.IPackedFileDescriptor[] pfds = package.FindFiles(Data.MetaData.OBJD_FILE); mmat.GetSaveItem("objectGUID").UIntegerValue = 0x00000000; foreach (Interfaces.Files.IPackedFileDescriptor pfd in pfds) { SimPe.PackedFiles.Wrapper.Objd objd = new SimPe.PackedFiles.Wrapper.Objd(null); objd.ProcessData(pfds[0], package); mmat.GetSaveItem("objectGUID").UIntegerValue = objd.SimId; if (pfd.Instance == 0x000041A7) { break; } } ObjectRecolor.FixMMAT(mmat); mmat.SynchronizeUserData(); gm_pkg.Add(mmat.FileDescriptor); //alternate states if (!substate) { string name = mmat.GetSaveItem("name").StringValue; pfds = ObjectCloner.FindStateMatchingMatd(name, package); if (pfds != null) { if (pfds.Length > 0) { SimPe.Plugin.Rcol submatd = new GenericRcol(null, false); submatd.ProcessData(pfds[0], package); SimPe.PackedFiles.Wrapper.Cpf mmat2 = AddMMAT(submatd, subset, cresname, instance, true); mmat2.GetSaveItem("family").StringValue = mmat.GetSaveItem("family").StringValue; } } } return(mmat); }
/// <summary> /// Extracts the Content of a Packed File and returs them as a MemoryStream /// </summary> /// <param name="pfd">The PackedFileDescriptor</param> /// <returns>The MemoryStream representing the PackedFile</returns> public System.IO.MemoryStream Extract(PackedFileDescriptor pfd) { IPackedFile pf = base.Read(pfd); return(new MemoryStream(pf.UncompressedData)); }