mirror of
https://github.com/misternebula/quantum-space-buddies.git
synced 2025-02-06 18:40:47 +00:00
update weaver
This commit is contained in:
parent
2ca7046480
commit
613a2704b7
@ -12,8 +12,18 @@ namespace Mirror.Weaver
|
|||||||
? td.GetElementType().FullName == type.FullName
|
? td.GetElementType().FullName == type.FullName
|
||||||
: td.FullName == type.FullName;
|
: td.FullName == type.FullName;
|
||||||
|
|
||||||
|
// check if 'td' is exactly of type T.
|
||||||
|
// it does not check if any base type is of <T>, only the specific type.
|
||||||
|
// for example:
|
||||||
|
// NetworkConnection Is NetworkConnection: true
|
||||||
|
// NetworkConnectionToClient Is NetworkConnection: false
|
||||||
public static bool Is<T>(this TypeReference td) => Is(td, typeof(T));
|
public static bool Is<T>(this TypeReference td) => Is(td, typeof(T));
|
||||||
|
|
||||||
|
// check if 'tr' is derived from T.
|
||||||
|
// it does not check if 'tr' is exactly T.
|
||||||
|
// for example:
|
||||||
|
// NetworkConnection IsDerivedFrom<NetworkConnection>: false
|
||||||
|
// NetworkConnectionToClient IsDerivedFrom<NetworkConnection>: true
|
||||||
public static bool IsDerivedFrom<T>(this TypeReference tr) => IsDerivedFrom(tr, typeof(T));
|
public static bool IsDerivedFrom<T>(this TypeReference tr) => IsDerivedFrom(tr, typeof(T));
|
||||||
|
|
||||||
public static bool IsDerivedFrom(this TypeReference tr, Type baseClass)
|
public static bool IsDerivedFrom(this TypeReference tr, Type baseClass)
|
||||||
@ -79,7 +89,10 @@ namespace Mirror.Weaver
|
|||||||
public static bool IsNetworkIdentityField(this TypeReference tr) =>
|
public static bool IsNetworkIdentityField(this TypeReference tr) =>
|
||||||
tr.Is<UnityEngine.GameObject>() ||
|
tr.Is<UnityEngine.GameObject>() ||
|
||||||
tr.Is<NetworkIdentity>() ||
|
tr.Is<NetworkIdentity>() ||
|
||||||
tr.IsDerivedFrom<NetworkBehaviour>();
|
// handle both NetworkBehaviour and inheritors.
|
||||||
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2939
|
||||||
|
tr.IsDerivedFrom<NetworkBehaviour>() ||
|
||||||
|
tr.Is<NetworkBehaviour>();
|
||||||
|
|
||||||
public static bool CanBeResolved(this TypeReference parent)
|
public static bool CanBeResolved(this TypeReference parent)
|
||||||
{
|
{
|
||||||
@ -266,7 +279,7 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
// Takes generic arguments from child class and applies them to parent reference, if possible
|
// Takes generic arguments from child class and applies them to parent reference, if possible
|
||||||
// eg makes `Base<T>` in Child<int> : Base<int> have `int` instead of `T`
|
// eg makes `Base<T>` in Child<int> : Base<int> have `int` instead of `T`
|
||||||
// Originally by James-Frowen under MIT
|
// Originally by James-Frowen under MIT
|
||||||
// https://github.com/MirageNet/Mirage/commit/cf91e1d54796866d2cf87f8e919bb5c681977e45
|
// https://github.com/MirageNet/Mirage/commit/cf91e1d54796866d2cf87f8e919bb5c681977e45
|
||||||
public static TypeReference ApplyGenericParameters(this TypeReference parentReference,
|
public static TypeReference ApplyGenericParameters(this TypeReference parentReference,
|
||||||
TypeReference childReference)
|
TypeReference childReference)
|
||||||
@ -306,7 +319,7 @@ namespace Mirror.Weaver
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finds the type reference for a generic parameter with the provided name in the child reference
|
// Finds the type reference for a generic parameter with the provided name in the child reference
|
||||||
// Originally by James-Frowen under MIT
|
// Originally by James-Frowen under MIT
|
||||||
// https://github.com/MirageNet/Mirage/commit/cf91e1d54796866d2cf87f8e919bb5c681977e45
|
// https://github.com/MirageNet/Mirage/commit/cf91e1d54796866d2cf87f8e919bb5c681977e45
|
||||||
static TypeReference FindMatchingGenericArgument(TypeReference childReference, string paramName)
|
static TypeReference FindMatchingGenericArgument(TypeReference childReference, string paramName)
|
||||||
{
|
{
|
||||||
|
@ -10,10 +10,11 @@ namespace Mirror.Weaver
|
|||||||
// generates code like:
|
// generates code like:
|
||||||
public void CmdThrust(float thrusting, int spin)
|
public void CmdThrust(float thrusting, int spin)
|
||||||
{
|
{
|
||||||
NetworkWriter networkWriter = new NetworkWriter();
|
NetworkWriterPooled writer = NetworkWriterPool.Get();
|
||||||
networkWriter.Write(thrusting);
|
writer.Write(thrusting);
|
||||||
networkWriter.WritePackedUInt32((uint)spin);
|
writer.WritePackedUInt32((uint)spin);
|
||||||
base.SendCommandInternal(cmdName, networkWriter, channel);
|
base.SendCommandInternal(cmdName, cmdHash, writer, channel);
|
||||||
|
NetworkWriterPool.Return(writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CallCmdThrust(float thrusting, int spin)
|
public void CallCmdThrust(float thrusting, int spin)
|
||||||
@ -38,7 +39,7 @@ namespace Mirror.Weaver
|
|||||||
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
|
||||||
|
|
||||||
// NetworkWriter writer = new NetworkWriter();
|
// NetworkWriter writer = new NetworkWriter();
|
||||||
NetworkBehaviourProcessor.WriteCreateWriter(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);
|
||||||
|
|
||||||
// write all the arguments that the user passed to the Cmd call
|
// write all the arguments that the user passed to the Cmd call
|
||||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.Command, ref WeavingFailed))
|
if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.Command, ref WeavingFailed))
|
||||||
@ -52,6 +53,11 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(OpCodes.Ldarg_0);
|
worker.Emit(OpCodes.Ldarg_0);
|
||||||
// pass full function name to avoid ClassA.Func <-> ClassB.Func collisions
|
// pass full function name to avoid ClassA.Func <-> ClassB.Func collisions
|
||||||
worker.Emit(OpCodes.Ldstr, md.FullName);
|
worker.Emit(OpCodes.Ldstr, md.FullName);
|
||||||
|
// pass the function hash so we don't have to compute it at runtime
|
||||||
|
// otherwise each GetStableHash call requires O(N) complexity.
|
||||||
|
// noticeable for long function names:
|
||||||
|
// https://github.com/MirrorNetworking/Mirror/issues/3375
|
||||||
|
worker.Emit(OpCodes.Ldc_I4, md.FullName.GetStableHashCode());
|
||||||
// writer
|
// writer
|
||||||
worker.Emit(OpCodes.Ldloc_0);
|
worker.Emit(OpCodes.Ldloc_0);
|
||||||
worker.Emit(OpCodes.Ldc_I4, channel);
|
worker.Emit(OpCodes.Ldc_I4, channel);
|
||||||
@ -59,7 +65,7 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(requiresAuthority ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
|
worker.Emit(requiresAuthority ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
|
||||||
worker.Emit(OpCodes.Call, weaverTypes.sendCommandInternal);
|
worker.Emit(OpCodes.Call, weaverTypes.sendCommandInternal);
|
||||||
|
|
||||||
NetworkBehaviourProcessor.WriteRecycleWriter(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteReturnWriter(worker, weaverTypes);
|
||||||
|
|
||||||
worker.Emit(OpCodes.Ret);
|
worker.Emit(OpCodes.Ret);
|
||||||
return cmd;
|
return cmd;
|
||||||
|
@ -137,21 +137,21 @@ namespace Mirror.Weaver
|
|||||||
public static void WriteSetupLocals(ILProcessor worker, WeaverTypes weaverTypes)
|
public static void WriteSetupLocals(ILProcessor worker, WeaverTypes weaverTypes)
|
||||||
{
|
{
|
||||||
worker.Body.InitLocals = true;
|
worker.Body.InitLocals = true;
|
||||||
worker.Body.Variables.Add(new VariableDefinition(weaverTypes.Import<PooledNetworkWriter>()));
|
worker.Body.Variables.Add(new VariableDefinition(weaverTypes.Import<NetworkWriterPooled>()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteCreateWriter(ILProcessor worker, WeaverTypes weaverTypes)
|
public static void WriteGetWriter(ILProcessor worker, WeaverTypes weaverTypes)
|
||||||
{
|
{
|
||||||
// create writer
|
// create writer
|
||||||
worker.Emit(OpCodes.Call, weaverTypes.GetPooledWriterReference);
|
worker.Emit(OpCodes.Call, weaverTypes.GetWriterReference);
|
||||||
worker.Emit(OpCodes.Stloc_0);
|
worker.Emit(OpCodes.Stloc_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void WriteRecycleWriter(ILProcessor worker, WeaverTypes weaverTypes)
|
public static void WriteReturnWriter(ILProcessor worker, WeaverTypes weaverTypes)
|
||||||
{
|
{
|
||||||
// NetworkWriterPool.Recycle(writer);
|
// NetworkWriterPool.Recycle(writer);
|
||||||
worker.Emit(OpCodes.Ldloc_0);
|
worker.Emit(OpCodes.Ldloc_0);
|
||||||
worker.Emit(OpCodes.Call, weaverTypes.RecycleWriterReference);
|
worker.Emit(OpCodes.Call, weaverTypes.ReturnWriterReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool WriteArguments(ILProcessor worker, Writers writers, Logger Log, MethodDefinition method, RemoteCallType callType, ref bool WeavingFailed)
|
public static bool WriteArguments(ILProcessor worker, Writers writers, Logger Log, MethodDefinition method, RemoteCallType callType, ref bool WeavingFailed)
|
||||||
@ -397,7 +397,7 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
MethodDefinition serialize = new MethodDefinition(SerializeMethodName,
|
MethodDefinition serialize = new MethodDefinition(SerializeMethodName,
|
||||||
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
|
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
|
||||||
weaverTypes.Import<bool>());
|
weaverTypes.Import(typeof(void)));
|
||||||
|
|
||||||
serialize.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, weaverTypes.Import<NetworkWriter>()));
|
serialize.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, weaverTypes.Import<NetworkWriter>()));
|
||||||
serialize.Parameters.Add(new ParameterDefinition("forceAll", ParameterAttributes.None, weaverTypes.Import<bool>()));
|
serialize.Parameters.Add(new ParameterDefinition("forceAll", ParameterAttributes.None, weaverTypes.Import<bool>()));
|
||||||
@ -405,10 +405,7 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
serialize.Body.InitLocals = true;
|
serialize.Body.InitLocals = true;
|
||||||
|
|
||||||
// loc_0, this local variable is to determine if any variable was dirty
|
// base.SerializeSyncVars(writer, forceAll);
|
||||||
VariableDefinition dirtyLocal = new VariableDefinition(weaverTypes.Import<bool>());
|
|
||||||
serialize.Body.Variables.Add(dirtyLocal);
|
|
||||||
|
|
||||||
MethodReference baseSerialize = Resolvers.TryResolveMethodInParents(netBehaviourSubclass.BaseType, assembly, SerializeMethodName);
|
MethodReference baseSerialize = Resolvers.TryResolveMethodInParents(netBehaviourSubclass.BaseType, assembly, SerializeMethodName);
|
||||||
if (baseSerialize != null)
|
if (baseSerialize != null)
|
||||||
{
|
{
|
||||||
@ -419,16 +416,20 @@ namespace Mirror.Weaver
|
|||||||
// forceAll
|
// forceAll
|
||||||
worker.Emit(OpCodes.Ldarg_2);
|
worker.Emit(OpCodes.Ldarg_2);
|
||||||
worker.Emit(OpCodes.Call, baseSerialize);
|
worker.Emit(OpCodes.Call, baseSerialize);
|
||||||
// set dirtyLocal to result of base.OnSerialize()
|
|
||||||
worker.Emit(OpCodes.Stloc_0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates: if (forceAll);
|
// Generates:
|
||||||
|
// if (forceAll)
|
||||||
|
// {
|
||||||
|
// writer.WriteInt(health);
|
||||||
|
// ...
|
||||||
|
// }
|
||||||
Instruction initialStateLabel = worker.Create(OpCodes.Nop);
|
Instruction initialStateLabel = worker.Create(OpCodes.Nop);
|
||||||
// forceAll
|
// forceAll
|
||||||
worker.Emit(OpCodes.Ldarg_2);
|
worker.Emit(OpCodes.Ldarg_2); // load 'forceAll' flag
|
||||||
worker.Emit(OpCodes.Brfalse, initialStateLabel);
|
worker.Emit(OpCodes.Brfalse, initialStateLabel); // start the 'if forceAll' branch
|
||||||
|
|
||||||
|
// generates write.Write(syncVar) for each SyncVar in forceAll case
|
||||||
foreach (FieldDefinition syncVarDef in syncVars)
|
foreach (FieldDefinition syncVarDef in syncVars)
|
||||||
{
|
{
|
||||||
FieldReference syncVar = syncVarDef;
|
FieldReference syncVar = syncVarDef;
|
||||||
@ -442,7 +443,21 @@ namespace Mirror.Weaver
|
|||||||
// this
|
// this
|
||||||
worker.Emit(OpCodes.Ldarg_0);
|
worker.Emit(OpCodes.Ldarg_0);
|
||||||
worker.Emit(OpCodes.Ldfld, syncVar);
|
worker.Emit(OpCodes.Ldfld, syncVar);
|
||||||
MethodReference writeFunc = writers.GetWriteFunc(syncVar.FieldType, ref WeavingFailed);
|
MethodReference writeFunc;
|
||||||
|
// For NBs we always need to use the default NetworkBehaviour write func
|
||||||
|
// since the reader counter part uses that exact layout which is not easy to change
|
||||||
|
// without introducing more edge cases
|
||||||
|
// effectively this disallows custom NB-type writers/readers on SyncVars
|
||||||
|
// see: https://github.com/MirrorNetworking/Mirror/issues/2680
|
||||||
|
if (syncVar.FieldType.IsDerivedFrom<NetworkBehaviour>())
|
||||||
|
{
|
||||||
|
writeFunc = writers.GetWriteFunc(weaverTypes.Import<NetworkBehaviour>(), ref WeavingFailed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeFunc = writers.GetWriteFunc(syncVar.FieldType, ref WeavingFailed);
|
||||||
|
}
|
||||||
|
|
||||||
if (writeFunc != null)
|
if (writeFunc != null)
|
||||||
{
|
{
|
||||||
worker.Emit(OpCodes.Call, writeFunc);
|
worker.Emit(OpCodes.Call, writeFunc);
|
||||||
@ -455,15 +470,14 @@ namespace Mirror.Weaver
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// always return true if forceAll
|
// if (forceAll) then always return at the end of the 'if' case
|
||||||
|
|
||||||
// Generates: return true
|
|
||||||
worker.Emit(OpCodes.Ldc_I4_1);
|
|
||||||
worker.Emit(OpCodes.Ret);
|
worker.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
// Generates: end if (forceAll);
|
// end the 'if' case for "if (forceAll)"
|
||||||
worker.Append(initialStateLabel);
|
worker.Append(initialStateLabel);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// write dirty bits before the data fields
|
// write dirty bits before the data fields
|
||||||
// Generates: writer.WritePackedUInt64 (base.get_syncVarDirtyBits ());
|
// Generates: writer.WritePackedUInt64 (base.get_syncVarDirtyBits ());
|
||||||
// writer
|
// writer
|
||||||
@ -480,7 +494,6 @@ namespace Mirror.Weaver
|
|||||||
int dirtyBit = syncVarAccessLists.GetSyncVarStart(netBehaviourSubclass.BaseType.FullName);
|
int dirtyBit = syncVarAccessLists.GetSyncVarStart(netBehaviourSubclass.BaseType.FullName);
|
||||||
foreach (FieldDefinition syncVarDef in syncVars)
|
foreach (FieldDefinition syncVarDef in syncVars)
|
||||||
{
|
{
|
||||||
|
|
||||||
FieldReference syncVar = syncVarDef;
|
FieldReference syncVar = syncVarDef;
|
||||||
if (netBehaviourSubclass.HasGenericParameters)
|
if (netBehaviourSubclass.HasGenericParameters)
|
||||||
{
|
{
|
||||||
@ -504,7 +517,21 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(OpCodes.Ldarg_0);
|
worker.Emit(OpCodes.Ldarg_0);
|
||||||
worker.Emit(OpCodes.Ldfld, syncVar);
|
worker.Emit(OpCodes.Ldfld, syncVar);
|
||||||
|
|
||||||
MethodReference writeFunc = writers.GetWriteFunc(syncVar.FieldType, ref WeavingFailed);
|
MethodReference writeFunc;
|
||||||
|
// For NBs we always need to use the default NetworkBehaviour write func
|
||||||
|
// since the reader counter part uses that exact layout which is not easy to change
|
||||||
|
// without introducing more edge cases
|
||||||
|
// effectively this disallows custom NB-type writers/readers on SyncVars
|
||||||
|
// see: https://github.com/MirrorNetworking/Mirror/issues/2680
|
||||||
|
if (syncVar.FieldType.IsDerivedFrom<NetworkBehaviour>())
|
||||||
|
{
|
||||||
|
writeFunc = writers.GetWriteFunc(weaverTypes.Import<NetworkBehaviour>(), ref WeavingFailed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writeFunc = writers.GetWriteFunc(syncVar.FieldType, ref WeavingFailed);
|
||||||
|
}
|
||||||
|
|
||||||
if (writeFunc != null)
|
if (writeFunc != null)
|
||||||
{
|
{
|
||||||
worker.Emit(OpCodes.Call, writeFunc);
|
worker.Emit(OpCodes.Call, writeFunc);
|
||||||
@ -516,11 +543,6 @@ namespace Mirror.Weaver
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// something was dirty
|
|
||||||
worker.Emit(OpCodes.Ldc_I4_1);
|
|
||||||
// set dirtyLocal to true
|
|
||||||
worker.Emit(OpCodes.Stloc_0);
|
|
||||||
|
|
||||||
worker.Append(varLabel);
|
worker.Append(varLabel);
|
||||||
dirtyBit += 1;
|
dirtyBit += 1;
|
||||||
}
|
}
|
||||||
@ -529,8 +551,7 @@ namespace Mirror.Weaver
|
|||||||
//worker.Emit(OpCodes.Ldstr, $"Injected Serialize {netBehaviourSubclass.Name}");
|
//worker.Emit(OpCodes.Ldstr, $"Injected Serialize {netBehaviourSubclass.Name}");
|
||||||
//worker.Emit(OpCodes.Call, WeaverTypes.logErrorReference);
|
//worker.Emit(OpCodes.Call, WeaverTypes.logErrorReference);
|
||||||
|
|
||||||
// generate: return dirtyLocal
|
// generate: return
|
||||||
worker.Emit(OpCodes.Ldloc_0);
|
|
||||||
worker.Emit(OpCodes.Ret);
|
worker.Emit(OpCodes.Ret);
|
||||||
netBehaviourSubclass.Methods.Add(serialize);
|
netBehaviourSubclass.Methods.Add(serialize);
|
||||||
}
|
}
|
||||||
@ -589,10 +610,9 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(OpCodes.Ldflda, netIdField);
|
worker.Emit(OpCodes.Ldflda, netIdField);
|
||||||
worker.Emit(OpCodes.Call, weaverTypes.generatedSyncVarDeserialize_NetworkIdentity);
|
worker.Emit(OpCodes.Call, weaverTypes.generatedSyncVarDeserialize_NetworkIdentity);
|
||||||
}
|
}
|
||||||
// TODO this only uses the persistent netId for types DERIVED FROM NB.
|
// handle both NetworkBehaviour and inheritors.
|
||||||
// not if the type is just 'NetworkBehaviour'.
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2939
|
||||||
// this is what original implementation did too. fix it after.
|
else if (syncVar.FieldType.IsDerivedFrom<NetworkBehaviour>() || syncVar.FieldType.Is<NetworkBehaviour>())
|
||||||
else if (syncVar.FieldType.IsDerivedFrom<NetworkBehaviour>())
|
|
||||||
{
|
{
|
||||||
// reader
|
// reader
|
||||||
worker.Emit(OpCodes.Ldarg_1);
|
worker.Emit(OpCodes.Ldarg_1);
|
||||||
|
@ -68,7 +68,7 @@ namespace Mirror.Weaver
|
|||||||
//worker.Emit(OpCodes.Ldstr, $"Call ClientRpc function {md.Name}");
|
//worker.Emit(OpCodes.Ldstr, $"Call ClientRpc function {md.Name}");
|
||||||
//worker.Emit(OpCodes.Call, WeaverTypes.logErrorReference);
|
//worker.Emit(OpCodes.Call, WeaverTypes.logErrorReference);
|
||||||
|
|
||||||
NetworkBehaviourProcessor.WriteCreateWriter(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);
|
||||||
|
|
||||||
// write all the arguments that the user passed to the Rpc call
|
// write all the arguments that the user passed to the Rpc call
|
||||||
if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.ClientRpc, ref WeavingFailed))
|
if (!NetworkBehaviourProcessor.WriteArguments(worker, writers, Log, md, RemoteCallType.ClientRpc, ref WeavingFailed))
|
||||||
@ -82,6 +82,11 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(OpCodes.Ldarg_0);
|
worker.Emit(OpCodes.Ldarg_0);
|
||||||
// pass full function name to avoid ClassA.Func <-> ClassB.Func collisions
|
// pass full function name to avoid ClassA.Func <-> ClassB.Func collisions
|
||||||
worker.Emit(OpCodes.Ldstr, md.FullName);
|
worker.Emit(OpCodes.Ldstr, md.FullName);
|
||||||
|
// pass the function hash so we don't have to compute it at runtime
|
||||||
|
// otherwise each GetStableHash call requires O(N) complexity.
|
||||||
|
// noticeable for long function names:
|
||||||
|
// https://github.com/MirrorNetworking/Mirror/issues/3375
|
||||||
|
worker.Emit(OpCodes.Ldc_I4, md.FullName.GetStableHashCode());
|
||||||
// writer
|
// writer
|
||||||
worker.Emit(OpCodes.Ldloc_0);
|
worker.Emit(OpCodes.Ldloc_0);
|
||||||
worker.Emit(OpCodes.Ldc_I4, channel);
|
worker.Emit(OpCodes.Ldc_I4, channel);
|
||||||
@ -89,7 +94,7 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(includeOwner ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
|
worker.Emit(includeOwner ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
|
||||||
worker.Emit(OpCodes.Callvirt, weaverTypes.sendRpcInternal);
|
worker.Emit(OpCodes.Callvirt, weaverTypes.sendRpcInternal);
|
||||||
|
|
||||||
NetworkBehaviourProcessor.WriteRecycleWriter(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteReturnWriter(worker, weaverTypes);
|
||||||
|
|
||||||
worker.Emit(OpCodes.Ret);
|
worker.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
foreach (FieldDefinition fd in td.Fields)
|
foreach (FieldDefinition fd in td.Fields)
|
||||||
{
|
{
|
||||||
if (fd.FieldType.IsGenericParameter)
|
if (fd.FieldType.IsGenericParameter || fd.ContainsGenericParameter)
|
||||||
{
|
{
|
||||||
// can't call .Resolve on generic ones
|
// can't call .Resolve on generic ones
|
||||||
continue;
|
continue;
|
||||||
|
@ -203,7 +203,9 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(OpCodes.Call, weaverTypes.getSyncVarNetworkIdentityReference);
|
worker.Emit(OpCodes.Call, weaverTypes.getSyncVarNetworkIdentityReference);
|
||||||
worker.Emit(OpCodes.Ret);
|
worker.Emit(OpCodes.Ret);
|
||||||
}
|
}
|
||||||
else if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>())
|
// handle both NetworkBehaviour and inheritors.
|
||||||
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2939
|
||||||
|
else if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>() || fd.FieldType.Is<NetworkBehaviour>())
|
||||||
{
|
{
|
||||||
// return this.GetSyncVarNetworkBehaviour<T>(ref field, uint netId);
|
// return this.GetSyncVarNetworkBehaviour<T>(ref field, uint netId);
|
||||||
// this.
|
// this.
|
||||||
@ -331,10 +333,9 @@ namespace Mirror.Weaver
|
|||||||
worker.Emit(OpCodes.Ldflda, netIdFieldReference);
|
worker.Emit(OpCodes.Ldflda, netIdFieldReference);
|
||||||
worker.Emit(OpCodes.Call, weaverTypes.generatedSyncVarSetter_NetworkIdentity);
|
worker.Emit(OpCodes.Call, weaverTypes.generatedSyncVarSetter_NetworkIdentity);
|
||||||
}
|
}
|
||||||
// TODO this only uses the persistent netId for types DERIVED FROM NB.
|
// handle both NetworkBehaviour and inheritors.
|
||||||
// not if the type is just 'NetworkBehaviour'.
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2939
|
||||||
// this is what original implementation did too. fix it after.
|
else if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>() || fd.FieldType.Is<NetworkBehaviour>())
|
||||||
else if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>())
|
|
||||||
{
|
{
|
||||||
// NetworkIdentity setter needs one more parameter: netId field ref
|
// NetworkIdentity setter needs one more parameter: netId field ref
|
||||||
// (actually its a NetworkBehaviourSyncVar type)
|
// (actually its a NetworkBehaviourSyncVar type)
|
||||||
@ -368,11 +369,13 @@ namespace Mirror.Weaver
|
|||||||
// GameObject/NetworkIdentity SyncVars have a new field for netId
|
// GameObject/NetworkIdentity SyncVars have a new field for netId
|
||||||
FieldDefinition netIdField = null;
|
FieldDefinition netIdField = null;
|
||||||
// NetworkBehaviour has different field type than other NetworkIdentityFields
|
// NetworkBehaviour has different field type than other NetworkIdentityFields
|
||||||
if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>())
|
// handle both NetworkBehaviour and inheritors.
|
||||||
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2939
|
||||||
|
if (fd.FieldType.IsDerivedFrom<NetworkBehaviour>() || fd.FieldType.Is<NetworkBehaviour>())
|
||||||
{
|
{
|
||||||
netIdField = new FieldDefinition($"___{fd.Name}NetId",
|
netIdField = new FieldDefinition($"___{fd.Name}NetId",
|
||||||
FieldAttributes.Family, // needs to be protected for generic classes, otherwise access isn't allowed
|
FieldAttributes.Family, // needs to be protected for generic classes, otherwise access isn't allowed
|
||||||
weaverTypes.Import<NetworkBehaviour.NetworkBehaviourSyncVar>());
|
weaverTypes.Import<NetworkBehaviourSyncVar>());
|
||||||
netIdField.DeclaringType = td;
|
netIdField.DeclaringType = td;
|
||||||
|
|
||||||
syncVarNetIds[fd] = netIdField;
|
syncVarNetIds[fd] = netIdField;
|
||||||
@ -475,7 +478,11 @@ namespace Mirror.Weaver
|
|||||||
{
|
{
|
||||||
td.Fields.Add(fd);
|
td.Fields.Add(fd);
|
||||||
}
|
}
|
||||||
syncVarAccessLists.SetNumSyncVars(td.FullName, syncVars.Count);
|
|
||||||
|
// include parent class syncvars
|
||||||
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/3457
|
||||||
|
int parentSyncVarCount = syncVarAccessLists.GetSyncVarStart(td.BaseType.FullName);
|
||||||
|
syncVarAccessLists.SetNumSyncVars(td.FullName, parentSyncVarCount + syncVars.Count);
|
||||||
|
|
||||||
return (syncVars, syncVarNetIds);
|
return (syncVars, syncVarNetIds);
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,16 @@ namespace Mirror.Weaver
|
|||||||
// helper functions to check if the method has a NetworkConnection parameter
|
// helper functions to check if the method has a NetworkConnection parameter
|
||||||
public static bool HasNetworkConnectionParameter(MethodDefinition md)
|
public static bool HasNetworkConnectionParameter(MethodDefinition md)
|
||||||
{
|
{
|
||||||
return md.Parameters.Count > 0 &&
|
if (md.Parameters.Count > 0)
|
||||||
md.Parameters[0].ParameterType.Is<NetworkConnection>();
|
{
|
||||||
|
// we need to allow both NetworkConnection, and inheriting types.
|
||||||
|
// NetworkBehaviour.SendTargetRpc takes a NetworkConnection parameter.
|
||||||
|
// fixes https://github.com/vis2k/Mirror/issues/3290
|
||||||
|
TypeReference type = md.Parameters[0].ParameterType;
|
||||||
|
return type.Is<NetworkConnection>() ||
|
||||||
|
type.IsDerivedFrom<NetworkConnection>();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MethodDefinition ProcessTargetRpcInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
|
public static MethodDefinition ProcessTargetRpcInvoke(WeaverTypes weaverTypes, Readers readers, Logger Log, TypeDefinition td, MethodDefinition md, MethodDefinition rpcCallFunc, ref bool WeavingFailed)
|
||||||
@ -34,16 +42,25 @@ namespace Mirror.Weaver
|
|||||||
// NetworkConnection parameter is optional
|
// NetworkConnection parameter is optional
|
||||||
if (HasNetworkConnectionParameter(md))
|
if (HasNetworkConnectionParameter(md))
|
||||||
{
|
{
|
||||||
// on server, the NetworkConnection parameter is a connection to client.
|
// TargetRpcs are sent from server to client.
|
||||||
// when the rpc is invoked on the client, it still has the same
|
// on server, we currently support two types:
|
||||||
// function signature. we pass in the connection to server,
|
// TargetRpc(NetworkConnection)
|
||||||
// which is cleaner than just passing null)
|
// TargetRpc(NetworkConnectionToClient)
|
||||||
//NetworkClient.readyconnection
|
// however, it's always a connection to client.
|
||||||
|
// in the future, only NetworkConnectionToClient will be supported.
|
||||||
|
// explicit typing helps catch issues at compile time.
|
||||||
//
|
//
|
||||||
// TODO
|
// on client, InvokeTargetRpc calls the original code.
|
||||||
// a) .connectionToServer = best solution. no doubt.
|
// we need to fill in the NetworkConnection parameter.
|
||||||
// b) NetworkClient.connection for now. add TODO to not use static later.
|
// NetworkClient.connection is always a connection to server.
|
||||||
worker.Emit(OpCodes.Call, weaverTypes.NetworkClientConnectionReference);
|
//
|
||||||
|
// we used to pass NetworkClient.connection as the TargetRpc parameter.
|
||||||
|
// which caused: https://github.com/MirrorNetworking/Mirror/issues/3455
|
||||||
|
// when the parameter is defined as a NetworkConnectionToClient.
|
||||||
|
//
|
||||||
|
// a client's connection never fits into a NetworkConnectionToClient.
|
||||||
|
// we need to always pass null here.
|
||||||
|
worker.Emit(OpCodes.Ldnull);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process reader parameters and skip first one if first one is NetworkConnection
|
// process reader parameters and skip first one if first one is NetworkConnection
|
||||||
@ -100,7 +117,7 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteSetupLocals(worker, weaverTypes);
|
||||||
|
|
||||||
NetworkBehaviourProcessor.WriteCreateWriter(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteGetWriter(worker, weaverTypes);
|
||||||
|
|
||||||
// write all the arguments that the user passed to the TargetRpc call
|
// write all the arguments that the user passed to the TargetRpc call
|
||||||
// (skip first one if first one is NetworkConnection)
|
// (skip first one if first one is NetworkConnection)
|
||||||
@ -122,12 +139,17 @@ namespace Mirror.Weaver
|
|||||||
}
|
}
|
||||||
// pass full function name to avoid ClassA.Func <-> ClassB.Func collisions
|
// pass full function name to avoid ClassA.Func <-> ClassB.Func collisions
|
||||||
worker.Emit(OpCodes.Ldstr, md.FullName);
|
worker.Emit(OpCodes.Ldstr, md.FullName);
|
||||||
|
// pass the function hash so we don't have to compute it at runtime
|
||||||
|
// otherwise each GetStableHash call requires O(N) complexity.
|
||||||
|
// noticeable for long function names:
|
||||||
|
// https://github.com/MirrorNetworking/Mirror/issues/3375
|
||||||
|
worker.Emit(OpCodes.Ldc_I4, md.FullName.GetStableHashCode());
|
||||||
// writer
|
// writer
|
||||||
worker.Emit(OpCodes.Ldloc_0);
|
worker.Emit(OpCodes.Ldloc_0);
|
||||||
worker.Emit(OpCodes.Ldc_I4, targetRpcAttr.GetField("channel", 0));
|
worker.Emit(OpCodes.Ldc_I4, targetRpcAttr.GetField("channel", 0));
|
||||||
worker.Emit(OpCodes.Callvirt, weaverTypes.sendTargetRpcInternal);
|
worker.Emit(OpCodes.Callvirt, weaverTypes.sendTargetRpcInternal);
|
||||||
|
|
||||||
NetworkBehaviourProcessor.WriteRecycleWriter(worker, weaverTypes);
|
NetworkBehaviourProcessor.WriteReturnWriter(worker, weaverTypes);
|
||||||
|
|
||||||
worker.Emit(OpCodes.Ret);
|
worker.Emit(OpCodes.Ret);
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ namespace Mirror.Weaver
|
|||||||
AssemblyDefinition assembly;
|
AssemblyDefinition assembly;
|
||||||
WeaverTypes weaverTypes;
|
WeaverTypes weaverTypes;
|
||||||
TypeDefinition GeneratedCodeClass;
|
TypeDefinition GeneratedCodeClass;
|
||||||
|
// CHANGED
|
||||||
internal Logger Log;
|
internal Logger Log;
|
||||||
|
|
||||||
Dictionary<TypeReference, MethodReference> readFuncs =
|
Dictionary<TypeReference, MethodReference> readFuncs =
|
||||||
@ -114,7 +115,9 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
return GenerateReadCollection(variableReference, elementType, nameof(NetworkReaderExtensions.ReadList), ref WeavingFailed);
|
return GenerateReadCollection(variableReference, elementType, nameof(NetworkReaderExtensions.ReadList), ref WeavingFailed);
|
||||||
}
|
}
|
||||||
else if (variableReference.IsDerivedFrom<NetworkBehaviour>())
|
// handle both NetworkBehaviour and inheritors.
|
||||||
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2939
|
||||||
|
else if (variableReference.IsDerivedFrom<NetworkBehaviour>() || variableReference.Is<NetworkBehaviour>())
|
||||||
{
|
{
|
||||||
return GetNetworkBehaviourReader(variableReference);
|
return GetNetworkBehaviourReader(variableReference);
|
||||||
}
|
}
|
||||||
@ -138,6 +141,7 @@ namespace Mirror.Weaver
|
|||||||
WeavingFailed = true;
|
WeavingFailed = true;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
// CHANGED
|
||||||
/*
|
/*
|
||||||
if (variableDefinition.HasGenericParameters)
|
if (variableDefinition.HasGenericParameters)
|
||||||
{
|
{
|
||||||
@ -270,6 +274,7 @@ namespace Mirror.Weaver
|
|||||||
GenerateNullCheck(worker, ref WeavingFailed);
|
GenerateNullCheck(worker, ref WeavingFailed);
|
||||||
|
|
||||||
CreateNew(variable, worker, td, ref WeavingFailed);
|
CreateNew(variable, worker, td, ref WeavingFailed);
|
||||||
|
// CHANGED
|
||||||
this.ReadAllFieldsGeneric(variable, worker, ref WeavingFailed);
|
this.ReadAllFieldsGeneric(variable, worker, ref WeavingFailed);
|
||||||
|
|
||||||
worker.Emit(OpCodes.Ldloc_0);
|
worker.Emit(OpCodes.Ldloc_0);
|
||||||
|
@ -25,6 +25,12 @@ namespace Mirror.Weaver
|
|||||||
AssemblyDefinition CurrentAssembly;
|
AssemblyDefinition CurrentAssembly;
|
||||||
Writers writers;
|
Writers writers;
|
||||||
Readers readers;
|
Readers readers;
|
||||||
|
|
||||||
|
// in case of weaver errors, we don't stop immediately.
|
||||||
|
// we log all errors and then eventually return false if
|
||||||
|
// weaving has failed.
|
||||||
|
// this way the user can fix multiple errors at once, instead of having
|
||||||
|
// to fix -> recompile -> fix -> recompile for one error at a time.
|
||||||
bool WeavingFailed;
|
bool WeavingFailed;
|
||||||
|
|
||||||
// logger functions can be set from the outside.
|
// logger functions can be set from the outside.
|
||||||
@ -200,6 +206,7 @@ namespace Mirror.Weaver
|
|||||||
ModuleDefinition moduleDefinition = CurrentAssembly.MainModule;
|
ModuleDefinition moduleDefinition = CurrentAssembly.MainModule;
|
||||||
Console.WriteLine($"Script Module: {moduleDefinition.Name}");
|
Console.WriteLine($"Script Module: {moduleDefinition.Name}");
|
||||||
|
|
||||||
|
// CHANGED
|
||||||
QSBReaderWriterProcessor.Process(moduleDefinition, writers, readers, ref WeavingFailed);
|
QSBReaderWriterProcessor.Process(moduleDefinition, writers, readers, ref WeavingFailed);
|
||||||
|
|
||||||
modified |= WeaveModule(moduleDefinition);
|
modified |= WeaveModule(moduleDefinition);
|
||||||
|
@ -11,8 +11,8 @@ namespace Mirror.Weaver
|
|||||||
public MethodReference ScriptableObjectCreateInstanceMethod;
|
public MethodReference ScriptableObjectCreateInstanceMethod;
|
||||||
|
|
||||||
public MethodReference NetworkBehaviourDirtyBitsReference;
|
public MethodReference NetworkBehaviourDirtyBitsReference;
|
||||||
public MethodReference GetPooledWriterReference;
|
public MethodReference GetWriterReference;
|
||||||
public MethodReference RecycleWriterReference;
|
public MethodReference ReturnWriterReference;
|
||||||
|
|
||||||
public MethodReference NetworkClientConnectionReference;
|
public MethodReference NetworkClientConnectionReference;
|
||||||
|
|
||||||
@ -77,28 +77,14 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
TypeReference NetworkServerType = Import(typeof(NetworkServer));
|
TypeReference NetworkServerType = Import(typeof(NetworkServer));
|
||||||
NetworkServerGetActive = Resolvers.ResolveMethod(NetworkServerType, assembly, Log, "get_active", ref WeavingFailed);
|
NetworkServerGetActive = Resolvers.ResolveMethod(NetworkServerType, assembly, Log, "get_active", ref WeavingFailed);
|
||||||
|
|
||||||
TypeReference NetworkClientType = Import(typeof(NetworkClient));
|
TypeReference NetworkClientType = Import(typeof(NetworkClient));
|
||||||
NetworkClientGetActive = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_active", ref WeavingFailed);
|
NetworkClientGetActive = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_active", ref WeavingFailed);
|
||||||
|
NetworkClientConnectionReference = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_connection", ref WeavingFailed);
|
||||||
TypeReference RemoteCallDelegateType = Import<RemoteCalls.RemoteCallDelegate>();
|
|
||||||
RemoteCallDelegateConstructor = Resolvers.ResolveMethod(RemoteCallDelegateType, assembly, Log, ".ctor", ref WeavingFailed);
|
|
||||||
|
|
||||||
TypeReference NetworkBehaviourType = Import<NetworkBehaviour>();
|
TypeReference NetworkBehaviourType = Import<NetworkBehaviour>();
|
||||||
TypeReference RemoteProcedureCallsType = Import(typeof(RemoteCalls.RemoteProcedureCalls));
|
|
||||||
|
|
||||||
TypeReference ScriptableObjectType = Import<ScriptableObject>();
|
|
||||||
|
|
||||||
ScriptableObjectCreateInstanceMethod = Resolvers.ResolveMethod(
|
|
||||||
ScriptableObjectType, assembly, Log,
|
|
||||||
md => md.Name == "CreateInstance" && md.HasGenericParameters,
|
|
||||||
ref WeavingFailed);
|
|
||||||
|
|
||||||
NetworkBehaviourDirtyBitsReference = Resolvers.ResolveProperty(NetworkBehaviourType, assembly, "syncVarDirtyBits");
|
NetworkBehaviourDirtyBitsReference = Resolvers.ResolveProperty(NetworkBehaviourType, assembly, "syncVarDirtyBits");
|
||||||
TypeReference NetworkWriterPoolType = Import(typeof(NetworkWriterPool));
|
|
||||||
GetPooledWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "GetWriter", ref WeavingFailed);
|
|
||||||
RecycleWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "Recycle", ref WeavingFailed);
|
|
||||||
|
|
||||||
NetworkClientConnectionReference = Resolvers.ResolveMethod(NetworkClientType, assembly, Log, "get_connection", ref WeavingFailed);
|
|
||||||
|
|
||||||
generatedSyncVarSetter = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter", ref WeavingFailed);
|
generatedSyncVarSetter = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter", ref WeavingFailed);
|
||||||
generatedSyncVarSetter_GameObject = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter_GameObject", ref WeavingFailed);
|
generatedSyncVarSetter_GameObject = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GeneratedSyncVarSetter_GameObject", ref WeavingFailed);
|
||||||
@ -114,9 +100,25 @@ namespace Mirror.Weaver
|
|||||||
getSyncVarNetworkIdentityReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarNetworkIdentity", ref WeavingFailed);
|
getSyncVarNetworkIdentityReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarNetworkIdentity", ref WeavingFailed);
|
||||||
getSyncVarNetworkBehaviourReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarNetworkBehaviour", ref WeavingFailed);
|
getSyncVarNetworkBehaviourReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "GetSyncVarNetworkBehaviour", ref WeavingFailed);
|
||||||
|
|
||||||
|
sendCommandInternal = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SendCommandInternal", ref WeavingFailed);
|
||||||
|
sendRpcInternal = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SendRPCInternal", ref WeavingFailed);
|
||||||
|
sendTargetRpcInternal = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SendTargetRPCInternal", ref WeavingFailed);
|
||||||
|
|
||||||
|
InitSyncObjectReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "InitSyncObject", ref WeavingFailed);
|
||||||
|
|
||||||
|
TypeReference RemoteProcedureCallsType = Import(typeof(RemoteCalls.RemoteProcedureCalls));
|
||||||
registerCommandReference = Resolvers.ResolveMethod(RemoteProcedureCallsType, assembly, Log, "RegisterCommand", ref WeavingFailed);
|
registerCommandReference = Resolvers.ResolveMethod(RemoteProcedureCallsType, assembly, Log, "RegisterCommand", ref WeavingFailed);
|
||||||
registerRpcReference = Resolvers.ResolveMethod(RemoteProcedureCallsType, assembly, Log, "RegisterRpc", ref WeavingFailed);
|
registerRpcReference = Resolvers.ResolveMethod(RemoteProcedureCallsType, assembly, Log, "RegisterRpc", ref WeavingFailed);
|
||||||
|
|
||||||
|
TypeReference RemoteCallDelegateType = Import<RemoteCalls.RemoteCallDelegate>();
|
||||||
|
RemoteCallDelegateConstructor = Resolvers.ResolveMethod(RemoteCallDelegateType, assembly, Log, ".ctor", ref WeavingFailed);
|
||||||
|
|
||||||
|
TypeReference ScriptableObjectType = Import<ScriptableObject>();
|
||||||
|
ScriptableObjectCreateInstanceMethod = Resolvers.ResolveMethod(
|
||||||
|
ScriptableObjectType, assembly, Log,
|
||||||
|
md => md.Name == "CreateInstance" && md.HasGenericParameters,
|
||||||
|
ref WeavingFailed);
|
||||||
|
|
||||||
TypeReference unityDebug = Import(typeof(UnityEngine.Debug));
|
TypeReference unityDebug = Import(typeof(UnityEngine.Debug));
|
||||||
// these have multiple methods with same name, so need to check parameters too
|
// these have multiple methods with same name, so need to check parameters too
|
||||||
logErrorReference = Resolvers.ResolveMethod(unityDebug, assembly, Log, md =>
|
logErrorReference = Resolvers.ResolveMethod(unityDebug, assembly, Log, md =>
|
||||||
@ -133,11 +135,10 @@ namespace Mirror.Weaver
|
|||||||
|
|
||||||
TypeReference typeType = Import(typeof(Type));
|
TypeReference typeType = Import(typeof(Type));
|
||||||
getTypeFromHandleReference = Resolvers.ResolveMethod(typeType, assembly, Log, "GetTypeFromHandle", ref WeavingFailed);
|
getTypeFromHandleReference = Resolvers.ResolveMethod(typeType, assembly, Log, "GetTypeFromHandle", ref WeavingFailed);
|
||||||
sendCommandInternal = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SendCommandInternal", ref WeavingFailed);
|
|
||||||
sendRpcInternal = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SendRPCInternal", ref WeavingFailed);
|
|
||||||
sendTargetRpcInternal = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "SendTargetRPCInternal", ref WeavingFailed);
|
|
||||||
|
|
||||||
InitSyncObjectReference = Resolvers.ResolveMethod(NetworkBehaviourType, assembly, Log, "InitSyncObject", ref WeavingFailed);
|
TypeReference NetworkWriterPoolType = Import(typeof(NetworkWriterPool));
|
||||||
|
GetWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "Get", ref WeavingFailed);
|
||||||
|
ReturnWriterReference = Resolvers.ResolveMethod(NetworkWriterPoolType, assembly, Log, "Return", ref WeavingFailed);
|
||||||
|
|
||||||
TypeReference readerExtensions = Import(typeof(NetworkReaderExtensions));
|
TypeReference readerExtensions = Import(typeof(NetworkReaderExtensions));
|
||||||
readNetworkBehaviourGeneric = Resolvers.ResolveMethod(readerExtensions, assembly, Log, (md =>
|
readNetworkBehaviourGeneric = Resolvers.ResolveMethod(readerExtensions, assembly, Log, (md =>
|
||||||
@ -147,6 +148,7 @@ namespace Mirror.Weaver
|
|||||||
}),
|
}),
|
||||||
ref WeavingFailed);
|
ref WeavingFailed);
|
||||||
|
|
||||||
|
// CHANGED
|
||||||
/*
|
/*
|
||||||
// [InitializeOnLoadMethod]
|
// [InitializeOnLoadMethod]
|
||||||
// 'UnityEditor' is not available in builds.
|
// 'UnityEditor' is not available in builds.
|
||||||
|
@ -116,7 +116,9 @@ namespace Mirror.Weaver
|
|||||||
return GenerateCollectionWriter(variableReference, elementType, nameof(NetworkWriterExtensions.WriteList), ref WeavingFailed);
|
return GenerateCollectionWriter(variableReference, elementType, nameof(NetworkWriterExtensions.WriteList), ref WeavingFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variableReference.IsDerivedFrom<NetworkBehaviour>())
|
// handle both NetworkBehaviour and inheritors.
|
||||||
|
// fixes: https://github.com/MirrorNetworking/Mirror/issues/2939
|
||||||
|
if (variableReference.IsDerivedFrom<NetworkBehaviour>() || variableReference.Is<NetworkBehaviour>())
|
||||||
{
|
{
|
||||||
return GetNetworkBehaviourWriter(variableReference);
|
return GetNetworkBehaviourWriter(variableReference);
|
||||||
}
|
}
|
||||||
@ -139,6 +141,7 @@ namespace Mirror.Weaver
|
|||||||
{
|
{
|
||||||
throw new GenerateWriterException($"Cannot generate writer for {variableReference.Name}. Use a supported type or provide a custom writer", variableReference);
|
throw new GenerateWriterException($"Cannot generate writer for {variableReference.Name}. Use a supported type or provide a custom writer", variableReference);
|
||||||
}
|
}
|
||||||
|
// CHANGED
|
||||||
/*
|
/*
|
||||||
if (variableDefinition.HasGenericParameters)
|
if (variableDefinition.HasGenericParameters)
|
||||||
{
|
{
|
||||||
@ -219,6 +222,7 @@ namespace Mirror.Weaver
|
|||||||
if (!variable.Resolve().IsValueType)
|
if (!variable.Resolve().IsValueType)
|
||||||
WriteNullCheck(worker, ref WeavingFailed);
|
WriteNullCheck(worker, ref WeavingFailed);
|
||||||
|
|
||||||
|
// CHANGED
|
||||||
if (!this.WriteAllFieldsGeneric(variable, worker, ref WeavingFailed))
|
if (!this.WriteAllFieldsGeneric(variable, worker, ref WeavingFailed))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user