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;
|
||||
}
|
||||
|
||||
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
|
||||
MethodDefinition foundMethod;
|
||||
if (!SyncVarProcessor.CheckForHookFunction(m_td, syncVar, out foundMethod))
|
||||
@ -615,6 +515,82 @@ void GenerateDeSerialization()
|
||||
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);
|
||||
dirtyBit += 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user