• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

luttje / Key2Joy / 6517266969

14 Oct 2023 11:05AM UTC coverage: 12.469% (+0.2%) from 12.308%
6517266969

push

github

web-flow
Implementing plugins for better separation (#39)

* Start implementing plugins for better separation
* massive refactor in attempt to split appdomains for plugins
* (breaks old mapping profiles)
* Fix error when switching from mouse button trigger to keyboard trigger and clicking in the combobox where the mouse button capture textbox is.
* Simplify code by removing legacy
* SImplify grouping actions
* Fix profile and add helpful opposite mapping generator tool
* Change solution hierarchy
* Restrict AppDomain plugins went from Zone.MyComputer -> .Internet
* create keypair in ci
* Install the .NET framework tools
* Run command in workflow
* Plugin permissions. Plugins disabled by default
* update readme (icon is no longer used)
* Plugin action runs in seperated process
* Remove unused dependencies.
* Fix action name display for mapping
* Fix Lua plugin script calls (NOTE: laggy when using MessageBox)
* convert project to sdk style
* Add editorconfig and start cleaning up
* Fix documentation. Update namespaces to match files (breaks profiles)
* Include all projects in tests, disable building docs on debug
* Add messagebox script action
* Add tests for pluginhost
* Remove administrator from window title test
* add some icons to ui
* Add enabling/disabling plugins
* Close plugins when Key2Joy shuts down
* Fix appcommand failing
* Fix plugin permission form crashing. Fix plugin load exception not showing warning
* Handle plugin host closing better when app has crashed
* Seperate host and client logic in remote event subscriber
* Ensure the PluginHost shuts down if the app crashes
* Better error output for plugins
* Fix cmd interop not working, add some tests
* also generate docs on plugins
* Fix build order with docs
* Fix enum script parameters and ensure actions share environment scopes
* Fix _wpftmp folders being created dotnet/wpf#2930
* Fix sequence action. Add disabled trigger/action for unloaded plugins on start... (continued)

180 of 1703 branches covered (0.0%)

Branch coverage included in aggregate %.

6419 of 6419 new or added lines in 207 files covered. (100.0%)

1035 of 8041 relevant lines covered (12.87%)

8445.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

37.37
/Core/Key2Joy.Core/Config/ConfigManager.cs
1
using System.IO;
2
using System.Text.Json;
3
using Key2Joy.Contracts;
4

5
namespace Key2Joy.Config;
6

7
public class ConfigManager
8
{
9
    private const string CONFIG_PATH = "config.json";
10

11
    private static ConfigManager instance;
12

13
    internal static ConfigManager Instance
14
    {
15
        get
16
        {
16✔
17
            instance ??= LoadOrCreate();
16✔
18

19
            return instance;
16✔
20
        }
16✔
21
    }
22

23
    public static ConfigState Config => Instance.configState;
8✔
24

25
    internal bool IsInitialized { get; private set; }
5✔
26
    private ConfigState configState;
27

28
    private ConfigManager()
1✔
29
    { }
2✔
30

31
    internal void Save()
32
    {
5✔
33
        var options = GetSerializerOptions();
5✔
34
        var configPath = Path.Combine(
5✔
35
            Output.GetAppDataDirectory(),
5✔
36
            CONFIG_PATH);
5✔
37

38
        File.WriteAllText(configPath, JsonSerializer.Serialize(this.configState, options));
5✔
39
    }
5✔
40

41
    private static ConfigManager LoadOrCreate()
42
    {
1✔
43
        var configPath = Path.Combine(
1✔
44
            Output.GetAppDataDirectory(),
1✔
45
            CONFIG_PATH);
1✔
46

47
        if (!File.Exists(configPath))
1!
48
        {
1✔
49
            instance = new ConfigManager();
1✔
50
#pragma warning disable IDE0017 // Simplify object initialization (would break since ConfigState checks IsInitialized)
51
            instance.configState = new ConfigState();
1✔
52
            instance.IsInitialized = true;
1✔
53
#pragma warning restore IDE0017 // Simplify object initialization
54
            instance.Save();
1✔
55
            return instance;
1✔
56
        }
57

58
        var options = GetSerializerOptions();
×
59
        instance = new ConfigManager();
×
60
#pragma warning disable IDE0017 // Simplify object initialization (would break since ConfigState checks IsInitialized)
61
        instance.configState = JsonSerializer.Deserialize<ConfigState>(File.ReadAllText(configPath), options);
×
62
#pragma warning restore IDE0017 // Simplify object initialization
63

64
        var assembly = System.Reflection.Assembly.GetEntryAssembly();
×
65

66
        // If the assembly is null then we are running in a unit test
67
        if (assembly == null)
×
68
        {
×
69
            instance.IsInitialized = true;
×
70
            return instance;
×
71
        }
72

73
        var executablePath = assembly.Location;
×
74
        if (executablePath.EndsWith("Key2Joy.exe")
×
75
            && instance.configState.LastInstallPath != executablePath)
×
76
        {
×
77
            instance.configState.LastInstallPath = executablePath;
×
78
            instance.Save();
×
79
        }
×
80

81
        instance.IsInitialized = true;
×
82

83
        return instance;
×
84
    }
1✔
85

86
    private static JsonSerializerOptions GetSerializerOptions()
87
    {
5✔
88
        JsonSerializerOptions options = new()
5✔
89
        {
5✔
90
            WriteIndented = true
5✔
91
        };
5✔
92

93
        return options;
5✔
94
    }
5✔
95

96
    /// <summary>
97
    /// Turns the plugin path into a relative one from the app directory
98
    /// </summary>
99
    /// <param name="pluginAssemblyPath"></param>
100
    /// <returns></returns>
101
    private string NormalizePluginPath(string pluginAssemblyPath)
102
    {
×
103
        var appDirectory = Path.GetDirectoryName(this.configState.LastInstallPath);
×
104
        var pluginPath = Path.GetFullPath(pluginAssemblyPath);
×
105
        var relativePath = pluginPath.Replace(appDirectory, string.Empty).TrimStart('\\');
×
106

107
        return relativePath;
×
108
    }
×
109

110
    /// <summary>
111
    /// Sets a plugin as enabled, the permissions checksum is stored so no changes to the permissions
112
    /// are accepted when loading the plugin later.
113
    ///
114
    /// Set permissionsChecksumOrNull to null to disable the plugin.
115
    /// </summary>
116
    /// <param name="pluginAssemblyPath"></param>
117
    /// <param name="permissionsChecksumOrNull"></param>
118
    internal void SetPluginEnabled(string pluginAssemblyPath, string permissionsChecksumOrNull)
119
    {
×
120
        pluginAssemblyPath = this.NormalizePluginPath(pluginAssemblyPath);
×
121

122
        if (permissionsChecksumOrNull != null)
×
123
        {
×
124
            if (!this.configState.EnabledPlugins.ContainsKey(pluginAssemblyPath))
×
125
            {
×
126
                this.configState.EnabledPlugins.Add(pluginAssemblyPath, permissionsChecksumOrNull);
×
127
            }
×
128
            else
129
            {
×
130
                this.configState.EnabledPlugins[pluginAssemblyPath] = permissionsChecksumOrNull;
×
131
            }
×
132
        }
×
133
        else
134
        {
×
135
            if (this.configState.EnabledPlugins.ContainsKey(pluginAssemblyPath))
×
136
            {
×
137
                this.configState.EnabledPlugins.Remove(pluginAssemblyPath);
×
138
            }
×
139
        }
×
140

141
        this.Save();
×
142
    }
×
143

144
    internal bool IsPluginEnabled(string pluginAssemblyPath)
145
        => this.configState.EnabledPlugins.ContainsKey(this.NormalizePluginPath(pluginAssemblyPath));
×
146

147
    internal string GetExpectedChecksum(string pluginAssemblyPath)
148
        => this.configState.EnabledPlugins.ContainsKey(this.NormalizePluginPath(pluginAssemblyPath))
×
149
            ? this.configState.EnabledPlugins[this.NormalizePluginPath(pluginAssemblyPath)]
×
150
            : null;
×
151
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc