sources editor
All checks were successful
Build / Compute Version (push) Successful in 6s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 2m13s
Build / Build Nuget package (NuGet) (push) Successful in 2m13s
Build / Build Nuget package (CringePlugins) (push) Successful in 2m55s
Build / Build Nuget package (SharedCringe) (push) Successful in 2m35s
Build / Build Launcher (push) Successful in 3m23s

This commit is contained in:
zznty
2024-11-03 18:07:57 +07:00
parent a243d85146
commit f2d75e5408
6 changed files with 237 additions and 67 deletions

View File

@@ -1,10 +1,12 @@
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
using CringeBootstrap.Abstractions; using CringeBootstrap.Abstractions;
using CringeLauncher.Utils; using CringeLauncher.Utils;
using CringePlugins.Loader; using CringePlugins.Loader;
using CringePlugins.Splash; using CringePlugins.Splash;
using HarmonyLib; using HarmonyLib;
using NLog; using NLog;
using ParallelTasks;
using Sandbox; using Sandbox;
using Sandbox.Engine.Networking; using Sandbox.Engine.Networking;
using Sandbox.Engine.Platform.VideoMode; using Sandbox.Engine.Platform.VideoMode;
@@ -26,6 +28,7 @@ using VRage.Steam;
using VRage.UserInterface; using VRage.UserInterface;
using VRageRender; using VRageRender;
using VRageRender.ExternalApp; using VRageRender.ExternalApp;
using Task = System.Threading.Tasks.Task;
namespace CringeLauncher; namespace CringeLauncher;
@@ -40,7 +43,11 @@ public class Launcher : ICorePlugin
public void Initialize(string[] args) public void Initialize(string[] args)
{ {
if (Type.GetType("GameAnalyticsSDK.Net.Logging.GALogger, GameAnalytics.Mono") is { } gaLoggerType)
RuntimeHelpers.RunClassConstructor(gaLoggerType.TypeHandle);
LogManager.Setup() LogManager.Setup()
.LoadConfigurationFromFile()
.SetupExtensions(s => .SetupExtensions(s =>
{ {
s.RegisterLayoutRenderer("cringe-exception", e => s.RegisterLayoutRenderer("cringe-exception", e =>
@@ -53,6 +60,8 @@ public class Launcher : ICorePlugin
LogManager.ReconfigExistingLoggers(); LogManager.ReconfigExistingLoggers();
LogManager.GetLogger("CringeBootstrap").Info("Bootstrapping");
//environment variable for viktor's plugins //environment variable for viktor's plugins
Environment.SetEnvironmentVariable("SE_PLUGIN_DISABLE_METHOD_VERIFICATION", "True"); Environment.SetEnvironmentVariable("SE_PLUGIN_DISABLE_METHOD_VERIFICATION", "True");
@@ -156,8 +165,8 @@ public class Launcher : ICorePlugin
private static void InitThreadPool() private static void InitThreadPool()
{ {
// ParallelTasks.Parallel.Scheduler = new ThreadPoolScheduler(); ParallelTasks.Parallel.Scheduler = new ThreadPoolScheduler();
MySandboxGame.InitMultithreading(); // MySandboxGame.InitMultithreading();
} }
private static void ConfigureSettings() private static void ConfigureSettings()

View File

@@ -8,7 +8,6 @@ using CringeTask = ParallelTasks.Task;
namespace CringeLauncher.Utils; namespace CringeLauncher.Utils;
/*
public class ThreadPoolScheduler : IWorkScheduler public class ThreadPoolScheduler : IWorkScheduler
{ {
public void Schedule(CringeTask item) public void Schedule(CringeTask item)
@@ -83,4 +82,4 @@ internal class ThreadPoolWorkItemTask(CringeTask task) : IThreadPoolWorkItem
HkBaseSystem.QuitThread(); HkBaseSystem.QuitThread();
Debug.WriteLine($"Hk Shutdown for {Thread.CurrentThread.Name}"); Debug.WriteLine($"Hk Shutdown for {Thread.CurrentThread.Name}");
} }
}*/ }

View File

@@ -8,7 +8,7 @@ namespace CringePlugins.Config;
public record PackagesConfig(ImmutableArray<PackageSource> Sources, ImmutableArray<PackageReference> Packages) public record PackagesConfig(ImmutableArray<PackageSource> Sources, ImmutableArray<PackageReference> Packages)
{ {
public static PackagesConfig Default { get; } = new([ public static PackagesConfig Default { get; } = new([
new(@"^SpaceEngineersDedicated\.ReferenceAssemblies$|^ImGui\.NET\.DirectX$|^NuGet$|^Cringe.+$|^SharedCringe$|^Plugin.+$", "https://ng.zznty.ru/v3/index.json"), new("zznty", @"^SpaceEngineersDedicated\.ReferenceAssemblies$|^ImGui\.NET\.DirectX$|^NuGet$|^Cringe.+$|^SharedCringe$|^Plugin.+$", "https://ng.zznty.ru/v3/index.json"),
new(string.Empty, "https://api.nuget.org/v3/index.json") new("nuget.org", string.Empty, "https://api.nuget.org/v3/index.json")
], []); ], []);
} }

View File

@@ -1,15 +1,29 @@
namespace CringePlugins.Splash; using NLog;
namespace CringePlugins.Splash;
public class Splash : ISplashProgress public class Splash : ISplashProgress
{ {
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private readonly List<ILoadingStage> _loadingStages = []; private readonly List<ILoadingStage> _loadingStages = [];
private ProgressInfo? _lastInfo;
public void Report(ProgressInfo value) public void Report(ProgressInfo value)
{ {
_lastInfo = value;
if (value is PercentProgressInfo percentProgressInfo)
Logger.Info("{Text} {Percent:P0}", percentProgressInfo.Text, percentProgressInfo.Percent);
else
Logger.Info("{Text}", value.Text);
} }
public void Report(float value) public void Report(float value)
{ {
if (_lastInfo is not null)
Logger.Info("{Text} {Percent:P0}", _lastInfo.Text, value);
} }
public void DefineStage(ILoadingStage stage) => _loadingStages.Add(stage); public void DefineStage(ILoadingStage stage) => _loadingStages.Add(stage);
@@ -24,6 +38,7 @@ public class Splash : ISplashProgress
{ {
// todo sync context // todo sync context
loadingStage.Load(this).AsTask().GetAwaiter().GetResult(); loadingStage.Load(this).AsTask().GetAwaiter().GetResult();
_lastInfo = null;
} }
} }
} }

View File

@@ -28,28 +28,30 @@ internal class PluginListComponent : IRenderComponent
private bool _changed; private bool _changed;
private bool _open = true; private bool _open = true;
private readonly PackagesConfig _packagesConfig; private PackagesConfig _packagesConfig;
private readonly PackageSourceMapping _sources; private readonly PackageSourceMapping _sourceMapping;
private ImmutableHashSet<PackageSource>? _selectedSources;
private readonly string _configPath; private readonly string _configPath;
private readonly ImmutableArray<PluginInstance> _plugins; private readonly ImmutableArray<PluginInstance> _plugins;
private (SearchResultEntry entry, NuGetClient client)? _selected; private (SearchResultEntry entry, NuGetClient client)? _selected;
private (PackageSource source, int index)? _selectedSource;
public PluginListComponent(PackagesConfig packagesConfig, PackageSourceMapping sources, string configPath, public PluginListComponent(PackagesConfig packagesConfig, PackageSourceMapping sourceMapping, string configPath,
ImmutableArray<PluginInstance> plugins) ImmutableArray<PluginInstance> plugins)
{ {
_packagesConfig = packagesConfig; _packagesConfig = packagesConfig;
_sources = sources; _sourceMapping = sourceMapping;
_configPath = configPath; _configPath = configPath;
_plugins = plugins; _plugins = plugins;
_packages = packagesConfig.Packages.ToImmutableDictionary(b => b.Id, b => b.Range, StringComparer.OrdinalIgnoreCase); _packages = packagesConfig.Packages.ToImmutableDictionary(b => b.Id, b => b.Range,
StringComparer.OrdinalIgnoreCase);
MyGuiSandbox.GuiControlCreated += GuiControlCreated; MyGuiSandbox.GuiControlCreated += GuiControlCreated;
} }
private void GuiControlCreated(object obj) private void GuiControlCreated(object obj)
{ {
if (obj is MyGuiScreenMainMenu && MyGuiScreenGamePlay.Static is null) _open = obj is MyGuiScreenMainMenu && MyGuiScreenGamePlay.Static is null;
_open = true;
} }
public void OnFrame() public void OnFrame()
@@ -58,7 +60,7 @@ internal class PluginListComponent : IRenderComponent
SetNextWindowSize(new(700, 500), ImGuiCond.FirstUseEver); SetNextWindowSize(new(700, 500), ImGuiCond.FirstUseEver);
if (!Begin("Plugin List", ref _open)) if (!Begin("Plugin List"))
{ {
End(); End();
return; return;
@@ -112,10 +114,123 @@ internal class PluginListComponent : IRenderComponent
EndTabItem(); EndTabItem();
} }
if (BeginTabItem("Configure Sources")) if (BeginTabItem("Sources Configuration"))
{ {
//todo BeginChild("Sources List", new(400, 0), ImGuiChildFlags.Border | ImGuiChildFlags.ResizeX);
Text("Todo"); {
if (BeginTable("Sources Table", 2,
ImGuiTableFlags.ScrollY | ImGuiTableFlags.Resizable | ImGuiTableFlags.SizingStretchProp))
{
TableSetupColumn("Name", ImGuiTableColumnFlags.None, .2f);
TableSetupColumn("Url", ImGuiTableColumnFlags.None, .8f);
TableHeadersRow();
for (var index = 0; index < _packagesConfig.Sources.Length; index++)
{
var source = _packagesConfig.Sources[index];
TableNextRow();
TableNextColumn();
if (Selectable(source.Name, index == _selectedSource?.index, ImGuiSelectableFlags.SpanAllColumns))
{
_selectedSource = (source, index);
}
TableNextColumn();
Text(source.Url);
}
EndTable();
}
EndChild();
}
SameLine();
BeginGroup();
BeginChild("Source View", new(0, -GetFrameHeightWithSpacing())); // Leave room for 1 line below us
{
if (_selectedSource is not null)
{
var (selectedSource, index) = _selectedSource.Value;
var name = selectedSource.Name;
if (InputText("Name", ref name, 256))
selectedSource = selectedSource with
{
Name = name
};
var url = selectedSource.Url;
if (InputText("Url", ref url, 1024))
selectedSource = selectedSource with
{
Url = url
};
var pattern = selectedSource.Pattern;
if (InputText("Pattern", ref pattern, 1024))
selectedSource = selectedSource with
{
Pattern = pattern
};
_selectedSource = (selectedSource, index);
if (Button("Save"))
{
var array = _packagesConfig.Sources.RemoveAt(index).Insert(index, selectedSource);
_packagesConfig = _packagesConfig with
{
Sources = array
};
_selectedSource = null;
Save();
}
SameLine();
if (Button("Delete"))
{
var array = _packagesConfig.Sources.RemoveAt(index);
_packagesConfig = _packagesConfig with
{
Sources = array
};
_selectedSource = null;
Save();
}
}
EndChild();
}
if (Button("Add New"))
{
var source = new PackageSource("source name", "", "https://url.to/index.json");
var array = _packagesConfig.Sources.Add(source);
_packagesConfig = _packagesConfig with
{
Sources = array
};
_selectedSource = (source, array.Length - 1);
}
EndGroup();
EndTabItem(); EndTabItem();
} }
@@ -141,6 +256,42 @@ internal class PluginListComponent : IRenderComponent
_searchTask = RefreshAsync(); _searchTask = RefreshAsync();
} }
InputText("##searchbox", ref _searchQuery, 256);
SameLine();
if (Button("Search"))
{
_searchTask = RefreshAsync();
return;
}
SameLine();
if (BeginCombo("##sources",
_selectedSources is null ? "All Sources" :
_selectedSources.Count > 2 ? $"{_selectedSources.First().Name} +{_selectedSources.Count - 1}" :
string.Join(",", _selectedSources.Select(b => b.Name)), ImGuiComboFlags.WidthFitPreview))
{
foreach (var source in _packagesConfig.Sources)
{
var selected = _selectedSources?.Contains(source) ?? true;
if (Selectable(source.Name, ref selected))
{
_selectedSources = selected
? (_selectedSources?.Count ?? 0) + 1 == _packagesConfig.Sources.Length ? null : _selectedSources?.Add(source)
: (_selectedSources ?? _packagesConfig.Sources.ToImmutableHashSet()).Remove(source);
_searchTask = RefreshAsync();
return;
}
}
EndCombo();
}
Spacing();
switch (_searchTask) switch (_searchTask)
{ {
case { IsCompleted: false }: case { IsCompleted: false }:
@@ -162,16 +313,6 @@ internal class PluginListComponent : IRenderComponent
var searchResults = _searchResults ?? ImmutableDictionary<NuGetClient, SearchResult>.Empty; var searchResults = _searchResults ?? ImmutableDictionary<NuGetClient, SearchResult>.Empty;
InputText("##searchbox", ref _searchQuery, 256);
SameLine();
if (Button("Search"))
{
_searchTask = RefreshAsync();
return;
}
if (searchResults.IsEmpty || searchResults.Values.All(b => b.Entries.IsEmpty)) if (searchResults.IsEmpty || searchResults.Values.All(b => b.Entries.IsEmpty))
{ {
TextDisabled("Nothing found"); TextDisabled("Nothing found");
@@ -180,11 +321,12 @@ internal class PluginListComponent : IRenderComponent
BeginChild("List", new(400, 0), ImGuiChildFlags.Border | ImGuiChildFlags.ResizeX); BeginChild("List", new(400, 0), ImGuiChildFlags.Border | ImGuiChildFlags.ResizeX);
{ {
if (BeginTable("AvailableTable", 3, ImGuiTableFlags.ScrollY | ImGuiTableFlags.Resizable | ImGuiTableFlags.SizingStretchProp)) if (BeginTable("AvailableTable", 3,
ImGuiTableFlags.ScrollY | ImGuiTableFlags.Resizable | ImGuiTableFlags.SizingStretchProp))
{ {
TableSetupColumn("Id", ImGuiTableColumnFlags.None, .5f); TableSetupColumn("Id", ImGuiTableColumnFlags.None, .5f);
TableSetupColumn("Version", ImGuiTableColumnFlags.None, .3f); TableSetupColumn("Version", ImGuiTableColumnFlags.None, .25f);
TableSetupColumn("Installed", ImGuiTableColumnFlags.None, .2f); TableSetupColumn("Installed", ImGuiTableColumnFlags.None, .25f);
TableHeadersRow(); TableHeadersRow();
foreach (var (client, result) in searchResults) foreach (var (client, result) in searchResults)
@@ -195,7 +337,8 @@ internal class PluginListComponent : IRenderComponent
TableNextColumn(); TableNextColumn();
var selected = _selected?.entry.Id.Equals(package.Id, StringComparison.OrdinalIgnoreCase) == true; var selected = _selected?.entry.Id.Equals(package.Id, StringComparison.OrdinalIgnoreCase) ==
true;
if (Selectable(package.Title ?? package.Id, ref selected, ImGuiSelectableFlags.SpanAllColumns)) if (Selectable(package.Title ?? package.Id, ref selected, ImGuiSelectableFlags.SpanAllColumns))
{ {
@@ -251,7 +394,7 @@ internal class PluginListComponent : IRenderComponent
Text("Pulled from"); Text("Pulled from");
SameLine(); SameLine();
var url = _selected.Value.client.ToString(); var url = _selected.Value.client.ToString();
TextLinkOpenURL(url, url); TextLinkOpenURL(_packagesConfig.Sources.FirstOrDefault(b => b.Url == url)?.Name ?? url, url);
if (selected.Authors is not null) if (selected.Authors is not null)
{ {
@@ -266,6 +409,7 @@ internal class PluginListComponent : IRenderComponent
SameLine(); SameLine();
TextColored(*GetStyleColorVec4(ImGuiCol.TextLink), selected.TotalDownloads.ToString()); TextColored(*GetStyleColorVec4(ImGuiCol.TextLink), selected.TotalDownloads.ToString());
} }
if (!string.IsNullOrEmpty(selected.ProjectUrl)) if (!string.IsNullOrEmpty(selected.ProjectUrl))
TextLinkOpenURL("Project URL", selected.ProjectUrl); TextLinkOpenURL("Project URL", selected.ProjectUrl);
@@ -302,8 +446,11 @@ internal class PluginListComponent : IRenderComponent
var builder = ImmutableDictionary.CreateBuilder<NuGetClient, SearchResult>(); var builder = ImmutableDictionary.CreateBuilder<NuGetClient, SearchResult>();
await foreach (var source in _sources) await foreach (var source in _sourceMapping)
{ {
if (_selectedSources is not null && _selectedSources.All(b => b.Url != source.ToString()))
continue;
try try
{ {
var result = await source.SearchPackagesAsync(_searchQuery, take: 1000, packageType: "CringePlugin"); var result = await source.SearchPackagesAsync(_searchQuery, take: 1000, packageType: "CringePlugin");

View File

@@ -25,4 +25,4 @@ public class PackageSourceMapping(ImmutableArray<PackageSource> sources)
} }
} }
public record PackageSource([StringSyntax("Regex")] string Pattern, [StringSyntax("Uri")] string Url); public record PackageSource(string Name, [StringSyntax("Regex")] string Pattern, [StringSyntax("Uri")] string Url);