Skip to content
This repository was archived by the owner on Jun 29, 2025. It is now read-only.

Commit 3da6080

Browse files
authored
Merge pull request #32 from sepluginloader/dev
v1.10.0
2 parents e7c61c7 + 5af5d2c commit 3da6080

18 files changed

+681
-52
lines changed

PluginLoader/Compiler/RoslynCompiler.cs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,59 @@
66
using System.Collections.Generic;
77
using System.IO;
88
using System.Linq;
9+
using System.Reflection;
10+
using System.Text;
911

1012
namespace avaness.PluginLoader.Compiler
1113
{
1214
public class RoslynCompiler
1315
{
1416
private readonly List<Source> source = new List<Source>();
17+
private bool debugBuild;
18+
19+
public RoslynCompiler(bool debugBuild = false)
20+
{
21+
this.debugBuild = debugBuild;
22+
}
1523

1624
public void Load(Stream s, string name)
1725
{
1826
MemoryStream mem = new MemoryStream();
1927
using (mem)
2028
{
2129
s.CopyTo(mem);
22-
source.Add(new Source(mem, name));
30+
source.Add(new Source(mem, name, debugBuild));
2331
}
2432
}
2533

26-
public byte[] Compile(string assemblyName)
34+
public byte[] Compile(string assemblyName, out byte[] symbols)
2735
{
36+
symbols = null;
37+
2838
CSharpCompilation compilation = CSharpCompilation.Create(
29-
assemblyName,
30-
syntaxTrees: source.Select(x => x.Tree),
31-
references: RoslynReferences.EnumerateAllReferences(),
32-
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release));
39+
assemblyName,
40+
syntaxTrees: source.Select(x => x.Tree),
41+
references: RoslynReferences.EnumerateAllReferences(),
42+
options: new CSharpCompilationOptions(
43+
OutputKind.DynamicallyLinkedLibrary,
44+
optimizationLevel: debugBuild ? OptimizationLevel.Debug : OptimizationLevel.Release));
3345

34-
using (var ms = new MemoryStream())
46+
using (MemoryStream pdb = new MemoryStream())
47+
using (MemoryStream ms = new MemoryStream())
3548
{
3649
// write IL code into memory
37-
EmitResult result = compilation.Emit(ms);
50+
EmitResult result;
51+
if (debugBuild)
52+
{
53+
result = compilation.Emit(ms, pdb,
54+
embeddedTexts: source.Select(x => x.Text),
55+
options: new EmitOptions(debugInformationFormat: DebugInformationFormat.PortablePdb, pdbFilePath: Path.ChangeExtension(assemblyName, "pdb")));
56+
}
57+
else
58+
{
59+
result = compilation.Emit(ms);
60+
}
61+
3862
if (!result.Success)
3963
{
4064
// handle exceptions
@@ -52,24 +76,38 @@ public byte[] Compile(string assemblyName)
5276
}
5377
else
5478
{
55-
// load this 'virtual' DLL so that we can use
79+
if(debugBuild)
80+
{
81+
pdb.Seek(0, SeekOrigin.Begin);
82+
symbols = pdb.ToArray();
83+
}
84+
5685
ms.Seek(0, SeekOrigin.Begin);
5786
return ms.ToArray();
5887
}
5988
}
6089

6190
}
6291

63-
6492
private class Source
6593
{
6694
public string Name { get; }
6795
public SyntaxTree Tree { get; }
96+
public EmbeddedText Text { get; }
6897

69-
public Source(Stream s, string name)
98+
public Source(Stream s, string name, bool includeText)
7099
{
71100
Name = name;
72-
Tree = CSharpSyntaxTree.ParseText(SourceText.From(s), new CSharpParseOptions(LanguageVersion.Latest));
101+
SourceText source = SourceText.From(s, canBeEmbedded: includeText);
102+
if (includeText)
103+
{
104+
Text = EmbeddedText.FromSource(name, source);
105+
Tree = CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Latest), name);
106+
}
107+
else
108+
{
109+
Tree = CSharpSyntaxTree.ParseText(source, new CSharpParseOptions(LanguageVersion.Latest));
110+
}
73111
}
74112
}
75113
}

PluginLoader/Compiler/RoslynReferences.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ public static void GenerateAssemblyList()
1717
{
1818
if (allReferences.Count > 0)
1919
return;
20-
20+
21+
AssemblyName harmonyInfo = typeof(HarmonyLib.Harmony).Assembly.GetName();
22+
2123
Stack<Assembly> loadedAssemblies = new Stack<Assembly>(AppDomain.CurrentDomain.GetAssemblies().Where(IsValidReference));
2224

2325
StringBuilder sb = new StringBuilder();
@@ -32,6 +34,14 @@ public static void GenerateAssemblyList()
3234
{
3335
foreach (Assembly a in loadedAssemblies)
3436
{
37+
// Prevent other Harmony versions from being loaded
38+
AssemblyName name = a.GetName();
39+
if (name.Name == harmonyInfo.Name && name.Version != harmonyInfo.Version)
40+
{
41+
LogFile.WriteLine($"WARNING: Multiple Harmony assemblies are loaded. Plugin Loader is using {harmonyInfo} but found {name}");
42+
continue;
43+
}
44+
3545
AddAssemblyReference(a);
3646
sb.AppendLine(a.FullName);
3747
}
@@ -42,6 +52,13 @@ public static void GenerateAssemblyList()
4252

4353
foreach (AssemblyName name in a.GetReferencedAssemblies())
4454
{
55+
// Prevent other Harmony versions from being loaded
56+
if (name.Name == harmonyInfo.Name && name.Version != harmonyInfo.Version)
57+
{
58+
LogFile.WriteLine($"WARNING: Multiple Harmony assemblies are loaded. Plugin Loader is using {harmonyInfo} but found {name}");
59+
continue;
60+
}
61+
4562
if (!ContainsReference(name) && TryLoadAssembly(name, out Assembly aRef) && IsValidReference(aRef))
4663
{
4764
AddAssemblyReference(aRef);

PluginLoader/Data/GitHubPlugin.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public byte[] CompileFromSource(Action<float> callback = null)
122122
}
123123
callback?.Invoke(1);
124124
}
125-
return compiler.Compile(assemblyName + '_' + Path.GetRandomFileName());
125+
return compiler.Compile(assemblyName + '_' + Path.GetRandomFileName(), out _);
126126
}
127127

128128
private void CompileFromSource(RoslynCompiler compiler, ZipArchiveEntry entry)

0 commit comments

Comments
 (0)