Пример #1
0
        public void WriteToFile(string treeName, string mainpath)
        {
            TreePath = treeName;
            using (FileStream fs = new FileStream(treeName, FileMode.Create, FileAccess.Write))
            {
                using (BinaryWriter bin = new BinaryWriter(fs))
                {
                    bin.Write(1991); // KFreon: Marker for advanced features
                    bin.Write(TexCount);
                    for (int i = 0; i < TexCount; i++)
                    {
                        TreeTexInfo tex = GetTex(i);
                        bin.Write(tex.TexName.Length);
                        bin.Write(tex.TexName.ToCharArray());

                        bin.Write(tex.Hash);

                        string fullpackage = tex.FullPackage;
                        if (String.IsNullOrEmpty(fullpackage))
                        {
                            fullpackage = "Base Package";
                        }
                        bin.Write(fullpackage.Length);
                        bin.Write(fullpackage.ToCharArray());

                        string thumbpath = tex.ThumbnailPath != null?tex.ThumbnailPath.Split('\\').Last() : "placeholder.ico";

                        bin.Write(thumbpath.Length);
                        bin.Write(thumbpath.ToCharArray());

                        bin.Write(tex.NumMips);

                        string format = Textures.Methods.StringifyFormat(tex.Format);
                        bin.Write(format.Length);
                        bin.Write(format.ToCharArray());

                        bin.Write(tex.Files.Count);

                        /*if (GameVersion != 1)
                         *  KFreonLib.PCCObjects.Misc.ReorderFiles(ref tex.Files, ref tex.ExpIDs, Path.Combine(mainpath, "BIOGame"), GameVersion);*/


                        foreach (string file in tex.Files)
                        {
                            string tempfile = file;
                            tempfile = tempfile.Remove(0, mainpath.Length + 1);

                            bin.Write(tempfile.Length);
                            bin.Write(tempfile.ToCharArray());
                        }

                        foreach (int expid in tex.ExpIDs)
                        {
                            bin.Write(expid);
                        }
                    }
                }
            }
        }
Пример #2
0
        public void PerformTreeComparison()
        {
            int count = -1;

            // KFreon: Get number of textures waiting to be processed
            lock (Sync)
                count = TreeTempTexes.Count;

            // KFreon: Add each element with duplicate checking
            while (count > 0)
            {
                // KFreon: Get elements from list as added previously
                List <object> item;
                lock (Sync)
                    item = TreeTempTexes[0];

                TreeTexInfo tex      = (TreeTexInfo)item[0];
                string      PackName = (string)item[1];
                string      filename = (string)item[2];

                // KFreon: Add to list if not a duplicate
                TreeTexInfo temp = null;
                if ((temp = Contains(tex, PackName, filename)) != null)
                {
                    temp.Update(tex, pathBIOGame);

                    if (GameVersion == 2 && !temp.ValidFirstPCC && tex.ValidFirstPCC)
                    {
                        // KFreon: Get index of new first file in 'old' list
                        int index = temp.Files.IndexOf(tex.Files[0]);

                        // KFreon: Move pcc
                        var element = temp.Files.Pop(index);
                        temp.Files.Insert(0, element);

                        // KFreon: Move expid
                        var exp = temp.ExpIDs.Pop(index);
                        temp.ExpIDs.Insert(0, exp);

                        // KFreon: Update originals lists
                        temp.OriginalExpIDs = new List <int>(temp.ExpIDs);
                        temp.OriginalFiles  = new List <string>(temp.Files);

                        temp.ValidFirstPCC = true;
                    }
                }
                else
                {
                    BlindAddTex(tex);
                }

                // KFreon: Remove item from temp list
                lock (Sync)
                {
                    TreeTempTexes.RemoveAt(0);
                    count = TreeTempTexes.Count;
                }
            }
        }
Пример #3
0
 public void BlindAddTex(TreeTexInfo tex)
 {
     lock (Sync)
     {
         tex.TreeInd = TexCount;
         Texes.Add(tex);
     }
 }
Пример #4
0
        private TreeTexInfo Contains(TreeTexInfo tex, string PackName, string filename)
        {
            for (int i = 0; i < TexCount; i++)
            {
                if (Compare(tex, i, PackName, filename))
                {
                    return(Texes[i]);
                }
            }

            return(null);
        }
Пример #5
0
 public bool ReplaceTex(int index, TreeTexInfo tex)
 {
     lock (Sync)
     {
         if (index < 0 || index >= TexCount)
         {
             return(false);
         }
         else
         {
             Texes[index] = tex;
             return(true);
         }
     }
 }
Пример #6
0
 private bool Compare(TreeTexInfo tex, int i, string PackName, string filename)
 {
     if (tex.TexName == Texes[i].TexName)
     {
         if ((tex.Hash == 0 && tex.tfcOffset == Texes[i].tfcOffset) || (tex.Hash != 0 && tex.Hash == Texes[i].Hash))
         {
             if (tex.GameVersion == 1 && (tex.Package.ToLowerInvariant() == PackName.ToLowerInvariant() || Path.GetFileNameWithoutExtension(filename).ToLowerInvariant().Contains(tex.Package.ToLowerInvariant())))
             {
                 return(true);
             }
             else if (tex.GameVersion != 1)
             {
                 return(true);
             }
             else
             {
                 return(false);
             }
         }
     }
     return(false);
 }
Пример #7
0
        /// <summary>
        /// Adds texture to tree with duplicate checks
        /// </summary>
        /// <param name="tex">Texture to add</param>
        public void AddTex(TreeTexInfo tex, string PackName, string filename)
        {
            lock (Sync)
            {
                List <object> tmp = new List <object>();
                tmp.Add(tex);
                tmp.Add(PackName);
                tmp.Add(filename);
                TreeTempTexes.Add(tmp);


                // KFreon: Start again if finished
                if (TreeAddTask.Status == TaskStatus.RanToCompletion)
                {
                    TreeAddTask = null;
                    TreeAddTask = new Task(() => PerformTreeComparison());
                    TreeAddTask.Start();
                }
                else if (TreeAddTask.Status == TaskStatus.Created)   // KFreon: Start if never started before
                {
                    TreeAddTask.Start();
                }
            }
        }
Пример #8
0
        public bool ReadFromFile(string TreeName, string mainpath, string thumbpath, out int status, Form invokeObject = null)
        {
            status = 0;
            if (!File.Exists(TreeName))
            {
                return(false);
            }

            TreePath = TreeName;

            try
            {
                using (FileStream fs = new FileStream(TreeName, FileMode.Open, FileAccess.Read))
                {
                    using (BinaryReader bin = new BinaryReader(fs))
                    {
                        int numthings = bin.ReadInt32();
                        if (numthings == 1991)
                        {
                            AdvancedFeatures = true;
                            numthings        = bin.ReadInt32();
                            Debugging.DebugOutput.PrintLn("Advanced ME" + GameVersion + " Tree features detected.");
                        }
                        else
                        {
                            Debugging.DebugOutput.PrintLn("Advanced ME" + GameVersion + " Tree features disabled.");
                        }

                        for (int i = 0; i < numthings; i++)
                        {
                            TreeTexInfo tempStruct = new TreeTexInfo();
                            int         temp       = bin.ReadInt32();
                            char[]      tempChar   = bin.ReadChars(temp);
                            tempStruct.TexName     = new string(tempChar);
                            tempStruct.Hash        = bin.ReadUInt32();
                            tempChar               = bin.ReadChars(bin.ReadInt32());
                            tempStruct.FullPackage = new string(tempChar);
                            tempChar               = bin.ReadChars(bin.ReadInt32());

                            if (AdvancedFeatures)
                            {
                                string thum = new string(tempChar);
                                tempStruct.ThumbnailPath = thum != null?Path.Combine(thumbpath, thum) : null;
                            }

                            tempStruct.NumMips = bin.ReadInt32();
                            int formatlen = bin.ReadInt32();
                            tempChar          = bin.ReadChars(formatlen);
                            tempStruct.Format = Textures.Methods.ParseFormat(new string(tempChar));

                            int numFiles = bin.ReadInt32();
                            tempStruct.Files = new List <string>();
                            for (int j = 0; j < numFiles; j++)
                            {
                                tempChar = bin.ReadChars(bin.ReadInt32());
                                string tempStr = new string(tempChar);
                                tempStruct.Files.Add(Path.Combine(mainpath, tempStr));
                            }

                            tempStruct.ExpIDs           = new List <int>();
                            tempStruct.TriedThumbUpdate = false;
                            for (int j = 0; j < numFiles; j++)
                            {
                                tempStruct.ExpIDs.Add(bin.ReadInt32());
                            }

                            tempStruct.OriginalFiles  = new List <string>(tempStruct.Files);
                            tempStruct.OriginalExpIDs = new List <int>(tempStruct.ExpIDs);
                            BlindAddTex(tempStruct);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Debugging.DebugOutput.PrintLn("Failed to load tree: " + e.Message);
                if (invokeObject != null)
                {
                    int temp = status;
                    invokeObject.Invoke(new Action(() =>
                    {
                        if (MessageBox.Show("Tree is corrupted or wrong tree loaded  :(" + Environment.NewLine + "Do you want to build a new tree?", "Mission Failure.", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == System.Windows.Forms.DialogResult.Yes)
                        {
                            File.Delete(TreeName);
                            temp = 1;
                        }
                        else
                        {
                            temp = 2;
                        }
                    }));
                    status = temp;
                }
                else
                {
                    status = 2;
                }
                return(false);
            }
            return(true);
        }
Пример #9
0
        public void SearchAllv5(string searchString, ListBox box, string searchType)
        {
            box.Invoke(new Action(() => box.ClearSelected()));
            string pattern = Regex.Escape(searchString).ToLower();

            if (searchString != string.Empty)
            {
                List <string> list = new List <string>();

                // KFreon: Hash search
                if (searchString.Length > 2 && searchString.Substring(0, 2) == "0x")
                {
                    for (int i = 0; i < texes.Count; i++)
                    {
                        TreeTexInfo tex      = texes[i];
                        string      thing    = searchString.Substring(2).ToLowerInvariant();
                        string      fromGame = KFreonLib.Textures.Methods.FormatTexmodHashAsString(tex.Hash).Substring(2).ToLowerInvariant();
                        if (fromGame.Contains(thing))
                        {
                            list.Add(tex.TexName + " (" + tex.ParentNode.Text.ToLower() + ")");
                        }
                    }
                }
                else if (searchString[0] == '@')   // KFreon: Export ID search
                {
                    int expID = 0;
                    if (!int.TryParse(searchString.Substring(1), out expID))
                    {
                        return;
                    }

                    for (int i = 0; i < texes.Count; i++)
                    {
                        TreeTexInfo tex = texes[i];
                        if (tex.ExpIDs.Contains(expID))
                        {
                            list.Add(tex.TexName + " (" + tex.ParentNode.Text.ToLower() + ")");
                        }
                    }
                }
                else if (searchString[0] == '\\')  // KFreon: Filename search
                {
                    int    exppos = searchString.IndexOf('@');
                    int    length = searchString.Length - (searchString.Length - exppos) - 2;
                    string name   = (exppos == -1) ? searchString.Substring(1).ToLowerInvariant() : searchString.Substring(1, length).ToLowerInvariant();


                    if (exppos != -1)  // KFreon: Filename + ExpID search
                    {
                        int expID = 0;
                        if (!int.TryParse(searchString.Substring(exppos + 1), out expID))
                        {
                            return;
                        }

                        for (int i = 0; i < texes.Count; i++)
                        {
                            TreeTexInfo tex = texes[i];
                            for (int j = 0; j < tex.Files.Count; j++)
                            {
                                if (tex.Files[j].Split('\\').Last().ToLowerInvariant().Contains(name) && tex.ExpIDs[j] == expID)
                                {
                                    list.Add(tex.TexName + " (" + tex.ParentNode.Text.ToLower() + ")");
                                }
                            }
                        }
                    }
                    else  // KFreon: Normal filename search
                    {
                        for (int i = 0; i < texes.Count; i++)
                        {
                            TreeTexInfo tex = texes[i];
                            foreach (string filename in tex.Files)
                            {
                                if (filename.Split('\\').Last().ToLowerInvariant().Contains(name))
                                {
                                    list.Add(tex.TexName + " (" + tex.ParentNode.Text.ToLower() + ")");
                                }
                            }
                        }
                    }
                }
                else if (searchString[0] == '-')  // KFreon: Thumbnail search
                {
                    string searchstr = searchString.Substring(1).ToLowerInvariant();
                    foreach (TreeTexInfo tex in texes)
                    {
                        string name = Path.GetFileNameWithoutExtension(tex.ThumbnailPath).ToLowerInvariant();
                        if (name.Contains(searchstr))
                        {
                            list.Add(tex.TexName + " (" + tex.ParentNode.Text.ToLower() + ")");
                        }
                    }
                }
                else  // KFreon: Normal search
                {
                    for (int i = 0; i < texes.Count; i++)
                    {
                        TreeTexInfo tex   = texes[i];
                        string      name  = tex.TexName + " (" + tex.ParentNode.Text.ToLower() + ")";
                        string      s     = name.ToLower();
                        Match       match = Regex.Match(s, pattern, RegexOptions.IgnoreCase);
                        if (match.Success)
                        {
                            list.Add(s);
                        }
                    }
                }
                box.Invoke(new Action(() =>
                {
                    box.Items.Clear();
                    box.Items.AddRange(list.ToArray());
                }));
            }
        }
Пример #10
0
        void RecursivelyCreateFolders(string package, string oldFilter, TexplorerTextureFolder topFolder, TreeTexInfo texture)
        {
            int dotInd = package.IndexOf('.') + 1;
            string name = package;
            if (dotInd != 0)
                name = package.Substring(0, dotInd).Trim('.');

            string filter = oldFilter + '.' + name;
            filter = filter.Trim('.');

            TexplorerTextureFolder newFolder = new TexplorerTextureFolder(name, filter, topFolder);

            // Add texture if part of this folder
            if (newFolder.Filter == texture.FullPackage)
                newFolder.Textures.Add(texture);

            TexplorerTextureFolder existingFolder = topFolder.Folders.FirstOrDefault(folder => newFolder.Name == folder.Name);
            if (existingFolder == null)  // newFolder not found in existing folders
            {
                topFolder.Folders.Add(newFolder);
                AllFolders.Add(newFolder);

                // No more folders in package
                if (dotInd == 0)
                    return;

                string newPackage = package.Substring(dotInd).Trim('.');
                RecursivelyCreateFolders(newPackage, filter, newFolder, texture);
            }
            else
            {  // No subfolders for newFolder yet, need to make them if there are any

                // Add texture if necessary
                if (existingFolder.Filter == texture.FullPackage)
                    existingFolder.Textures.Add(texture);

                // No more folders in package
                if (dotInd == 0)
                    return;

                string newPackage = package.Substring(dotInd).Trim('.');
                RecursivelyCreateFolders(newPackage, filter, existingFolder, texture);
            }
        }
Пример #11
0
        public bool ReadFromFile(string fileName = null)
        {
            lock (Textures)
            {
                if (Textures.Count > 0)  // When it comes back into this after Texplorer has been closed but the Toolset hasn't, it needs to "rebuild" itself i.e. mark itself as valid if it's been loaded previously.
                {
                    Valid = true;
                    return true;
                }
            }
            

            OnPropertyChanged(nameof(Exists));

            string tempFilename = fileName;
            if (fileName == null)
                tempFilename = TreePath;

            if (!File.Exists(tempFilename))
                return false;

            List<TreeTexInfo> TempTextures = new List<TreeTexInfo>();
            try
            {
                using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(tempFilename)))
                {
                    using (GZipStream compressed = new GZipStream(ms, CompressionMode.Decompress))  // Compressed for nice small trees
                    {
                        using (BinaryReader bin = new BinaryReader(compressed))
                        {
                            // Check tree is suitable for this version
                            int magic = bin.ReadInt32();
                            if (magic != 631991)
                            {
                                DebugOutput.PrintLn("Tree too old. Delete and rebuild tree.");
                                return false;
                            }

                            // Tree is suitable. Begin reading
                            int gameVersion = bin.ReadInt32();
                            if (GameDirecs.GameVersion != GameVersion)
                                throw new InvalidOperationException($"Incorrect Tree Loaded. Expected: ME{GameDirecs.GameVersion}, Got: {GameVersion}");

                            TreeVersion = bin.ReadString();

                            // PCCS
                            lock (ScannedPCCs)
                            {
                                int pccCount = bin.ReadInt32();
                                for (int i = 0; i < pccCount; i++)
                                    ScannedPCCs.Add(bin.ReadString());
                            }
                            

                            // Textures
                            lock (Textures)
                            {
                                int texCount = bin.ReadInt32();
                                for (int i = 0; i < texCount; i++)
                                {
                                    TreeTexInfo tex = new TreeTexInfo(GameDirecs);
                                    tex.TexName = bin.ReadString();
                                    tex.Hash = bin.ReadUInt32();
                                    //tex.StorageType = (Texture2D.storage)bin.ReadInt32();
                                    tex.FullPackage = bin.ReadString();
                                    tex.Format = (ImageEngineFormat)bin.ReadInt32();

                                    Thumbnail thumb = new Thumbnail(GameDirecs.ThumbnailCachePath);
                                    thumb.Offset = bin.ReadInt64();
                                    thumb.Length = bin.ReadInt32();
                                    tex.Thumb = thumb;

                                    tex.Mips = bin.ReadInt32();
                                    tex.Width = bin.ReadInt32();
                                    tex.Height = bin.ReadInt32();
                                    tex.LODGroup = bin.ReadString();

                                    int numPccs = bin.ReadInt32();
                                    for (int j = 0; j < numPccs; j++)
                                    {
                                        string userAgnosticPath = ScannedPCCs[bin.ReadInt32()];
                                        int ExpID = bin.ReadInt32();
                                        tex.PCCs.Add(new PCCEntry(Path.Combine(GameDirecs.BasePath, userAgnosticPath), ExpID, GameDirecs));
                                    }

                                    TempTextures.Add(tex);
                                }
                            }

                            lock (Textures)
                                Textures.AddRange(TempTextures);

                            // Sort ME1 files
                            if (GameVersion == 1)
                                ToolsetTextureEngine.ME1_SortTexturesPCCs(Textures);

                            // Texture folders
                            // Top all encompassing node
                            lock (TextureFolders)
                            {
                                TexplorerTextureFolder TopTextureFolder = new TexplorerTextureFolder("All Texture Files", null, null);

                                var folderCount = bin.ReadInt32();
                                var tempFolders = new List<TexplorerTextureFolder>();
                                for (int i = 0; i < folderCount; i++)
                                {
                                    var folder = ReadTreeFolders(bin, TopTextureFolder);
                                    tempFolders.Add(folder);
                                }

                                TopTextureFolder.Folders.AddRange(tempFolders);
                                TextureFolders.Add(TopTextureFolder);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                DebugOutput.PrintLn($"Failed to load tree: {fileName}. Reason: {e.ToString()}");
                return false;
            }

            Valid = true;
            return true;
        }
Пример #12
0
        public void AddTexture(TreeTexInfo tex)
        {
            lock (Locker)
            {
                if (!Textures.Contains<TreeTexInfo>(tex))  // Enable comparison by IEquatable interface
                    Textures.Add(tex);
                else
                {
                    var existing = Textures[Textures.IndexOf(tex)];
                    existing.Update(tex);
                    tex.GenerateThumbnail = null; // clear generation code - frees up many large objects for GC.
                    return;
                }
            }

            // Generate thumbnail if new texture
            tex.GenerateThumbnail();
            tex.GenerateThumbnail = null; // clear generation code - frees up many large objects for GC.
        }