Files
SPT-Server-Build/Patches/Ceciler.Virtualizer/VirtualizerPatch.cs
T
2025-07-28 19:39:29 +00:00

84 lines
2.4 KiB
C#

using Ceciler.Interfaces;
using Mono.Cecil;
namespace Ceciler.Virtualizer;
public class VirtualizerPatch : IPatcher
{
public void Patch(AssemblyDefinition assembly)
{
foreach (var typeDefinition in assembly.MainModule.Types)
{
foreach (var typeDefinitionMethod in typeDefinition.Methods)
{
if (typeDefinitionMethod == null)
{
continue;
}
if (typeDefinitionMethod.IsConstructor)
{
continue;
}
if (typeDefinitionMethod.IsFinal && typeDefinitionMethod.IsVirtual)
{
typeDefinitionMethod.IsFinal = false;
continue;
}
if (typeDefinitionMethod.IsFinal)
{
continue;
}
if (typeDefinitionMethod.IsVirtual)
{
continue;
}
if (typeDefinitionMethod.IsStatic)
{
continue;
}
if (typeDefinitionMethod.IsPrivate)
{
continue;
}
if (MethodIsSerializationCallback(typeDefinitionMethod))
{
continue;
}
typeDefinitionMethod.IsVirtual = true;
typeDefinitionMethod.IsNewSlot = true;
}
}
#if DEBUG
var writerParams = new WriterParameters() { WriteSymbols = true };
assembly.Write(writerParams);
#else
assembly.Write();
#endif
}
static bool MethodIsSerializationCallback(MethodDefinition method)
{
return ContainsAttribute(method.CustomAttributes, "OnSerializingAttribute")
|| ContainsAttribute(method.CustomAttributes, "OnSerializedAttribute")
|| ContainsAttribute(method.CustomAttributes, "OnDeserializingAttribute")
|| ContainsAttribute(method.CustomAttributes, "OnDeserializedAttribute");
}
public static bool ContainsAttribute(IEnumerable<CustomAttribute> attributes, string attributeName) =>
attributes.Any(attribute => attribute.Constructor.DeclaringType.Name == attributeName);
public string Name
{
get { return "Virtualizer"; }
}
}