static void ProcessSyncVars(TypeDefinition td) { // find syncvars foreach (FieldDefinition fd in td.Fields) { if (fd.HasCustomAttribute <SyncVarAttribute>()) { Weaver.Error($"SyncVar {fd.Name} must be inside a NetworkBehaviour. {td.Name} is not a NetworkBehaviour", fd); } if (SyncObjectProcessor.ImplementsSyncObject(fd.FieldType)) { Weaver.Error($"{fd.Name} is a SyncObject and must be inside a NetworkBehaviour. {td.Name} is not a NetworkBehaviour", fd); } } }
static void ProcessSyncVars(TypeDefinition td) { // find syncvars foreach (FieldDefinition fd in td.Fields) { foreach (CustomAttribute ca in fd.CustomAttributes) { if (ca.AttributeType.FullName == Weaver.SyncVarType.FullName) { Weaver.Error("Script " + td.FullName + " uses [SyncVar] " + fd.Name + " but is not a NetworkBehaviour."); } } if (SyncObjectProcessor.ImplementsSyncObject(fd.FieldType)) { Weaver.Error(string.Format("Script {0} defines field {1} with type {2}, but it's not a NetworkBehaviour", td.FullName, fd.Name, Helpers.PrettyPrintType(fd.FieldType))); } } }
public static void ProcessSyncVars(TypeDefinition td, List <FieldDefinition> syncVars, List <FieldDefinition> syncObjects, Dictionary <FieldDefinition, FieldDefinition> syncVarNetIds) { int numSyncVars = 0; // the mapping of dirtybits to sync-vars is implicit in the order of the fields here. this order is recorded in m_replacementProperties. // start assigning syncvars at the place the base class stopped, if any int dirtyBitCounter = Weaver.GetSyncVarStart(td.BaseType.FullName); syncVarNetIds.Clear(); // find syncvars foreach (FieldDefinition fd in td.Fields) { foreach (var ca in fd.CustomAttributes) { if (ca.AttributeType.FullName == Weaver.SyncVarType.FullName) { var resolvedField = fd.FieldType.Resolve(); if (resolvedField.IsDerivedFrom(Weaver.NetworkBehaviourType)) { Log.Error("SyncVar [" + fd.FullName + "] cannot be derived from NetworkBehaviour."); Weaver.fail = true; return; } if (resolvedField.IsDerivedFrom(Weaver.ScriptableObjectType)) { Log.Error("SyncVar [" + fd.FullName + "] cannot be derived from ScriptableObject."); Weaver.fail = true; return; } if ((fd.Attributes & FieldAttributes.Static) != 0) { Log.Error("SyncVar [" + fd.FullName + "] cannot be static."); Weaver.fail = true; return; } if (resolvedField.HasGenericParameters) { Log.Error("SyncVar [" + fd.FullName + "] cannot have generic parameters."); Weaver.fail = true; return; } if (resolvedField.IsInterface) { Log.Error("SyncVar [" + fd.FullName + "] cannot be an interface."); Weaver.fail = true; return; } var fieldModuleName = resolvedField.Module.Name; if (fieldModuleName != Weaver.scriptDef.MainModule.Name && fieldModuleName != Weaver.m_UnityAssemblyDefinition.MainModule.Name && fieldModuleName != Weaver.m_UNetAssemblyDefinition.MainModule.Name && fieldModuleName != Weaver.corLib.Name && fieldModuleName != "System.Runtime.dll" && // this is only for Metro, built-in types are not in corlib on metro fieldModuleName != "netstandard.dll" // handle built-in types when weaving new C#7 compiler assemblies ) { Log.Error("SyncVar [" + fd.FullName + "] from " + resolvedField.Module.ToString() + " cannot be a different module."); Weaver.fail = true; return; } if (fd.FieldType.IsArray) { Log.Error("SyncVar [" + fd.FullName + "] cannot be an array. Use a SyncList instead."); Weaver.fail = true; return; } if (SyncObjectProcessor.ImplementsSyncObject(fd.FieldType)) { Log.Warning(string.Format("Script class [{0}] has [SyncVar] attribute on SyncList field {1}, SyncLists should not be marked with SyncVar.", td.FullName, fd.Name)); break; } syncVars.Add(fd); ProcessSyncVar(td, fd, syncVarNetIds, 1L << dirtyBitCounter); dirtyBitCounter += 1; numSyncVars += 1; if (dirtyBitCounter == k_SyncVarLimit) { Log.Error("Script class [" + td.FullName + "] has too many SyncVars (" + k_SyncVarLimit + "). (This could include base classes)"); Weaver.fail = true; return; } break; } } if (fd.FieldType.FullName.Contains("Mirror.SyncListStruct")) { Log.Error("SyncListStruct member variable [" + fd.FullName + "] must use a dervied class, like \"class MySyncList : SyncListStruct<MyStruct> {}\"."); Weaver.fail = true; return; } if (fd.FieldType.Resolve().ImplementsInterface(Weaver.SyncObjectType)) { if (fd.IsStatic) { Log.Error("SyncList [" + td.FullName + ":" + fd.FullName + "] cannot be a static"); Weaver.fail = true; return; } syncObjects.Add(fd); } } // add all the new SyncVar __netId fields foreach (FieldDefinition fd in syncVarNetIds.Values) { td.Fields.Add(fd); } Weaver.SetNumSyncVars(td.FullName, numSyncVars); }