public static void TestAllExcelScripts() { ExcelScript.GlobalDebug(true); FileManager fileManager = new FileManager(Config.HglDir); fileManager.BeginAllDatReadAccess(); fileManager.LoadTableFiles(); fileManager.EndAllDatAccess(); StringWriter results = new StringWriter(); Dictionary<String, int> excelScriptDecompileFails = new Dictionary<String, int>(); Dictionary<String, int> excelScriptRecompileFails = new Dictionary<String, int>(); Dictionary<String, int> excelScriptComparisonFails = new Dictionary<String, int>(); int grandTotalScripts = 0; int grandTotalScriptsDecompiled = 0; int grandTotalScriptsFailedDecompilation = 0; int grandTotalScriptsRecompiled = 0; int grandTotalScriptsFailedRecompilation = 0; int grandTotalScriptsCompared = 0; int grandTotalScriptsFailedComparison = 0; foreach (ExcelFile excelFile in fileManager.DataFiles.Values.Where(dataFile => dataFile.IsExcelFile)) { String excelStringId = String.Format("{0}...", excelFile.StringId); Debug.Write(excelStringId); results.Write(excelStringId); //if (excelFile.StringId != "SKILLS") continue; if (excelFile.Delegator == null || excelFile.ScriptCode == null || excelFile.ScriptCode.Length == 0) { Debug.WriteLine(" No script data"); results.WriteLine(" No script data"); continue; } String scriptIntValues = String.Format(" {0} script int values...", excelFile.ScriptCode.Length); Debug.WriteLine(scriptIntValues); results.WriteLine(scriptIntValues); StringWriter excelFileResults = new StringWriter(); int colIndex = -1; int totalScriptsFound = 0; int totalScriptsDecompiled = 0; int totalScriptsFailedDecompilation = 0; int totalScriptsRecompiled = 0; int totalScriptsFailedRecompilation = 0; int totalScriptsCompared = 0; int totalScriptsFailedComparison = 0; foreach (FieldDelegate fieldDelegate in excelFile.Delegator) { colIndex++; ExcelAttributes excelAtributes = (ExcelAttributes)fieldDelegate.Info.GetCustomAttributes(typeof(ExcelAttributes), true).FirstOrDefault(); if (excelAtributes == null || !excelAtributes.IsScript) continue; String currentColumn = String.Format("\tColumn[{0}] = {1}", colIndex, fieldDelegate.Name); Debug.WriteLine(currentColumn); results.WriteLine(currentColumn); excelFileResults.WriteLine(currentColumn); int rowIndex = -1; int prevOffset = 0; int scriptCount = 0; int scriptsDecompiled = 0; int scriptsFailedDecompilation = 0; int scriptsRecompiled = 0; int scriptsFailedRecompilation = 0; int scriptsCompared = 0; int scriptsFailedComparison = 0; foreach (Object row in excelFile.Rows) { rowIndex++; int byteOffset = (int)fieldDelegate.GetValue(row); if (byteOffset == 0) continue; Debug.Assert(byteOffset > prevOffset); prevOffset = byteOffset; if (byteOffset == 9649 && excelFile.StringId == "SKILLS") // todo: not sure what's with this script... { continue; } excelFileResults.WriteLine(String.Format("\t\tColumn({0}) = {3}, Row({1}), ByteOffset({2}):", colIndex, rowIndex, byteOffset, fieldDelegate.Name)); ExcelScript excelScript = new ExcelScript(fileManager); scriptCount++; String script; int[] scriptCodes = excelFile.ReadScriptTable(byteOffset); String scriptCodesStr = scriptCodes.ToString(","); String semiDecompiledScript = _ReadScriptTable(excelScript, scriptCodes); //if (scriptCodesStr == "707,0,714,666,0,3,201,673,603979779,26,5,2,284,0,0") //{ // int bp = 0; //} // test decompiling try { script = excelScript.Decompile(excelFile.ScriptBuffer, byteOffset, scriptCodesStr, excelFile.StringId, rowIndex, colIndex, fieldDelegate.Name); scriptsDecompiled++; } catch (Exception e) { if (!excelScriptDecompileFails.ContainsKey(excelFile.StringId)) { excelScriptDecompileFails.Add(excelFile.StringId, 1); } else { excelScriptDecompileFails[excelFile.StringId]++; } scriptsFailedDecompilation++; excelFileResults.WriteLine("Script Decompile Failed:\n" + semiDecompiledScript + "\n" + e + "\n"); continue; } // test compiling of decompiled script int[] recompiledScriptCode; try { ExcelScript excelScriptCompile = new ExcelScript(fileManager); recompiledScriptCode = excelScriptCompile.Compile(script, scriptCodesStr, excelFile.StringId, rowIndex, colIndex, fieldDelegate.Name); scriptsRecompiled++; } catch (Exception e) { if (!excelScriptRecompileFails.ContainsKey(excelFile.StringId)) { excelScriptRecompileFails.Add(excelFile.StringId, 1); } else { excelScriptRecompileFails[excelFile.StringId]++; } scriptsFailedRecompilation++; excelFileResults.WriteLine("Script Recompile Failed:\n" + semiDecompiledScript + "\n" + e + "\n"); continue; } // check recompiled fidelity scriptsCompared++; if (!scriptCodes.SequenceEqual(recompiledScriptCode)) { if (!excelScriptComparisonFails.ContainsKey(excelFile.StringId)) { excelScriptComparisonFails.Add(excelFile.StringId, 1); } else { excelScriptComparisonFails[excelFile.StringId]++; } scriptsFailedComparison++; String compareFailed = String.Format("Script Comparison Failed:\nOriginal Script: {0} = {1}\nRecompiled Script: {2}\nSemi-Decompiled:\n{3}", scriptCodesStr, script, recompiledScriptCode.ToString(","), semiDecompiledScript); excelFileResults.WriteLine(compareFailed); continue; } excelFileResults.WriteLine(script + "\n"); } totalScriptsFound += scriptCount; totalScriptsDecompiled += scriptsDecompiled; totalScriptsFailedDecompilation += scriptsFailedDecompilation; totalScriptsRecompiled += scriptsRecompiled; totalScriptsFailedRecompilation += scriptsFailedRecompilation; totalScriptsCompared += scriptsCompared; totalScriptsFailedComparison += scriptsFailedComparison; String columnStats = String.Format("\t\t{0} scripts found, {1} scripts decompiled, {2} scripts failed to decompile.\n", scriptCount, scriptsDecompiled, scriptsFailedDecompilation); columnStats += String.Format("\t\t\t{0} scripts recompiled, {1} scripts failed to recompile, {2} scripts compared, {3} scripts failed comparison", scriptsRecompiled, scriptsFailedRecompilation, scriptsCompared, scriptsFailedComparison); Debug.WriteLine(columnStats); excelFileResults.WriteLine(columnStats); } grandTotalScripts += totalScriptsFound; grandTotalScriptsDecompiled += totalScriptsDecompiled; grandTotalScriptsFailedDecompilation += totalScriptsFailedDecompilation; grandTotalScriptsRecompiled += totalScriptsRecompiled; grandTotalScriptsFailedRecompilation += totalScriptsFailedRecompilation; grandTotalScriptsCompared += totalScriptsCompared; grandTotalScriptsFailedComparison += totalScriptsFailedComparison; String totalStats = String.Format("Totals: {0} scripts found, {1} scripts decompiled, {2} scripts failed to decompile.\n", totalScriptsFound, totalScriptsDecompiled, totalScriptsFailedDecompilation); totalStats += String.Format("\t{0} scripts recompiled, {1} scripts failed to recompile, {2} scripts compared, {3} scripts failed comparison", totalScriptsRecompiled, totalScriptsFailedRecompilation, totalScriptsCompared, totalScriptsFailedComparison); Debug.WriteLine(totalStats); results.WriteLine(totalStats); excelFileResults.WriteLine(totalStats); File.WriteAllText(@"C:\TestScripts\excelScripts_" + excelFile.StringId + ".txt", excelFileResults.ToString()); excelFileResults.Close(); } foreach (KeyValuePair<String, int> keyValuePair in excelScriptDecompileFails) { String excelFileFails = String.Format("{0} had {1} failed decompilation.", keyValuePair.Key, keyValuePair.Value); Debug.WriteLine(excelFileFails); results.WriteLine(excelFileFails); } String grandTotalStats = String.Format("Grand Totals: {0} scripts found, {1} scripts decompiled, {2} scripts failed to decompile.\n", grandTotalScripts, grandTotalScriptsDecompiled, grandTotalScriptsFailedDecompilation); grandTotalStats += String.Format("\t{0} scripts recompiled, {1} scripts failed to recompile, {2} scripts compared, {3} scripts failed comparison", grandTotalScriptsRecompiled, grandTotalScriptsFailedRecompilation, grandTotalScriptsCompared, grandTotalScriptsFailedComparison); Debug.WriteLine(grandTotalStats); results.WriteLine(grandTotalStats); File.WriteAllText(@"C:\TestScripts\excelScripts_Results.txt", results.ToString()); }
public byte[] ExportSQL(FileManager fileManager, string tablePrefix = "") { string[] sqlReserved = new string[] { "group", "condition", "left", "right", "default", "key", "force", "analyze", "kill", "usage", "order" }; StringWriter stringWriter = new StringWriter(); string tableName = String.Format("{0}{1}", tablePrefix, StringId.ToLower()); stringWriter.WriteLine(String.Format("CREATE TABLE {0} (", tableName)); stringWriter.WriteLine("\tid INT NOT NULL PRIMARY KEY,"); String columnDec = "\t{0} {1}{2}"; int colCount = 1; ObjectDelegator objectDelegator; if (fileManager == null || !fileManager.DataFileDelegators.ContainsKey(StringId)) { objectDelegator = new ObjectDelegator(Attributes.RowType.GetFields()); FieldInfo headerField = DataType.GetField("header", BindingFlags.Instance | BindingFlags.NonPublic); objectDelegator.AddField(headerField); } else { objectDelegator = fileManager.DataFileDelegators[StringId]; } int noColumns = objectDelegator.FieldCount - 1; // remove header foreach (ObjectDelegator.FieldDelegate field in objectDelegator) { if (field.Name == "header") continue; // dont want this String columnName = field.Name; String dataType = String.Empty; String formatted = String.Empty; if (sqlReserved.Where(str => str == columnName.ToLower()).Any() == true) { columnName = "a" + columnName; } // Special types OutputAttribute excelOutput = GetExcelAttribute(field.Info); if (excelOutput != null) { if (excelOutput.IsScript || excelOutput.IsSecondaryString || excelOutput.IsStringOffset) dataType = "TEXT"; else if (excelOutput.IsBitmask) dataType = "BIGINT"; } if (dataType == String.Empty) { if (field.FieldType == typeof(int)) dataType = "INT"; else if (field.FieldType == typeof(float)) dataType = "DECIMAL"; else if (field.FieldType == typeof(byte)) dataType = "TINYINT"; else if (field.FieldType == typeof(short)) dataType = "SMALLINT"; else if (field.FieldType == typeof(uint) || field.FieldType == typeof(Int64)) dataType = "BIGINT"; else if (field.FieldType == typeof(string)) { MarshalAsAttribute marshalAs = (MarshalAsAttribute)field.Info.GetCustomAttributes(typeof(MarshalAsAttribute), false).First(); dataType = String.Format("VARCHAR({0})", marshalAs.SizeConst); } else if (field.FieldType.BaseType == typeof(Array)) { dataType = "TEXT"; } } formatted = String.Format(columnDec, columnName, dataType, colCount < noColumns ? "," : String.Empty); stringWriter.WriteLine(formatted); colCount++; } stringWriter.WriteLine(");"); stringWriter.WriteLine("INSERT INTO {0}", tableName); stringWriter.WriteLine("VALUES"); colCount = 1; int rowCount = 0; int noRows = Rows.Count; StringWriter valueString = new StringWriter(); foreach (Object rowObject in Rows) { valueString.Write(String.Format("\t({0},", rowCount)); // write the id foreach (ObjectDelegator.FieldDelegate field in objectDelegator) { if (field.Name == "header") continue; // dont want this OutputAttribute excelOutput = GetExcelAttribute(field.Info); Object objValue = field.GetValue(rowObject); bool valueParsed = false; if (excelOutput != null) { if (excelOutput.IsScript) { int[] scriptTable = ReadScriptTable((int)objValue); if (scriptTable != null) { int offset = (int)objValue; int[] scriptbuffer = ReadScriptTable(offset); String scriptString = FileTools.ArrayToStringGeneric(scriptbuffer, ","); try { if (fileManager != null) { ExcelScript excelScript = new ExcelScript(fileManager); scriptString = excelScript.Decompile(_scriptBuffer, offset); scriptString = StringToSQLString(scriptString); scriptString = EncapsulateString(scriptString); valueString.Write(scriptString); } else { valueString.Write(scriptString); } } catch (Exception e) { valueString.Write(EncapsulateString(scriptString)); Debug.WriteLine(e.ToString()); scriptString = "ScriptError(" + scriptString + ")"; } } else { valueString.Write("\"\""); } valueParsed = true; } else if (excelOutput.IsSecondaryString) { if ((int)objValue != -1) { string secString = ReadSecondaryStringTable((int)objValue); valueString.Write(String.Format("\"{0}\"", secString)); } else { valueString.Write("\"\""); } valueParsed = true; } else if (excelOutput.IsStringOffset) { string offString = ReadStringTable((int)objValue); offString = StringToSQLString(offString); offString = String.Format("\"{0}\"", offString); valueString.Write(offString); valueParsed = true; } else if (excelOutput.IsBitmask) { valueString.Write((uint)objValue); valueParsed = true; } } if (valueParsed == false) { if (field.FieldType == typeof(string)) { string strValue = EncapsulateString(StringToSQLString((objValue.ToString()))); valueString.Write(strValue); } else if (field.FieldType.BaseType == typeof(Array)) { string strValue = EncapsulateString(((Array)objValue).ToString(",")); valueString.Write(strValue); } else if (field.FieldType == typeof(float)) { string strValue = ((float)objValue).ToString("r"); valueString.Write(strValue); } else { valueString.Write(objValue); } } if (colCount < noColumns) valueString.Write(","); else valueString.Write(")"); colCount++; } if (rowCount < noRows - 1) valueString.WriteLine(","); else valueString.WriteLine(";"); rowCount++; colCount = 1; } stringWriter.Write(valueString.ToString()); byte[] buffer = FileTools.StringToASCIIByteArray(stringWriter.ToString()); return buffer; }
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; }
public byte[] ExportCSV(FileManager fileManager, IEnumerable<String> columnNames = null) { if (Attributes.IsEmpty) return new byte[0]; //// init stuffs byte[] csvBuffer = new byte[1024]; int csvOffset = 0; bool isProperties = (StringId == "PROPERTIES" || StringId == "_TCv4_PROPERTIES"); ObjectDelegator objectDelegator; if (fileManager == null || !fileManager.DataFileDelegators.ContainsKey(StringId)) { objectDelegator = new ObjectDelegator(Attributes.RowType.GetFields()); FieldInfo headerField = DataType.GetField("header", BindingFlags.Instance | BindingFlags.NonPublic); objectDelegator.AddField(headerField); } else { objectDelegator = fileManager.DataFileDelegators[StringId]; } //// header row // tables can have different header values String tableHeaderStr = String.Format("{0}({1})", StringId, FileTools.ObjectToStringGeneric(_excelFileHeader, ",")); // rest of columns List<String> columnsList = new List<String> { tableHeaderStr }; foreach (ObjectDelegator.FieldDelegate fieldDelegate in objectDelegator) { if (columnNames == null) { if (!fieldDelegate.IsPublic) continue; } else if (!columnNames.Contains(fieldDelegate.Name)) { continue; } columnsList.Add(fieldDelegate.Name); } // excel table type-specific columns if (Attributes.HasStats) columnsList.Add("Stats"); if (isProperties) columnsList.Add("Script"); // column header row String[] columns = columnsList.ToArray(); int colCount = columns.Length; int rowCount = Count + 1; // +1 for column headers //// csv generation String[][] strings = new string[rowCount][]; strings[0] = columns; int col = -1; foreach (ObjectDelegator.FieldDelegate fieldDelegate in objectDelegator) { if (!columns.Contains(fieldDelegate.Name) && fieldDelegate.Name != "header") continue; col++; OutputAttribute excelAttribute = GetExcelAttribute(fieldDelegate.Info); //if (fieldDelegate.Name == "spawnFromMonsterUnitType") //{ // int bp = 0; //} int row = 0; foreach (Object rowObject in Rows) { String[] rowStr = strings[++row]; if (rowStr == null) { rowStr = new String[colCount]; strings[row] = rowStr; } if (fieldDelegate.Name == "header") { RowHeader rowHeader = (RowHeader)fieldDelegate.GetValue(rowObject); rowStr[col] = FileTools.ObjectToStringGeneric(rowHeader, ","); continue; } if (fieldDelegate.Name == "code") { int code; if (fieldDelegate.FieldType == typeof(short)) { code = (int)(short)fieldDelegate.GetValue(rowObject); // yes, that extra (int) is *needed* to cast the short correctly } else { code = (int)fieldDelegate.GetValue(rowObject); } if (StringId == "REGION") // can't export region code values as chars due to weird chars { rowStr[col] = "\"" + code + "\""; } else { rowStr[col] = "\"" + _CodeToString(code) + "\""; } continue; } bool isArray = (fieldDelegate.FieldType.BaseType == typeof(Array)); if (excelAttribute != null) { if (excelAttribute.IsTableIndex && fileManager != null) { int[] indexValues; Object indexObj = fieldDelegate.GetValue(rowObject); if (isArray) { indexValues = (int[])indexObj; } else { indexValues = new[] { (int)indexObj }; } String[] indexStrs = new String[indexValues.Length]; for (int i = 0; i < indexStrs.Length; i++) { if (indexValues[i] == -1) // empty string/no code { indexStrs[i] = "-1"; continue; } String tableStringId = excelAttribute.TableStringId; String negative = String.Empty; if (indexValues[i] < 0) { indexValues[i] *= -1; negative = "-"; } String indexStr = null; if (fileManager.DataTableHasColumn(tableStringId, "code")) { int code = fileManager.GetExcelIntFromStringId(tableStringId, indexValues[i], "code"); if (code != 0) indexStr = _CodeToString(code); } else if (fileManager.DataTableHasColumn(tableStringId, "name")) { indexStr = fileManager.GetExcelStringFromStringId(tableStringId, indexValues[i], "name"); } if (indexStr == null) { indexStr = fileManager.GetExcelStringFromStringId(tableStringId, indexValues[i]); } indexStrs[i] = negative + indexStr; } rowStr[col] = "\"" + String.Join(",", indexStrs) + "\""; continue; } if (excelAttribute.IsStringOffset) { int offset = (int)fieldDelegate.GetValue(rowObject); if (offset != -1) { rowStr[col] = ReadStringTable(offset); } continue; } if (excelAttribute.IsScript) { int offset = (int)fieldDelegate.GetValue(rowObject); if ((offset == 0)) { FileTools.WriteToBuffer(ref csvBuffer, ref csvOffset, FileTools.StringToASCIIByteArray("0")); continue; } int[] buffer = ReadScriptTable(offset); if (buffer == null) throw new Exceptions.ScriptFormatException("The script bytes were unable to be read using ReadScriptTable.", offset); String scriptString = FileTools.ArrayToStringGeneric(buffer, ","); if (fileManager != null) { if (offset == 9325 /*from DataTable export*/ || offset == 9649 /*from Object export*/ && 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 */ scriptString = "ScriptError(" + scriptString + ")"; } else { try { ExcelScript excelScript = new ExcelScript(fileManager); scriptString = "\"" + excelScript.Decompile(_scriptBuffer, offset, scriptString, StringId, row, col, fieldDelegate.Name) + "\""; } catch (Exception e) { Debug.WriteLine(e.ToString()); scriptString = "ScriptError(" + scriptString + ")"; } } } rowStr[col] = scriptString; continue; } if (excelAttribute.IsSecondaryString) { int index = (int)fieldDelegate.GetValue(rowObject); if (index != -1) { rowStr[col] = SecondaryStrings[index]; } continue; } if (excelAttribute.IsBitmask) { rowStr[col] = "\"" + fieldDelegate.GetValue(rowObject) + "\""; continue; } } Object outValue = fieldDelegate.GetValue(rowObject); if (isArray) { rowStr[col] = ((Array)outValue).ToString(","); } else if (fieldDelegate.FieldType == typeof(float)) { rowStr[col] = ((float)outValue).ToString("r"); } //else if (fieldDelegate.FieldType.BaseType == typeof(Enum)) // might as well export enums as their string representations //{ // rowStr[col] = ((UInt32)outValue).ToString(); //} else { rowStr[col] = outValue.ToString(); } } } // stats if (Attributes.HasStats) { col++; int row = -1; foreach (String[] rowStr in strings) { if (row == -1) // columns header row { row++; continue; } rowStr[col] = StatsBuffer[row++].ToString(","); } } // properties scripts if (isProperties) { // not point in doing this //if (tableHeader.Unknown1 != 2 || scriptRow == ExcelFunctions.Count - 1) // need 1 extra row for some reason col++; int row = -1; foreach (String[] rowStr in strings) { if (row == -1) { row++; continue; } if (row >= ExcelFunctions.Count) break; ExcelFunction excelScript = ExcelFunctions[row++]; String excelScriptFunction = String.Empty; foreach (ExcelFunction.Parameter paramater in excelScript.Parameters) { excelScriptFunction += String.Format("\n{0},{1},{2},{3}", paramater.Name, paramater.Unknown, paramater.TypeId, paramater.TypeValues.ToString(",")); } if (excelScript.ScriptByteCode != null) { int offset = 0; excelScriptFunction += "\n" + FileTools.ByteArrayToInt32Array(excelScript.ScriptByteCode, ref offset, excelScript.ScriptByteCode.Length / 4).ToString(",") + "\n"; } rowStr[col] = excelScriptFunction; } } //// join string arrays and create byte array String[] rows = new String[rowCount]; col = 0; foreach (String[] rowStr in strings) { rows[col] = String.Join("\t", rowStr); col++; } String csvString = String.Join(Environment.NewLine, rows); return csvString.ToASCIIByteArray(); }