Skip to content

Commit

Permalink
Properly generate a working, publicized DLL
Browse files Browse the repository at this point in the history
  • Loading branch information
psyGamer committed Jan 20, 2024
1 parent 3fb41f9 commit c4c9156
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 19 deletions.
6 changes: 3 additions & 3 deletions CelestePublicizer.Testing/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// See https://aka.ms/new-console-template for more information

// using Celeste;
using Celeste;
// using Monocle;

Console.WriteLine("Hello, World!");

// Player p = null;
// Console.WriteLine(p.jumpGraceTimer);
Player p = null;
Console.WriteLine(p.jumpGraceTimer);
10 changes: 5 additions & 5 deletions CelestePublicizer/CelestePublicizer.props
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

<Target Name="Publicize" AfterTargets="ResolveReferences" BeforeTargets="FindReferenceAssembliesForReferences">
<PublicizeTask IntermediateOutputPath="$(IntermediateOutputPath)" PackageReference="@(PackageReference)">
<Output TaskParameter="PublicizedReference" ItemName="_PublicizedReference" />
</PublicizeTask>

<ItemGroup>
<!-- <ReferencePath Remove="@(_RemovedReferences)" />-->
<!-- <ReferencePath Include="@(_PublicizedReferences)" />-->
<ReferencePath Include="@(_PublicizedReference)" />

<!-- <AssemblyAttribute Include="System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute">-->
<!-- <_Parameter1>%(_PublicizedReferences.Filename)</_Parameter1>-->
<!-- </AssemblyAttribute>-->
<AssemblyAttribute Include="System.Runtime.CompilerServices.IgnoresAccessChecksToAttribute">
<_Parameter1>Celeste</_Parameter1>
</AssemblyAttribute>
</ItemGroup>

<PropertyGroup>
Expand Down
42 changes: 31 additions & 11 deletions CelestePublicizer/CelestePublicizerTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,15 @@
namespace CelestePublicizer;

public class PublicizeTask : Task {

[Required]
public string IntermediateOutputPath { get; set; }

[Required]
public ITaskItem[] PackageReference { get; set; }

[Output]
public ITaskItem PublicizedReference { get; private set; }

public override bool Execute() {
const string PackageName = "CelestePublicizer";
Expand All @@ -45,21 +49,41 @@ public override bool Execute() {
}

string outputAssemblyPath = $"{IntermediateOutputPath}Celeste-publicized.dll";
string outputHashPath = $"{IntermediateOutputPath}Celeste-publicized.dll.md5";
string outputHashPath = $"{outputAssemblyPath}.md5";

var taskAssembly = typeof(PublicizeTask).Assembly;

var celesteAssembly = AssemblyDefinition.FromFile(celesteAssemblyPath);
var celesteAssemblyBytes = File.ReadAllBytes(celesteAssemblyPath);
var celesteAssembly = AssemblyDefinition.FromBytes(celesteAssemblyBytes);

var origAssemblyStream = taskAssembly.GetManifestResourceStream($"{PackageName}.Assets.Celeste.exe")!;
var memoryStream = new MemoryStream();
origAssemblyStream.CopyTo(memoryStream);
var origAssembly = AssemblyDefinition.FromBytes(memoryStream.ToArray());
var origAssemblyBytes = memoryStream.ToArray();
var origAssembly = AssemblyDefinition.FromBytes(origAssemblyBytes);

var hash = ComputeHash(celesteAssemblyBytes, origAssemblyBytes);
if (File.Exists(outputHashPath) && File.ReadAllText(outputHashPath) == hash) {
Log.LogMessage($"{celesteAssemblyPath} was already publicized, skipping");
// return true;
}

PublicizeAssembly(celesteAssembly, origAssembly);

var module = celesteAssembly.ManifestModule;
module.FatalWrite(outputAssemblyPath);

PublicizedReference = new TaskItem(outputAssemblyPath);
celestePackage.CopyMetadataTo(PublicizedReference);
celestePackage.RemoveMetadata("ReferenceAssembly");

var originalDocumentationPath = Path.ChangeExtension(celesteAssemblyPath, "xml");
if (File.Exists(originalDocumentationPath)) {
File.Copy(originalDocumentationPath, Path.ChangeExtension(outputAssemblyPath, "xml"), true);
}

File.WriteAllText(outputHashPath, hash);
Log.LogMessage($"Publicized {celesteAssemblyPath}");

return true;
}
Expand Down Expand Up @@ -136,19 +160,17 @@ private static void PublicizeMethod(MethodDefinition methodDefinition, bool igno
}

// Adapted from https://github.com/BepInEx/BepInEx.AssemblyPublicizer/blob/master/BepInEx.AssemblyPublicizer.MSBuild/PublicizeTask.cs#L132-L168
private static string ComputeHash(byte[] bytes, string mask) {
private static string ComputeHash(byte[] bytes, byte[] maskBytes) {
static void Hash(ICryptoTransform hash, byte[] buffer) {
hash.TransformBlock(buffer, 0, buffer.Length, buffer, 0);
}

static void HashString(ICryptoTransform hash, string str) => Hash(hash, Encoding.UTF8.GetBytes(str));
static void HashBool(ICryptoTransform hash, bool value) => Hash(hash, BitConverter.GetBytes(value));
static void HashInt(ICryptoTransform hash, int value) => Hash(hash, BitConverter.GetBytes(value));

using var md5 = MD5.Create();

HashString(md5, typeof(PublicizeTask).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion);
HashString(md5, mask);
HashString(md5, typeof(PublicizeTask).Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()!.InformationalVersion);
Hash(md5, maskBytes);

md5.TransformFinalBlock(bytes, 0, bytes.Length);

Expand All @@ -157,11 +179,9 @@ static void Hash(ICryptoTransform hash, byte[] buffer) {

private static string ByteArrayToString(IReadOnlyCollection<byte> data) {
var builder = new StringBuilder(data.Count * 2);

foreach (var b in data) {
builder.AppendFormat("{0:x2}", b);
builder.Append($"{b:x2}");
}

return builder.ToString();
}
}
Expand Down

0 comments on commit c4c9156

Please sign in to comment.