Skip to content

Commit 546fd87

Browse files
committed
Annotate properties and function params
1 parent 7d83dab commit 546fd87

4 files changed

Lines changed: 142 additions & 8 deletions

File tree

RepSeedResolver/Builders/ClassNetCacheBuilder.cs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@ public static JObject Build(SeedData seed, ScanResult scan)
1616
var fieldsArr = new JArray();
1717
foreach (var f in sc.NetFields)
1818
{
19-
fieldsArr.Add(new JObject
19+
var entry = new JObject
2020
{
2121
["name"] = f["name"]?.ToString() ?? "",
2222
["type"] = f["type"]?.ToString() ?? "property",
2323
["class"] = f["class"]?.ToString() ?? name,
24-
});
24+
};
25+
if (f["params"] is JArray seedParams && seedParams.Count > 0)
26+
entry["params"] = seedParams;
27+
if (f["offset"] is JValue offsetVal)
28+
entry["offset"] = offsetVal;
29+
fieldsArr.Add(entry);
2530
}
2631

2732
classes[name] = new JObject
@@ -56,6 +61,9 @@ public static JObject Build(SeedData seed, ScanResult scan)
5661
["class"] = bpName,
5762
};
5863
if (f.ArrayDim > 1) entry["array_dim"] = f.ArrayDim;
64+
if (f.Params is { Count: > 0 })
65+
entry["params"] = SerializeParams(f.Params);
66+
5967
fieldsArr.Add(entry);
6068
}
6169

@@ -98,6 +106,45 @@ public static JObject Build(SeedData seed, ScanResult scan)
98106
return FindAncestorInSeed(info.Parent, bpClasses, seedMax, visited);
99107
}
100108

109+
private static JArray SerializeParams(List<RepPropInfo> parms)
110+
{
111+
var arr = new JArray();
112+
foreach (var p in parms)
113+
arr.Add(SerializeProp(p));
114+
return arr;
115+
}
116+
117+
private static JObject SerializeProp(RepPropInfo p)
118+
{
119+
var obj = new JObject
120+
{
121+
["name"] = p.Name,
122+
["type"] = p.TypeStr,
123+
};
124+
if (p.EnumName != null) obj["enum"] = p.EnumName;
125+
if (p.Bits.HasValue) obj["max"] = p.Bits.Value;
126+
if (p.EnumValues is { Count: > 0 })
127+
obj["values"] = JObject.FromObject(p.EnumValues);
128+
if (p.StructType != null) obj["struct_type"] = p.StructType;
129+
if (p.StructFields is { Count: > 0 })
130+
{
131+
var fields = new JArray();
132+
foreach (var f in p.StructFields)
133+
fields.Add(SerializeProp(f));
134+
obj["fields"] = fields;
135+
}
136+
if (p.MetaClass != null) obj["meta_class"] = p.MetaClass;
137+
if (p.ObjectClass != null) obj["object_class"] = p.ObjectClass;
138+
if (p.InnerProps is { Count: > 0 })
139+
{
140+
var inner = new JArray();
141+
foreach (var i in p.InnerProps)
142+
inner.Add(SerializeProp(i));
143+
obj["inner"] = inner;
144+
}
145+
return obj;
146+
}
147+
101148
private static int? ResolveNetFieldMax(
102149
string name,
103150
HashSet<string> visited,

RepSeedResolver/Builders/PropertyMapper.cs

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ internal static class PropertyMapper
2828
FStrProperty => new RepPropInfo(name, "string", arrayDim),
2929
FNameProperty => new RepPropInfo(name, "name", arrayDim),
3030
FTextProperty => new RepPropInfo(name, "text", arrayDim),
31-
FClassProperty => new RepPropInfo(name, "class_ref", arrayDim),
31+
FClassProperty cp => MapClassRef(name, cp, arrayDim),
3232
FSoftObjectProperty => new RepPropInfo(name, "soft_obj", arrayDim),
3333
FWeakObjectProperty => new RepPropInfo(name, "weak_obj", arrayDim),
34-
FObjectProperty => new RepPropInfo(name, "object", arrayDim),
34+
FObjectProperty op => MapObject(name, op, arrayDim),
3535
FInterfaceProperty => new RepPropInfo(name, "interface", arrayDim),
3636
FStructProperty sp => MapStruct(name, sp, arrayDim),
3737
FArrayProperty ap => MapArray(name, ap, arrayDim),
@@ -47,6 +47,7 @@ private static RepPropInfo MapByte(string name, FByteProperty bp, int arrayDim)
4747
{
4848
var info = new RepPropInfo(name, "byte", arrayDim) { EnumName = bp.Enum.Name };
4949
info.Bits = EnumHelper.ComputeMax(bp.Enum);
50+
info.EnumValues = EnumHelper.GetValues(bp.Enum);
5051
return info;
5152
}
5253
return new RepPropInfo(name, "byte", arrayDim);
@@ -56,14 +57,57 @@ private static RepPropInfo MapEnum(string name, FEnumProperty ep, int arrayDim)
5657
{
5758
var enumName = !ep.Enum.IsNull ? ep.Enum.Name : null;
5859
var info = new RepPropInfo(name, "byte", arrayDim) { EnumName = enumName };
59-
if (!ep.Enum.IsNull) info.Bits = EnumHelper.ComputeMax(ep.Enum);
60+
if (!ep.Enum.IsNull)
61+
{
62+
info.Bits = EnumHelper.ComputeMax(ep.Enum);
63+
info.EnumValues = EnumHelper.GetValues(ep.Enum);
64+
}
6065
return info;
6166
}
6267

6368
private static RepPropInfo MapStruct(string name, FStructProperty sp, int arrayDim)
6469
{
6570
var sn = !sp.Struct.IsNull ? sp.Struct.Name : "Unknown";
66-
return new RepPropInfo(name, $"struct:{sn}", arrayDim) { StructType = sn };
71+
var info = new RepPropInfo(name, $"struct:{sn}", arrayDim) { StructType = sn };
72+
info.StructFields = ExpandStructFields(sp.Struct);
73+
return info;
74+
}
75+
76+
private static RepPropInfo MapClassRef(string name, FClassProperty cp, int arrayDim)
77+
{
78+
var info = new RepPropInfo(name, "class_ref", arrayDim);
79+
if (cp.MetaClass is { IsNull: false })
80+
info.MetaClass = cp.MetaClass.Name;
81+
return info;
82+
}
83+
84+
private static RepPropInfo MapObject(string name, FObjectProperty op, int arrayDim)
85+
{
86+
var info = new RepPropInfo(name, "object", arrayDim);
87+
if (op.PropertyClass is { IsNull: false })
88+
info.ObjectClass = op.PropertyClass.Name;
89+
return info;
90+
}
91+
92+
private static List<RepPropInfo>? ExpandStructFields(FPackageIndex structRef)
93+
{
94+
try
95+
{
96+
if (structRef.IsNull) return null;
97+
var ueStruct = structRef.Load<UStruct>();
98+
if (ueStruct?.ChildProperties == null || ueStruct.ChildProperties.Length == 0)
99+
return null;
100+
101+
var fields = new List<RepPropInfo>();
102+
foreach (var child in ueStruct.ChildProperties)
103+
{
104+
if (child is not FProperty prop) continue;
105+
var mapped = Map(prop);
106+
if (mapped != null) fields.Add(mapped);
107+
}
108+
return fields.Count > 0 ? fields : null;
109+
}
110+
catch { return null; }
67111
}
68112

69113
private static RepPropInfo MapArray(string name, FArrayProperty ap, int arrayDim)
@@ -93,6 +137,28 @@ private static RepPropInfo MapMap(string name, FMapProperty mp, int arrayDim)
93137

94138
internal static class EnumHelper
95139
{
140+
public static Dictionary<string, long>? GetValues(FPackageIndex enumRef)
141+
{
142+
try
143+
{
144+
var ueEnum = enumRef.Load<UEnum>();
145+
if (ueEnum == null || ueEnum.Names.Length == 0) return null;
146+
147+
var values = new Dictionary<string, long>();
148+
foreach (var (name, value) in ueEnum.Names)
149+
{
150+
var s = name.ToString();
151+
var pos = s.LastIndexOf("::", StringComparison.Ordinal);
152+
if (pos >= 0) s = s[(pos + 2)..];
153+
if (s.Equals("MAX", StringComparison.OrdinalIgnoreCase)
154+
|| s.EndsWith("_MAX", StringComparison.OrdinalIgnoreCase)) continue;
155+
values[s] = value;
156+
}
157+
return values.Count > 0 ? values : null;
158+
}
159+
catch { return null; }
160+
}
161+
96162
public static int? ComputeMax(FPackageIndex enumRef)
97163
{
98164
try

RepSeedResolver/Models/Records.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal sealed record SeedClass(JArray Handles, JArray NetFields);
2020
internal sealed record SeedData(Dictionary<string, SeedClass> Classes);
2121

2222
internal sealed record BpClassInfo(string Parent, List<RepPropInfo> RepProps, List<BpNetField> NetFields);
23-
internal sealed record BpNetField(string Name, string Type, int ArrayDim);
23+
internal sealed record BpNetField(string Name, string Type, int ArrayDim, List<RepPropInfo>? Params = null);
2424

2525
internal sealed record ScanStats(int PackageCount, int BlueprintCount, int ErrorCount, int SkippedCount);
2626
internal sealed record ScanResult(Dictionary<string, BpClassInfo> Classes, ScanStats Stats);
@@ -34,6 +34,10 @@ internal sealed class RepPropInfo
3434
public string? StructType { get; set; }
3535
public int? Bits { get; set; }
3636
public List<RepPropInfo>? InnerProps { get; set; }
37+
public Dictionary<string, long>? EnumValues { get; set; }
38+
public List<RepPropInfo>? StructFields { get; set; }
39+
public string? MetaClass { get; set; }
40+
public string? ObjectClass { get; set; }
3741

3842
public RepPropInfo(string name, string typeStr, int arrayDim)
3943
{

RepSeedResolver/SeedResolver.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,24 @@ private static void ProcessBpClass(
218218
if (funcIdx.TryLoad<UFunction>(out var f)
219219
&& f.FunctionFlags.HasFlag(EFunctionFlags.FUNC_Net))
220220
{
221-
netFields.Add(new BpNetField(funcName.Text, "function", 0));
221+
List<RepPropInfo>? funcParams = null;
222+
if (f.ChildProperties != null)
223+
{
224+
foreach (var child in f.ChildProperties)
225+
{
226+
if (child is not FProperty prop) continue;
227+
if (!prop.PropertyFlags.HasFlag(EPropertyFlags.Parm)) continue;
228+
if (prop.PropertyFlags.HasFlag(EPropertyFlags.ReturnParm)) continue;
229+
230+
var mapped = PropertyMapper.Map(prop);
231+
if (mapped != null)
232+
{
233+
funcParams ??= new List<RepPropInfo>();
234+
funcParams.Add(mapped);
235+
}
236+
}
237+
}
238+
netFields.Add(new BpNetField(funcName.Text, "function", 0, funcParams));
222239
}
223240
}
224241
catch { }

0 commit comments

Comments
 (0)