-
Notifications
You must be signed in to change notification settings - Fork 429
Open
Labels
App: EmuHawkRelating to EmuHawk frontendRelating to EmuHawk frontendRepro: Affects 2.9 devNeeds to be re-triagedNeeds to be re-triagedReproducible bugShould only be added to issues with a `Repro: Affects` label.Should only be added to issues with a `Repro: Affects` label.re: APIHawkRelating to EmuHawk's public .NET API or to the creation of external toolsRelating to EmuHawk's public .NET API or to the creation of external tools
Description
Summary
If the external tool is opened at least once, and the external tool uses the following C# codes below, in theory, the configuration file config.ini will include information of the external tool.
[ConfigPersist]
public GeneticAlgorithmBotSettings Settings { get; set; }public class GeneticAlgorithmBotSettings {
public RecentFiles RecentBotFiles { get; set; } = new RecentFiles();
public bool TurboWhenBotting { get; set; } = true;
public bool InvisibleEmulation { get; set; }
}Below is the snippet of the config.ini:
...
"CommonToolSettings": {
"BizHawk.Client.EmuHawk.TAStudio": {
"_wndx": 543,
"_wndy": 55,
"Width": 525,
"Height": 615,
"SaveWindowPosition": true,
"TopMost": false,
"FloatingWindow": true,
"AutoLoad": false
},
"GeneticAlgorithmBot.GeneticAlgorithmBot": {
"_wndx": 1091,
"_wndy": 149,
"Width": 723,
"Height": 626,
"SaveWindowPosition": true,
"TopMost": false,
"FloatingWindow": true,
"AutoLoad": false
}
},
"CustomToolSettings": {
"BizHawk.Client.EmuHawk.TAStudio": {
"Settings": {
"$type": "BizHawk.Client.EmuHawk.TAStudio+TAStudioSettings, EmuHawk",
"RecentTas": {
"recentlist": [],
"MAX_RECENT_FILES": 8,
"AutoLoad": false,
"Frozen": false
},
"AutoPause": true,
"AutoRestoreLastPosition": false,
"FollowCursor": true,
"EmptyMarkers": false,
"ScrollSpeed": 6,
"FollowCursorAlwaysScroll": false,
"FollowCursorScrollMethod": "near",
"BranchCellHoverInterval": 1,
"SeekingCutoffInterval": 2,
"AutosaveInterval": 120000,
"AutosaveAsBk2": false,
"AutosaveAsBackupFile": false,
"BackupPerFileSave": false,
"SingleClickAxisEdit": false,
"OldControlSchemeForBranches": false,
"LoadBranchOnDoubleClick": true,
"DenoteStatesWithIcons": false,
"DenoteStatesWithBGColor": true,
"DenoteMarkersWithIcons": false,
"DenoteMarkersWithBGColor": true,
"MainVerticalSplitDistance": 0,
"BranchMarkerSplitDistance": 183,
"BindMarkersToInput": false,
"CopyIncludesFrameNo": false,
"Palette": {
"CurrentFrame_InputLog": "181, 231, 247",
"GreenZone_FrameCol": "221, 255, 221",
"GreenZone_InputLog": "210, 249, 211",
"GreenZone_InputLog_Stated": "196, 247, 200",
"GreenZone_InputLog_Invalidated": "224, 251, 224",
"LagZone_FrameCol": "255, 220, 221",
"LagZone_InputLog": "244, 218, 218",
"LagZone_InputLog_Stated": "240, 208, 210",
"LagZone_InputLog_Invalidated": "247, 229, 229",
"Marker_FrameCol": "247, 255, 201",
"AnalogEdit_Col": "144, 144, 112"
}
},
"TasViewFont": "Arial, 8.25pt, style=Bold"
},
"GeneticAlgorithmBot.GeneticAlgorithmBot": {
"Settings": {
"$type": "GeneticAlgorithmBot.GeneticAlgorithmBotSettings, GeneticAlgorithmBot",
"RecentBotFiles": {
"recentlist": [],
"MAX_RECENT_FILES": 8,
"AutoLoad": false,
"Frozen": false
},
"TurboWhenBotting": true,
"InvisibleEmulation": false
}
}
},
...I suspect that the formatting of the JSON object for CustomToolSettings and CommonToolSettings both didn't expect there to be an external tool reference if the external tool is using [ConfigPersist] attribute in the code.
Repro
- Use any blank C# project that is set up to create an external tool for BizHawk.
- Declare a class type with the
[ConfigPersist]attribute and create a class type with any properties (int,float, or evenRecentFilesclass type). - Build the external tool.
- Load the external tool in EmuHawk just 1 time.
- Close the external tool window (Important step!)
- Close EmuHawk.
- Open EmuHawk again.
- Observe crash.
Output
Full stack trace below:
It appears your config file (config.ini) is corrupted; an exception was thrown while loading it.
On closing this warning, EmuHawk will delete your config file and generate a new one. You can go make a backup now if you'd like to look into diffs.
The caught exception was:
System.InvalidOperationException: Config Error ---> Newtonsoft.Json.JsonSerializationException: Error resolving type specified in JSON 'GeneticAlgorithmBot.GeneticAlgorithmBotSettings, GeneticAlgorithmBot'. Path 'CustomToolSettings['GeneticAlgorithmBot.GeneticAlgorithmBot'].Settings.$type', line 1573, position 87. ---> Newtonsoft.Json.JsonSerializationException: Could not load assembly 'GeneticAlgorithmBot'.
at Newtonsoft.Json.Serialization.DefaultSerializationBinder.GetTypeFromTypeNameKey(StructMultiKey`2 typeNameKey)
at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
at Newtonsoft.Json.Serialization.DefaultSerializationBinder.BindToType(String assemblyName, String typeName)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolveTypeName(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, String qualifiedTypeName)
--- End of inner exception stack trace ---
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolveTypeName(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, String qualifiedTypeName)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
at BizHawk.Client.Common.ConfigService.Load[T](String filepath) in E:\LargeGithubProjects\BizHawk\src\BizHawk.Client.Common\config\ConfigService.cs:line 97
--- End of inner exception stack trace ---
at BizHawk.Client.Common.ConfigService.Load[T](String filepath) in E:\LargeGithubProjects\BizHawk\src\BizHawk.Client.Common\config\ConfigService.cs:line 102
at BizHawk.Client.EmuHawk.Program.SubMain(String[] args)
Host env.
- BizHawk dev build at 070e703; Win10 Pro 21H1; Intel/NVIDIA
Metadata
Metadata
Assignees
Labels
App: EmuHawkRelating to EmuHawk frontendRelating to EmuHawk frontendRepro: Affects 2.9 devNeeds to be re-triagedNeeds to be re-triagedReproducible bugShould only be added to issues with a `Repro: Affects` label.Should only be added to issues with a `Repro: Affects` label.re: APIHawkRelating to EmuHawk's public .NET API or to the creation of external toolsRelating to EmuHawk's public .NET API or to the creation of external tools