diff --git a/src/dumper/dumper.cs b/src/dumper/dumper.cs index b154b6b..1898f13 100644 --- a/src/dumper/dumper.cs +++ b/src/dumper/dumper.cs @@ -123,198 +123,129 @@ class Dumper */ public void DumpCharacters() { - if (_dataPak == null || _provider == null) - throw new InvalidOperationException("Attempted to call dump function without dumper initialization/state"); - - _log.Info("Dumping characters"); - - List charDbPaths = _dataPak.Files.Keys.Where(x => x.Contains("/CharacterDescriptionDB.uasset", StringComparison.OrdinalIgnoreCase)).ToList(); - - foreach (string path in charDbPaths) + ProcessDataTables("/CharacterDescriptionDB.uasset", "characters", (rowKey, props) => { - string cleanPath = path.Contains('.') ? path[..path.LastIndexOf('.')] : path; + if (!TryGetProp(props, "CharacterIndex", out int charIndex)) + throw new KeyNotFoundException("CharacterIndex was not found."); - if (_provider.TryLoadPackageObject(cleanPath, out UDataTable? dataTable)) + if (charIndex == -1) return; + + if (!TryGetStringProp(props, "DisplayName", out string charName) || !TryGetStringProp(props, "IconFilePath", out string charIconFilePath)) + throw new KeyNotFoundException("DisplayName or IconFilePath was not found."); + + _characterMap[charIndex] = new CharacterInfo { - foreach (KeyValuePair row in dataTable.RowMap) - { - List props = row.Value.Properties; - - if (!TryGetProp(props, "CharacterIndex", out int charIndex)) - throw new KeyNotFoundException("CharacterIndex was not found."); - if (charIndex == -1) continue; - - if (!TryGetStringProp(props, "DisplayName", out string charName) || !TryGetStringProp(props, "IconFilePath", out string charIconFilePath)) - throw new KeyNotFoundException("DisplayName or IconFilePath was not found."); - - _characterMap[charIndex] = new CharacterInfo - { - name = charName, - idx = charIndex, - iconFilePath = charIconFilePath - }; - } - } - } + name = charName, + idx = charIndex, + iconFilePath = charIconFilePath + }; + }); _log.Info("Dumped {0} characters", _characterMap.Count); - WriteJson("characters", _characterMap.Values); - - return; - } - - public void DumpCharacterIcons() - { - if (_provider == null) - throw new InvalidOperationException("Attempted to call dump function without dumper initialization/state"); - - _log.Info("Dumping character icons"); - - foreach (CharacterInfo info in _characterMap.Values) - ExportIcon(info.iconFilePath, "/character-icons/"); - - _log.Info("Dumped all character icons"); - - return; } public void DumpItems() { - if (_dataPak == null || _provider == null) - throw new InvalidOperationException("Attempted to call dump function without dumper initialization/state"); - - _log.Info("Dumping items"); - - List itemDBPaths = _dataPak.Files.Keys.Where(x => x.Contains("/ItemDB.uasset", StringComparison.OrdinalIgnoreCase)).ToList(); - - foreach (string path in itemDBPaths) + ProcessDataTables("/ItemDB.uasset", "items", (rowKey, props) => { - string cleanPath = path.Contains('.') ? path[..path.LastIndexOf('.')] : path; + if (!TryGetProp(props, "Type", out EInventoryItemType itemType) + || !TryGetProp(props, "UIData", out FStructFallback uiDataFb) + || !TryGetProp(props, "Role", out EPlayerRole role) + || !TryGetProp(props, "Inventory", out bool isInventory) + || !TryGetProp(props, "IsFakeItem", out bool isFakeItem)) + throw new KeyNotFoundException("Type, UIData, Role, Inventory or IsFakeItem was not found."); - if (_provider.TryLoadPackageObject(cleanPath, out UDataTable? dataTable)) + UIDataStruct uiData = uiDataFb.MapToStruct(); + + if (isFakeItem || !isInventory || itemType != EInventoryItemType.Item || role != EPlayerRole.VE_Camper) + return; + + if (uiData.IconAssetList.Length == 0) + throw new InvalidDataException("Item's UIData had no icons"); + + _itemMap[rowKey] = new ItemInfo { - foreach (KeyValuePair row in dataTable.RowMap) - { - List props = row.Value.Properties; + id = rowKey, + name = uiData.DisplayName.ToString(), + iconFilePath = uiData.IconAssetList[0].ToString() + }; + }); - string itemId = row.Key.Text; - - if (!TryGetProp(props, "Type", out EInventoryItemType itemType) - || !TryGetProp(props, "UIData", out FStructFallback uiDataFb) - || !TryGetProp(props, "Role", out EPlayerRole role) - || !TryGetProp(props, "Inventory", out bool isInventory) - || !TryGetProp(props, "IsFakeItem", out bool isFakeItem) - ) - throw new KeyNotFoundException("Type, UIData, Role, Inventory or IsFakeItem was not found."); - - UIDataStruct uiData = uiDataFb.MapToStruct(); - - if (isFakeItem || !isInventory || itemType != EInventoryItemType.Item || role != EPlayerRole.VE_Camper) - { - _log.Verbose("Ignoring invalid item ({0})", itemId); - continue; - } - - if (uiData.IconAssetList.Length == 0) - throw new InvalidDataException("Item's UIData had no icons"); - - _itemMap[itemId] = new ItemInfo - { - id = itemId, - name = uiData.DisplayName.ToString(), - iconFilePath = uiData.IconAssetList[0].ToString() - }; - } - } - } - - WriteJson("items", _itemMap.Values); _log.Info("Dumped {0} items", _itemMap.Count); - } - - public void DumpItemIcons() - { - if (_provider == null) - throw new InvalidOperationException("Attempted to call dump function without dumper initialization/state"); - - _log.Info("Dumping item icons"); - - foreach (ItemInfo info in _itemMap.Values) - ExportIcon(info.iconFilePath, "/item-icons/"); - - _log.Info("Dumped all item icons"); - - return; + WriteJson("items", _itemMap.Values); } public void DumpOfferings() + { + ProcessDataTables("/OfferingDB.uasset", "offerings", (rowKey, props) => + { + if (!TryGetProp(props, "Role", out EPlayerRole role) + || !TryGetProp(props, "UIData", out FStructFallback uiDataFb) + || !TryGetProp(props, "Inventory", out bool isInventory) + || !TryGetProp(props, "IsFakeItem", out bool isFakeItem)) + throw new KeyNotFoundException("Role, UIData, Inventory or IsFakeItem was not found"); + + UIDataStruct uiData = uiDataFb.MapToStruct(); + + if (!isInventory || isFakeItem) + return; + + if (uiData.IconAssetList.Length == 0) + throw new InvalidDataException("Offerings's UIData had no icons"); + + _offeringMap[rowKey] = new OfferingInfo + { + id = rowKey, + name = uiData.DisplayName.ToString(), + iconFilePath = uiData.IconAssetList[0].ToString(), + role = role + }; + }); + + _log.Info("Dumped {0} offerings", _offeringMap.Count); + WriteJson("offerings", _offeringMap.Values); + } + + public void DumpCharacterIcons() => ExportIcons(_characterMap.Values.Select(x => x.iconFilePath), "character", "/character-icons/"); + public void DumpItemIcons() => ExportIcons(_itemMap.Values.Select(x => x.iconFilePath), "item", "/item-icons/"); + public void DumpOfferingIcons() => ExportIcons(_offeringMap.Values.Select(x => x.iconFilePath), "offering", "/offering-icons/"); + + /* + * bulk functions for dumping + */ + private void ProcessDataTables(string pathFilter, string logName, Action> rowProcessor) { if (_dataPak == null || _provider == null) throw new InvalidOperationException("Attempted to call dump function without dumper initialization/state"); - _log.Info("Dumping offerings"); + _log.Info($"Dumping {logName}"); - List offeringDBPaths = _dataPak.Files.Keys.Where(x => x.Contains("/OfferingDB.uasset", StringComparison.OrdinalIgnoreCase)).ToList(); + var dbPaths = _dataPak.Files.Keys.Where(x => x.Contains(pathFilter, StringComparison.OrdinalIgnoreCase)); - foreach (string path in offeringDBPaths) + foreach (string path in dbPaths) { string cleanPath = path.Contains('.') ? path[..path.LastIndexOf('.')] : path; if (_provider.TryLoadPackageObject(cleanPath, out UDataTable? dataTable)) { foreach (KeyValuePair row in dataTable.RowMap) - { - List props = row.Value.Properties; - - string offeringId = row.Key.Text; - - if (!TryGetProp(props, "Role", out EPlayerRole role) - || !TryGetProp(props, "UIData", out FStructFallback uiDataFb) - || !TryGetProp(props, "Inventory", out bool isInventory) - || !TryGetProp(props, "IsFakeItem", out bool isFakeItem) - ) - throw new KeyNotFoundException("Role, UIData, Inventory or IsFakeItem was not found"); - - UIDataStruct uiData = uiDataFb.MapToStruct(); - - if (!isInventory || isFakeItem) - { - _log.Verbose("Ignoring invalid offering ({0})", offeringDBPaths); - continue; - } - - if (uiData.IconAssetList.Length == 0) - throw new InvalidDataException("Offerings's UIData had no icons"); - - _offeringMap[offeringId] = new OfferingInfo - { - id = offeringId, - name = uiData.DisplayName.ToString(), - iconFilePath = uiData.IconAssetList[0].ToString(), - role = role - }; - } + rowProcessor(row.Key.Text, row.Value.Properties); } } - - WriteJson("offerings", _offeringMap.Values); - _log.Info("Dumped {0} offerings", _offeringMap.Count); } - public void DumpOfferingIcons() + private void ExportIcons(IEnumerable iconPaths, string logName, string outFolder) { if (_provider == null) throw new InvalidOperationException("Attempted to call dump function without dumper initialization/state"); - _log.Info("Dumping offering icons"); + _log.Info($"Dumping {logName} icons"); - foreach (OfferingInfo info in _offeringMap.Values) - ExportIcon(info.iconFilePath, "/offering-icons/"); + foreach (string path in iconPaths) + ExportIcon(path, outFolder); - _log.Info("Dumped all offering icons"); - - return; + _log.Info($"Dumped all {logName} icons"); } /* @@ -413,7 +344,6 @@ class Dumper Directory.CreateDirectory(parentFolder); File.WriteAllBytes(fullPath, bytes); - _log.Verbose("Exported icon: {0}", fileName); } else throw new InvalidDataException("Bitmap was invalid");