CVR Manager 1.0.0

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Exterrata
2026-10-25 02:46:35 -04:00
commit 9bb4f85802
59 changed files with 7913 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Security.Cryptography;
namespace CVRManager.Services;
public record AssemblyDetails(string FileName, string AssemblyName, string Version, string MelonName, string MelonVersion, string MelonAuthor, string MelonLink, string Sha256);
public static class AssemblyReader
{
public static AssemblyDetails Read(string path)
{
var file = Path.GetFileName(path);
var bytes = File.ReadAllBytes(path);
var hash = Convert.ToBase64String(SHA256.HashData(bytes));
string asmName = Path.GetFileNameWithoutExtension(file), version = "", mName = "", mVer = "", mAuthor = "", mLink = "";
try
{
using var pe = new PEReader(new MemoryStream(bytes));
if (pe.HasMetadata)
{
var md = pe.GetMetadataReader();
var def = md.GetAssemblyDefinition();
asmName = md.GetString(def.Name);
version = def.Version.ToString();
foreach (var h in def.GetCustomAttributes())
{
var attr = md.GetCustomAttribute(h);
if (!IsMelonInfo(md, attr.Constructor)) continue;
var strings = attr.DecodeValue(new Provider()).FixedArguments
.Where(a => a.Type is PrimitiveTypeCode.String && a.Value is string).Select(a => (string)a.Value!).ToList();
if (strings.Count > 0) mName = strings[0];
if (strings.Count > 1) mVer = strings[1];
if (strings.Count > 2) mAuthor = strings[2];
if (strings.Count > 3) mLink = strings[3];
break;
}
}
}
catch (Exception e) when (e is BadImageFormatException or InvalidOperationException or ArgumentException) { }
var fv = System.Diagnostics.FileVersionInfo.GetVersionInfo(path).ProductVersion?.Split('+', '-')[0];
return new AssemblyDetails(file, asmName, string.IsNullOrEmpty(fv) ? version : fv, mName, mVer, mAuthor, mLink, hash);
}
static bool IsMelonInfo(MetadataReader md, EntityHandle ctor)
{
if (ctor.Kind != HandleKind.MemberReference) return false;
var member = md.GetMemberReference((MemberReferenceHandle)ctor);
if (member.Parent.Kind != HandleKind.TypeReference) return false;
var type = md.GetTypeReference((TypeReferenceHandle)member.Parent);
return md.GetString(type.Name) == "MelonInfoAttribute";
}
sealed class Provider : ICustomAttributeTypeProvider<object?>
{
const string SystemType = "System.Type";
public object? GetPrimitiveType(PrimitiveTypeCode typeCode) => typeCode;
public object? GetSystemType() => SystemType;
public object? GetSZArrayType(object? elementType) => elementType;
public object? GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind) => new object();
public object? GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
var t = reader.GetTypeReference(handle);
return reader.GetString(t.Name) == "Type" && reader.GetString(t.Namespace) == "System" ? SystemType : new object();
}
public object? GetTypeFromSerializedName(string name) => name;
public PrimitiveTypeCode GetUnderlyingEnumType(object? type) => PrimitiveTypeCode.Int32;
public bool IsSystemType(object? type) => type is string s && s == SystemType;
}
}