From d6b2da13f0aa4a42f7dc80b7a66c1308a9782e9b Mon Sep 17 00:00:00 2001 From: KalopsiaTwilight Date: Tue, 20 Aug 2024 16:56:38 +0200 Subject: [PATCH] Fix incorrect handling of array fields --- .../{ConvertHelper.cs => DBCDRowHelper.cs} | 61 +++++++++++++------ WDBXEditor2/MainWindow.xaml.cs | 8 +-- WDBXEditor2/Views/ReplaceColumnWindow.xaml.cs | 2 +- WDBXEditor2/Views/SetColumnWindow.xaml.cs | 2 +- .../Views/SetDependentColumnWindow.xaml.cs | 2 +- WDBXEditor2/Views/SetFlagWindow.xaml.cs | 4 +- 6 files changed, 52 insertions(+), 27 deletions(-) rename WDBXEditor2/Helpers/{ConvertHelper.cs => DBCDRowHelper.cs} (50%) diff --git a/WDBXEditor2/Helpers/ConvertHelper.cs b/WDBXEditor2/Helpers/DBCDRowHelper.cs similarity index 50% rename from WDBXEditor2/Helpers/ConvertHelper.cs rename to WDBXEditor2/Helpers/DBCDRowHelper.cs index 43bb6cd..0e6e71f 100644 --- a/WDBXEditor2/Helpers/ConvertHelper.cs +++ b/WDBXEditor2/Helpers/DBCDRowHelper.cs @@ -1,10 +1,13 @@ -using Newtonsoft.Json.Linq; +using DBCD; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; +using System.IO.Packaging; +using System.Reflection; namespace WDBXEditor2.Helpers { - internal class ConvertHelper + internal class DBCDRowHelper { private static Dictionary> _arrayConverters = new Dictionary>() { @@ -26,31 +29,53 @@ public static object ConvertArray(Type type, int size, string[] records) return _arrayConverters[type](size, records); } - public static object ConvertValue (Type type, string fieldName, object value) + public static void SetDBCRowColumn(DBCDRow row, string colName, object value) { - return Convert.ChangeType(value, GetFieldType(type, fieldName)); + var fieldName = GetUnderlyingFieldName(row.GetUnderlyingType(), colName, out var arrayIndex); + var field = row.GetUnderlyingType().GetField(fieldName); + if (field.FieldType.IsArray) + { + ((Array)row[fieldName]).SetValue(Convert.ChangeType(value, field.FieldType.GetElementType()), arrayIndex); + } else + { + row[fieldName] = Convert.ChangeType(value, field.FieldType); + } + } + + public static object GetDBCRowColumn(DBCDRow row, string colName) + { + var fieldName = GetUnderlyingFieldName(row.GetUnderlyingType(), colName, out var arrayIndex); + var field = row.GetUnderlyingType().GetField(fieldName); + if (field.FieldType.IsArray) + { + return ((Array)row[fieldName]).GetValue(arrayIndex); + } else + { + return row[fieldName]; + } } - public static Type GetFieldType(Type type, string fieldName) + public static Type GetFieldType(DBCDRow row, string fieldName) { - var field = type.GetField(fieldName); - if (field == null) + var field = row.GetUnderlyingType().GetField(GetUnderlyingFieldName(row.GetUnderlyingType(), fieldName, out _)); + if (field.FieldType.IsArray) { - var index = 0; - var n = 1; - while (int.TryParse(fieldName[^1].ToString(), out var indexN)) - { - fieldName = fieldName.Substring(0, fieldName.Length - 1); - index += n * indexN; - n *= 10; - } - field = type.GetField(fieldName); return field.FieldType.GetElementType(); } - else + return field.FieldType; + } + + private static string GetUnderlyingFieldName(Type type, string fieldName, out int index) + { + index = 0; + var n = 1; + while (int.TryParse(fieldName[^1].ToString(), out var indexN)) { - return field.FieldType; + fieldName = fieldName.Substring(0, fieldName.Length - 1); + index += n * indexN; + n *= 10; } + return fieldName; } diff --git a/WDBXEditor2/MainWindow.xaml.cs b/WDBXEditor2/MainWindow.xaml.cs index d046c1a..2dc0535 100644 --- a/WDBXEditor2/MainWindow.xaml.cs +++ b/WDBXEditor2/MainWindow.xaml.cs @@ -1,4 +1,4 @@ -using CsvHelper; +using CsvHelper; using CsvHelper.Configuration; using DBCD; using Microsoft.Win32; @@ -196,7 +196,7 @@ private void DB2DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEve var colName = e.Column.Header.ToString(); try { - dbcRow[colName] = ConvertHelper.ConvertValue(dbcRow.GetUnderlyingType(), colName, newVal.Text); + DBCDRowHelper.SetDBCRowColumn(dbcRow, colName, newVal.Text); if (colName == dbcRow.GetDynamicMemberNames().FirstOrDefault()) { OpenedDB2Storage.Remove(dbcRow.ID); @@ -206,9 +206,9 @@ private void DB2DataGrid_CellEditEnding(object sender, DataGridCellEditEndingEve } catch(Exception exc) { - newVal.Text = dbcRow[colName].ToString(); + newVal.Text = DBCDRowHelper.GetDBCRowColumn(dbcRow, colName).ToString(); var exceptionWindow = new ExceptionWindow(); - var fieldType = ConvertHelper.GetFieldType(dbcRow.GetUnderlyingType(), colName); + var fieldType = DBCDRowHelper.GetFieldType(dbcRow, colName); exceptionWindow.DisplayException(exc.InnerException ?? exc, $"An error occured setting this value for this cell. This is likely due to an invalid value for conversion to '{fieldType.Name}':"); exceptionWindow.Show(); diff --git a/WDBXEditor2/Views/ReplaceColumnWindow.xaml.cs b/WDBXEditor2/Views/ReplaceColumnWindow.xaml.cs index 5257bb6..f568dcd 100644 --- a/WDBXEditor2/Views/ReplaceColumnWindow.xaml.cs +++ b/WDBXEditor2/Views/ReplaceColumnWindow.xaml.cs @@ -23,7 +23,7 @@ private void Ok_Click(object sender, RoutedEventArgs e) { if (row[columnName].ToString() == txtValueReplace.Text) { - row[columnName] = ConvertHelper.ConvertValue(row.GetUnderlyingType(), columnName, txtValue.Text); + DBCDRowHelper.SetDBCRowColumn(row, columnName, txtValue.Text); } } _mainWindow.ReloadDataView(); diff --git a/WDBXEditor2/Views/SetColumnWindow.xaml.cs b/WDBXEditor2/Views/SetColumnWindow.xaml.cs index 1b78722..0a62b86 100644 --- a/WDBXEditor2/Views/SetColumnWindow.xaml.cs +++ b/WDBXEditor2/Views/SetColumnWindow.xaml.cs @@ -21,7 +21,7 @@ private void Ok_Click(object sender, RoutedEventArgs e) var columnName = ddlColumnName.SelectedValue.ToString(); foreach (var row in dbcdStorage.Values) { - row[columnName] = ConvertHelper.ConvertValue(row.GetUnderlyingType(), columnName, txtValue.Text); ; + DBCDRowHelper.SetDBCRowColumn(row, columnName, txtValue.Text); } _mainWindow.ReloadDataView(); Close(); diff --git a/WDBXEditor2/Views/SetDependentColumnWindow.xaml.cs b/WDBXEditor2/Views/SetDependentColumnWindow.xaml.cs index 435298a..605ef08 100644 --- a/WDBXEditor2/Views/SetDependentColumnWindow.xaml.cs +++ b/WDBXEditor2/Views/SetDependentColumnWindow.xaml.cs @@ -27,7 +27,7 @@ private void Ok_Click(object sender, RoutedEventArgs e) { if (row[columnName].ToString() == txtPrimaryValue.Text) { - row[foreignColumnName] = ConvertHelper.ConvertValue(row.GetUnderlyingType(), foreignColumnName, txtForeignValue.Text); + DBCDRowHelper.SetDBCRowColumn(row, foreignColumnName, txtForeignValue.Text); } } _mainWindow.ReloadDataView(); diff --git a/WDBXEditor2/Views/SetFlagWindow.xaml.cs b/WDBXEditor2/Views/SetFlagWindow.xaml.cs index 8f93d75..7f0dae5 100644 --- a/WDBXEditor2/Views/SetFlagWindow.xaml.cs +++ b/WDBXEditor2/Views/SetFlagWindow.xaml.cs @@ -28,13 +28,13 @@ private void Ok_Click(object sender, RoutedEventArgs e) { if ((rowVal & bitVal) > 0) { - row[columnName] = ConvertHelper.ConvertValue(row.GetUnderlyingType(), columnName, rowVal - bitVal); + DBCDRowHelper.SetDBCRowColumn(row, columnName, rowVal - bitVal); } } else { if ((rowVal & bitVal) == 0) { - row[columnName] = ConvertHelper.ConvertValue(row.GetUnderlyingType(), columnName, rowVal + bitVal); + DBCDRowHelper.SetDBCRowColumn(row, columnName, rowVal + bitVal); } }