-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RF] AquaMai configuration refactor (#82)
更新了配置文件格式,原有的配置文件将被自动无缝迁移,详情请见新的配置文件中的注释(例外:`SlideJudgeTweak` 不再默认启用) 旧配置文件将被重命名备份,如果更新到此版本遇到 Bug 请联系我们 Updated configuration file schema. The old config file will be migrated automatically and seamlessly. See the comments in the new configuration file for details. (Except for `SlideJudgeTweak` is no longer enabled by default) Your old configuration file will be renamed as a backup. If you encounter any bug with this version, please contact us.
- Loading branch information
Showing
217 changed files
with
6,053 additions
and
3,042 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -372,6 +372,3 @@ MigrationBackup/ | |
|
||
Output | ||
.idea | ||
Libs/Assembly-CSharp.dll | ||
Libs/AMDaemon.NET.dll | ||
packages |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<ProjectGuid>{4C0C68C3-8B2E-4CA8-A26D-AE87CF2A38A5}</ProjectGuid> | ||
<OutputType>Library</OutputType> | ||
<RootNamespace>AquaMai.Build</RootNamespace> | ||
<AssemblyName>AquaMai.Build</AssemblyName> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<FileAlignment>512</FileAlignment> | ||
<Deterministic>true</Deterministic> | ||
<LangVersion>12</LangVersion> | ||
<NoWarn>414;NU1702</NoWarn> | ||
<LibsPath>$(ProjectDir)../Libs/</LibsPath> | ||
<OutputPath>$(ProjectDir)../Output/</OutputPath> | ||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> | ||
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||
<DebugSymbols>false</DebugSymbols> | ||
<DebugType>None</DebugType> | ||
<Optimize>true</Optimize> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
<Prefer32Bit>false</Prefer32Bit> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||
<DefineConstants>DEBUG</DefineConstants> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="../AquaMai.Config.HeadlessLoader/AquaMai.Config.HeadlessLoader.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Reference Include="Mono.Cecil"> | ||
<HintPath>$(LibsPath)Mono.Cecil.dll</HintPath> | ||
</Reference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Build.Framework" Version="17.0.0" /> | ||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
using System; | ||
using System.IO; | ||
using AquaMai.Config.Interfaces; | ||
using AquaMai.Config.HeadlessLoader; | ||
using Microsoft.Build.Framework; | ||
using Microsoft.Build.Utilities; | ||
|
||
public class GenerateExampleConfig : Task | ||
{ | ||
[Required] | ||
public string DllPath { get; set; } | ||
|
||
[Required] | ||
public string OutputPath { get; set; } | ||
|
||
public override bool Execute() | ||
{ | ||
try | ||
{ | ||
var configInterface = HeadlessConfigLoader.LoadFromPacked(DllPath); | ||
var config = configInterface.CreateConfig(); | ||
foreach (var lang in (string[]) ["en", "zh"]) | ||
{ | ||
var configSerializer = configInterface.CreateConfigSerializer(new IConfigSerializer.Options() | ||
{ | ||
Lang = lang, | ||
IncludeBanner = true, | ||
OverrideLocaleValue = true | ||
}); | ||
var example = configSerializer.Serialize(config); | ||
File.WriteAllText(Path.Combine(OutputPath, $"AquaMai.{lang}.toml"), example); | ||
} | ||
|
||
return true; | ||
} | ||
catch (Exception e) | ||
{ | ||
Log.LogErrorFromException(e, true); | ||
return false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System; | ||
using System.IO; | ||
using System.IO.Compression; | ||
using System.Linq; | ||
using Microsoft.Build.Framework; | ||
using Microsoft.Build.Utilities; | ||
using Mono.Cecil; | ||
|
||
public class PostBuildPatch : Task | ||
{ | ||
[Required] | ||
public string DllPath { get; set; } | ||
|
||
public override bool Execute() | ||
{ | ||
try | ||
{ | ||
var assembly = AssemblyDefinition.ReadAssembly(new MemoryStream(File.ReadAllBytes(DllPath))); | ||
CompressEmbeddedAssemblies(assembly); | ||
var outputStream = new MemoryStream(); | ||
assembly.Write(outputStream); | ||
File.WriteAllBytes(DllPath, outputStream.ToArray()); | ||
return true; | ||
} | ||
catch (Exception e) | ||
{ | ||
Log.LogErrorFromException(e, true); | ||
return false; | ||
} | ||
} | ||
|
||
private void CompressEmbeddedAssemblies(AssemblyDefinition assembly) | ||
{ | ||
foreach (var resource in assembly.MainModule.Resources.ToList()) | ||
{ | ||
if (resource.Name.EndsWith(".dll") && resource is EmbeddedResource embeddedResource) | ||
{ | ||
using var compressedStream = new MemoryStream(); | ||
using (var deflateStream = new DeflateStream(compressedStream, CompressionLevel.Optimal)) | ||
{ | ||
embeddedResource.GetResourceStream().CopyTo(deflateStream); | ||
} | ||
var compressedBytes = compressedStream.ToArray(); | ||
|
||
Log.LogMessage($"Compressed {resource.Name} from {embeddedResource.GetResourceStream().Length} to {compressedBytes.Length} bytes"); | ||
|
||
assembly.MainModule.Resources.Remove(resource); | ||
assembly.MainModule.Resources.Add(new EmbeddedResource(resource.Name + ".compressed", resource.Attributes, compressedBytes)); | ||
} | ||
} | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
AquaMai/AquaMai.Config.HeadlessLoader/AquaMai.Config.HeadlessLoader.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<Configuration Condition=" '$(Configuration)' == '' ">Release</Configuration> | ||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||
<ProjectGuid>{6B5E1F3E-D012-4CFB-A2FA-26A6CE06BE66}</ProjectGuid> | ||
<OutputType>Library</OutputType> | ||
<RootNamespace>AquaMai.Config.HeadlessLoader</RootNamespace> | ||
<AssemblyName>AquaMai.Config.HeadlessLoader</AssemblyName> | ||
<TargetFramework>netstandard2.0</TargetFramework> | ||
<FileAlignment>512</FileAlignment> | ||
<Deterministic>true</Deterministic> | ||
<LangVersion>12</LangVersion> | ||
<NoWarn>414;NU1702</NoWarn> | ||
<LibsPath>$(ProjectDir)../Libs/</LibsPath> | ||
<OutputPath>$(ProjectDir)../Output/</OutputPath> | ||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath> | ||
<EnableDefaultEmbeddedResourceItems>false</EnableDefaultEmbeddedResourceItems> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||
<DebugSymbols>false</DebugSymbols> | ||
<DebugType>None</DebugType> | ||
<Optimize>true</Optimize> | ||
<ErrorReport>prompt</ErrorReport> | ||
<WarningLevel>4</WarningLevel> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
<Prefer32Bit>false</Prefer32Bit> | ||
</PropertyGroup> | ||
|
||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||
<DefineConstants>DEBUG</DefineConstants> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="../AquaMai.Config.Interfaces/AquaMai.Config.Interfaces.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Reference Include="Mono.Cecil"> | ||
<HintPath>$(LibsPath)Mono.Cecil.dll</HintPath> | ||
</Reference> | ||
</ItemGroup> | ||
|
||
</Project> |
68 changes: 68 additions & 0 deletions
68
AquaMai/AquaMai.Config.HeadlessLoader/ConfigAssemblyLoader.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Reflection; | ||
using Mono.Cecil; | ||
|
||
namespace AquaMai.Config.HeadlessLoader; | ||
|
||
class ConfigAssemblyLoader | ||
{ | ||
public static Assembly LoadConfigAssembly(AssemblyDefinition assembly) | ||
{ | ||
var references = assembly.MainModule.AssemblyReferences; | ||
foreach (var reference in references) | ||
{ | ||
if (reference.Name == "mscorlib" || reference.Name == "System" || reference.Name.StartsWith("System.")) | ||
{ | ||
reference.Name = "netstandard"; | ||
reference.Version = new Version(2, 0, 0, 0); | ||
reference.PublicKeyToken = null; | ||
} | ||
} | ||
|
||
var targetFrameworkAttribute = assembly.CustomAttributes.FirstOrDefault(attr => attr.AttributeType.Name == "TargetFrameworkAttribute"); | ||
if (targetFrameworkAttribute != null) | ||
{ | ||
targetFrameworkAttribute.ConstructorArguments.Clear(); | ||
targetFrameworkAttribute.ConstructorArguments.Add(new CustomAttributeArgument( | ||
assembly.MainModule.TypeSystem.String, ".NETStandard,Version=v2.0")); | ||
targetFrameworkAttribute.Properties.Clear(); | ||
targetFrameworkAttribute.Properties.Add(new Mono.Cecil.CustomAttributeNamedArgument( | ||
"FrameworkDisplayName", new CustomAttributeArgument(assembly.MainModule.TypeSystem.String, ".NET Standard 2.0"))); | ||
} | ||
|
||
var stream = new MemoryStream(); | ||
assembly.Write(stream); | ||
FixLoadedAssemblyResolution(); | ||
return AppDomain.CurrentDomain.Load(stream.ToArray()); | ||
} | ||
|
||
private static bool FixedLoadedAssemblyResolution = false; | ||
|
||
// XXX: Why, without this, the already loaded assemblies are not resolved? | ||
public static void FixLoadedAssemblyResolution() | ||
{ | ||
if (FixedLoadedAssemblyResolution) | ||
{ | ||
return; | ||
} | ||
FixedLoadedAssemblyResolution = true; | ||
|
||
var loadedAssemblies = new Dictionary<string, Assembly>(); | ||
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) | ||
{ | ||
loadedAssemblies[assembly.FullName] = assembly; | ||
} | ||
|
||
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => | ||
{ | ||
if (loadedAssemblies.TryGetValue(args.Name, out var assembly)) | ||
{ | ||
return assembly; | ||
} | ||
return null; | ||
}; | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
AquaMai/AquaMai.Config.HeadlessLoader/CustomAssemblyResolver.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using Mono.Cecil; | ||
|
||
namespace AquaMai.Config.HeadlessLoader; | ||
|
||
public class CustomAssemblyResolver : DefaultAssemblyResolver | ||
{ | ||
public new void RegisterAssembly(AssemblyDefinition assembly) | ||
{ | ||
base.RegisterAssembly(assembly); | ||
} | ||
} |
59 changes: 59 additions & 0 deletions
59
AquaMai/AquaMai.Config.HeadlessLoader/HeadlessConfigInterface.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
using System; | ||
using System.Reflection; | ||
using AquaMai.Config.Interfaces; | ||
using Mono.Cecil; | ||
|
||
namespace AquaMai.Config.HeadlessLoader; | ||
|
||
public class HeadlessConfigInterface | ||
{ | ||
private readonly Assembly loadedConfigAssembly; | ||
|
||
public IReflectionProvider ReflectionProvider { get; init; } | ||
public IReflectionManager ReflectionManager { get; init; } | ||
|
||
public HeadlessConfigInterface(Assembly loadedConfigAssembly, AssemblyDefinition modsAssembly) | ||
{ | ||
this.loadedConfigAssembly = loadedConfigAssembly; | ||
|
||
ReflectionProvider = Activator.CreateInstance( | ||
loadedConfigAssembly.GetType("AquaMai.Config.Reflection.MonoCecilReflectionProvider"), [modsAssembly]) as IReflectionProvider; | ||
ReflectionManager = Activator.CreateInstance( | ||
loadedConfigAssembly.GetType("AquaMai.Config.Reflection.ReflectionManager"), [ReflectionProvider]) as IReflectionManager; | ||
} | ||
|
||
public IConfigView CreateConfigView(string tomlString = null) | ||
{ | ||
return Activator.CreateInstance( | ||
loadedConfigAssembly.GetType("AquaMai.Config.ConfigView"), | ||
tomlString == null ? [] : [tomlString]) as IConfigView; | ||
} | ||
|
||
public IConfig CreateConfig() | ||
{ | ||
return Activator.CreateInstance( | ||
loadedConfigAssembly.GetType("AquaMai.Config.Config"), [ReflectionManager]) as IConfig; | ||
} | ||
|
||
public IConfigParser GetConfigParser() | ||
{ | ||
return loadedConfigAssembly | ||
.GetType("AquaMai.Config.ConfigParser") | ||
.GetField("Instance", BindingFlags.Public | BindingFlags.Static) | ||
.GetValue(null) as IConfigParser; | ||
} | ||
|
||
public IConfigSerializer CreateConfigSerializer(IConfigSerializer.Options options) | ||
{ | ||
return Activator.CreateInstance( | ||
loadedConfigAssembly.GetType("AquaMai.Config.ConfigSerializer"), [options]) as IConfigSerializer; | ||
} | ||
|
||
public IConfigMigrationManager GetConfigMigrationManager() | ||
{ | ||
return loadedConfigAssembly | ||
.GetType("AquaMai.Config.Migration.ConfigMigrationManager") | ||
.GetField("Instance", BindingFlags.Public | BindingFlags.Static) | ||
.GetValue(null) as IConfigMigrationManager; | ||
} | ||
} |
Oops, something went wrong.