2022-01-27 08:27:41 +00:00
|
|
|
|
using Mirror;
|
|
|
|
|
using Mirror.Weaver;
|
|
|
|
|
using Mono.Cecil;
|
2022-02-14 03:45:29 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Diagnostics;
|
2022-01-27 08:27:41 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
namespace MirrorWeaver;
|
|
|
|
|
|
|
|
|
|
public static class QSBReaderWriterProcessor
|
2022-01-27 08:27:41 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// finds usages of the generic read/write methods and generates read/write functions for them.
|
|
|
|
|
/// <para/>
|
|
|
|
|
/// traverses from non generic classes up thru base types
|
|
|
|
|
/// in order to replace generic parameters with their corresponding generic arguments.
|
|
|
|
|
/// </summary>
|
2023-05-16 17:58:37 +00:00
|
|
|
|
public static bool Process(ModuleDefinition module, Writers writers, Readers readers, ref bool weavingFailed)
|
2022-01-27 08:27:41 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
var sw = Stopwatch.StartNew();
|
2022-02-27 12:40:44 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
var NetworkWriter_Write = typeof(NetworkWriter).GetMethod(nameof(NetworkWriter.Write));
|
|
|
|
|
var NetworkReader_Read = typeof(NetworkReader).GetMethod(nameof(NetworkReader.Read));
|
2022-01-27 08:27:41 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
var count = 0;
|
|
|
|
|
foreach (var type in module.GetTypes())
|
|
|
|
|
{
|
|
|
|
|
if (type.HasGenericParameters)
|
2022-02-25 06:04:54 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-02-25 06:04:54 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
TypeReference currentType = type;
|
|
|
|
|
while (currentType != null)
|
|
|
|
|
{
|
|
|
|
|
var currentTypeDef = currentType.Resolve();
|
|
|
|
|
foreach (var method in currentTypeDef.Methods)
|
2022-02-27 12:40:44 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
if (!method.HasBody)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
foreach (var instruction in method.Body.Instructions)
|
2022-01-27 08:27:41 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
if (instruction.Operand is not GenericInstanceMethod calledMethod)
|
2022-02-25 05:09:49 +00:00
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-02-25 05:43:40 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
if (calledMethod.DeclaringType.FullName == NetworkWriter_Write.DeclaringType.FullName &&
|
|
|
|
|
calledMethod.Name == NetworkWriter_Write.Name)
|
2022-01-27 08:27:41 +00:00
|
|
|
|
{
|
2022-03-03 03:46:33 +00:00
|
|
|
|
var argType = calledMethod.GenericArguments[0];
|
2022-01-27 08:27:41 +00:00
|
|
|
|
|
2022-03-04 09:13:22 +00:00
|
|
|
|
if (currentType is GenericInstanceType genericInstanceType &&
|
|
|
|
|
argType is GenericParameter genericParameter &&
|
|
|
|
|
genericParameter.Owner == currentTypeDef)
|
2022-02-25 06:04:54 +00:00
|
|
|
|
{
|
2022-03-04 09:13:22 +00:00
|
|
|
|
argType = genericInstanceType.GenericArguments[genericParameter.Position];
|
2022-01-27 08:27:41 +00:00
|
|
|
|
}
|
2022-02-27 12:40:44 +00:00
|
|
|
|
|
2022-03-03 03:46:33 +00:00
|
|
|
|
writers.GetWriteFunc(argType, ref weavingFailed);
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
else if (calledMethod.DeclaringType.FullName == NetworkReader_Read.DeclaringType.FullName &&
|
|
|
|
|
calledMethod.Name == NetworkReader_Read.Name)
|
|
|
|
|
{
|
|
|
|
|
var argType = calledMethod.GenericArguments[0];
|
2022-02-25 06:04:54 +00:00
|
|
|
|
|
2022-03-04 09:13:22 +00:00
|
|
|
|
if (currentType is GenericInstanceType genericInstanceType &&
|
|
|
|
|
argType is GenericParameter genericParameter &&
|
|
|
|
|
genericParameter.Owner == currentTypeDef)
|
2022-03-03 03:46:33 +00:00
|
|
|
|
{
|
2022-03-04 09:13:22 +00:00
|
|
|
|
argType = genericInstanceType.GenericArguments[genericParameter.Position];
|
2022-02-27 12:40:44 +00:00
|
|
|
|
}
|
2022-03-03 03:46:33 +00:00
|
|
|
|
|
|
|
|
|
readers.GetReadFunc(argType, ref weavingFailed);
|
|
|
|
|
count++;
|
2022-01-27 08:27:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-27 12:40:44 +00:00
|
|
|
|
}
|
2022-02-25 06:04:54 +00:00
|
|
|
|
|
2022-03-04 09:13:22 +00:00
|
|
|
|
currentType = currentTypeDef.BaseType?.ApplyGenericParameters(currentType);
|
2022-03-03 03:46:33 +00:00
|
|
|
|
}
|
2022-02-27 12:40:44 +00:00
|
|
|
|
}
|
2022-03-03 03:46:33 +00:00
|
|
|
|
|
|
|
|
|
Console.WriteLine($"got/generated {count} read/write funcs in {sw.ElapsedMilliseconds} ms");
|
2023-05-16 17:58:37 +00:00
|
|
|
|
return count > 0;
|
2022-01-27 08:27:41 +00:00
|
|
|
|
}
|
2022-02-25 06:04:54 +00:00
|
|
|
|
}
|