113 lines
4.2 KiB
C#
113 lines
4.2 KiB
C#
using System.Reflection.Metadata;
|
|
using System.Reflection.PortableExecutable;
|
|
|
|
string path = "/home/dazed/.local/share/Steam/steamapps/common/worldbox/worldbox_Data/Managed/Assembly-CSharp.dll";
|
|
using var fs = File.OpenRead(path);
|
|
using var pe = new PEReader(fs);
|
|
var md = pe.GetMetadataReader();
|
|
|
|
string DecodeType(ref BlobReader r) {
|
|
var code = r.ReadSignatureTypeCode();
|
|
switch (code) {
|
|
case SignatureTypeCode.GenericTypeInstance:
|
|
var gen = DecodeType(ref r);
|
|
int arity = r.ReadCompressedInteger();
|
|
var args = new string[arity];
|
|
for (int i=0;i<arity;i++) args[i]=DecodeType(ref r);
|
|
return gen+"<"+string.Join(",", args)+">";
|
|
case SignatureTypeCode.SZArray:
|
|
return DecodeType(ref r)+"[]";
|
|
case SignatureTypeCode.TypeHandle:
|
|
var h = r.ReadTypeHandle();
|
|
return Resolve(h);
|
|
case SignatureTypeCode.Object: return "object";
|
|
case SignatureTypeCode.String: return "string";
|
|
case SignatureTypeCode.Int32: return "int";
|
|
case SignatureTypeCode.Boolean: return "bool";
|
|
case SignatureTypeCode.Void: return "void";
|
|
default:
|
|
return code.ToString();
|
|
}
|
|
}
|
|
string Resolve(EntityHandle h) {
|
|
if (h.Kind==HandleKind.TypeDefinition) {
|
|
var t=md.GetTypeDefinition((TypeDefinitionHandle)h);
|
|
var ns=md.GetString(t.Namespace);
|
|
var n=md.GetString(t.Name);
|
|
return string.IsNullOrEmpty(ns)?n:ns+"."+n;
|
|
}
|
|
if (h.Kind==HandleKind.TypeReference) {
|
|
var t=md.GetTypeReference((TypeReferenceHandle)h);
|
|
var ns=md.GetString(t.Namespace);
|
|
var n=md.GetString(t.Name);
|
|
return string.IsNullOrEmpty(ns)?n:ns+"."+n;
|
|
}
|
|
return h.Kind.ToString();
|
|
}
|
|
|
|
foreach (var typeName in new[]{"Plot","Family","War","Army","Clan"}) {
|
|
foreach (var th in md.TypeDefinitions) {
|
|
var t=md.GetTypeDefinition(th);
|
|
if (md.GetString(t.Name)!=typeName) continue;
|
|
if (t.BaseType.Kind==HandleKind.TypeSpecification) {
|
|
var ts=md.GetTypeSpecification((TypeSpecificationHandle)t.BaseType);
|
|
var br=md.GetBlobReader(ts.Signature);
|
|
Console.WriteLine(typeName+" : "+DecodeType(ref br));
|
|
} else {
|
|
Console.WriteLine(typeName+" : "+Resolve(t.BaseType));
|
|
}
|
|
}
|
|
}
|
|
|
|
// Dump MetaObject members if found by pattern MetaObject*
|
|
Console.WriteLine("\nTypes matching MetaObject*:");
|
|
foreach (var th in md.TypeDefinitions) {
|
|
var t=md.GetTypeDefinition(th);
|
|
var n=md.GetString(t.Name);
|
|
if (n.StartsWith("MetaObject") || n.Contains("MetaObject")) {
|
|
Console.WriteLine(" "+n+" arity?");
|
|
// list unit-related
|
|
foreach (var fh in t.GetFields()) {
|
|
var f=md.GetFieldDefinition(fh);
|
|
var fn=md.GetString(f.Name);
|
|
if (fn.Contains("unit")||fn.Contains("member")||fn.Contains("list")||fn.Contains("hash")||fn.Contains("actor"))
|
|
Console.WriteLine(" field "+fn);
|
|
}
|
|
foreach (var mh in t.GetMethods()) {
|
|
var m=md.GetMethodDefinition(mh);
|
|
var mn=md.GetString(m.Name);
|
|
if (mn.Contains("unit")||mn.Contains("Unit")||mn.Contains("member")||mn.Contains("Member")||mn=="units" || mn.StartsWith("get_units") || mn.StartsWith("get_"))
|
|
if ((m.Attributes & System.Reflection.MethodAttributes.Public)!=0)
|
|
Console.WriteLine(" method "+mn);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Specifically look for getSupporters signature return - decode method sig for Plot.getSupporters
|
|
foreach (var th in md.TypeDefinitions) {
|
|
var t=md.GetTypeDefinition(th);
|
|
if (md.GetString(t.Name)!="Plot") continue;
|
|
foreach (var mh in t.GetMethods()) {
|
|
var m=md.GetMethodDefinition(mh);
|
|
var n=md.GetString(m.Name);
|
|
if (n is "getSupporters" or "getAuthor" or "hasSupporter" or "getMaxSupporters" or "getAsset") {
|
|
var br=md.GetBlobReader(m.Signature);
|
|
// MethodDefSig: callingconv, paramCount, retType, params...
|
|
var hdr=br.ReadSignatureHeader();
|
|
int pc=br.ReadCompressedInteger();
|
|
string ret=DecodeType(ref br);
|
|
Console.WriteLine("Plot."+n+" -> "+ret+" (params="+pc+")");
|
|
}
|
|
}
|
|
// field types for targets
|
|
foreach (var fh in t.GetFields()) {
|
|
var f=md.GetFieldDefinition(fh);
|
|
var n=md.GetString(f.Name);
|
|
if (n.StartsWith("target_") || n=="_plot_author" || n=="_plot_asset") {
|
|
var br=md.GetBlobReader(f.Signature);
|
|
var hdr=br.ReadSignatureHeader(); // Field
|
|
string ty=DecodeType(ref br);
|
|
Console.WriteLine("Plot."+n+" : "+ty);
|
|
}
|
|
}
|
|
}
|