Extension data patch fix (#567)

* Made extension data init only and fixed static references incorrectly

* Made JsonExtensionData not be nullable

---------

Co-authored-by: Alex <clodanSPT@hotmail.com>
This commit is contained in:
clodanSPT
2025-08-21 12:58:31 +01:00
committed by GitHub
parent bd41cf4061
commit 4cc18b61fc
@@ -1,4 +1,4 @@
using Ceciler.Interfaces;
using Ceciler.Interfaces;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
@@ -17,9 +17,7 @@ public class JsonExtensionDataPatch : IPatcher
public void Patch(AssemblyDefinition assembly)
{
_dictionaryStringObjectReference ??= assembly.MainModule.ImportReference(typeof(Dictionary<string, object>));
_dictionaryStringObjectCtorReference ??= assembly.MainModule.ImportReference(
typeof(Dictionary<string, object>).GetConstructor(Type.EmptyTypes)
);
_dictionaryStringObjectCtorReference ??= assembly.MainModule.ImportReference(typeof(Dictionary<string, object>).GetConstructor(Type.EmptyTypes));
if (_jsonExtensionDataAttributeReference is null)
{
@@ -40,46 +38,50 @@ public class JsonExtensionDataPatch : IPatcher
_jsonIgnoreAttributeReference = assembly.MainModule.ImportReference(jsonIgnoreConstructorReference);
}
var isExternalInitType = assembly.MainModule.ImportReference(typeof(System.Runtime.CompilerServices.IsExternalInit));
var isExternalInitType = assembly.MainModule.ImportReference(
typeof(System.Runtime.CompilerServices.IsExternalInit)
);
var compilerGenerated = assembly.MainModule.ImportReference(
assembly.MainModule.ImportReference(
typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute).GetConstructor(Type.EmptyTypes)
)
);
typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute).GetConstructor(Type.EmptyTypes)));
var nullableAttrType = assembly.MainModule.ImportReference(typeof(System.Runtime.CompilerServices.NullableAttribute));
var attrCtor = assembly.MainModule.ImportReference(nullableAttrType.Resolve().Methods.First(m => m.IsConstructor && m.Parameters.Count == 1 && m.Parameters[0].ParameterType.Name == "Byte"));
var attr = new CustomAttribute(attrCtor);
attr.ConstructorArguments.Add(new CustomAttributeArgument(assembly.MainModule.TypeSystem.Byte, (byte)1));
var processed = new HashSet<string>();
foreach (var typeDefinition in assembly.MainModule.Types)
{
if (
!typeDefinition.Namespace.Contains("SPTarkov.Server.Core.Models")
|| typeDefinition.IsInterface
|| typeDefinition.IsEnum
|| IsStaticClass(typeDefinition)
|| processed.Contains(typeDefinition.FullName)
)
if (!typeDefinition.Namespace.Contains("SPTarkov.Server.Core.Models") ||
typeDefinition.IsInterface ||
typeDefinition.IsEnum ||
IsStaticClass(typeDefinition) ||
processed.Contains(typeDefinition.FullName))
{
continue;
}
var propertyDefinition = new PropertyDefinition("ExtensionData", PropertyAttributes.None, _dictionaryStringObjectReference);
propertyDefinition.CustomAttributes.Add(new CustomAttribute(_jsonExtensionDataAttributeReference));
propertyDefinition.CustomAttributes.Add(attr);
// Add backing field
var field = new FieldDefinition(
"<ExtensionData>k__BackingField",
var field = new FieldDefinition("<ExtensionData>k__BackingField",
FieldAttributes.Private | FieldAttributes.InitOnly,
_dictionaryStringObjectReference
);
_dictionaryStringObjectReference);
field.CustomAttributes.Add(new CustomAttribute(compilerGenerated));
field.CustomAttributes.Add(attr);
typeDefinition.Fields.Add(field);
// Add getter
var get = new MethodDefinition(
"get_ExtensionData",
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,
_dictionaryStringObjectReference
);
_dictionaryStringObjectReference);
get.CustomAttributes.Add(new CustomAttribute(compilerGenerated));
get.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0));
get.Body.Instructions.Add(Instruction.Create(OpCodes.Ldfld, field));
@@ -136,7 +138,9 @@ public class JsonExtensionDataPatch : IPatcher
private bool IsStaticClass(TypeDefinition type)
{
return type.IsClass && type.IsAbstract && type.IsSealed;
return type.IsClass &&
type.IsAbstract &&
type.IsSealed;
}
public string Name