mirror of
https://github.com/gwdevhub/Daybreak.git
synced 2026-07-15 15:19:57 +00:00
@@ -1,4 +1,5 @@
|
||||
using Daybreak.Shared.Services.ApplicationArguments;
|
||||
using Daybreak.Shared.Services.FileProviders;
|
||||
using Daybreak.Shared.Services.Initialization;
|
||||
using Daybreak.Shared.Services.Metrics;
|
||||
using Daybreak.Shared.Utils;
|
||||
@@ -25,6 +26,7 @@ public abstract class PluginConfigurationBase
|
||||
public virtual void RegisterLaunchArgumentHandlers(IArgumentHandlerProducer argumentHandlerProducer) { }
|
||||
public virtual void RegisterMenuButtons(IMenuServiceProducer menuServiceProducer) { }
|
||||
public virtual void RegisterThemes(IThemeProducer themeProducer) { }
|
||||
public virtual void RegisterProviderAssemblies(IFileProviderProducer fileProviderProducer) { }
|
||||
|
||||
public PluginConfigurationBase()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Daybreak.Shared.Services.FileProviders;
|
||||
|
||||
public interface IFileProviderProducer
|
||||
{
|
||||
void RegisterAssembly(Assembly assembly);
|
||||
}
|
||||
@@ -15,6 +15,7 @@ using Daybreak.Services.Events;
|
||||
using Daybreak.Services.ExceptionHandling;
|
||||
using Daybreak.Services.ExecutableManagement;
|
||||
using Daybreak.Services.Experience;
|
||||
using Daybreak.Services.FileProviders;
|
||||
using Daybreak.Services.Graph;
|
||||
using Daybreak.Services.Graph.Models;
|
||||
using Daybreak.Services.Guildwars;
|
||||
@@ -63,6 +64,7 @@ using Daybreak.Shared.Services.Downloads;
|
||||
using Daybreak.Shared.Services.Events;
|
||||
using Daybreak.Shared.Services.ExecutableManagement;
|
||||
using Daybreak.Shared.Services.Experience;
|
||||
using Daybreak.Shared.Services.FileProviders;
|
||||
using Daybreak.Shared.Services.Guildwars;
|
||||
using Daybreak.Shared.Services.Initialization;
|
||||
using Daybreak.Shared.Services.Injection;
|
||||
@@ -97,6 +99,7 @@ using Daybreak.Views.Installation;
|
||||
using Daybreak.Views.Mods;
|
||||
using Daybreak.Views.Trade;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.FluentUI.AspNetCore.Components;
|
||||
using Microsoft.Identity.Client;
|
||||
@@ -118,10 +121,10 @@ public class ProjectConfiguration : PluginConfigurationBase
|
||||
{
|
||||
services.ThrowIfNull();
|
||||
|
||||
// Add FluentUI components
|
||||
services.AddFluentUIComponents();
|
||||
|
||||
services.AddTrailBlazr();
|
||||
services.AddSingleton<IFileProvider, DaybreakFileProvider>();
|
||||
|
||||
RegisterHttpClients(services);
|
||||
services.RegisterClientWebSocket<TradeChatService<KamadanTradeChatOptions>>()
|
||||
.Build();
|
||||
@@ -417,6 +420,11 @@ public class ProjectConfiguration : PluginConfigurationBase
|
||||
}
|
||||
}
|
||||
|
||||
public override void RegisterProviderAssemblies(IFileProviderProducer fileProviderProducer)
|
||||
{
|
||||
fileProviderProducer.RegisterAssembly(typeof(ProjectConfiguration).Assembly);
|
||||
}
|
||||
|
||||
private static IServiceCollection RegisterHttpClients(IServiceCollection services)
|
||||
{
|
||||
return services
|
||||
|
||||
@@ -81,21 +81,16 @@
|
||||
<WikiFiles Include="$(WikiSourcePath)\**\*.*" Exclude="$(WikiSourcePath)\.git\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyWikiToWwwroot" BeforeTargets="BeforeBuild">
|
||||
<Target Name="CopyWikiToWwwroot" BeforeTargets="PrepareForBuild">
|
||||
<Message Importance="high" Text="📦 Daybreak.wiki -> wwwroot/wiki" />
|
||||
<Copy SourceFiles="@(WikiFiles)" DestinationFiles="@(WikiFiles->'wwwroot\wiki\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy wwwroot to output directory for Photino.Blazor -->
|
||||
<!-- Embed wwwroot files as embedded resources -->
|
||||
<ItemGroup>
|
||||
<WwwrootFiles Include="wwwroot\**\*.*" />
|
||||
<EmbeddedResource Include="wwwroot\**\*.*" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyWwwrootToOutput" AfterTargets="Build">
|
||||
<Message Importance="high" Text="📦 wwwroot -> $(DependencyOutput)\wwwroot" />
|
||||
<Copy SourceFiles="@(WwwrootFiles)" DestinationFiles="@(WwwrootFiles->'$(DependencyOutput)\wwwroot\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(Configuration)' == 'Release'">
|
||||
<Exec Command="echo.>$(Version).version" />
|
||||
</Target>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Daybreak.Configuration;
|
||||
using Daybreak.Services.FileProviders;
|
||||
using Daybreak.Services.Initialization;
|
||||
using Daybreak.Shared.Models.Guildwars;
|
||||
using Daybreak.Shared.Models.Menu;
|
||||
@@ -103,6 +104,7 @@ public partial class Launcher
|
||||
RegisterNotificationHandlers(bootstrap, builder, configuration, scopedLogger);
|
||||
RegisterArgumentHandlers(bootstrap, builder, configuration, scopedLogger);
|
||||
RegisterMenuEntries(configuration, menuProducer, scopedLogger);
|
||||
RegisterFileProviders(bootstrap, builder, configuration, scopedLogger);
|
||||
|
||||
scopedLogger.LogInformation("Finished loading configuration for {Configuration.Name}", name);
|
||||
}
|
||||
@@ -234,4 +236,17 @@ public partial class Launcher
|
||||
scopedLogger.LogError(ex, "An error occurred while registering menu entries");
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterFileProviders(IServiceProvider bootstrap, PhotinoBlazorAppBuilder builder, PluginConfigurationBase configuration, ScopedLogger<Launcher> scopedLogger)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fileProviderProducer = new AssemblyFileProviderProducer(builder.Services, bootstrap.GetRequiredService<ILogger<AssemblyFileProviderProducer>>());
|
||||
configuration.RegisterProviderAssemblies(fileProviderProducer);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
scopedLogger.LogError(ex, "An error occurred while registering file providers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Daybreak.Models;
|
||||
|
||||
public sealed record FileProviderAssembly(Assembly Assembly, string Name)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Shared.Services.FileProviders;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Extensions.Core;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Daybreak.Services.FileProviders;
|
||||
|
||||
public sealed class AssemblyFileProviderProducer(
|
||||
IServiceCollection services,
|
||||
ILogger<AssemblyFileProviderProducer> logger) : IFileProviderProducer
|
||||
{
|
||||
private readonly IServiceCollection services = services;
|
||||
private readonly ILogger<AssemblyFileProviderProducer> logger = logger;
|
||||
|
||||
public void RegisterAssembly(Assembly assembly)
|
||||
{
|
||||
var assemblyName = assembly.FullName ?? string.Empty;
|
||||
var scopedLogger = this.logger.CreateScopedLogger();
|
||||
this.services.AddSingleton(new FileProviderAssembly(assembly, assemblyName));
|
||||
scopedLogger.LogDebug("Registered provider assembly {assemblyName}", assemblyName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Daybreak.Models;
|
||||
using Daybreak.Shared.Utils;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Daybreak.Services.FileProviders;
|
||||
|
||||
internal sealed class DaybreakFileProvider
|
||||
: IFileProvider
|
||||
{
|
||||
private static readonly string WwwrootPath = PathUtils.GetAbsolutePathFromRoot("wwwroot");
|
||||
private readonly Dictionary<string, FileProviderAssembly> manifestMapping = [];
|
||||
private readonly IEnumerable<FileProviderAssembly> fileProviderAssemblies;
|
||||
private readonly ILogger<DaybreakFileProvider> logger;
|
||||
|
||||
public DaybreakFileProvider(
|
||||
IEnumerable<FileProviderAssembly> fileProviderAssemblies,
|
||||
ILogger<DaybreakFileProvider> logger)
|
||||
{
|
||||
this.fileProviderAssemblies = fileProviderAssemblies;
|
||||
this.logger = logger;
|
||||
|
||||
foreach(var provider in this.fileProviderAssemblies)
|
||||
{
|
||||
var manifestNames = provider.Assembly.GetManifestResourceNames();
|
||||
foreach(var name in manifestNames)
|
||||
{
|
||||
this.manifestMapping[name] = provider;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IDirectoryContents GetDirectoryContents(string subpath)
|
||||
{
|
||||
var path = Path.Combine(WwwrootPath, subpath);
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
return new Microsoft.Extensions.FileProviders.Physical.PhysicalDirectoryInfo(new DirectoryInfo(path));
|
||||
}
|
||||
|
||||
return NotFoundDirectoryContents.Singleton;
|
||||
}
|
||||
|
||||
public IFileInfo GetFileInfo(string subpath)
|
||||
{
|
||||
var key = subpath.Replace("/", "\\");
|
||||
if (this.manifestMapping.TryGetValue(key, out var provider))
|
||||
{
|
||||
var name = Path.GetFileName(subpath);
|
||||
return new Microsoft.Extensions.FileProviders.Embedded.EmbeddedResourceFileInfo(
|
||||
provider.Assembly,
|
||||
key,
|
||||
name,
|
||||
DateTime.UtcNow);
|
||||
}
|
||||
|
||||
var path = Path.Combine(WwwrootPath, subpath);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
return new Microsoft.Extensions.FileProviders.Physical.PhysicalFileInfo(new FileInfo(path));
|
||||
}
|
||||
|
||||
return new NotFoundFileInfo(subpath);
|
||||
}
|
||||
|
||||
public IChangeToken Watch(string filter)
|
||||
{
|
||||
return NullChangeToken.Singleton;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using Daybreak.Shared.Models.Plugins;
|
||||
using Daybreak.Shared.Services.FileProviders;
|
||||
using Daybreak.Shared.Services.Initialization;
|
||||
using Daybreak.Shared.Services.Notifications;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SimplePlugin.Options;
|
||||
using SimplePlugin.Services;
|
||||
using SimplePlugin.Themes;
|
||||
|
||||
namespace SimplePlugin.Configuration;
|
||||
|
||||
@@ -20,6 +22,7 @@ public sealed class PluginConfiguration : PluginConfigurationBase
|
||||
|
||||
public override void RegisterThemes(IThemeProducer themeProducer)
|
||||
{
|
||||
themeProducer.RegisterTheme(SimpleTheme.Instance);
|
||||
}
|
||||
|
||||
public override void RegisterStartupActions(IStartupActionProducer startupActionProducer)
|
||||
@@ -58,4 +61,9 @@ public sealed class PluginConfiguration : PluginConfigurationBase
|
||||
{
|
||||
modsProducer.RegisterMod<SimpleNotificationMod, SimpleNotificationMod>(true);
|
||||
}
|
||||
|
||||
public override void RegisterProviderAssemblies(IFileProviderProducer fileProviderProducer)
|
||||
{
|
||||
fileProviderProducer.RegisterAssembly(typeof(PluginConfiguration).Assembly);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,4 +10,9 @@
|
||||
<ProjectReference Include="..\..\..\..\Daybreak.Shared\Daybreak.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Embed wwwroot files as embedded resources -->
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="wwwroot\**\*.*" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
using Daybreak.Shared.Models.ColorPalette;
|
||||
using Daybreak.Shared.Models.Themes;
|
||||
|
||||
namespace SimplePlugin.Themes;
|
||||
|
||||
internal class SimpleTheme
|
||||
{
|
||||
public static readonly Theme Instance = new ("Simple", AccentColor.Red, new StaticBackground("img/Simple.png"), Theme.LightDarkMode.Light, string.Empty);
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
Reference in New Issue
Block a user