Пример #1
0
        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;
            FileManager      HellgateFileManager;
            string           cookingMessage = "Cooking {0}...";
            string           path           = RevivalMod.DataPath;

            string[] excelToCook   = null;
            string[] stringsToCook = null;
            string[] xmlToCook     = null;
            string[] filesToPack   = null;


            // Step One: Initialize the FileManager
            toolStripStatusLabel.Text = "Initializing the Hellgate File Manager...";
            HellgateFileManager       = new FileManager(Config.HglDir);

            if (HellgateFileManager.HasIntegrity == false)
            {
                Console.WriteLine("Could not initialize the File Manager, Integrity check failed.");
                e.Cancel = true;

                string caption = "Integrity Error";
                string message = "Could not initialize the File Manager. Check Hellgate London is not running and that the installation is not corrupt.";
                MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);

                return;
            }

            // Check if the user wants to cancel.
            if (backgroundWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }

            // Step Two: Revert modifications automatically if flagged in the mod install xml.
            if (RevivalMod.Data.Modifications.DoRevert == true)
            {
                DialogResult dialogResult = DialogResult.Retry;
                while (dialogResult == DialogResult.Retry)
                {
                    toolStripStatusLabel.Text = "Reverting previous Hellgate London modifications...";
                    bool error = Modification.RemoveModifications(HellgateFileManager);
                    if (error == true)
                    {
                        string caption = "Reversion Error";
                        string message = "One or more errors occurred while reverting Hellgate London modifications. Check Hellgate London is not running and the files are not in use. It is highly recommended you ammend this before continuing, even if it means reinstalling the game.";
                        dialogResult = MessageBox.Show(message, caption, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Error);

                        if (dialogResult == DialogResult.Abort)
                        {
                            e.Cancel = true;
                            return;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
                toolStripStatusLabel.Text = "Reloading the Hellgate File Manager...";
                HellgateFileManager.Reload();
            }

            // Check if the user wants to cancel.
            if (backgroundWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }


            // Load the Excel tables
            toolStripStatusLabel.Text = "Caching the Hellgate London excel tables...";
            HellgateFileManager.LoadTableFiles();


            // Step Three: Cook Excel, String and XML files.

            // Search for files to cook
            excelToCook   = Hellpack.SearchForExcelFiles(path);
            stringsToCook = Hellpack.SearchForStringFiles(path);
            xmlToCook     = Hellpack.SearchForXmlFiles(path);

            if (excelToCook != null)
            {
                for (int i = 0; i < excelToCook.Length; i++)
                {
                    // Check if the user wants to cancel.
                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    string epath   = excelToCook[i];
                    string hglPath = epath.Substring(epath.IndexOf("data"), epath.Length - epath.IndexOf("data"));
                    string report  = String.Format(cookingMessage, hglPath);
                    toolStripStatusLabel.Text = report;
                    Hellpack.CookExcelFile(epath);
                }
            }

            if (stringsToCook != null)
            {
                for (int i = 0; i < stringsToCook.Length; i++)
                {
                    // Check if the user wants to cancel.
                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    string epath   = stringsToCook[i];
                    string hglPath = epath.Substring(epath.IndexOf("data"), epath.Length - epath.IndexOf("data"));
                    string report  = String.Format(cookingMessage, hglPath);
                    toolStripStatusLabel.Text = report;
                    Hellpack.CookStringFile(epath);
                }
            }

            if (xmlToCook != null)
            {
                for (int i = 0; i < xmlToCook.Length; i++)
                {
                    // Check if the user wants to cancel.
                    if (backgroundWorker.CancellationPending)
                    {
                        e.Cancel = true;
                        return;
                    }

                    string epath   = xmlToCook[i];
                    string hglPath = epath.Substring(epath.IndexOf("data"), epath.Length - epath.IndexOf("data"));
                    string report  = String.Format(cookingMessage, hglPath);
                    toolStripStatusLabel.Text = report;
                    Hellpack.CookXmlFile(epath, HellgateFileManager);
                }
            }

            // Step Four: Pack the base idx/dat.
            filesToPack = Hellpack.SearchForFilesToPack(path, true);
            toolStripStatusLabel.Text = String.Format("Packing {0}...", RevivalMod.Data.Modifications.ID + ".idx");
            string hglDataPath = Path.Combine(Config.HglDir, "data");
            string modDatPath  = Path.Combine(hglDataPath, RevivalMod.Data.Modifications.ID) + ".idx";
            bool   packResult  = Hellpack.PackDatFile(filesToPack, modDatPath, true);

            if (packResult == false)
            {
                HellgateFileManager.Dispose();

                string caption = "Fatal Error";
                string message = "An error occurred while packing the modification.";
                MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }


            // Step Five: Apply scripts. Scripts are only applied if they are checked or are hidden.
            if (optionalCheckedListBox.CheckedItems.Count != 0 ||
                RevivalMod.Data.Modifications.Scripts.Where(s => s.Type == "hidden").Any() == true)
            {
                List <Script> scriptList = new List <Script>();

                // Append optional list
                foreach (Script script in optionalCheckedListBox.CheckedItems)
                {
                    scriptList.Add(script);
                }

                // Append hidden list
                foreach (Script script in RevivalMod.Data.Modifications.Scripts.Where(s => s.Type == "hidden"))
                {
                    scriptList.Add(script);
                }


                // Reinitalize the File Manager
                HellgateFileManager.Reload();
                HellgateFileManager.LoadTableFiles();



                string    indexPath = Path.Combine(Config.HglDir, "data", RevivalMod.Data.Modifications.ID + "_125.idx");
                IndexFile indexFile = new IndexFile(indexPath);

                // Apply the scripts
                List <string> modifiedTables = new List <string>();
                foreach (Script script in scriptList)
                {
                    // Interface stuff
                    toolStripStatusLabel.Text = String.Format("Applying {0} script...", script.Title);
                    if (script.Extraction != null)
                    {
                        toolStripStatusLabel.Text = "MP conversion in progress, this may between 5 and 10 minutes.";
                    }

                    // The script
                    Modification.ApplyScript(script, ref HellgateFileManager);
                    if (script.Tables != null)
                    {
                        foreach (Script.Table table in script.Tables)
                        {
                            string tableID = table.ID.ToUpper();
                            if (modifiedTables.Contains(tableID) == false)
                            {
                                modifiedTables.Add(tableID);
                            }
                        }
                    }

                    // Copy files if any
                    if (String.IsNullOrEmpty(script.ID) == false)
                    {
                        string optionalPath = Path.Combine(path, "optional", script.ID);
                        if (Directory.Exists(optionalPath) == false)
                        {
                            continue;
                        }

                        string[] fileList = Directory.GetFiles(optionalPath, "*", SearchOption.AllDirectories);
                        if (fileList == null)
                        {
                            continue;
                        }
                        if (fileList.Length == 0)
                        {
                            continue;
                        }

                        foreach (string filePath in fileList)
                        {
                            string relativePath = filePath.Replace(optionalPath + "\\", "");
                            string directory    = Path.GetDirectoryName(relativePath) + "\\";
                            string fileName     = Path.GetFileName(relativePath);
                            byte[] fbuffer      = null;
                            try
                            {
                                fbuffer = File.ReadAllBytes(filePath);
                            }
                            catch (Exception ex)
                            {
                                ExceptionLogger.LogException(ex);
                                continue;
                            }
                            indexFile.AddFile(directory, fileName, fbuffer, DateTime.Now);
                        }
                    }
                }

                // Repack the modified Tables.
                // These go in their own idx/dat under the same name as the base modification with the string _125 appended.
                foreach (string tableID in modifiedTables)
                {
                    DataFile dataTable = HellgateFileManager.DataFiles[tableID];
                    byte[]   ebuffer   = dataTable.ToByteArray();
                    string   fileName  = Path.GetFileName(dataTable.FilePath);
                    string   fileDir   = Path.GetDirectoryName(dataTable.FilePath) + "\\";
                    indexFile.AddFile(fileDir, fileName, ebuffer, DateTime.Now);
                }

                if (indexFile.Count > 0)
                {
                    // Write the index
                    byte[] ibuffer = indexFile.ToByteArray();
                    Crypt.Encrypt(ibuffer);
                    try
                    {
                        File.WriteAllBytes(indexPath, ibuffer);
                        HellgateFileManager.Dispose();
                        indexFile.EndDatAccess();
                        indexFile.Dispose();
                    }
                    catch (Exception ex)
                    {
                        ExceptionLogger.LogException(ex);
                        HellgateFileManager.Dispose();
                        indexFile.EndDatAccess();
                        indexFile.Dispose();

                        string caption = "Fatal Error";
                        string message = "An error occurred while packing the optional modification.";
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
            }

            string msgCaption     = "Success";
            string msgDescription = "Modification successfully installed!";

            MessageBox.Show(msgDescription, msgCaption, MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="script"></param>
        /// <param name="fileManager"></param>
        /// <returns></returns>
        public static bool ApplyScript(Script script, ref FileManager fileManager)
        {
            #region Table Modifications
            if (script.Tables != null)
            {
                foreach (Script.Table table in script.Tables)
                {
                    string tableID = table.ID.ToUpper();
                    if (fileManager.DataFiles.ContainsKey(tableID) == false)
                    {
                        Console.WriteLine(String.Format("Error: The table id is incorrect or does not exist: {0} ", tableID));
                        continue;
                    }

                    ExcelFile dataTable = fileManager.DataFiles[tableID] as ExcelFile;
                    if (dataTable == null)
                    {
                        Console.WriteLine(String.Format("Error: Could not open {0} due to null reference.", tableID));
                        continue;
                    }

                    foreach (Script.Table.Entity entity in table.Entities)
                    {
                        foreach (Script.Table.Entity.Attribute attribute in entity.Attributes)
                        {
                            string   whereColumn = String.Empty;
                            string[] whereValue  = null;
                            int      step        = 0;
                            int      min         = 1;
                            int      max         = 0;
                            int      last        = 0; //for recursive function
                            string   function;
                            int[]    list;

                            try
                            {
                                //determine the range
                                if (entity.ID.Contains(","))
                                {
                                    string[] explode = entity.ID.Split(',');
                                    list = new int[explode.Length];

                                    for (int i = 0; i < list.Length; i++)
                                    {
                                        list[i] = Convert.ToInt32(explode[i]);
                                    }
                                }
                                else
                                {
                                    if (entity.ID.Contains("*"))
                                    {
                                        min = 0;
                                        max = dataTable.Count - 1;
                                    }
                                    else if (entity.ID.Contains("-"))
                                    {
                                        int idx = entity.ID.IndexOf('-');
                                        int len = entity.ID.Length - idx - 1;
                                        min = Convert.ToInt32(entity.ID.Substring(0, idx));
                                        max = Convert.ToInt32(entity.ID.Substring(idx + 1, len));
                                    }
                                    else
                                    {
                                        min = Convert.ToInt32(entity.ID);
                                        max = Convert.ToInt32(entity.ID);
                                    }

                                    int listlen = max - min + 1;
                                    list = new int[listlen];
                                    int i = 0;

                                    for (int row = min; row <= max; row++)
                                    {
                                        list[i++] = row;
                                    }
                                }

                                //check for where condition
                                if (attribute.Where != null)
                                {
                                    int equalsIndex = attribute.Where.IndexOf('=');
                                    if (equalsIndex == -1)
                                    {
                                        Console.WriteLine("Bad syntax in where condition.");
                                        return(false);
                                    }
                                    whereColumn = attribute.Where.Substring(0, equalsIndex);
                                    string whereValueString = attribute.Where.Substring(equalsIndex + 1, attribute.Where.Length - equalsIndex - 1);
                                    if (whereValueString.Contains('|'))
                                    {
                                        whereValue = whereValueString.Split('|');
                                    }
                                    else
                                    {
                                        whereValue = new string[] { whereValueString };
                                    }
                                }

                                //determine function
                                if (attribute.Bit != null)
                                {
                                    function = "bitwise";
                                }
                                else if (attribute.Operation == null)
                                {
                                    function = "replace";
                                }
                                else if (attribute.Operation.Contains("*"))
                                {
                                    function = "multiply";
                                }
                                else if (attribute.Operation.Contains("/"))
                                {
                                    function = "divide";
                                }
                                else if (attribute.Operation.Contains("+"))
                                {
                                    string s = attribute.Operation.Remove(0);
                                    step     = Convert.ToInt32(s);
                                    function = "recursive";
                                }
                                else if (attribute.Operation.Contains("-"))
                                {
                                    step     = Convert.ToInt32(attribute.Operation);
                                    function = "recursive";
                                }
                                else
                                {
                                    continue; // syntax error
                                }

                                //main loop, alters the dataset
                                foreach (int row in list)
                                {
                                    object obj          = null;
                                    string col          = attribute.ID;
                                    Type   type         = dataTable.DataType.GetField(col).FieldType;
                                    Object currentValue = dataTable.DataType.GetField(col).GetValue(dataTable.Rows[row]);

                                    if (String.IsNullOrEmpty(whereColumn) == false)
                                    {
                                        Type   typeWhere         = dataTable.DataType.GetField(whereColumn).FieldType;
                                        Object currentValueWhere = dataTable.DataType.GetField(whereColumn).GetValue(dataTable.Rows[row]);
                                        if (whereValue.Where(val => FileTools.StringToObject(val, typeWhere).Equals(currentValueWhere)).Any() == false)
                                        {
                                            continue;
                                        }
                                    }

                                    switch (function)
                                    {
                                    case "replace":
                                        obj = FileTools.StringToObject(attribute.Data, type);
                                        break;

                                    case "multiply":
                                        if (type.Equals(typeof(int)))
                                        {
                                            obj = (int)currentValue * Convert.ToInt32(attribute.Data);
                                        }
                                        else if (type.Equals(typeof(float)))
                                        {
                                            obj = (float)currentValue * Convert.ToSingle(attribute.Data);
                                        }
                                        break;

                                    case "divide":
                                        if (type.Equals(typeof(int)))
                                        {
                                            obj = (int)currentValue / Convert.ToInt32(attribute.Data);
                                        }
                                        else if (type.Equals(typeof(float)))
                                        {
                                            obj = (float)currentValue / Convert.ToSingle(attribute.Data);
                                        }
                                        break;

                                    case "bitwise":
                                        uint bit     = (uint)Enum.Parse(type, attribute.Bit, true);
                                        uint mask    = (uint)currentValue;
                                        bool flick   = Convert.ToBoolean(attribute.Data);
                                        bool current = (mask & bit) > 0;
                                        if (flick != current)
                                        {
                                            obj = mask ^= bit;
                                        }
                                        else
                                        {
                                            obj = mask;
                                        }
                                        break;

                                    case "recursive":
                                        if (row.Equals(min))    //first time only
                                        {
                                            if (type.Equals(typeof(int)))
                                            {
                                                obj  = Convert.ToInt32(attribute.Data);
                                                last = (int)obj;
                                            }
                                        }
                                        else
                                        {
                                            last += step;
                                            obj   = last;
                                        }
                                        break;
                                    }
                                    dataTable.DataType.GetField(col).SetValue(dataTable.Rows[row], obj);
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionLogger.LogException(ex);
                                return(false);
                            }
                        }
                    }
                    fileManager.DataFiles[tableID] = dataTable;
                }
            }
            #endregion

            #region Extraction Script
            if (script.Extraction != null)
            {
                string sourcePath      = Path.Combine(fileManager.HellgateDataPath, script.Extraction.Source + ".idx");
                string destinationPath = sourcePath.Replace(script.Extraction.Source, script.Extraction.Destination);

                // Check source index exists
                if (File.Exists(sourcePath) == false)
                {
                    return(false);
                }

                // Try open the index file
                //byte[] sbuffer;
                PackFile sourceIndex      = new IndexFile(sourcePath);
                PackFile destinationIndex = new IndexFile(destinationPath);
                try
                {
                    sourceIndex.ParseFileBytes(File.ReadAllBytes(sourcePath));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: {0} filed to load. Make sure you have run Hellgate London at least once (MP version for MP files) before installating this modification.", sourceIndex);
                    ExceptionLogger.LogException(ex);
                    return(false);
                }

                sourceIndex.BeginDatReading();

                // Extract each path/file
                foreach (PackFileEntry fileEntry in sourceIndex.Files)
                {
                    if (!script.Extraction.paths.Where(p => Regex.IsMatch(fileEntry.Path, p.Replace(@"\", @"\\"))).Any())
                    {
                        continue;
                    }

                    byte[] fileBytes = sourceIndex.GetFileBytes(fileEntry);
                    //if (fileEntry.FileNameString.Contains(XmlCookedFile.FileExtention))
                    //{
                    //    try
                    //    {
                    //        XmlCookedFile xmlCookedFile = new XmlCookedFile();
                    //        xmlCookedFile.Uncook(fileBytes);

                    //        XmlCookedFile reCooked = new XmlCookedFile();
                    //        fileBytes = reCooked.CookXmlDocument(xmlCookedFile.XmlDoc);
                    //    }
                    //    catch (Exception) { }
                    //}

                    destinationIndex.AddFile(fileEntry.Directory, fileEntry.Name, fileBytes);
                }

                // Write the file
                byte[] ibuffer = destinationIndex.ToByteArray();
                Crypt.Encrypt(ibuffer);
                try
                {
                    File.WriteAllBytes(destinationIndex.Path, ibuffer);
                }
                catch (Exception ex)
                {
                    ExceptionLogger.LogException(ex);
                    return(false);
                }
                finally
                {
                    sourceIndex.EndDatAccess();
                    sourceIndex.Dispose();
                    destinationIndex.Dispose();
                }
            }
            #endregion

            return(true);
        }