Skip to content

Commit

Permalink
Catch file IO errors with FMG and MTD loading (#89)
Browse files Browse the repository at this point in the history
This allows the tasks to fail gracefully and not block loading new projects
  • Loading branch information
katalash authored Aug 15, 2022
1 parent 3eadd00 commit 6195ab9
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 91 deletions.
70 changes: 39 additions & 31 deletions StudioCore/MsbEditor/MtdBank.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,49 +37,57 @@ public static void ReloadMtds()

TaskManager.Run("MB:LoadMtds", true, false, true, () =>
{
IBinder mtdBinder = null;
if (AssetLocator.Type == GameType.DarkSoulsIII || AssetLocator.Type == GameType.Sekiro)
try
{
mtdBinder = BND4.Read(AssetLocator.GetAssetPath($@"mtd\allmaterialbnd.mtdbnd.dcx"));
IsMatbin = false;
}
else if (AssetLocator.Type == GameType.EldenRing)
{
mtdBinder = BND4.Read(AssetLocator.GetAssetPath($@"material\allmaterial.matbinbnd.dcx"));
IsMatbin = true;
}
IBinder mtdBinder = null;
if (AssetLocator.Type == GameType.DarkSoulsIII || AssetLocator.Type == GameType.Sekiro)
{
mtdBinder = BND4.Read(AssetLocator.GetAssetPath($@"mtd\allmaterialbnd.mtdbnd.dcx"));
IsMatbin = false;
}
else if (AssetLocator.Type == GameType.EldenRing)
{
mtdBinder = BND4.Read(AssetLocator.GetAssetPath($@"material\allmaterial.matbinbnd.dcx"));
IsMatbin = true;
}

if (mtdBinder == null)
{
return;
}
if (mtdBinder == null)
{
return;
}

if (IsMatbin)
{
_matbins = new Dictionary<string, MATBIN>();
foreach (var f in mtdBinder.Files)
if (IsMatbin)
{
var matname = Path.GetFileNameWithoutExtension(f.Name);
// Because *certain* mods contain duplicate entries for the same material
if (!_matbins.ContainsKey(matname))
_matbins = new Dictionary<string, MATBIN>();
foreach (var f in mtdBinder.Files)
{
_matbins.Add(matname, MATBIN.Read(f.Bytes));
var matname = Path.GetFileNameWithoutExtension(f.Name);
// Because *certain* mods contain duplicate entries for the same material
if (!_matbins.ContainsKey(matname))
{
_matbins.Add(matname, MATBIN.Read(f.Bytes));
}
}
}
}
else
{
_mtds = new Dictionary<string, MTD>();
foreach (var f in mtdBinder.Files)
else
{
var mtdname = Path.GetFileNameWithoutExtension(f.Name);
// Because *certain* mods contain duplicate entries for the same material
if (!_mtds.ContainsKey(mtdname))
_mtds = new Dictionary<string, MTD>();
foreach (var f in mtdBinder.Files)
{
_mtds.Add(mtdname, MTD.Read(f.Bytes));
var mtdname = Path.GetFileNameWithoutExtension(f.Name);
// Because *certain* mods contain duplicate entries for the same material
if (!_mtds.ContainsKey(mtdname))
{
_mtds.Add(mtdname, MTD.Read(f.Bytes));
}
}
}
}
catch (Exception e) when (e is FileNotFoundException or DirectoryNotFoundException)
{
_mtds = new Dictionary<string, MTD>();
_matbins = new Dictionary<string, MATBIN>();
}
});
}

Expand Down
137 changes: 77 additions & 60 deletions StudioCore/TextEditor/FMGBank.cs
Original file line number Diff line number Diff line change
Expand Up @@ -733,78 +733,95 @@ public static void ReloadFMGs(string languageFolder = "")

TaskManager.Run("FB:Reload", true, false, true, () =>
{
if (AssetLocator.Type == GameType.Undefined)
try
{
return;
}
if (AssetLocator.Type == GameType.Undefined)
{
return;
}

if (AssetLocator.Type == GameType.DarkSoulsIISOTFS)
{
ReloadFMGsDS2(ref _languageFolder);
IsLoading = false;
IsLoaded = true;
return;
}
if (AssetLocator.Type == GameType.DarkSoulsIISOTFS)
{
ReloadFMGsDS2(ref _languageFolder);
IsLoading = false;
IsLoaded = true;
return;
}

var itemMsgPath = AssetLocator.GetItemMsgbnd(ref _languageFolder);
var menuMsgPath = AssetLocator.GetMenuMsgbnd(ref _languageFolder);
if (itemMsgPath.AssetPath == null)
{
MessageBox.Show($"Could not find item.msgbnd in {_languageFolder}", "Error");
IsLoaded = true; //permits loading default language
IsLoading = false;
return;
}
if (menuMsgPath.AssetPath == null)
{
MessageBox.Show($"Could not find menu.msgbnd in {_languageFolder}", "Error");
IsLoaded = true; //permits loading default language
IsLoading = false;
return;
}
var itemMsgPath = AssetLocator.GetItemMsgbnd(ref _languageFolder);
var menuMsgPath = AssetLocator.GetMenuMsgbnd(ref _languageFolder);
if (itemMsgPath.AssetPath == null)
{
MessageBox.Show($"Could not find item.msgbnd in {_languageFolder}", "Error");
IsLoaded = true; //permits loading default language
IsLoading = false;
return;
}

IBinder fmgBinderItem;
IBinder fmgBinderMenu;
if (AssetLocator.Type == GameType.DemonsSouls || AssetLocator.Type == GameType.DarkSoulsPTDE || AssetLocator.Type == GameType.DarkSoulsRemastered)
{
fmgBinderItem = BND3.Read(itemMsgPath.AssetPath);
fmgBinderMenu = BND3.Read(menuMsgPath.AssetPath);
}
else
{
fmgBinderItem = BND4.Read(itemMsgPath.AssetPath);
fmgBinderMenu = BND4.Read(menuMsgPath.AssetPath);
}
if (menuMsgPath.AssetPath == null)
{
MessageBox.Show($"Could not find menu.msgbnd in {_languageFolder}", "Error");
IsLoaded = true; //permits loading default language
IsLoading = false;
return;
}

_itemFMGs = new Dictionary<ItemFMGTypes, FMG>();
_menuFMGs = new Dictionary<MenuFMGTypes, FMG>();
foreach (var file in fmgBinderItem.Files)
{
if (Enum.IsDefined(typeof(ItemFMGTypes), file.ID))
_itemFMGs.Add((ItemFMGTypes)file.ID, FMG.Read(file.Bytes));
else if (Enum.IsDefined(typeof(MenuFMGTypes), file.ID))
_menuFMGs.Add((MenuFMGTypes)file.ID, FMG.Read(file.Bytes));
IBinder fmgBinderItem;
IBinder fmgBinderMenu;
if (AssetLocator.Type == GameType.DemonsSouls || AssetLocator.Type == GameType.DarkSoulsPTDE ||
AssetLocator.Type == GameType.DarkSoulsRemastered)
{
fmgBinderItem = BND3.Read(itemMsgPath.AssetPath);
fmgBinderMenu = BND3.Read(menuMsgPath.AssetPath);
}
else
MessageBox.Show($"Didn't expect FMG ID \"{file.ID}\" in \"item.msgbnd\". Please report this error.", "FMG skipped");
}
{
fmgBinderItem = BND4.Read(itemMsgPath.AssetPath);
fmgBinderMenu = BND4.Read(menuMsgPath.AssetPath);
}

_itemFMGs = new Dictionary<ItemFMGTypes, FMG>();
_menuFMGs = new Dictionary<MenuFMGTypes, FMG>();
foreach (var file in fmgBinderItem.Files)
{
if (Enum.IsDefined(typeof(ItemFMGTypes), file.ID))
_itemFMGs.Add((ItemFMGTypes)file.ID, FMG.Read(file.Bytes));
else if (Enum.IsDefined(typeof(MenuFMGTypes), file.ID))
_menuFMGs.Add((MenuFMGTypes)file.ID, FMG.Read(file.Bytes));
else
MessageBox.Show(
$"Didn't expect FMG ID \"{file.ID}\" in \"item.msgbnd\". Please report this error.",
"FMG skipped");
}

foreach (var file in fmgBinderMenu.Files)
{
if (Enum.IsDefined(typeof(ItemFMGTypes), file.ID))
_itemFMGs.Add((ItemFMGTypes)file.ID, FMG.Read(file.Bytes));
else if (Enum.IsDefined(typeof(MenuFMGTypes), file.ID))
_menuFMGs.Add((MenuFMGTypes)file.ID, FMG.Read(file.Bytes));
else
MessageBox.Show(
$"Didn't expect FMG ID \"{file.ID}\" in \"menu.msgbnd\". Please report this error.",
"FMG skipped");
}

foreach (var file in fmgBinderMenu.Files)
_itemFMGs = _itemFMGs.OrderBy(e => e.Key.ToString()).ToDictionary(e => e.Key, e => e.Value);
_menuFMGs = _menuFMGs.OrderBy(e => MenuEnumString(e.Key)).ToDictionary(e => e.Key, e => e.Value);
IsLoaded = true;
IsLoading = false;
}
catch (Exception e) when (e is DirectoryNotFoundException or FileNotFoundException)
{
if (Enum.IsDefined(typeof(ItemFMGTypes), file.ID))
_itemFMGs.Add((ItemFMGTypes)file.ID, FMG.Read(file.Bytes));
else if (Enum.IsDefined(typeof(MenuFMGTypes), file.ID))
_menuFMGs.Add((MenuFMGTypes)file.ID, FMG.Read(file.Bytes));
else
MessageBox.Show($"Didn't expect FMG ID \"{file.ID}\" in \"menu.msgbnd\". Please report this error.", "FMG skipped");
_itemFMGs = new Dictionary<ItemFMGTypes, FMG>();
_menuFMGs = new Dictionary<MenuFMGTypes, FMG>();
IsLoaded = false;
IsLoading = false;
}
_itemFMGs = _itemFMGs.OrderBy(e => e.Key.ToString()).ToDictionary(e => e.Key, e => e.Value);
_menuFMGs = _menuFMGs.OrderBy(e => MenuEnumString(e.Key)).ToDictionary(e => e.Key, e => e.Value);
IsLoaded = true;
IsLoading = false;
});
}

public static void SaveFMGsDS2()
private static void SaveFMGsDS2()
{
foreach (var fmg in _ds2fmgs)
{
Expand Down
4 changes: 4 additions & 0 deletions StudioCore/TextEditor/TextEditorScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,10 @@ private void EditorGUI(bool doFocus)
{
ImGui.Text("Loading...");
}
else
{
ImGui.Text("This editor requires a project with the game unpacked to be loaded.");
}
return;
}
var dsid = ImGui.GetID("DockSpace_TextEntries");
Expand Down

0 comments on commit 6195ab9

Please sign in to comment.