Example #1
0
        public int _GetExcelRowIndex(ExcelFile excelTable, String value)
        {
            FieldInfo field         = excelTable.Attributes.RowType.GetFields()[0];
            bool      isStringField = (field.FieldType == typeof(String));

            ObjectDelegator excelDelegator = DataFileDelegators[excelTable.StringId];

            ObjectDelegator.FieldGetValueDelegate getValue = excelDelegator[field.Name];

            int i = 0;

            foreach (Object row in excelTable.Rows)
            {
                if (isStringField)
                {
                    String val = (String)getValue(row);
                    if (val == value)
                    {
                        return(i);
                    }
                }
                else // string offset
                {
                    int    offset    = (int)getValue(row);
                    String stringVal = excelTable.ReadStringTable(offset);
                    if (stringVal == value)
                    {
                        return(i);
                    }
                }
                i++;
            }

            return(-1);
        }
Example #2
0
        /// <summary>
        /// Gets the RowIndex of a row containing a string, using the column name to search by.
        /// Returns -2 on error, -1 on not found
        /// </summary>
        /// <param name="stringId">An Excel Table StringId.</param>
        /// <param name="value">The value to search for.</param>
        /// <param name="colName">The column name to check.</param>
        /// <returns>Row index string found in column colName. (-2=error, -1=not found)</returns>
        public int GetExcelRowIndexFromStringId(String stringId, String value, String colName)
        {
            if (DataFiles == null || String.IsNullOrEmpty(stringId) || DataFiles.ContainsKey(stringId) == false)
            {
                return(-2);
            }

            ExcelFile excelTable = DataFiles[stringId] as ExcelFile;

            if (excelTable == null)
            {
                return(-2);
            }

            ObjectDelegator excelDelegator = DataFileDelegators[stringId];

            ObjectDelegator.FieldDelegate fieldDelegate = excelDelegator.GetFieldDelegate(colName);
            if (fieldDelegate == null)
            {
                return(-2);
            }

            bool isStringField = (fieldDelegate.FieldType == typeof(String));
            int  rowIndex      = -1;

            foreach (Object row in excelTable.Rows)
            {
                rowIndex++;

                if (isStringField)
                {
                    if ((String)fieldDelegate.GetValue(row) == value)
                    {
                        return(rowIndex);
                    }
                }
                else
                {
                    int offset = (int)fieldDelegate.GetValue(row);
                    if (excelTable.ReadStringTable(offset) == value)
                    {
                        return(rowIndex);
                    }
                }
            }

            return(-1);
        }
Example #3
0
        /// <summary>
        /// Obtains a String value from an excel table using a StringId, column name, and row index.
        /// Returns null on fail
        /// </summary>
        /// <param name="stringId">An Excel Table StringId.</param>
        /// <param name="rowIndex">The row index to obtain the value from.</param>
        /// <param name="colName">The column name to check.</param>
        /// <returns></returns>
        public String GetExcelStringFromStringId(String stringId, int rowIndex, String colName)
        {
            if (DataFiles == null || String.IsNullOrEmpty(stringId) || DataFiles.ContainsKey(stringId) == false)
            {
                return(null);
            }

            ExcelFile excelTable = DataFiles[stringId] as ExcelFile;

            if (excelTable == null)
            {
                return(null);
            }
            if (rowIndex < 0 || rowIndex >= excelTable.Rows.Count)
            {
                return(null);
            }

            ObjectDelegator excelDelegator = DataFileDelegators[stringId];

            ObjectDelegator.FieldDelegate fieldDelegate = excelDelegator.GetFieldDelegate(colName);
            if (fieldDelegate == null)
            {
                return(null);
            }

            bool   isStringField = (fieldDelegate.FieldType == typeof(String));
            Object row           = excelTable.Rows[rowIndex];

            if (isStringField)
            {
                return((String)fieldDelegate.GetValue(row));
            }

            int    offset    = (int)fieldDelegate.GetValue(row);
            String stringVal = excelTable.ReadStringTable(offset);

            return(stringVal);
        }
Example #4
0
        private String _GetExcelStringFromExcelFile(ExcelFile excelTable, int rowIndex, int colIndex)
        {
            if (excelTable == null || rowIndex >= excelTable.Rows.Count)
            {
                return(null);
            }

            ObjectDelegator tableDelegator = DataFileDelegators[excelTable.StringId];

            ObjectDelegator.FieldDelegate fieldDelegate = tableDelegator.GetPublicFieldDelegate(colIndex);

            bool   isStringField = (fieldDelegate.FieldType == typeof(String));
            Object row           = excelTable.Rows[rowIndex];

            if (isStringField)
            {
                return((String)fieldDelegate.GetValue(row));
            }

            int    offset    = (int)fieldDelegate.GetValue(row);
            String stringVal = excelTable.ReadStringTable(offset);

            return(stringVal);
        }
Example #5
0
        /// <summary>
        /// Function to test all excel files cooking/recooking/etc to/from byte arrays and csv types.
        /// </summary>
        public static void TestExcelCooking(bool doTCv4 = false)
        {
            /*																0
            0   byte[] fileBytes = fileManager.GetFileBytes(excelFile.FilePath, true);	Bytes													0-gen bytes

                                                                            0      1           2        3            4
            foreach (DataFile dataFile in fileManager.DataFiles.Values)				Bytes->Xls												1-gen Xls file
            1   byte[] dataFileBytes = dataFile.ToByteArray();							Bytes->Xls->Bytes										1-gen bytes
            fromBytesExcel.ParseData(dataFileBytes);								Bytes->Xls->Bytes->Xls									2-gen Xls file
            1a  byte[] bytesXlsBytesXlsBytes = fromBytesExcel.ToByteArray();			Bytes->Xls->Bytes->Xls->Bytes							2-gen bytes
            1ba byte[] bytesXlsCsv = dataFile.ExportCSV(fileManager);					Bytes->Xls->CSV											1-gen CSV-bytes
            bytesXlsCsvXls.ParseCSV(bytesXlsCsv, fileManager);						Bytes->Xls->CSV  ->Xls									2-gen Xls file
            1bb byte[] bytesXlsCsvXlsBytes = bytesXlsCsvXls.ToByteArray();				Bytes->Xls->CSV  ->Xls->Bytes							2-gen CSV-bytes
            1b  byte[] csvBytes = fromBytesExcel.ExportCSV(fileManager);				Bytes->Xls->Bytes->Xls->CSV								2-gen CSV file
            csvExcel.ParseCSV(csvBytes, fileManager);								Bytes->Xls->Bytes->Xls->CSV->Xls						3-gen Xls file
            1c  byte[] bytesXlsBytesXlsCsvXlsBytes = csvExcel.ToByteArray();			Bytes->Xls->Bytes->Xls->CSV->Xls->Bytes					3-gen bytes
            finalExcel.ParseData(recookedExcelBytes);								Bytes->Xls->Bytes->Xls->CSV->Xls->Bytes->Xls			4-gen Xls file
            1d  byte[] csvCheck = finalExcel.ExportCSV(fileManager);					Bytes->Xls->Bytes->Xls->CSV->Xls->Bytes->Xls->CSV		4-gen CSV file
            1e  byte[] finalCheck = finalExcel.ToByteArray();							Bytes->Xls->Bytes->Xls->CSV->Xls->Bytes->Xls->Bytes		4-gen bytes
             */

            String root = @"C:\excel_debug";
            FileManager.ClientVersions clientVersion = FileManager.ClientVersions.SinglePlayer;
            if (doTCv4)
            {
                root = Path.Combine(root, "tcv4");
                clientVersion = FileManager.ClientVersions.TestCenter;
            }
            root += @"\"; // lazy
            Directory.CreateDirectory(root);

            FileManager fileManager = new FileManager(Config.HglDir, clientVersion);
            fileManager.BeginAllDatReadAccess();
            fileManager.LoadTableFiles();
            ExcelFile.EnableDebug = true;

            int checkedCount = 0;
            List<String> excelFailed = new List<String>();
            foreach (DataFile bytesXls in fileManager.DataFiles.Values)
            {
                ExcelFile excelFile = bytesXls as ExcelFile;
                if (excelFile == null) continue;

                const String debugStr = "SKILLS";
                //if (excelFile.StringId != debugStr) continue;
                //if (excelFile.StringId == debugStr)
                //{
                //    int bp = 0;
                //}

                checkedCount++;
                Debug.Write(String.Format("Checking {0}... ", bytesXls.StringId));

                byte[] bytes = fileManager.GetFileBytes(excelFile.FilePath, true);
                try
                {
                    byte[] bytesXlsBytes = bytesXls.ToByteArray();
                    if (bytesXls.StringId == "SOUNDS" && false)
                    {
                        byte[] csvBytesSounds = excelFile.ExportCSV(fileManager);
                        ExcelFile soundsCSV = new ExcelFile(excelFile.FilePath);
                        soundsCSV.ParseCSV(csvBytesSounds, fileManager);
                        byte[] soundsBytes = soundsCSV.ToByteArray();
                        //byte[] soundsBytesFromCSV = soundsCSV.ExportCSV();
                        //ExcelFile soundsCSVFromBytesFromCSV = new ExcelFile(soundsBytesFromCSV, fileEntry.RelativeFullPathWithoutPatch);

                        // some brute force ftw
                        byte[][] bytesArrays = new[] { bytes, soundsBytes };
                        for (int z = 0; z < bytesArrays.Length; z++)
                        {
                            byte[] bytesBrute = bytesArrays[z];

                            int offset = 0x20;
                            int stringsBytesCount = FileTools.ByteArrayToInt32(bytesBrute, ref offset);

                            StringWriter stringWriterByteStrings = new StringWriter();
                            stringWriterByteStrings.WriteLine(stringsBytesCount + " bytes");
                            List<String> strings = new List<String>();
                            List<int> offsets = new List<int>();

                            while (offset < stringsBytesCount + 0x20)
                            {
                                String str = FileTools.ByteArrayToStringASCII(bytesBrute, offset);
                                strings.Add(str);
                                offsets.Add(offset);

                                offset += str.Length + 1;
                            }

                            String[] sortedStrings = strings.ToArray();
                            int[] sortedOffsets = offsets.ToArray();
                            Array.Sort(sortedStrings, sortedOffsets);
                            stringWriterByteStrings.WriteLine(strings.Count + " strings");
                            for (int i = 0; i < strings.Count; i++)
                            {
                                stringWriterByteStrings.WriteLine(sortedStrings[i] + "\t\t\t" + sortedOffsets[i]);
                            }

                            File.WriteAllText(@"C:\excel_debug\strings" + z + ".txt", stringWriterByteStrings.ToString());
                        }
                    }

                    Debug.Write("ToByteArray... ");
                    if (bytes.Length != bytesXlsBytes.Length && !doTCv4) // some TCv4 tables don't have their sort columns yet
                    {
                        Debug.WriteLine("ToByteArray() dataFileBytes has differing length: " + bytesXls.StringId);
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    ExcelFile bytesXlsBytesXls = new ExcelFile(excelFile.FilePath, fileManager.ClientVersion);
                    bytesXlsBytesXls.ParseData(bytesXlsBytes);
                    Debug.Write("new ExcelFile... ");
                    if (!bytesXlsBytesXls.HasIntegrity)
                    {
                        Debug.WriteLine("fromBytesExcel = new Excel from ToByteArray() failed!");
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    // more checks
                    Debug.Write("ToByteArray->ToByteArray... ");
                    byte[] bytesXlsBytesXlsBytes = bytesXlsBytesXls.ToByteArray(); // bytesXlsBytesXlsBytes
                    if (bytes.Length != bytesXlsBytesXlsBytes.Length && !doTCv4) // some TCv4 tables don't have their sort columns yet
                    {
                        Debug.WriteLine("ToByteArray() dataFileBytesFromToByteArray has differing length!");
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1a.toByteArrayFromByteArray", bytesXlsBytesXlsBytes);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    // check generated sort index arrays);
                    Debug.Write("IndexSortArrays... ");
                    if (excelFile.IndexSortArray != null)
                    {
                        if (bytesXlsBytesXls.IndexSortArray == null || excelFile.IndexSortArray.Count != bytesXlsBytesXls.IndexSortArray.Count)
                        {
                            Debug.WriteLine("fromBytesExcel has not-matching IndexSortArray count!");
                            excelFailed.Add(bytesXls.StringId);
                            continue;
                        }

                        bool hasError = false;
                        for (int i = 0; i < excelFile.IndexSortArray.Count; i++)
                        {
                            if (excelFile.IndexSortArray[i].SequenceEqual(bytesXlsBytesXls.IndexSortArray[i])) continue;

                            Debug.WriteLine(String.Format("IndexSortArray[{0}] NOT EQUAL to original!", i));
                            hasError = true;
                        }

                        if (hasError)
                        {
                            File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                            excelFailed.Add(bytesXls.StringId);
                            continue;
                        }
                    }

                    // some csv stuff
                    Debug.Write("BaseXls->BaseCSV==");
                    byte[] bytesXlsCsv = bytesXls.ExportCSV(fileManager); // Bytes->Xls->CSV
                    Debug.Write("ExportCSV... ");
                    byte[] bytesXlsBytesXlsCsv = bytesXlsBytesXls.ExportCSV(fileManager);
                    if (!bytesXlsCsv.SequenceEqual(bytesXlsBytesXlsCsv))
                    {
                        Debug.WriteLine("FALSE!");
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1b.bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1ba.bytesXlsCsv.csv", bytesXlsCsv);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    ExcelFile bytesXlsCsvXls = new ExcelFile(excelFile.FilePath, fileManager.ClientVersion);
                    bytesXlsCsvXls.ParseCSV(bytesXlsCsv, fileManager);
                    byte[] bytesXlsCsvXlsBytes = bytesXlsCsvXls.ToByteArray(); // used later as well
                    if (excelFile.ScriptBuffer == null && // can only compare here for no-script tables - can't compare to pure-base xls-bytes as xls->csv->xls rearranges script code
                        !excelFile.HasStringBuffer) // xls->csv->xls also rearranges the strings buffer
                    {
                        Debug.Write("BytesXlsBytesXlsBytes==BytesXlsCsvXlsBytes... ");
                        if (!bytesXlsBytesXlsBytes.SequenceEqual(bytesXlsCsvXlsBytes))
                        {
                            Debug.WriteLine("FALSE!");
                            File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1b.bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                            File.WriteAllBytes(root + bytesXls.StringId + "1ba.bytesXlsCsv.csv", bytesXlsCsv);
                            File.WriteAllBytes(root + bytesXls.StringId + "1bb.bytesXlsCsvXlsBytes", bytesXlsCsvXlsBytes);
                            excelFailed.Add(bytesXls.StringId);
                            continue;
                        }

                        Debug.Write("BytesXlsBytes==BytesXlsCsvXlsBytes... ");
                        if (!bytesXlsBytes.SequenceEqual(bytesXlsCsvXlsBytes))
                        {
                            Debug.WriteLine("FALSE!");
                            File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                            File.WriteAllBytes(root + bytesXls.StringId + "1b.bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                            File.WriteAllBytes(root + bytesXls.StringId + "1ba.bytesXlsCsv.csv", bytesXlsCsv);
                            File.WriteAllBytes(root + bytesXls.StringId + "1bb.bytesXlsCsvXlsBytes", bytesXlsCsvXlsBytes);
                            excelFailed.Add(bytesXls.StringId);
                            continue;
                        }
                    }

                    Debug.Write("BytesXlsBytesXlsCsv -> new ExcelFile");
                    ExcelFile bytesXlsBytesXlsCsvXls = new ExcelFile(excelFile.FilePath, fileManager.ClientVersion);
                    bytesXlsBytesXlsCsvXls.ParseCSV(bytesXlsBytesXlsCsv, fileManager);
                    Debug.Write("... ");
                    if (!bytesXlsBytesXlsCsvXls.HasIntegrity)
                    {
                        Debug.WriteLine("Failed!");
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1b.bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1ba.bytesXlsCsv.csv", bytesXlsCsv);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    byte[] bytesXlsBytesXlsCsvXlsBytes = bytesXlsBytesXlsCsvXls.ToByteArray();
                    Debug.Write("BytesXlsCsvXlsBytes==BytesXlsBytesXlsCsvXlsBytes... ");
                    if (!bytesXlsCsvXlsBytes.SequenceEqual(bytesXlsBytesXlsCsvXlsBytes))
                    {
                        Debug.WriteLine("FALSE!");
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1b.bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1ba.bytesXlsCsv.csv", bytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1bb.bytesXlsCsvXlsBytes", bytesXlsCsvXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1c.bytesXlsBytesXlsCsvXlsBytes", bytesXlsBytesXlsCsvXlsBytes);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    if (!fileManager.IsVersionTestCenter)
                    {
                        Debug.Write("StructureId... ");
                        UInt32 structureId = BitConverter.ToUInt32(bytes, 4);
                        UInt32 fromCSVStructureId = BitConverter.ToUInt32(bytesXlsBytesXlsCsvXlsBytes, 4);
                        if (structureId != fromCSVStructureId)
                        {
                            Debug.WriteLine("Structure Id value do not match: " + structureId + " != " + fromCSVStructureId);
                            excelFailed.Add(bytesXls.StringId);
                            continue;
                        }
                    }

                    Debug.Write("Almost Done... ");
                    ExcelFile bytesXlsBytesXlsCsvXlsBytesXls = new ExcelFile(excelFile.FilePath, fileManager.ClientVersion);
                    bytesXlsBytesXlsCsvXlsBytesXls.ParseData(bytesXlsBytesXlsCsvXlsBytes);
                    byte[] bytesXlsBytesXlsCsvXlsBytesXlsCsv = bytesXlsBytesXlsCsvXlsBytesXls.ExportCSV(fileManager);

                    int recookedLength = bytesXlsBytesXlsCsvXlsBytes.Length;
                    if (excelFile.StringId == "SKILLS") recookedLength += 12; // 12 bytes in int ptr data not used/referenced at all and are removed/lost in bytes -> csv -> bytes
                    if (bytes.Length != recookedLength && !doTCv4) // some TCv4 tables don't have their sort columns yet
                    {
                        Debug.WriteLine("Recooked Excel file has differing length!");
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1b.bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1ba.bytesXlsCsv.csv", bytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1c.bytesXlsBytesXlsCsvXlsBytes", bytesXlsBytesXlsCsvXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1d.bytesXlsBytesXlsCsvXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsvXlsBytesXlsCsv);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    Debug.Assert(bytesXlsBytesXlsCsvXlsBytesXls.HasIntegrity);
                    byte[] bytesXlsBytesXlsCsvXlsBytesXlsBytes = bytesXlsBytesXlsCsvXlsBytesXls.ToByteArray();
                    if (excelFile.StringId == "SKILLS") Debug.Assert(bytesXlsBytesXlsCsvXlsBytesXlsBytes.Length + 12 == bytesXlsBytes.Length);
                    else Debug.Assert(bytesXlsBytesXlsCsvXlsBytesXlsBytes.Length == bytesXlsBytes.Length || doTCv4);

                    if (!bytesXlsBytesXlsCsv.SequenceEqual(bytesXlsBytesXlsCsvXlsBytesXlsCsv))
                    {
                        Debug.WriteLine("csvBytes.SequenceEqual failed!");
                        File.WriteAllBytes(root + bytesXls.StringId + "0.bytes", bytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1.bytesXlsBytes", bytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1a.bytesXlsBytesXlsBytes", bytesXlsBytesXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1b.bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1ba.bytesXlsCsv.csv", bytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1c.bytesXlsBytesXlsCsvXlsBytes", bytesXlsBytesXlsCsvXlsBytes);
                        File.WriteAllBytes(root + bytesXls.StringId + "1d.bytesXlsBytesXlsCsvXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsvXlsBytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + "1e.bytesXlsBytesXlsCsvXlsBytesXlsBytes", bytesXlsBytesXlsCsvXlsBytesXlsBytes);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    Debug.Write("\nPerforming deep scan: ");
                    ObjectDelegator objectDelegator = fileManager.DataFileDelegators[excelFile.StringId];
                    int lastPercent = 0;
                    int col = 0;
                    bool failed = false;
                    foreach (FieldDelegate fieldDelegate in objectDelegator)
                    {
                        int percent = col * 100 / objectDelegator.FieldCount - 1;
                        int dotCount = percent - lastPercent;
                        for (int i = 0; i < dotCount; i++) Debug.Write(".");

                        lastPercent = percent;

                        ExcelFile.OutputAttribute excelAttribute = ExcelFile.GetExcelAttribute(fieldDelegate.Info);
                        bool isArray = (fieldDelegate.FieldType.BaseType == typeof(Array));

                        for (int row = 0; row < excelFile.Rows.Count; row++)
                        {
                            Object obj1 = fieldDelegate.GetValue(excelFile.Rows[row]);
                            Object obj2 = fieldDelegate.GetValue(bytesXlsBytesXlsCsvXlsBytesXls.Rows[row]);

                            if (isArray)
                            {
                                //if (excelFile.StringId == "TREASURE")
                                //{
                                //    int bp = 0;
                                //}
                                IEnumerator arrayEnumator1 = ((Array)obj1).GetEnumerator();
                                IEnumerator arrayEnumator2 = ((Array)obj2).GetEnumerator();
                                int index = -1;
                                while (arrayEnumator1.MoveNext() && arrayEnumator2.MoveNext())
                                {
                                    index++;
                                    Object elementVal1 = arrayEnumator1.Current;
                                    Object elementVal2 = arrayEnumator2.Current;

                                    if (elementVal1.Equals(elementVal2)) continue;

                                    Debug.WriteLine(String.Format("Array Element '{0}' != '{1}' on col({2}) = '{3}', row({4}), index({5})", elementVal1, elementVal2, col, fieldDelegate.Name, row, index));
                                    failed = true;
                                    break;
                                }
                                if (failed) break;

                                continue;
                            }

                            if (obj1.Equals(obj2)) continue;

                            if (excelAttribute != null)
                            {
                                if (excelAttribute.IsStringOffset)
                                {
                                    int offset1 = (int)obj1;
                                    int offset2 = (int)obj2;

                                    String str1 = excelFile.ReadStringTable(offset1);
                                    String str2 = bytesXlsBytesXlsCsvXlsBytesXls.ReadStringTable(offset2);

                                    if (str1 == str2) continue;

                                    obj1 = str1;
                                    obj2 = str2;
                                }

                                if (excelAttribute.IsScript)
                                {
                                    int offset1 = (int)obj1;
                                    int offset2 = (int)obj2;

                                    Int32[] script1 = excelFile.ReadScriptTable(offset1);
                                    Int32[] script2 = bytesXlsBytesXlsCsvXlsBytesXls.ReadScriptTable(offset2);

                                    if (script1.SequenceEqual(script2)) continue;

                                    obj1 = script1.ToString(",");
                                    obj2 = script2.ToString(",");
                                }
                            }

                            String str = obj1 as String;
                            if ((str != null && str.StartsWith("+N%-N% base damage as [elem]")) ||  // "+N%-N% base damage as [elem]…" != "+N%-N% base damage as [elem]?" on col(2) = 'exampleDescription', row(132) // the '?' at end
                                fieldDelegate.Name == "bonusStartingTreasure")                      // refernces multiple different blank rows
                                continue;

                            Debug.WriteLine(String.Format("'{0}' != '{1}' on col({2}) = '{3}', row({4})", obj1, obj2, col, fieldDelegate.Name, row));
                            failed = true;
                            break;
                        }
                        if (failed) break;

                        col++;
                    }

                    if (failed)
                    {
                        File.WriteAllBytes(root + bytesXls.StringId + ".bytesXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsv);
                        File.WriteAllBytes(root + bytesXls.StringId + ".bytesXlsBytesXlsCsvXlsBytesXlsCsv.csv", bytesXlsBytesXlsCsvXlsBytesXlsCsv);
                        excelFailed.Add(bytesXls.StringId);
                        continue;
                    }

                    Debug.WriteLine("OK\n");
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Excel file Exception: " + bytesXls.StringId + "\n" + e);
                }
            }

            Debug.WriteLine(checkedCount + " excel files checked.");

            if (excelFailed.Count <= 0) return;
            Debug.WriteLine(excelFailed.Count + " failed excel checks! (" + ((float)excelFailed.Count / checkedCount * 100) + "%)");
            foreach (String str in excelFailed) Debug.Write(str + ", ");
        }
Example #6
0
        private String _GetExcelStringFromExcelFile(ExcelFile excelTable, int rowIndex, int colIndex)
        {
            if (excelTable == null || rowIndex >= excelTable.Rows.Count) return null;

            ObjectDelegator tableDelegator = DataFileDelegators[excelTable.StringId];
            ObjectDelegator.FieldDelegate fieldDelegate = tableDelegator.GetPublicFieldDelegate(colIndex);

            bool isStringField = (fieldDelegate.FieldType == typeof(String));
            Object row = excelTable.Rows[rowIndex];

            if (isStringField) return (String)fieldDelegate.GetValue(row);

            int offset = (int)fieldDelegate.GetValue(row);
            String stringVal = excelTable.ReadStringTable(offset);
            return stringVal;
        }
Example #7
0
        public int _GetExcelRowIndex(ExcelFile excelTable, String value)
        {
            FieldInfo field = excelTable.Attributes.RowType.GetFields()[0];
            bool isStringField = (field.FieldType == typeof(String));

            ObjectDelegator excelDelegator = DataFileDelegators[excelTable.StringId];
            ObjectDelegator.FieldGetValueDelegate getValue = excelDelegator[field.Name];

            int i = 0;
            foreach (Object row in excelTable.Rows)
            {
                if (isStringField)
                {
                    String val = (String)getValue(row);
                    if (val == value) return i;
                }
                else // string offset
                {
                    int offset = (int)getValue(row);
                    String stringVal = excelTable.ReadStringTable(offset);
                    if (stringVal == value) return i;
                }
                i++;
            }

            return -1;
        }
Example #8
0
        private DataTable _LoadExcelTable(ExcelFile excelFile, bool doRelations, bool force)
        {
            String tableName = excelFile.StringId;
            DataTable dataTable = XlsDataSet.Tables[tableName];
            if (dataTable != null && !force) return dataTable;
            if (dataTable != null)
            {
                XlsDataSet.Relations.Clear();
                XlsDataSet.Tables.Remove(tableName);
            }
            dataTable = XlsDataSet.Tables.Add(tableName);
            dataTable.TableName = tableName;
            dataTable.ExtendedProperties.Add("FileHeader", excelFile._excelFileHeader.DeepClone());

            Type dataType = excelFile.Attributes.RowType;
            List<OutputAttribute> outputAttributes = new List<OutputAttribute>();

            #region Generate Columns
            DataColumn indexColumn = dataTable.Columns.Add("Index");
            indexColumn.AutoIncrement = true;
            indexColumn.Unique = true;
            dataTable.PrimaryKey = new[] { indexColumn };
            outputAttributes.Add(null);

            FieldInfo[] fieldInfos = dataType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (FieldInfo fieldInfo in fieldInfos)
            {
                OutputAttribute excelAttribute = ExcelFile.GetExcelAttribute(fieldInfo);

                // The only private field we add is the TableHeader
                if (fieldInfo.IsPrivate)
                {
                    if (fieldInfo.FieldType != typeof(ExcelFile.RowHeader)) continue;

                    outputAttributes.Add(null);
                    dataTable.Columns.Add(fieldInfo.Name, typeof(String));
                    continue;
                }

                Type fieldType = fieldInfo.FieldType;
                bool isArray = false;
                bool isEnum = false;
                if (fieldInfo.FieldType.BaseType == typeof(Array))
                {
                    fieldType = typeof(String);
                    isArray = true;
                }
                else if (fieldInfo.FieldType.BaseType == typeof(Enum) && excelAttribute == null)
                {
                    fieldType = fieldInfo.FieldType;
                    isEnum = true;
                }

                DataColumn dataColumn = dataTable.Columns.Add(fieldInfo.Name, fieldType);
                if (isArray)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsArray, true);
                }
                else if (isEnum)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsEnum, true);
                }

                if (excelAttribute == null)
                {
                    outputAttributes.Add(null);
                    continue;
                }

                outputAttributes.Add(excelAttribute);

                if (excelAttribute.IsStringOffset)
                {
                    dataColumn.DataType = typeof(String);
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsStringOffset, true);
                    dataColumn.DefaultValue = String.Empty;
                }

                if (excelAttribute.IsScript)
                {
                    dataColumn.DataType = typeof(String);
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsScript, true);
                    dataColumn.DefaultValue = String.Empty;
                }

                if (excelAttribute.IsSecondaryString)
                {
                    dataColumn.DataType = typeof(String);
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsSecondaryString, true);
                    dataColumn.DefaultValue = String.Empty;
                }

                if (excelAttribute.IsStringIndex)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsStringIndex, true);

                    // Add new column for the string
                    DataColumn dataColumnString = dataTable.Columns.Add(fieldInfo.Name + "_string", typeof(String));
                    dataColumnString.DefaultValue = String.Empty;
                    outputAttributes.Add(null);
                    dataColumnString.ExtendedProperties.Add(ColumnKeys.IsRelationGenerated, true);
                }

                if (excelAttribute.IsTableIndex)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsTableIndex, true);

                    // Add new column for the string
                    DataColumn dataColumnString = dataTable.Columns.Add(fieldInfo.Name + "_string", typeof(String));
                    dataColumnString.DefaultValue = String.Empty;
                    outputAttributes.Add(null);
                    dataColumnString.ExtendedProperties.Add(ColumnKeys.IsRelationGenerated, true);
                }

                if (excelAttribute.IsBitmask)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsBitmask, true);
                }

                if (excelAttribute.IsBool)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsBool, true);
                }
            }

            if (excelFile.Attributes.HasStats) // items, missiles, monsters, objects, players
            {
                DataColumn extendedDataColumn = dataTable.Columns.Add("Stats");
                extendedDataColumn.DataType = typeof(String);
                extendedDataColumn.ExtendedProperties.Add(ExcelFile.ColumnTypeKeys.IsStats, true);
                outputAttributes.Add(null);
            }
            #endregion

            #region Generate Rows
            int row = 1;
            object[] baseRow = new object[outputAttributes.Count];
            ObjectDelegator objectDelegator = new ObjectDelegator(fieldInfos);
            foreach (Object tableRow in excelFile.Rows)
            {
                int col = 1;
                foreach (FieldInfo fieldInfo in fieldInfos)
                {
                    Object value = objectDelegator[fieldInfo.Name](tableRow);

                    if (fieldInfo.IsPrivate)
                    {
                        if (fieldInfo.FieldType != typeof(ExcelFile.RowHeader)) continue;
                        baseRow[col++] = FileTools.ObjectToStringGeneric(value, ",");
                        continue;
                    }

                    OutputAttribute excelOutputAttribute = outputAttributes[col];

                    if (excelOutputAttribute == null)
                    {
                        if (value.GetType().BaseType == typeof(Array))
                        {
                            value = ((Array)value).ToString(",");
                        }

                        baseRow[col++] = value;
                        continue;
                    }

                    if (excelOutputAttribute.IsStringOffset)
                    {
                        int valueInt = (int)value;
                        baseRow[col++] = (valueInt != -1) ? excelFile.ReadStringTable(valueInt) : String.Empty;
                        continue;
                    }

                    if (excelOutputAttribute.IsSecondaryString)
                    {
                        int valueInt = (int)value;
                        baseRow[col++] = (valueInt != -1) ? excelFile.ReadSecondaryStringTable(valueInt) : String.Empty;
                        continue;
                    }

                    if (excelOutputAttribute.IsScript)
                    {
                        int scriptOffset = (int)value;
                        if (scriptOffset == 0)
                        {
                            baseRow[col++] = String.Empty;
                            continue;
                        }

                        String script;
                        if (scriptOffset == 9649 && excelFile.StringId == "SKILLS") // todo: not sure what's with this script...
                        {
                            /* Compiled Bytes:
                             * 26,30,700,6,26,1,399,358,669,616562688,711,26,62,3,17,669,641728512,26,8,711,26,62,3,17,358,669,322961408,26,5,700,6,26,1,399,358,388,0
                             *
                             * Ending Stack (FIFO):
                             * SetStat669('sfx_attack_pct', 'all', 30 * ($sklvl - 1))
                             * SetStat669('sfx_duration_pct', 'all', get_skill_level(@unit, 'Shield_Mastery'))
                             * SetStat669('damage_percent_skill', 8 * get_skill_level(@unit, 'Shield_Mastery'))
                             * SetStat669('damage_percent_skill', 8 * get_skill_level(@unit, 'Shield_Mastery')) + 5 * ($sklvl - 1)
                             *
                             * The last SetStat has strange overhang - decompiling wrong?
                             * Or is it "supposed" to be there?
                             * i.e. It's actually decompiling correctly, but because I've assumed such scripts to be wrong (as the end +5... segment is useless) we get the Stack exception
                             */
                            int[] scriptCode = excelFile.ReadScriptTable(scriptOffset);
                            script = scriptCode != null ? FileTools.ArrayToStringGeneric(scriptCode, ",") : "ScriptError";
                            baseRow[col++] = script;
                            continue;
                        }

                        //if (fieldInfo.Name == "props1" && row == 45)
                        //{
                        //    int bp = 0;
                        //}

                        ExcelScript excelScript = new ExcelScript(this);

                        try
                        {
                            if (ExcelScript.DebugEnabled)
                            {
                                int[] scriptCode = excelFile.ReadScriptTable(scriptOffset);
                                script = scriptCode != null ? FileTools.ArrayToStringGeneric(scriptCode, ",") : String.Empty;

                                script = excelScript.Decompile(excelFile.ScriptBuffer, scriptOffset, script, excelFile.StringId, row, col, fieldInfo.Name);
                            }
                            else
                            {
                                script = excelScript.Decompile(excelFile.ScriptBuffer, scriptOffset);
                            }

                            //if (script.StartsWith("GetStat666('skill_points_bonus_total', '') > -1;"))
                            //{
                            //    int bp = 0;
                            //}
                        }
                        catch (Exception)
                        {
                            int[] scriptCode = excelFile.ReadScriptTable(scriptOffset);
                            script = scriptCode != null ? FileTools.ArrayToStringGeneric(scriptCode, ",") : "ScriptError";
                        }

                        baseRow[col++] = script;
                        continue;
                    }

                    if (excelOutputAttribute.IsTableIndex || excelOutputAttribute.IsStringIndex)
                    {
                        if (value.GetType().BaseType == typeof(Array))
                        {
                            value = ((Array)value).ToString(",");
                        }
                        else
                        {
                            value = (int)value;
                        }

                        baseRow[col++] = value;
                        col++; // for _strings relational column
                        continue;
                    }

                    // Else its something else, ie bitmask, bool, table/string index
                    baseRow[col++] = value;
                }

                // stats, only a component of the UnitData row type
                if (excelFile.Attributes.HasStats)
                {
                    baseRow[col++] = FileTools.ArrayToStringGeneric(excelFile.ReadStats(row - 1), ",");
                }

                dataTable.Rows.Add(baseRow);
                row++;
            }

            #endregion

            // Generate Relationships as required
            if (doRelations) _GenerateRelations(excelFile);

            return dataTable;
        }
Example #9
0
        public void ProcessTables()
        {
            // excel tables
            ExcelFile excelTables = (ExcelFile)DataFiles[ExcelTablesStringId];

            foreach (ExcelTablesRow excelTableRow in excelTables.Rows)
            {
                Xls.TableCodes tableCode = (Xls.TableCodes)excelTableRow.code;

                ExcelFile excelTable = GetExcelTableFromCode(tableCode);
                if (excelTable == null)
                {
                    continue;
                }

                excelTable.TableCode = tableCode;
            }

            // stats table
            ExcelFile statsTable = (ExcelFile)DataFiles[StatsTableStringId];

            foreach (StatsRow stat in statsTable.Rows)
            {
                int bitCount = _GetTableRowBitMax(stat.valTable, false);
                if (bitCount != -1)
                {
                    stat.valbits = bitCount;
                }

                bitCount = _GetTableRowBitMax(stat.param1Table, true);
                if (bitCount != -1)
                {
                    stat.param1Bits = bitCount;
                }
                if (stat.param1Bits > 0)
                {
                    stat.ParamCount++;
                }

                bitCount = _GetTableRowBitMax(stat.param2Table, true);
                if (bitCount != -1)
                {
                    stat.param2Bits = bitCount;
                }
                if (stat.param2Bits > 0)
                {
                    stat.ParamCount++;
                }

                bitCount = _GetTableRowBitMax(stat.param3Table, true);
                if (bitCount != -1)
                {
                    stat.param3Bits = bitCount;
                }
                if (stat.param3Bits > 0)
                {
                    stat.ParamCount++;
                }

                bitCount = _GetTableRowBitMax(stat.param4Table, true);
                if (bitCount != -1)
                {
                    stat.param4Bits = bitCount;
                }
                if (stat.param4Bits > 0)
                {
                    stat.ParamCount++;
                }

                if (stat.valTable != -1)
                {
                    stat.ValueExcelTable = GetExcelTableFromIndex(stat.valTable);
                }
                if (stat.param1Table != -1)
                {
                    stat.Param1ExcelTable = GetExcelTableFromIndex(stat.param1Table);
                }
                if (stat.param2Table != -1)
                {
                    stat.Param2ExcelTable = GetExcelTableFromIndex(stat.param2Table);
                }
                if (stat.param3Table != -1)
                {
                    stat.Param3ExcelTable = GetExcelTableFromIndex(stat.param3Table);
                }
                if (stat.param4Table != -1)
                {
                    stat.Param4ExcelTable = GetExcelTableFromIndex(stat.param4Table);
                }
            }

            // level drlg choice table
            ExcelFile levelDrlgChoiceTable = (ExcelFile)DataFiles["LEVEL_DRLG_CHOICE"];

            foreach (LevelDrlgChoiceRow levelDrlgChoice in levelDrlgChoiceTable.Rows)
            {
                if (levelDrlgChoice.nameOffset == -1)
                {
                    continue;
                }

                levelDrlgChoice.name = levelDrlgChoiceTable.ReadStringTable(levelDrlgChoice.nameOffset);
                Debug.Assert(!String.IsNullOrEmpty(levelDrlgChoice.name));
            }
        }
Example #10
0
        private DataTable _LoadExcelTable(ExcelFile excelFile, bool doRelations, bool force)
        {
            String    tableName = excelFile.StringId;
            DataTable dataTable = XlsDataSet.Tables[tableName];

            if (dataTable != null && !force)
            {
                return(dataTable);
            }
            if (dataTable != null)
            {
                XlsDataSet.Relations.Clear();
                XlsDataSet.Tables.Remove(tableName);
            }
            dataTable           = XlsDataSet.Tables.Add(tableName);
            dataTable.TableName = tableName;
            dataTable.ExtendedProperties.Add("FileHeader", excelFile._excelFileHeader.DeepClone());

            Type dataType = excelFile.Attributes.RowType;
            List <OutputAttribute> outputAttributes = new List <OutputAttribute>();

            #region Generate Columns
            DataColumn indexColumn = dataTable.Columns.Add("Index");
            indexColumn.AutoIncrement = true;
            indexColumn.Unique        = true;
            dataTable.PrimaryKey      = new[] { indexColumn };
            outputAttributes.Add(null);

            FieldInfo[] fieldInfos = dataType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
            foreach (FieldInfo fieldInfo in fieldInfos)
            {
                OutputAttribute excelAttribute = ExcelFile.GetExcelAttribute(fieldInfo);

                // The only private field we add is the TableHeader
                if (fieldInfo.IsPrivate)
                {
                    if (fieldInfo.FieldType != typeof(ExcelFile.RowHeader))
                    {
                        continue;
                    }

                    outputAttributes.Add(null);
                    dataTable.Columns.Add(fieldInfo.Name, typeof(String));
                    continue;
                }

                Type fieldType = fieldInfo.FieldType;
                bool isArray   = false;
                bool isEnum    = false;
                if (fieldInfo.FieldType.BaseType == typeof(Array))
                {
                    fieldType = typeof(String);
                    isArray   = true;
                }
                else if (fieldInfo.FieldType.BaseType == typeof(Enum) && excelAttribute == null)
                {
                    fieldType = fieldInfo.FieldType;
                    isEnum    = true;
                }

                DataColumn dataColumn = dataTable.Columns.Add(fieldInfo.Name, fieldType);
                if (isArray)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsArray, true);
                }
                else if (isEnum)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsEnum, true);
                }

                if (excelAttribute == null)
                {
                    outputAttributes.Add(null);
                    continue;
                }

                outputAttributes.Add(excelAttribute);

                if (excelAttribute.IsStringOffset)
                {
                    dataColumn.DataType = typeof(String);
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsStringOffset, true);
                    dataColumn.DefaultValue = String.Empty;
                }

                if (excelAttribute.IsScript)
                {
                    dataColumn.DataType = typeof(String);
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsScript, true);
                    dataColumn.DefaultValue = String.Empty;
                }

                if (excelAttribute.IsSecondaryString)
                {
                    dataColumn.DataType = typeof(String);
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsSecondaryString, true);
                    dataColumn.DefaultValue = String.Empty;
                }

                if (excelAttribute.IsStringIndex)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsStringIndex, true);

                    // Add new column for the string
                    DataColumn dataColumnString = dataTable.Columns.Add(fieldInfo.Name + "_string", typeof(String));
                    dataColumnString.DefaultValue = String.Empty;
                    outputAttributes.Add(null);
                    dataColumnString.ExtendedProperties.Add(ColumnKeys.IsRelationGenerated, true);
                }

                if (excelAttribute.IsTableIndex)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsTableIndex, true);

                    // Add new column for the string
                    DataColumn dataColumnString = dataTable.Columns.Add(fieldInfo.Name + "_string", typeof(String));
                    dataColumnString.DefaultValue = String.Empty;
                    outputAttributes.Add(null);
                    dataColumnString.ExtendedProperties.Add(ColumnKeys.IsRelationGenerated, true);
                }

                if (excelAttribute.IsBitmask)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsBitmask, true);
                }

                if (excelAttribute.IsBool)
                {
                    dataColumn.ExtendedProperties.Add(ColumnKeys.IsBool, true);
                }
            }

            if (excelFile.Attributes.HasStats) // items, missiles, monsters, objects, players
            {
                DataColumn extendedDataColumn = dataTable.Columns.Add("Stats");
                extendedDataColumn.DataType = typeof(String);
                extendedDataColumn.ExtendedProperties.Add(ExcelFile.ColumnTypeKeys.IsStats, true);
                outputAttributes.Add(null);
            }
            #endregion

            #region Generate Rows
            int             row             = 1;
            object[]        baseRow         = new object[outputAttributes.Count];
            ObjectDelegator objectDelegator = new ObjectDelegator(fieldInfos);
            foreach (Object tableRow in excelFile.Rows)
            {
                int col = 1;
                foreach (FieldInfo fieldInfo in fieldInfos)
                {
                    Object value = objectDelegator[fieldInfo.Name](tableRow);

                    if (fieldInfo.IsPrivate)
                    {
                        if (fieldInfo.FieldType != typeof(ExcelFile.RowHeader))
                        {
                            continue;
                        }
                        baseRow[col++] = FileTools.ObjectToStringGeneric(value, ",");
                        continue;
                    }

                    OutputAttribute excelOutputAttribute = outputAttributes[col];

                    if (excelOutputAttribute == null)
                    {
                        if (value.GetType().BaseType == typeof(Array))
                        {
                            value = ((Array)value).ToString(",");
                        }

                        baseRow[col++] = value;
                        continue;
                    }

                    if (excelOutputAttribute.IsStringOffset)
                    {
                        int valueInt = (int)value;
                        baseRow[col++] = (valueInt != -1) ? excelFile.ReadStringTable(valueInt) : String.Empty;
                        continue;
                    }

                    if (excelOutputAttribute.IsSecondaryString)
                    {
                        int valueInt = (int)value;
                        baseRow[col++] = (valueInt != -1) ? excelFile.ReadSecondaryStringTable(valueInt) : String.Empty;
                        continue;
                    }

                    if (excelOutputAttribute.IsScript)
                    {
                        int scriptOffset = (int)value;
                        if (scriptOffset == 0)
                        {
                            baseRow[col++] = String.Empty;
                            continue;
                        }

                        String script;
                        if (scriptOffset == 9649 && excelFile.StringId == "SKILLS") // todo: not sure what's with this script...
                        {
                            /* Compiled Bytes:
                             * 26,30,700,6,26,1,399,358,669,616562688,711,26,62,3,17,669,641728512,26,8,711,26,62,3,17,358,669,322961408,26,5,700,6,26,1,399,358,388,0
                             *
                             * Ending Stack (FIFO):
                             * SetStat669('sfx_attack_pct', 'all', 30 * ($sklvl - 1))
                             * SetStat669('sfx_duration_pct', 'all', get_skill_level(@unit, 'Shield_Mastery'))
                             * SetStat669('damage_percent_skill', 8 * get_skill_level(@unit, 'Shield_Mastery'))
                             * SetStat669('damage_percent_skill', 8 * get_skill_level(@unit, 'Shield_Mastery')) + 5 * ($sklvl - 1)
                             *
                             * The last SetStat has strange overhang - decompiling wrong?
                             * Or is it "supposed" to be there?
                             * i.e. It's actually decompiling correctly, but because I've assumed such scripts to be wrong (as the end +5... segment is useless) we get the Stack exception
                             */
                            int[] scriptCode = excelFile.ReadScriptTable(scriptOffset);
                            script = scriptCode != null?FileTools.ArrayToStringGeneric(scriptCode, ",") : "ScriptError";

                            baseRow[col++] = script;
                            continue;
                        }

                        //if (fieldInfo.Name == "props1" && row == 45)
                        //{
                        //    int bp = 0;
                        //}

                        ExcelScript excelScript = new ExcelScript(this);

                        try
                        {
                            if (ExcelScript.DebugEnabled)
                            {
                                int[] scriptCode = excelFile.ReadScriptTable(scriptOffset);
                                script = scriptCode != null?FileTools.ArrayToStringGeneric(scriptCode, ",") : String.Empty;

                                script = excelScript.Decompile(excelFile.ScriptBuffer, scriptOffset, script, excelFile.StringId, row, col, fieldInfo.Name);
                            }
                            else
                            {
                                script = excelScript.Decompile(excelFile.ScriptBuffer, scriptOffset);
                            }

                            //if (script.StartsWith("GetStat666('skill_points_bonus_total', '') > -1;"))
                            //{
                            //    int bp = 0;
                            //}
                        }
                        catch (Exception)
                        {
                            int[] scriptCode = excelFile.ReadScriptTable(scriptOffset);
                            script = scriptCode != null?FileTools.ArrayToStringGeneric(scriptCode, ",") : "ScriptError";
                        }

                        baseRow[col++] = script;
                        continue;
                    }

                    if (excelOutputAttribute.IsTableIndex || excelOutputAttribute.IsStringIndex)
                    {
                        if (value.GetType().BaseType == typeof(Array))
                        {
                            value = ((Array)value).ToString(",");
                        }
                        else
                        {
                            value = (int)value;
                        }

                        baseRow[col++] = value;
                        col++; // for _strings relational column
                        continue;
                    }

                    // Else its something else, ie bitmask, bool, table/string index
                    baseRow[col++] = value;
                }

                // stats, only a component of the UnitData row type
                if (excelFile.Attributes.HasStats)
                {
                    baseRow[col++] = FileTools.ArrayToStringGeneric(excelFile.ReadStats(row - 1), ",");
                }

                dataTable.Rows.Add(baseRow);
                row++;
            }

            #endregion

            // Generate Relationships as required
            if (doRelations)
            {
                _GenerateRelations(excelFile);
            }

            return(dataTable);
        }