Mod config migration from plugin hub
All checks were successful
Build / Compute Version (push) Successful in 6s
Build / Build Nuget package (NuGet) (push) Successful in 50s
Build / Build Nuget package (SharedCringe) (push) Successful in 58s
Build / Build Nuget package (CringePlugins) (push) Successful in 1m11s
Build / Build Launcher (push) Successful in 1m42s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 3m5s
All checks were successful
Build / Compute Version (push) Successful in 6s
Build / Build Nuget package (NuGet) (push) Successful in 50s
Build / Build Nuget package (SharedCringe) (push) Successful in 58s
Build / Build Nuget package (CringePlugins) (push) Successful in 1m11s
Build / Build Launcher (push) Successful in 1m42s
Build / Build Nuget package (CringeBootstrap.Abstractions) (push) Successful in 3m5s
Update ui when migrating pluginhub config Added mod loader as a default plugin Temp fix for pbs
This commit is contained in:
@@ -12,7 +12,7 @@ using VRage.Scripting;
|
||||
namespace CringeLauncher.Patches;
|
||||
|
||||
[HarmonyPatch]
|
||||
public static class ModAssemblyLoadContextPatches
|
||||
public static class ModAssemblyLoadContextPatches //todo: use ModScriptCompilerPatch
|
||||
{
|
||||
private static ModAssemblyLoadContext? _currentSessionContext;
|
||||
private static readonly MyConcurrentHashSet<string> AssemblyNames = [];
|
||||
@@ -30,7 +30,7 @@ public static class ModAssemblyLoadContextPatches
|
||||
.InsertAndAdvance(new(OpCodes.Ldarg_0), CodeInstruction.LoadField(original.DeclaringType, "target"))
|
||||
.SetInstruction(CodeInstruction.CallClosure((byte[] assembly, byte[] symbols, MyApiTarget target) =>
|
||||
{
|
||||
if (target is not MyApiTarget.Mod) return Assembly.Load(assembly, symbols);
|
||||
//if (target is not MyApiTarget.Mod) return Assembly.Load(assembly, symbols);
|
||||
ArgumentNullException.ThrowIfNull(_currentSessionContext, "No session context");
|
||||
return _currentSessionContext.LoadFromStream(new MemoryStream(assembly), new MemoryStream(symbols));
|
||||
}))
|
||||
@@ -39,7 +39,7 @@ public static class ModAssemblyLoadContextPatches
|
||||
.InsertAndAdvance(new(OpCodes.Ldarg_0), CodeInstruction.LoadField(original.DeclaringType, "target"))
|
||||
.SetInstruction(CodeInstruction.CallClosure((byte[] assembly, MyApiTarget target) =>
|
||||
{
|
||||
if (target is not MyApiTarget.Mod) return Assembly.Load(assembly);
|
||||
//if (target is not MyApiTarget.Mod) return Assembly.Load(assembly);
|
||||
ArgumentNullException.ThrowIfNull(_currentSessionContext, "No session context");
|
||||
return _currentSessionContext.LoadFromStream(new MemoryStream(assembly));
|
||||
}))
|
||||
|
@@ -9,24 +9,39 @@ namespace CringePlugins.Compatability;
|
||||
[XmlType("PluginConfig")]
|
||||
public class PluginLoaderConfig
|
||||
{
|
||||
[XmlArrayItem("Id")]
|
||||
public string[] Plugins { get; set; } = [];
|
||||
/// <summary>
|
||||
/// Raw plugin and mod ids
|
||||
/// </summary>
|
||||
[XmlArrayItem("Id")] public string[] Plugins { get; set; } = [];
|
||||
|
||||
[XmlArrayItem("Profile")]
|
||||
public PluginLoaderProfile[] Profiles { get; set; } = [];
|
||||
/// <summary>
|
||||
/// Raw profiles
|
||||
/// </summary>
|
||||
[XmlArrayItem("Profile")] public PluginLoaderProfile[] Profiles { get; set; } = [];
|
||||
|
||||
public PackagesConfig Migrate(PackagesConfig old)
|
||||
public PackagesConfig MigratePlugins(PackagesConfig old)
|
||||
{
|
||||
//ensure defaults are installed
|
||||
var defaultConfig = PackagesConfig.Default;
|
||||
var sources = old.Sources.ToBuilder();
|
||||
foreach (var source in defaultConfig.Sources)
|
||||
{
|
||||
if (!sources.Contains(source))
|
||||
sources.Add(source);
|
||||
}
|
||||
|
||||
var pluginsBuilder = ImmutableArray.CreateBuilder<PackageReference>();
|
||||
var defaultVersion = new NuGetVersion(1, 0, 0);
|
||||
foreach (var plugin in Plugins)
|
||||
foreach (var plugin in GetPlugins())
|
||||
{
|
||||
if (!IsValidId(plugin))
|
||||
continue;
|
||||
|
||||
pluginsBuilder.Add(new PackageReference($"Plugin.{plugin.Replace('/', '.')}",
|
||||
new(defaultVersion)));
|
||||
}
|
||||
foreach (var package in defaultConfig.Packages)
|
||||
{
|
||||
if (!pluginsBuilder.Any(x => x.Id == package.Id))
|
||||
pluginsBuilder.Add(package);
|
||||
}
|
||||
|
||||
var profiles = new Dictionary<string, ImmutableArray<PackageReference>>();
|
||||
foreach (var profile in Profiles)
|
||||
@@ -34,24 +49,85 @@ public class PluginLoaderConfig
|
||||
var builder = ImmutableArray.CreateBuilder<PackageReference>();
|
||||
foreach (var plugin in profile.Plugins)
|
||||
{
|
||||
if (!IsValidId(plugin))
|
||||
if (!IsValidPluginId(plugin))
|
||||
continue;
|
||||
|
||||
builder.Add(new PackageReference($"Plugin.{plugin.Replace('/', '.')}",
|
||||
new(defaultVersion)));
|
||||
}
|
||||
|
||||
foreach (var package in defaultConfig.Packages)
|
||||
{
|
||||
if (!builder.Any(x => x.Id == package.Id))
|
||||
builder.Add(package);
|
||||
}
|
||||
|
||||
profiles[profile.Name] = builder.ToImmutable();
|
||||
}
|
||||
|
||||
return old with
|
||||
{
|
||||
Packages = pluginsBuilder.ToImmutableArray(),
|
||||
Profiles = profiles
|
||||
Packages = pluginsBuilder.ToImmutable(),
|
||||
Profiles = profiles,
|
||||
Sources = sources.ToImmutable()
|
||||
};
|
||||
}
|
||||
|
||||
private static bool IsValidId(string pluginId)
|
||||
public HashSet<string> GetPlugins() => GetPlugins(Plugins);
|
||||
public HashSet<ulong> GetMods() => GetMods(Plugins);
|
||||
public Dictionary<string, HashSet<string>> GetPluginProfiles()
|
||||
{
|
||||
var dict = new Dictionary<string, HashSet<string>>(Profiles.Length);
|
||||
|
||||
foreach (var profile in Profiles)
|
||||
{
|
||||
dict[profile.Name] = GetPlugins(profile.Plugins);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
public Dictionary<string, HashSet<ulong>> GetModProfiles()
|
||||
{
|
||||
var dict = new Dictionary<string, HashSet<ulong>>(Profiles.Length);
|
||||
|
||||
foreach (var profile in Profiles)
|
||||
{
|
||||
dict[profile.Name] = GetMods(profile.Plugins);
|
||||
}
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
|
||||
private static HashSet<string> GetPlugins(string[] mixed)
|
||||
{
|
||||
var plugins = new HashSet<string>();
|
||||
foreach (var plugin in mixed)
|
||||
{
|
||||
if (!IsValidPluginId(plugin))
|
||||
continue;
|
||||
|
||||
plugins.Add(plugin);
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
|
||||
private static HashSet<ulong> GetMods(string[] mixed)
|
||||
{
|
||||
var mods = new HashSet<ulong>();
|
||||
foreach (var plugin in mixed)
|
||||
{
|
||||
if (!ulong.TryParse(plugin, out var modId))
|
||||
continue;
|
||||
|
||||
mods.Add(modId);
|
||||
}
|
||||
|
||||
return mods;
|
||||
}
|
||||
|
||||
private static bool IsValidPluginId(string pluginId)
|
||||
{
|
||||
var count = 0;
|
||||
foreach (var c in pluginId)
|
||||
|
@@ -10,5 +10,9 @@ public record PackagesConfig(ImmutableArray<PackageSource> Sources, ImmutableArr
|
||||
public static PackagesConfig Default { get; } = new([
|
||||
new("zznty", @"^SpaceEngineersDedicated\.ReferenceAssemblies$|^ImGui\.NET\.DirectX$|^NuGet$|^Cringe.+$|^SharedCringe$|^Plugin.+$", "https://ng.zznty.ru/v3/index.json"),
|
||||
new("nuget.org", string.Empty, "https://api.nuget.org/v3/index.json")
|
||||
], [], []); //todo: default profile with recommended plugins?
|
||||
],
|
||||
[
|
||||
new PackageReference("Plugin.ClientModLoader", new(new(0,0,0)))
|
||||
],
|
||||
[]); //todo: default profile with recommended plugins?
|
||||
}
|
@@ -33,6 +33,7 @@ internal class PluginListComponent : IRenderComponent
|
||||
private bool _open = true;
|
||||
private PackagesConfig _packagesConfig;
|
||||
private readonly PackageSourceMapping _sourceMapping;
|
||||
private readonly JsonSerializerOptions _serializerOptions = new(JsonSerializerDefaults.Web);
|
||||
private ImmutableHashSet<PackageSource>? _selectedSources;
|
||||
private readonly string _configPath;
|
||||
private readonly string _gameFolder;
|
||||
@@ -255,17 +256,50 @@ internal class PluginListComponent : IRenderComponent
|
||||
if (BeginTabItem("Settings"))
|
||||
{
|
||||
var oldConfigPath = Path.Join(_gameFolder, "Plugins", "config.xml");
|
||||
if (File.Exists(oldConfigPath) && Button("Migrate PluginLoader Config"))
|
||||
if (File.Exists(oldConfigPath))
|
||||
{
|
||||
var configSerializer = new XmlSerializer(typeof(PluginLoaderConfig));
|
||||
using var fs = File.OpenRead(oldConfigPath);
|
||||
|
||||
if (configSerializer.Deserialize(fs) is PluginLoaderConfig oldConfig)
|
||||
if (Button("Migrate PluginLoader Plugins"))
|
||||
{
|
||||
_packagesConfig = oldConfig.Migrate(_packagesConfig);
|
||||
var configSerializer = new XmlSerializer(typeof(PluginLoaderConfig));
|
||||
using var fs = File.OpenRead(oldConfigPath);
|
||||
|
||||
if (configSerializer.Deserialize(fs) is PluginLoaderConfig oldConfig)
|
||||
{
|
||||
_packagesConfig = oldConfig.MigratePlugins(_packagesConfig);
|
||||
|
||||
Save(false);
|
||||
Save(false);
|
||||
|
||||
_packages = _packagesConfig.Packages.ToImmutableDictionary(b => b.Id, b => b.Range, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
var hasModLodaer = _packages.ContainsKey("Plugin.ClientModLoader");
|
||||
|
||||
if (!hasModLodaer)
|
||||
BeginDisabled();
|
||||
|
||||
if (Button("Migrate Pluginloader Mods"))
|
||||
{
|
||||
var configSerializer = new XmlSerializer(typeof(PluginLoaderConfig));
|
||||
using var fs = File.OpenRead(oldConfigPath);
|
||||
|
||||
if (configSerializer.Deserialize(fs) is PluginLoaderConfig plConfig)
|
||||
{
|
||||
var dir = new DirectoryInfo(Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"CringeLauncher"));
|
||||
var file = Path.Join(dir.FullName, "mods.json");
|
||||
|
||||
using var modsFile = File.Create(file);
|
||||
JsonSerializer.Serialize(modsFile, plConfig.GetMods(), _serializerOptions);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasModLodaer)
|
||||
{
|
||||
if (IsItemHovered())
|
||||
SetTooltip("Requires Plugin.ClientModLoader");
|
||||
|
||||
EndDisabled();
|
||||
}
|
||||
}
|
||||
EndTabItem();
|
||||
|
Reference in New Issue
Block a user