Adventure Game Studio | Forums

AGS Development => Editor Development => Topic started by: morganw on Mon 10/09/2018 23:29:19

Title: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Mon 10/09/2018 23:29:19
It was to get a namespace for the settings class, to differentiate between builds which are (effectively) portable and the actually releases where settings need to persist between versions. As long as the plug-in isn't mixed assembly, you can retrospectively sign it by decompiling and recompiling with a generated key.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: Crimson Wizard on Mon 10/09/2018 23:55:18
Quote from: SpeechCenter on Mon 10/09/2018 23:15:04
I recently had trouble to run the existing editor plugin with the 3.5.0 release.
The reason seems to be that all the AGS .net assemblies were changed to strong names. This is a breaking change, as the plugin compiled with an existing assembly (e.g. the plugin references AGS.Types) with a weak name is not compatible with the new one compiled with a strong name
Quote from: morganw on Mon 10/09/2018 23:29:19
It was to get a namespace for the settings class, to differentiate between builds which are (effectively) portable and the actually releases where settings need to persist between versions. As long as the plug-in isn't mixed assembly, you can retrospectively sign it by decompiling and recompiling with a generated key.

Alright, this looks like another consequence that was not thought of beforehand. There is a number of editor plugins, Speech Center is one of the most popular ones, and there is at least one other I know - Rulaman's Font Editor. Does this means we need plugin author to come by and recompile the plugin? (idk what are other editor plugins in use)
From now on writing editor plugin was relatively simple, now if someone does that will have to know to do this signing too. And also, does not this mean that there should be two version of each plugin from now on - for old Editor and for the new one?


May there be an alternate solution to signing, like using some third-party settings library instead of Microsoft's one?
I remember you've mentioned this library (https://github.com/taxophobia/CustomSettingsProvider), will it work without strongname? The strongname issue is mentioned in its readme, but it's not stated explicitly.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: SpeechCenter on Tue 11/09/2018 02:03:13
Signing the plugin will not solve the issue. The problem is that the plugin was compiled with a reference to an AGS.Types assembly that didn't have a strong name. With AGS.Types now having a strong name it is not backwards compatible with previous versions. When AGS tries to load the plugin, it can't since the plugin is missing one of the references.
So indeed the consequence is that all plugins will need to be recompiled with the new library reference.

I didn't go into the details of what was changed in the AGS settings class, so I don't know enough about the change to comment, but generally I would recommend limiting breaks only to major releases (meaning AGS 4.0 can understandably break some things, though hopefully not a lot)
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Tue 11/09/2018 10:22:45
Quote from: Crimson Wizard on Mon 10/09/2018 23:55:18
Alright, this looks like another consequence that was not thought of beforehand. There is a number of editor plugins, Speech Center is one of the most popular ones, and there is at least one other I know - Rulaman's Font Editor. Does this means we need plugin author to come by and recompile the plugin? (idk what are other editor plugins in use)
From now on writing editor plugin was relatively simple, now if someone does that will have to know to do this signing too. And also, does not this mean that there should be two version of each plugin from now on - for old Editor and for the new one?
I think the main restriction is that a signed assembly cannot load an unsigned one, although to permit access to internals for the unit tests I had permit access via the public key. For an external interface though, I would need to test it. Is there a plugin stub somewhere that I can test with? We could look at using something else though, the main benefit of this was that it was built-in, so for a Mono build it was likely to be well tested.

Quote from: Crimson Wizard on Mon 10/09/2018 23:55:18
May there be an alternate solution to signing, like using some third-party settings library instead of Microsoft's one?
I remember you've mentioned this library (https://github.com/taxophobia/CustomSettingsProvider), will it work without strongname? The strongname issue is mentioned in its readme, but it's not stated explicitly.
I think the problems are generally in terms of deployment, where the program is delivered using ClickOnce and installed per user. In that case you do end up with multiple installations, so using a strongname would override where the settings are loaded from. So the main purpose of the library is to just override the settings path (manually), so that you can store settings where you like.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: Crimson Wizard on Tue 11/09/2018 11:13:38
Quote from: morganw on Tue 11/09/2018 10:22:45For an external interface though, I would need to test it. Is there a plugin stub somewhere that I can test with?

Monkey0506's Android builder plugin is open source: https://github.com/monkey0506/AGS.Plugin.AndroidBuilder
Rulaman's font editor also supposed to be open source, but the link to source is dead (http://www.adventuregamestudio.co.uk/forums/index.php?topic=48527.msg636585400#msg636585400). I have very vague memories that I've seen the source on github, but maybe they're false.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Tue 11/09/2018 17:11:14
Found one here:
http://www.adventuregamestudio.co.uk/AGS.Plugin.Sample.zip (http://www.adventuregamestudio.co.uk/AGS.Plugin.Sample.zip)

...although I haven't tried it yet.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Tue 11/09/2018 22:49:12
Quote from: SpeechCenter on Tue 11/09/2018 02:03:13
Signing the plugin will not solve the issue. The problem is that the plugin was compiled with a reference to an AGS.Types assembly that didn't have a strong name. With AGS.Types now having a strong name it is not backwards compatible with previous versions. When AGS tries to load the plugin, it can't since the plugin is missing one of the references.
So indeed the consequence is that all plugins will need to be recompiled with the new library reference.

Do you also see an issue referencing a specific version of irrKlang? It looks like there are some options to redirect reference loading, but with (what I think is) the newest version of the SpeechCenter plugin the first error I get is trying to load irrKlang rather than AGS.Types.

Just to confirm, is this (http://www.adventuregamestudio.co.uk/forums/index.php?topic=45622.0) the latest version?
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: SpeechCenter on Tue 11/09/2018 23:10:17
Quote from: morganw on Tue 11/09/2018 22:49:12
Quote from: SpeechCenter on Tue 11/09/2018 02:03:13
Signing the plugin will not solve the issue. The problem is that the plugin was compiled with a reference to an AGS.Types assembly that didn't have a strong name. With AGS.Types now having a strong name it is not backwards compatible with previous versions. When AGS tries to load the plugin, it can't since the plugin is missing one of the references.
So indeed the consequence is that all plugins will need to be recompiled with the new library reference.

Do you also see an issue referencing a specific version of irrKlang? It looks like there are some options to redirect reference loading, but with (what I think is) the newest version of the SpeechCenter plugin the first error I get is trying to load irrKlang rather than AGS.Types.

Just to confirm, is this (http://www.adventuregamestudio.co.uk/forums/index.php?topic=45622.0) the latest version?

Yes, that's the latest version.
You're right that this may be the first error. The plugin doesn't include this library but relies on AGS functionality to include that for playback capability. I see the library was updated in AGS 3.5.0 to the .net 4.0 version which the plugin cannot load given the version it was compiled..
I think that if you try to temporarily go back to the .net 2.0 implementation of irrKlang then you'll hit the AGS.Types problem.

This functionality is not central to the plugin, as most of the functionality is the management of the text. I might look for a more robust way to load this external library to address that part, though with the .net version change this won't be trivial.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: Crimson Wizard on Tue 11/09/2018 23:56:27
I tested Rulaman's Font Editor plugin, and it also fails at loading AGS.Types. Exception sais something like "public key token" value does not match what it expects.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: Crimson Wizard on Wed 12/09/2018 11:32:41
Quote from: morganw on Tue 11/09/2018 10:22:45
I think the problems are generally in terms of deployment, where the program is delivered using ClickOnce and installed per user. In that case you do end up with multiple installations, so using a strongname would override where the settings are loaded from. So the main purpose of the library is to just override the settings path (manually), so that you can store settings where you like.

Does the strongname signing give any other benefit for AGS rather than making settings system have consistent path? If not, then it looks like more trouble than good. Not only we loose compatibility with existing editor plugins for no big reason, but also dropped XP support primarily because of that (I am not saying that using .NET 4.5 is bad, but we don't really take advantage of it yet). After this problem with plugins was found it's bugging me that assembly signing may bring more problems or inconveniences in the future.

I wonder if there is any way to only override the settings path with the standard Microsoft's settings system. I'd like to take a look into that. If we could do that, would not that make things much easier for us?
If not, then this custom settings library is an extra option, although I agree that it's safer to use builtin solutions.
Another option is to use XML serializer that AGS already has (uses to save Game with), although in that case we would have to write our own logic for getting settings from the previous versions if we need that.

PS. For the reference, this seems to be an opensourced code of the default LocalFileSettingsProvider:
https://referencesource.microsoft.com/#system/sys/system/configuration/LocalFileSettingsProvider.cs
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: tzachs on Wed 12/09/2018 16:48:26
Quote from: Crimson Wizard on Wed 12/09/2018 11:32:41
Does the strongname signing give any other benefit for AGS rather than making settings system have consistent path?
List of benefits here: https://stackoverflow.com/questions/2354129/why-use-strong-named-assemblies

Whether AGS actually needs any of this, idk.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Wed 12/09/2018 17:46:46
I think as long as there is no forked version, or alternate builds (like Alan's) which could then isolate itself with another set of keys, they isn't much additional benefit other than the settings paths managing themselves. '.NET 4.5' was either for the signed irrKlang or the NuGet package that is basically a simplified LocalFileSettingsProvider, so easiest solution is to remove the signing and add the NuGet package. Maybe it is preferable to use the built in serializer instead though?
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: Crimson Wizard on Thu 13/09/2018 09:41:10
From the looks of the code (and some info found in the web) the LocalFileSettingsProvider is made so you cannot pass any custom paths into it without rewriting it all... and even worse is that it uses "internal" (hidden) classes to make some work, which means its impossible to reuse them completely in custom implementation (as far as I can tell).
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Sun 16/09/2018 21:21:25
It looks fairly easy to just redirect a failed load attempt of an assembly which had a null key, to the version which has a key. I defined this event handler:

Code (csharp) Select
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    AssemblyName assembly = new AssemblyName(args.Name);

    if (assembly.Name == "AGS.Types")
    {
        return typeof(BuildTargetsInfo).Assembly;
    }

    return null;
}


Then registered it just before the plug-in is loaded:

Code (csharp) Select
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

...and monkey's Android builder and Rulaman's font editor seemed to work fine. You can use stricter checks, like checking requested versions and keys, but there seems to be no requirement for the plug-in itself to be signed. Maybe it is best to open an issue on GitHub, since future changes to the plug-in system are probably determined by the choice made here. The restrictions seem to only impact the assemblies directly referenced to build the Editor, rather than ones that it loads dynamically.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: Crimson Wizard on Sun 16/09/2018 22:40:35
I am afraid I don't fully understand the above, do we have to add this "resolve" part to the Editor code, or is it the plugin that has to have this?

Am I correct guessing that this will substitute the unsigned AGS.Types demanded by plugin with signed one?

Quote from: morganw on Sun 16/09/2018 21:21:25Maybe it is best to open an issue on GitHub, since future changes to the plug-in system are probably determined by the choice made here.
Could you also elaborate a little on this, what changes to plugin system will be determined by this (or how)? Just want to be sure that I understand the situation well.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Mon 17/09/2018 00:24:45
Quote from: Crimson Wizard on Sun 16/09/2018 22:40:35
Am I correct guessing that this will substitute the unsigned AGS.Types demanded by plugin with signed one?
Yes, to test this I made the relevant section of PluginsComponents.cs look like this:
Code (csharp) Select
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    AssemblyName assembly = new AssemblyName(args.Name);

    if (assembly.Name == "AGS.Types")
    {
        return typeof(BuildTargetsInfo).Assembly;
    }

    return null;
}
   
private void LoadEditorPluginIntoMemory(string fileName)
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);

    try
    {
        EditorPlugin plugin = new EditorPlugin(fileName, _pluginEditorController);
        _editorPlugins.Add(plugin);
    }
    catch (AGSEditorException ex)
    {
        _guiController.ShowMessage("There was an error loading plugin '" + fileName + "'." + Environment.NewLine + Environment.NewLine + ex.Message, MessageBoxIcon.Warning);
    }
    catch (Exception ex)
    {
        _guiController.ShowMessage("There was an error loading plugin '" + fileName + "'." + Environment.NewLine + Environment.NewLine + ex.ToString(), MessageBoxIcon.Warning);
    }
}


So rather than be an exception you get the chance to load something else, and in this example the only check performed is the name of the requested assembly. What is returned is the Assembly reference for the actual AGS.Types that was built (in this case, the one that is strongnamed).

There is probably a better way to reference the assembly directly, but this:
Code (csharp) Select
return typeof(BuildTargetsInfo).Assembly
just returns the Assembly (https://docs.microsoft.com/en-us/dotnet/api/system.reflection.assembly) instance of AGS.Types (the strongnamed one), because that is the assembly where BuildTargetsInfo is located.

Quote from: Crimson Wizard on Sun 16/09/2018 22:40:35
Could you also elaborate a little on this, what changes to plugin system will be determined by this (or how)? Just want to be sure that I understand the situation well.
The main restriction is that a strongnamed assembly cannot reference (i.e. build against) an assembly that isn't strongnamed (this is requested as a 'full' bind), but using Assembly.LoadFile is treated differently (this is requested as a 'partial' bind). The loading assembly is permitted to modify the loading behaviour since the code for this is in the signed part (so the handling is in the Editor, not in the plug-in).

I guess the main thing is, at the moment there isn't really any separation of plug-in and Editor, since there is no piece in-between to broker what is available in the Editor and what is requested in the plug-in. I don't know if anyone had plans to change it, but if it would stop using Assembly.LoadFile then however the separation is implemented would also have to be happy with plug-ins requesting signed and unsigned assemblies. I would imagine such a system would probably be more likely to declare and require interfaces rather than assemblies though.

Equally, this probably needs testing with the most complex plug-ins people can find. At the moment I've only started up these two plug-ins for testing, but I've not built anything for Android or actually edited a font.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: Crimson Wizard on Mon 17/09/2018 01:00:02
Oh, I think I am beginning to understand.

One more question: is it possible to make this change as a hotfix now? If it actually lets to use plugins again not likely it may make things worse than they are. I'd like to release an update to ags 3.5.0 soon and it would be wonderful if this issue is also solved even if with some temporary code.
Title: Re: AGS 3.5 Editor settings and assembly strongname issue
Post by: morganw on Mon 17/09/2018 01:09:21
I can give it a try over the next day or two...