#nullable enable using System; using System.Collections.Generic; using System.IO; using System.Linq; using ShrinkSDK.CodeGen; using Unity.CompilationPipeline.Common.Diagnostics; using Unity.CompilationPipeline.Common.ILPostProcessing; namespace ShrinkShared.CodeGen { public static class UnityShrinkCodeGenAdapter { public static ILPostProcessResult Process(ICompiledAssembly compiledAssembly, string diagnosticPrefix) { var diagnostics = new List(); var tempRoot = Path.Combine(Path.GetTempPath(), "ShrinkSDK.CodeGen", Guid.NewGuid().ToString("N")); Directory.CreateDirectory(tempRoot); try { var inputAssembly = Path.Combine(tempRoot, compiledAssembly.Name + ".dll"); var inputPdb = Path.Combine(tempRoot, compiledAssembly.Name + ".pdb"); var outputAssembly = Path.Combine(tempRoot, compiledAssembly.Name + ".woven.dll"); var outputPdb = Path.Combine(tempRoot, compiledAssembly.Name + ".woven.pdb"); File.WriteAllBytes(inputAssembly, compiledAssembly.InMemoryAssembly.PeData); var hasSymbols = compiledAssembly.InMemoryAssembly.PdbData != null && compiledAssembly.InMemoryAssembly.PdbData.Length > 0; if (hasSymbols) File.WriteAllBytes(inputPdb, compiledAssembly.InMemoryAssembly.PdbData); var result = ShrinkAssemblyWeaver.Weave(inputAssembly, hasSymbols ? inputPdb : null, compiledAssembly.References, outputAssembly, hasSymbols ? outputPdb : null, ShrinkCodeGenPlatform.Unity); foreach (var item in result.Diagnostics) { diagnostics.Add(new DiagnosticMessage { DiagnosticType = item.Severity == ShrinkCodeGenDiagnosticSeverity.Error ? DiagnosticType.Error : DiagnosticType.Warning, MessageData = $"[{diagnosticPrefix}] {item.Message}" }); } if (!result.Succeeded || !result.Changed) return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics); var pe = File.ReadAllBytes(outputAssembly); var pdb = hasSymbols && File.Exists(outputPdb) ? File.ReadAllBytes(outputPdb) : compiledAssembly.InMemoryAssembly.PdbData ?? Array.Empty(); return new ILPostProcessResult(new InMemoryAssembly(pe, pdb), diagnostics); } catch (Exception exception) { diagnostics.Add(new DiagnosticMessage { DiagnosticType = DiagnosticType.Error, MessageData = $"[{diagnosticPrefix}] {exception.Message}" }); return new ILPostProcessResult(compiledAssembly.InMemoryAssembly, diagnostics); } finally { try { Directory.Delete(tempRoot, true); } catch { } } } public static bool ReferencesAny(ICompiledAssembly compiledAssembly, params string[] assemblyNames) { return compiledAssembly.References.Any(reference => assemblyNames.Any(name => string.Equals(Path.GetFileNameWithoutExtension(reference), name, StringComparison.Ordinal))); } } }