Skip to content

Commit 876b73a

Browse files
committed
Use assembly level attribute for module declaration
1 parent 499857b commit 876b73a

File tree

14 files changed

+91
-52
lines changed

14 files changed

+91
-52
lines changed

Desktop/Constants.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
using System.Reflection;
2+
using Microsoft.VisualBasic.ApplicationServices;
3+
using OpenShock.Desktop.Ui.Utils;
24
using Semver;
35

46
namespace OpenShock.Desktop;
@@ -9,12 +11,13 @@ public static class Constants
911
Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), @"OpenShock\Desktop");
1012
public static readonly string LogsFolder = Path.Combine(AppdataFolder, "logs");
1113
public static readonly string ModuleData = Path.Combine(AppdataFolder, "moduleData");
14+
public static readonly string UserAgent = UserAgentUtil.GetUserAgent();
1215

1316
public static readonly SemVersion Version = SemVersion.Parse(typeof(Constants).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!.InformationalVersion, SemVersionStyles.Strict);
1417
public static readonly SemVersion VersionWithoutMetadata = Version.WithoutMetadata();
1518

1619
public static readonly IReadOnlyList<Uri> BuiltInModuleRepositories = new List<Uri>
1720
{
18-
new("https://nas.luc.cat/openshockmodules.json")
21+
new("https://repo.openshock.org/1")
1922
};
2023
}

Desktop/ModuleManager/Implementation/ModuleInstanceManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ public ModuleInstanceManager(
2626

2727
public async Task<IModuleConfig<T>> GetModuleConfig<T>() where T : new()
2828
{
29-
var moduleConfigPath = Path.Combine(Constants.ModuleData, _loadedModule.Module.Id);
29+
var moduleConfigPath = Path.Combine(Constants.ModuleData, _loadedModule.Id);
3030

3131
if(!Directory.Exists(moduleConfigPath)) Directory.CreateDirectory(moduleConfigPath);
3232

3333
var moduleConfigFile = Path.Combine(moduleConfigPath, "config.json");
3434

3535
return await ModuleConfig<T>.Create(moduleConfigFile,
36-
_loggerFactory.CreateLogger("ModuleConfig+" + _loadedModule.Module.Id));
36+
_loggerFactory.CreateLogger("ModuleConfig+" + _loadedModule.Id));
3737
}
3838

3939
public required IServiceProvider AppServiceProvider { get; init; }

Desktop/ModuleManager/LoadedModule.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ public sealed class LoadedModule
99
{
1010
public required ModuleAssemblyLoadContext LoadContext { get; init; }
1111
public required Assembly Assembly { get; init; }
12+
public required DesktopModuleAttribute ModuleAttribute { get; init; }
1213
public required DesktopModuleBase Module { get; init; }
1314
public required SemVersion Version { get; init; }
1415

1516
public required Module? RepositoryModule { get; set; }
1617
public required SemVersion? AvailableVersion { get; set; }
18+
19+
20+
public string Id => ModuleAttribute.Id;
21+
public string Name => ModuleAttribute.Name;
1722
}

Desktop/ModuleManager/ModuleManager.cs

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,21 +154,23 @@ private async Task<OneOf<Success, Error>> DownloadModule(string moduleId, Uri mo
154154

155155
private void LoadModule(string moduleFolderPath, string moduleDll, string moduleFolderName)
156156
{
157-
_logger.LogDebug("Attempting to load module: {Path}", moduleDll);
157+
_logger.LogInformation("Loading module: {Path}", moduleDll);
158158

159159
var assemblyLoadContext = new ModuleAssemblyLoadContext(moduleFolderPath);
160160
var assembly = assemblyLoadContext.LoadFromAssemblyPath(moduleDll);
161+
162+
var moduleAttribute = assembly.GetCustomAttribute<DesktopModuleAttribute>();
161163

162-
var moduleTypes = assembly.GetTypes();
163-
var pluginTypes = moduleTypes.Where(t => t.IsAssignableTo(ModuleBaseType)).ToImmutableArray();
164-
switch (pluginTypes.Length)
164+
if (moduleAttribute is null)
165+
{
166+
_logger.LogError("Module Assembly does not have a module attribute!");
167+
return;
168+
}
169+
170+
if (!moduleAttribute.ModuleType.IsAssignableTo(ModuleBaseType))
165171
{
166-
case 0:
167-
_logger.LogError("No modules found in DLL!");
168-
return;
169-
case > 1:
170-
_logger.LogError("Expected 1 module, found {NumberOfModules}", pluginTypes.Length);
171-
return;
172+
_logger.LogError("Module Attribute: Type does not inherit from DesktopModuleBase!");
173+
return;
172174
}
173175

174176
var assemblyVersion =
@@ -182,17 +184,18 @@ private void LoadModule(string moduleFolderPath, string moduleDll, string module
182184

183185
if (!SemVersion.TryParse(assemblyVersion, SemVersionStyles.Strict, out var loadedModuleVersion))
184186
{
185-
_logger.LogError("Failed to parse sem-version {Version} for module {ModuleId}. It needs to be a valid semantic version.", assemblyVersion, pluginTypes[0].FullName);
187+
_logger.LogError("Failed to parse sem-version {Version} for module {ModuleId}. It needs to be a valid semantic version.", assemblyVersion, moduleAttribute.ModuleType.FullName);
186188
return;
187189
}
188190

189-
var module = (DesktopModuleBase?)ActivatorUtilities.CreateInstance(_serviceProvider, pluginTypes[0]);
191+
var module = (DesktopModuleBase?)ActivatorUtilities.CreateInstance(_serviceProvider, moduleAttribute.ModuleType);
190192
if (module is null) throw new Exception("Failed to instantiate module!");
191193

192194

193195
var loadedModule = new LoadedModule
194196
{
195197
LoadContext = assemblyLoadContext,
198+
ModuleAttribute = moduleAttribute,
196199
Assembly = assembly,
197200
Module = module,
198201
Version = loadedModuleVersion,
@@ -210,15 +213,15 @@ private void LoadModule(string moduleFolderPath, string moduleDll, string module
210213
AppServiceProvider = _serviceProvider
211214
});
212215

213-
if (moduleFolderName != loadedModule.Module.Id)
216+
if (moduleFolderName != loadedModule.Id)
214217
{
215218
_logger.LogError(
216219
"Module folder name does not match module ID! [{FolderName} != {ModuleName}]. This might cause issues and is not expected. Updating for sure wont work properly :3 Please fix this",
217-
moduleFolderName, loadedModule.Module.Id);
220+
moduleFolderName, loadedModule.Id);
218221
return;
219222
}
220223

221-
if (!Modules.TryAdd(module.Id, loadedModule)) throw new Exception("Module already loaded!");
224+
if (!Modules.TryAdd(loadedModule.Id, loadedModule)) throw new Exception("Module already loaded!");
222225
}
223226

224227
private void RefreshRepositoryInformationOnLoaded()

Desktop/ModuleManager/Repository/Repository.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public sealed class Repository
77
public required string Name { get; init; }
88
public required string Id { get; init; }
99
public required string Author { get; init; }
10-
public required Uri Url { get; init; }
10+
public required Uri? Homepage { get; init; }
1111

1212
public required ImmutableDictionary<string, Module> Modules { get; init; }
1313
}

Desktop/ModuleManager/Repository/RepositoryLoadContext.cs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
using System.Diagnostics.CodeAnalysis;
22
using System.Net;
3+
using System.Net.Http.Headers;
34
using System.Text.Json;
45
using OneOf;
56
using OneOf.Types;
67
using OpenShock.Desktop.ModuleBase.Utils;
8+
using OpenShock.Desktop.Ui.Utils;
79
using OpenShock.Desktop.Utils;
810
using OpenShock.SDK.CSharp.Updatables;
911
using Serilog;
@@ -13,10 +15,19 @@ namespace OpenShock.Desktop.ModuleManager.Repository;
1315

1416
public sealed class RepositoryLoadContext
1517
{
16-
private static readonly HttpClient HttpClient = new HttpClient()
18+
private static readonly HttpClient HttpClient;
19+
20+
static RepositoryLoadContext()
1721
{
18-
Timeout = TimeSpan.FromSeconds(15)
19-
};
22+
HttpClient = new HttpClient(new SocketsHttpHandler
23+
{
24+
PooledConnectionLifetime = TimeSpan.FromHours(1)
25+
})
26+
{
27+
Timeout = TimeSpan.FromSeconds(15)
28+
};
29+
HttpClient.DefaultRequestHeaders.Add("User-Agent", Constants.UserAgent);
30+
}
2031

2132
private static readonly ILogger Logger = Log.ForContext<RepositoryLoadContext>();
2233

Desktop/OpenShockModuleComponentActivator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private void InjectModuleDependencies(object instance, Type componentType, Loade
6262
if (service == null)
6363
{
6464
throw new Exception(
65-
$"There is no registered service of type {prop.PropertyType.Name} for module {module.Module.Id}");
65+
$"There is no registered service of type {prop.PropertyType.Name} for module {module.Id}");
6666
}
6767

6868
prop.SetValue(instance, service);

Desktop/Ui/Pages/Authentication/LoginPart.razor

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@
3535
@if (!_useCustomServerDialog)
3636
{
3737
<MudSelect T="BackendServer" Label="Server" @bind-Value="Server" Variant="Variant.Outlined" AnchorOrigin="Origin.BottomCenter">
38-
<MudSelectItem T="BackendServer" Value="BackendServer.Production"><span class="server-url-backdrop">https://api.openshock.app/</span> (Production)</MudSelectItem>
39-
<MudSelectItem T="BackendServer" Value="BackendServer.Staging"><span class="server-url-backdrop">https://api-staging.openshock.app/</span> (Staging)</MudSelectItem>
38+
<MudSelectItem T="BackendServer" Value="BackendServer.Production"><span class="server-url-backdrop">https://api.openshock.app/</span> (OpenShock Official)</MudSelectItem>
4039
@if (_customServerUri != null)
4140
{
4241
<MudSelectItem T="BackendServer" Value="BackendServer.Custom"><span class="server-url-backdrop">@_customServerUri</span> (Custom)</MudSelectItem>
@@ -125,7 +124,6 @@
125124
private enum BackendServer
126125
{
127126
Production,
128-
Staging,
129127
Custom
130128
}
131129

@@ -136,13 +134,11 @@
136134
get => ConfigManager.Config.OpenShock.Backend.ToString() switch
137135
{
138136
ProductionServerString => BackendServer.Production,
139-
StagingServerString => BackendServer.Staging,
140137
_ => BackendServer.Custom
141138
};
142139
set => ConfigManager.Config.OpenShock.Backend = value switch
143140
{
144141
BackendServer.Production => _productionServer,
145-
BackendServer.Staging => _stagingServer,
146142
BackendServer.Custom => _customServerUri,
147143
_ => throw new ArgumentOutOfRangeException(nameof(value), value, null)
148144
} ?? throw new InvalidOperationException();
@@ -155,10 +151,8 @@
155151
private struct UriIsNotValid;
156152

157153
private const string ProductionServerString = "https://api.openshock.app/";
158-
private const string StagingServerString = "https://staging-api.openshock.app/";
159154

160155
private static Uri _productionServer = new(ProductionServerString);
161-
private static Uri _stagingServer = new(StagingServerString);
162156

163157
protected override void OnInitialized()
164158
{
@@ -169,7 +163,7 @@
169163
{
170164
Logger.LogTrace("Get API info");
171165
var httpClient = new HttpClient();
172-
httpClient.DefaultRequestHeaders.Add("User-Agent", "OpenShock.Desktop-Internal/1.0");
166+
httpClient.DefaultRequestHeaders.Add("User-Agent", Constants.UserAgent);
173167
httpClient.BaseAddress = ConfigManager.Config.OpenShock.Backend;
174168
var response = await httpClient.GetAsync("1");
175169
if (!response.IsSuccessStatusCode)
@@ -192,19 +186,6 @@
192186
var requestUri = new Uri(root.Data!.ShortLinkUrl, "/t/?name=OpenShock%20Desktop&redirect_uri=openshock:token/%&permissions=shockers.use,shockers.pause");
193187
UiUtils.OpenUrl(requestUri.ToString());
194188
}
195-
196-
private string GetUserAgent()
197-
{
198-
var desktopVersion = GetType().Assembly.GetName().Version!;
199-
200-
201-
var runtimeVersion = RuntimeInformation.FrameworkDescription;
202-
if (string.IsNullOrEmpty(runtimeVersion)) runtimeVersion = "Unknown Runtime";
203-
204-
return
205-
$"OpenShock.Desktop/{desktopVersion.Major}.{desktopVersion.Minor}.{desktopVersion.Build} " +
206-
$"({runtimeVersion}; {UserAgentUtils.GetOs()}; OpenShockDesktopInternals)";
207-
}
208189

209190
public sealed class RootResponse
210191
{

Desktop/Ui/Pages/Dash/Components/ModuleManagerItem.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@
114114
throw new ArgumentException("RepoModule and LoadedModule cannot both be null");
115115
}
116116

117-
_moduleName = RepoModule?.Name ?? (LoadedModule?.Module.Name ?? "error");
118-
_moduleIcon = RepoModule?.IconUrl?.ToString() ?? LoadedModule!.Module.IconPath;
117+
_moduleName = RepoModule?.Name ?? (LoadedModule?.Name ?? "error");
118+
_moduleIcon = RepoModule?.IconUrl?.ToString() ?? LoadedModule?.Module.IconPath;
119119
_availableVersions = GetAvailableVersions();
120120
}
121121

Desktop/Ui/Pages/Dash/Components/ModuleNavComponent.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@using OpenShock.Desktop.ModuleManager
22

3-
<ModuleNavGroup IconImage="@LoadedModule.Module.IconPath" Title="@LoadedModule.Module.Name">
3+
<ModuleNavGroup IconImage="@LoadedModule.Module.IconPath" Title="@LoadedModule.Name">
44
@foreach (var subComponent in LoadedModule.Module.NavigationComponents)
55
{
6-
<ModuleNavLink Icon="@subComponent.Icon" Href="@("/dash/module/" + LoadedModule.Module.Id + "/" + subComponent.Name)">@(subComponent.Name)</ModuleNavLink>
6+
<ModuleNavLink Icon="@subComponent.Icon" Href="@("/dash/module/" + LoadedModule.Id + "/" + subComponent.Name)">@(subComponent.Name)</ModuleNavLink>
77
}
88
</ModuleNavGroup>
99

0 commit comments

Comments
 (0)