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) { if (fd.HasCustomAttribute(Weaver.SyncVarType)) { if ((fd.Attributes & FieldAttributes.Static) != 0) { Weaver.Error($"{fd} cannot be static"); return; } if (fd.FieldType.IsArray) { Weaver.Error($"{fd} has invalid type. Use SyncLists instead of arrays"); return; } if (SyncObjectInitializer.ImplementsSyncObject(fd.FieldType)) { Log.Warning($"{fd} has [SyncVar] attribute. SyncLists should not be marked with SyncVar"); } else { syncVars.Add(fd); ProcessSyncVar(td, fd, syncVarNetIds, 1L << dirtyBitCounter); dirtyBitCounter += 1; numSyncVars += 1; if (dirtyBitCounter == SyncVarLimit) { Weaver.Error($"{td} has too many SyncVars. Consider refactoring your class into multiple components"); return; } } } if (fd.FieldType.Resolve().ImplementsInterface(Weaver.SyncObjectType)) { if (fd.IsStatic) { Weaver.Error($"{fd} cannot be static"); 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); }
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 (CustomAttribute ca in fd.CustomAttributes) { if (ca.AttributeType.FullName == Weaver.SyncVarType.FullName) { TypeDefinition resolvedField = fd.FieldType.Resolve(); if (resolvedField.IsDerivedFrom(Weaver.NetworkBehaviourType)) { Weaver.Error($"{fd} has invalid type. SyncVars cannot be NetworkBehaviours"); return; } if (resolvedField.IsDerivedFrom(Weaver.ScriptableObjectType)) { Weaver.Error($"{fd} has invalid type. SyncVars cannot be scriptable objects"); return; } if ((fd.Attributes & FieldAttributes.Static) != 0) { Weaver.Error($"{fd} cannot be static"); return; } if (resolvedField.HasGenericParameters) { Weaver.Error($"{fd} has invalid type. SyncVars cannot have generic parameters"); return; } if (resolvedField.IsInterface) { Weaver.Error($"{fd} has invalid type. Use a concrete type instead of interface {fd.FieldType}"); return; } string fieldModuleName = resolvedField.Module.Name; if (fieldModuleName != Weaver.CurrentAssembly.MainModule.Name && fieldModuleName != Weaver.UnityAssembly.MainModule.Name && fieldModuleName != Weaver.NetAssembly.MainModule.Name && fieldModuleName != Weaver.CorLibModule.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 ) { Weaver.Error($"{fd} has invalid type. Use a type defined in the same module {fd.Module}"); return; } if (fd.FieldType.IsArray) { Weaver.Error($"{fd} has invalid type. Use SyncLists instead of arrays"); return; } if (SyncObjectInitializer.ImplementsSyncObject(fd.FieldType)) { Log.Warning($"{fd} has [SyncVar] attribute. SyncLists should not be marked with SyncVar"); break; } syncVars.Add(fd); ProcessSyncVar(td, fd, syncVarNetIds, 1L << dirtyBitCounter); dirtyBitCounter += 1; numSyncVars += 1; if (dirtyBitCounter == SyncVarLimit) { Weaver.Error($"{td} has too many SyncVars. Consider refactoring your class into multiple components"); return; } break; } } if (fd.FieldType.Resolve().ImplementsInterface(Weaver.SyncObjectType)) { if (fd.IsStatic) { Weaver.Error($"{fd} cannot be static"); 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); }
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 (CustomAttribute ca in fd.CustomAttributes) { if (ca.AttributeType.FullName == Weaver.SyncVarType.FullName) { TypeDefinition resolvedField = fd.FieldType.Resolve(); if (resolvedField.IsDerivedFrom(Weaver.NetworkBehaviourType)) { Weaver.Error("SyncVar [" + fd.FullName + "] cannot be derived from NetworkBehaviour."); return; } if (resolvedField.IsDerivedFrom(Weaver.ScriptableObjectType)) { Weaver.Error("SyncVar [" + fd.FullName + "] cannot be derived from ScriptableObject."); return; } if ((fd.Attributes & FieldAttributes.Static) != 0) { Weaver.Error("SyncVar [" + fd.FullName + "] cannot be static."); return; } if (resolvedField.HasGenericParameters) { Weaver.Error("SyncVar [" + fd.FullName + "] cannot have generic parameters."); return; } if (resolvedField.IsInterface) { Weaver.Error("SyncVar [" + fd.FullName + "] cannot be an interface."); return; } string fieldModuleName = resolvedField.Module.Name; if (fieldModuleName != Weaver.CurrentAssembly.MainModule.Name && fieldModuleName != Weaver.UnityAssembly.MainModule.Name && fieldModuleName != Weaver.NetAssembly.MainModule.Name && fieldModuleName != Weaver.CorLibModule.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 ) { Weaver.Error("SyncVar [" + fd.FullName + "] from " + resolvedField.Module.ToString() + " cannot be a different module."); return; } if (fd.FieldType.IsArray) { Weaver.Error("SyncVar [" + fd.FullName + "] cannot be an array. Use a SyncList instead."); return; } if (SyncObjectInitializer.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 == SyncVarLimit) { Weaver.Error("Script class [" + td.FullName + "] has too many SyncVars (" + SyncVarLimit + "). (This could include base classes)"); return; } break; } } if (fd.FieldType.Resolve().ImplementsInterface(Weaver.SyncObjectType)) { if (fd.IsStatic) { Weaver.Error("SyncList [" + td.FullName + ":" + fd.FullName + "] cannot be a static"); 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); }
public (List <FieldDefinition> syncVars, Dictionary <FieldDefinition, FieldDefinition> syncVarNetIds) ProcessSyncVars(TypeDefinition td, ref bool WeavingFailed) { List <FieldDefinition> syncVars = new List <FieldDefinition>(); Dictionary <FieldDefinition, FieldDefinition> syncVarNetIds = new Dictionary <FieldDefinition, FieldDefinition>(); // 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 = syncVarAccessLists.GetSyncVarStart(td.BaseType.FullName); // find syncvars foreach (FieldDefinition fd in td.Fields) { if (fd.HasCustomAttribute <SyncVarAttribute>()) { if ((fd.Attributes & FieldAttributes.Static) != 0) { Log.Error($"{fd.Name} cannot be static", fd); WeavingFailed = true; continue; } if (fd.FieldType.IsGenericParameter) { Log.Error($"{fd.Name} has generic type. Generic SyncVars are not supported", fd); WeavingFailed = true; continue; } if (fd.FieldType.IsArray) { Log.Error($"{fd.Name} has invalid type. Use SyncLists instead of arrays", fd); WeavingFailed = true; continue; } if (SyncObjectInitializer.ImplementsSyncObject(fd.FieldType)) { Log.Warning($"{fd.Name} has [SyncVar] attribute. SyncLists should not be marked with SyncVar", fd); } else { syncVars.Add(fd); ProcessSyncVar(td, fd, syncVarNetIds, 1L << dirtyBitCounter, ref WeavingFailed); dirtyBitCounter += 1; if (dirtyBitCounter > SyncVarLimit) { Log.Error($"{td.Name} has > {SyncVarLimit} SyncVars. Consider refactoring your class into multiple components", td); WeavingFailed = true; continue; } } } } // add all the new SyncVar __netId fields foreach (FieldDefinition fd in syncVarNetIds.Values) { td.Fields.Add(fd); } syncVarAccessLists.SetNumSyncVars(td.FullName, syncVars.Count); return(syncVars, syncVarNetIds); }