mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
* Fix #372, call syncvar hook for spawn * Rebuilt the weaver with the changes
This commit is contained in:
parent
b7ef2b3521
commit
dfd0e02125
Binary file not shown.
@ -445,108 +445,8 @@ public static int GetChannelId(CustomAttribute ca)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateDeSerialization()
|
void DeserializeField(FieldDefinition syncVar, ILProcessor serWorker)
|
||||||
{
|
{
|
||||||
Weaver.DLog(m_td, " GenerateDeSerialization");
|
|
||||||
|
|
||||||
foreach (MethodDefinition m in m_td.Methods)
|
|
||||||
{
|
|
||||||
if (m.Name == "OnDeserialize")
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_SyncVars.Count == 0)
|
|
||||||
{
|
|
||||||
// no synvars, no need for custom OnDeserialize
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodDefinition serialize = new MethodDefinition("OnDeserialize",
|
|
||||||
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
|
|
||||||
Weaver.voidType);
|
|
||||||
|
|
||||||
serialize.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
|
|
||||||
serialize.Parameters.Add(new ParameterDefinition("initialState", ParameterAttributes.None, Weaver.boolType));
|
|
||||||
ILProcessor serWorker = serialize.Body.GetILProcessor();
|
|
||||||
|
|
||||||
MethodReference baseDeserialize = Resolvers.ResolveMethodInParents(m_td.BaseType, Weaver.scriptDef, "OnDeserialize");
|
|
||||||
if (baseDeserialize != null)
|
|
||||||
{
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0)); // base
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1)); // reader
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_2)); // initialState
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Call, baseDeserialize));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates: if (initialState);
|
|
||||||
Instruction initialStateLabel = serWorker.Create(OpCodes.Nop);
|
|
||||||
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_2));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Brfalse, initialStateLabel));
|
|
||||||
|
|
||||||
foreach (FieldDefinition syncVar in m_SyncVars)
|
|
||||||
{
|
|
||||||
// assign value
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
|
||||||
|
|
||||||
if (syncVar.FieldType.FullName == Weaver.gameObjectType.FullName ||
|
|
||||||
syncVar.FieldType.FullName == Weaver.NetworkIdentityType.FullName)
|
|
||||||
{
|
|
||||||
// GameObject/NetworkIdentity SyncVar:
|
|
||||||
// OnSerialize sends writer.Write(go);
|
|
||||||
// OnDeserialize reads to __netId manually so we can use
|
|
||||||
// lookups in the getter (so it still works if objects
|
|
||||||
// move in and out of range repeatedly)
|
|
||||||
FieldDefinition netIdField = m_SyncVarNetIds[syncVar];
|
|
||||||
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPacked32));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Stfld, netIdField));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
MethodReference readFunc = Weaver.GetReadFunc(syncVar.FieldType);
|
|
||||||
if (readFunc != null)
|
|
||||||
{
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Call, readFunc));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log.Error("GenerateDeSerialization for " + m_td.Name + " unknown type [" + syncVar.FieldType + "]. UNet [SyncVar] member variables must be basic types.");
|
|
||||||
Weaver.fail = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Stfld, syncVar));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ret));
|
|
||||||
|
|
||||||
// Generates: end if (initialState);
|
|
||||||
serWorker.Append(initialStateLabel);
|
|
||||||
|
|
||||||
// setup local for dirty bits
|
|
||||||
serialize.Body.InitLocals = true;
|
|
||||||
VariableDefinition dirtyBitsLocal = new VariableDefinition(Weaver.int64Type);
|
|
||||||
serialize.Body.Variables.Add(dirtyBitsLocal);
|
|
||||||
|
|
||||||
// get dirty bits
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPacked64));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Stloc_0));
|
|
||||||
|
|
||||||
// conditionally read each syncvar
|
|
||||||
int dirtyBit = Weaver.GetSyncVarStart(m_td.BaseType.FullName); // start at number of syncvars in parent
|
|
||||||
foreach (FieldDefinition syncVar in m_SyncVars)
|
|
||||||
{
|
|
||||||
Instruction varLabel = serWorker.Create(OpCodes.Nop);
|
|
||||||
|
|
||||||
// check if dirty bit is set
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldloc_0));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Ldc_I8, 1L << dirtyBit));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.And));
|
|
||||||
serWorker.Append(serWorker.Create(OpCodes.Brfalse, varLabel));
|
|
||||||
|
|
||||||
// check for Hook function
|
// check for Hook function
|
||||||
MethodDefinition foundMethod;
|
MethodDefinition foundMethod;
|
||||||
if (!SyncVarProcessor.CheckForHookFunction(m_td, syncVar, out foundMethod))
|
if (!SyncVarProcessor.CheckForHookFunction(m_td, syncVar, out foundMethod))
|
||||||
@ -615,6 +515,82 @@ void GenerateDeSerialization()
|
|||||||
serWorker.Append(serWorker.Create(OpCodes.Call, foundMethod));
|
serWorker.Append(serWorker.Create(OpCodes.Call, foundMethod));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateDeSerialization()
|
||||||
|
{
|
||||||
|
Weaver.DLog(m_td, " GenerateDeSerialization");
|
||||||
|
|
||||||
|
foreach (MethodDefinition m in m_td.Methods)
|
||||||
|
{
|
||||||
|
if (m.Name == "OnDeserialize")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_SyncVars.Count == 0)
|
||||||
|
{
|
||||||
|
// no synvars, no need for custom OnDeserialize
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodDefinition serialize = new MethodDefinition("OnDeserialize",
|
||||||
|
MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig,
|
||||||
|
Weaver.voidType);
|
||||||
|
|
||||||
|
serialize.Parameters.Add(new ParameterDefinition("reader", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkReaderType)));
|
||||||
|
serialize.Parameters.Add(new ParameterDefinition("initialState", ParameterAttributes.None, Weaver.boolType));
|
||||||
|
ILProcessor serWorker = serialize.Body.GetILProcessor();
|
||||||
|
|
||||||
|
MethodReference baseDeserialize = Resolvers.ResolveMethodInParents(m_td.BaseType, Weaver.scriptDef, "OnDeserialize");
|
||||||
|
if (baseDeserialize != null)
|
||||||
|
{
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ldarg_0)); // base
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1)); // reader
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ldarg_2)); // initialState
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Call, baseDeserialize));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates: if (initialState);
|
||||||
|
Instruction initialStateLabel = serWorker.Create(OpCodes.Nop);
|
||||||
|
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ldarg_2));
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Brfalse, initialStateLabel));
|
||||||
|
|
||||||
|
foreach (FieldDefinition syncVar in m_SyncVars)
|
||||||
|
{
|
||||||
|
DeserializeField(syncVar, serWorker);
|
||||||
|
}
|
||||||
|
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ret));
|
||||||
|
|
||||||
|
// Generates: end if (initialState);
|
||||||
|
serWorker.Append(initialStateLabel);
|
||||||
|
|
||||||
|
// setup local for dirty bits
|
||||||
|
serialize.Body.InitLocals = true;
|
||||||
|
VariableDefinition dirtyBitsLocal = new VariableDefinition(Weaver.int64Type);
|
||||||
|
serialize.Body.Variables.Add(dirtyBitsLocal);
|
||||||
|
|
||||||
|
// get dirty bits
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkReaderReadPacked64));
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Stloc_0));
|
||||||
|
|
||||||
|
// conditionally read each syncvar
|
||||||
|
int dirtyBit = Weaver.GetSyncVarStart(m_td.BaseType.FullName); // start at number of syncvars in parent
|
||||||
|
foreach (FieldDefinition syncVar in m_SyncVars)
|
||||||
|
{
|
||||||
|
Instruction varLabel = serWorker.Create(OpCodes.Nop);
|
||||||
|
|
||||||
|
// check if dirty bit is set
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ldloc_0));
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Ldc_I8, 1L << dirtyBit));
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.And));
|
||||||
|
serWorker.Append(serWorker.Create(OpCodes.Brfalse, varLabel));
|
||||||
|
|
||||||
|
DeserializeField(syncVar, serWorker);
|
||||||
|
|
||||||
serWorker.Append(varLabel);
|
serWorker.Append(varLabel);
|
||||||
dirtyBit += 1;
|
dirtyBit += 1;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user