using System.Reflection.Metadata; using System.Reflection.PortableExecutable; using System.Security.Cryptography; using Newtonsoft.Json; static class PrecompiledAudit { internal static int Run() { var root=Path.GetFullPath(Path.Combine(AppContext.BaseDirectory,"../../../../../..")); if(!Directory.Exists(Path.Combine(root,"Client/Assets"))) throw new InvalidOperationException("Project root required."); var files=new[]{"Client/Assets","Client/Packages","Client/LocalPackages","Client/Library/PackageCache"}.SelectMany(p=>Directory.Exists(Path.Combine(root,p)) ? Directory.EnumerateFiles(Path.Combine(root,p),"*.dll",SearchOption.AllDirectories) : Array.Empty()).OrderBy(p=>p,StringComparer.Ordinal).ToArray(); var rows=new List(); int blocked=0,managed=0,native=0; foreach(var file in files) { string kind="managed"; var references=new List(); var assemblies=new List(); using var stream=File.OpenRead(file); try { using var pe=new PEReader(stream); if(!pe.HasMetadata) { native++; kind="native"; } else { managed++; var reader=pe.GetMetadataReader(); foreach(var h in reader.AssemblyReferences) { var name=reader.GetString(reader.GetAssemblyReference(h).Name); if(name=="HotUpdate") assemblies.Add(name); } foreach(var h in reader.MemberReferences) { var member=reader.GetMemberReference(h); string name=reader.GetString(member.Name); if(name!="BuilderCapacity" || member.Parent.Kind!=HandleKind.TypeReference) continue; var t=reader.GetTypeReference((TypeReferenceHandle)member.Parent); if(reader.GetString(t.Namespace)=="EventPartnerGather" && reader.GetString(t.Name)=="PartnerInfoManager") references.Add("EventPartnerGather.PartnerInfoManager.BuilderCapacity"); } if(references.Count>0) blocked++; } } catch(BadImageFormatException) { kind="unreadable-PE"; blocked++; } rows.Add(new { path=Path.GetRelativePath(root,file).Replace('\\','/'),sha256=Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(file))),kind,fieldReferences=references,hotUpdateReferences=assemblies }); } var report=new { success=blocked==0,scope="Assets-Packages-LocalPackages-PackageCache-dlls",total=files.Length,managed,native,blocked,files=rows }; File.WriteAllText(Path.Combine(root,"CodexOutput/upserver/KVGameLoadTests/checkpoint2-D4-precompiled-audit.json"),JsonConvert.SerializeObject(report,Formatting.Indented)); Console.WriteLine($"PRECOMPILED total={files.Length} managed={managed} native={native} blocked={blocked}"); return blocked==0 ? 0 : 1; } }