Пример #1
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);
        }