public void Read(SerializedFileReader reader) { ClassID = (ClassIDType)reader.ReadInt32(); if (IsReadScriptType(reader.Generation)) { IsStrippedType = reader.ReadBoolean(); ScriptID = reader.ReadInt16(); } else { // For old version it specifies ClassIDType or -ScriptID for MonoBehaviour int uniqueTypeID = (int)ClassID; if (uniqueTypeID < 0) { ClassID = ClassIDType.MonoBehaviour; ScriptID = (short)(-uniqueTypeID - 1); } } if (IsReadHash(reader.Generation)) { if (ClassID == ClassIDType.MonoBehaviour) { ScriptHash.Read(reader); } TypeHash.Read(reader); } // isSerializeTypeTrees if (Tree != null) { Tree.Read(reader); } }
public void Write(SerializedWriter writer) { if (HasScriptType(writer.Generation)) { writer.Write((int)ClassID); writer.Write(IsStrippedType); writer.Write(ScriptID); } else { writer.Write(UniqueTypeID); } if (HasHash(writer.Generation)) { if (ClassID == ClassIDType.MonoBehaviour) { ScriptHash.Write(writer); } TypeHash.Write(writer); } // isSerializeTypeTrees Tree?.Write(writer); }
public string UserComment; // xml format #endregion Fields #region Constructors public G2File(String name, String hash, byte[] hashByte, TypeHash typeHash , long size, FileType fileType, String codecInfo , FileLocationFound filelocation, int lenghtMedia , String protocolName, String linkFile) : base(name,hash,hashByte,typeHash,size,fileType,codecInfo,filelocation,lenghtMedia,protocolName,linkFile) { }
static bool TranslateNode(GraphBuilder builder, INodeModel nodeModel, out INode node, out Dictionary <string, uint> portToOffsetMapping, out uint?preAllocatedDataIndex) { Assert.IsNotNull(nodeModel); preAllocatedDataIndex = null; switch (nodeModel) { case SetVariableNodeModel setVariableNodeModel: { node = setVariableNodeModel.Node; portToOffsetMapping = setVariableNodeModel.PortToOffsetMapping; if (setVariableNodeModel.DeclarationModel == null) { return(false); } preAllocatedDataIndex = builder.GetVariableDataIndex(setVariableNodeModel.DeclarationModel).DataIndex; return(true); } case IEventNodeModel eventNodeModel: node = eventNodeModel.Node; ((IEventNode)node).EventId = TypeHash.CalculateStableTypeHash( eventNodeModel.TypeHandle.Resolve(nodeModel.GraphModel.Stencil)); portToOffsetMapping = eventNodeModel.PortToOffsetMapping; return(true); case SubgraphReferenceNodeModel subgraphReferenceNodeModel: node = subgraphReferenceNodeModel.Node; portToOffsetMapping = subgraphReferenceNodeModel.PortToOffsetMapping; return(true); case IDotsNodeModel dotsNodeModel: node = dotsNodeModel.Node; portToOffsetMapping = dotsNodeModel.PortToOffsetMapping; if (nodeModel is IReferenceComponentTypes referenceComponentTypes) { foreach (var typeReference in referenceComponentTypes.ReferencedTypes) { if (typeReference.TypeIndex != -1) { builder.AddReferencedComponent(typeReference); } } } return(true); case IConstantNodeModel constantNodeModel: HandleConstants(builder, out node, out portToOffsetMapping, constantNodeModel); return(true); case IVariableModel variableModel: return(HandleVariable(builder, out node, out portToOffsetMapping, out preAllocatedDataIndex, variableModel)); default: throw new NotImplementedException( $"Don't know how to translate a node of type {nodeModel.GetType()}: {nodeModel}"); } }
public G2File(String name, String hash, byte[] hashByte, TypeHash typeHash , long size, FileType fileType, String codecInfo , FileLocationFound filelocation, int lenghtMedia , String protocolName, String linkFile) : base(name, hash, hashByte, typeHash, size, fileType, codecInfo, filelocation, lenghtMedia, protocolName, linkFile) { }
public void Read(SerializedFileStream stream) { ClassID = (ClassIDType)stream.ReadInt32(); if (IsReadUnknown(stream.Generation)) { Unknown = stream.ReadByte(); ScriptID = stream.ReadInt16(); } if (IsReadHash(stream.Generation)) { if (IsOldHashType(stream.Generation)) { if ((int)ClassID <= -1) { ScriptHash.Read(stream); } } else { if (ClassID == ClassIDType.MonoBehaviour) { ScriptHash.Read(stream); } } TypeHash.Read(stream); } // isSerializeTypeTrees if (Tree != null) { Tree.Read(stream); } }
public ulong CalculateVersionHash() { if (m_RpcData.Length >= ushort.MaxValue) { throw new InvalidOperationException(String.Format("RpcSystem does not support more than {0} RPCs", ushort.MaxValue)); } for (int i = 0; i < m_RpcData.Length; ++i) { if (m_RpcData[i].TypeHash == 0) #if ENABLE_UNITY_COLLECTIONS_CHECKS { throw new InvalidOperationException(String.Format("Missing RPC registration for {0} which is used to send data", m_RpcData[i].RpcType.GetManagedType())); } #else { throw new InvalidOperationException("Missing RPC registration for RPC which is used to send"); } #endif } m_RpcData.Sort(); m_RpcTypeHashToIndex.Clear(); for (int i = 0; i < m_RpcData.Length; ++i) { m_RpcTypeHashToIndex.Add(m_RpcData[i].TypeHash, i); } ulong hash = m_RpcData[0].TypeHash; for (int i = 0; i < m_RpcData.Length; ++i) { hash = TypeHash.CombineFNV1A64(hash, m_RpcData[i].TypeHash); } m_CanRegister = false; return(hash); }
public void Read(SerializedReader reader) { if (HasScriptType(reader.Generation)) { ClassID = (ClassIDType)reader.ReadInt32(); IsStrippedType = reader.ReadBoolean(); ScriptID = reader.ReadInt16(); } else { UniqueTypeID = reader.ReadInt32(); } if (HasHash(reader.Generation)) { if (ClassID == ClassIDType.MonoBehaviour) { ScriptHash.Read(reader); } TypeHash.Read(reader); } // isSerializeTypeTrees Tree?.Read(reader); }
public VisitStatus Visit <TProperty, TContainer>(IPropertyVisitor visitor, TProperty property, ref TContainer container, ref TypeReference value, ref ChangeTracker changeTracker) where TProperty : IProperty <TContainer, TypeReference> { if (!property.Attributes.HasAttribute <TypeSearcherAttribute>()) { return(VisitStatus.Unhandled); } var key = new Tuple <INodeModel, string>(VisitorModel, ((IProperty)property).GetName()); if (!SafeTypeCache.TryGetValue(key, out var previousType)) { int typeIndex = TypeManager.GetTypeIndexFromStableTypeHash(value.TypeHash); if (typeIndex != -1 && typeIndex != 0) { previousType = TypeManager.GetType(typeIndex).GenerateTypeHandle(Stencil); SafeTypeCache[key] = previousType; } else { previousType = default; } } if (ExposeProperty(property, ref changeTracker, ref previousType)) { SafeTypeCache[key] = previousType; value.TypeHash = TypeHash.CalculateStableTypeHash(previousType.Resolve(Stencil)); } return(VisitStatus.Handled); }
public void Write <T>(T evt, int index) where T : struct, IVisualScriptingEvent { m_Writer.BeginForEachIndex(index); m_Writer.Write(TypeHash.CalculateStableTypeHash(typeof(T))); m_Writer.Write(UnsafeUtility.SizeOf <T>()); m_Writer.Write(false); m_Writer.Write(evt); m_Writer.EndForEachIndex(); }
public static ulong ComputeVariantHash(Mono.Cecil.TypeReference variantType, Mono.Cecil.CustomAttribute attribute) { var hash = TypeHash.FNV1A64(attribute.AttributeType.FullName); var componentType = attribute.ConstructorArguments[0].Value as Mono.Cecil.TypeReference; var variantName = variantType.FullName; hash = TypeHash.CombineFNV1A64(hash, TypeHash.FNV1A64(componentType.FullName)); hash = TypeHash.CombineFNV1A64(hash, TypeHash.FNV1A64(variantName)); return(hash); }
protected override void ShowSearcher(Vector2 mousePosition, INodeModel nodeModel, Action <TypeReference> notifyChanged) { SearcherService.ShowTypes(nodeModel.VSGraphModel.Stencil, mousePosition, (handle, i) => { var typeReference = Target; typeReference.TypeHash = TypeHash.CalculateStableTypeHash(handle.Resolve(nodeModel.VSGraphModel.Stencil)); notifyChanged(typeReference); }, MakeSearcherAdapterFromAttribute(null, nodeModel)); }
public override int GetHashCode() => 0; // NB: Test code. public bool Equals(CollectionsClass other) { return(other != null && ((TypeHash == null && other.TypeHash == null) || (TypeHash != null && TypeHash.SequenceEqual(other.TypeHash))) && ((TypeList == null && other.TypeList == null) || (TypeList != null && TypeList.SequenceEqual(other.TypeList))) && ((TypeDictionary == null && other.TypeDictionary == null) || (TypeDictionary != null && TypeDictionary.SequenceEqual(other.TypeDictionary)))); }
static List <TypeObjectData> BuildObjectData() { var types = TypeCache.GetTypesWithAttribute <GenerateAuthoringComponentAttribute>(); return(types .Select(t => new TypeObjectData { Value = new TypeReference { TypeHash = TypeHash.CalculateStableTypeHash(t) }, SearcherTitle = t.Name }) .ToList()); }
public unsafe void RetrieveBlendShapeData(Mesh uMesh) { UBlendShapeChannel[] uBlendShapeChannels = new UBlendShapeChannel[uMesh.blendShapeCount]; int totalDeltaValuesCount = 0; int totalWeightCount = 0; for (int i = 0; i < uMesh.blendShapeCount; i++) { string blendShapeName = uMesh.GetBlendShapeName(i); int frameCount = uMesh.GetBlendShapeFrameCount(i); totalDeltaValuesCount += frameCount * uMesh.vertexCount * 3; totalWeightCount += frameCount; UBlendShapeChannel uBlendShapeChannel = new UBlendShapeChannel(); uBlendShapeChannel.nameHash = TypeHash.FNV1A64(blendShapeName); uBlendShapeChannel.frameCount = frameCount; uBlendShapeChannels[i] = uBlendShapeChannel; } channels = new NativeArray <UBlendShapeChannel>(uMesh.blendShapeCount, Allocator.TempJob); NativeArray <UBlendShapeChannel> .Copy(uBlendShapeChannels, channels, uBlendShapeChannels.Length); Vector3[] uDeltaValues = new Vector3[totalDeltaValuesCount]; float[] uWeights = new float[totalWeightCount]; int deltaValuesOffset = 0; int weightOffset = 0; for (int shapeIndex = 0; shapeIndex < uMesh.blendShapeCount; shapeIndex++) { UBlendShapeChannel uBlendShapeChannel = uBlendShapeChannels[shapeIndex]; int frameCount = uBlendShapeChannel.frameCount; for (int frameIndex = 0; frameIndex < frameCount; frameIndex++) { Vector3[] deltaVetices = new Vector3[uMesh.vertexCount]; Vector3[] deltaNormals = new Vector3[uMesh.vertexCount]; Vector3[] deltaTangents = new Vector3[uMesh.vertexCount]; uMesh.GetBlendShapeFrameVertices(shapeIndex, frameIndex, deltaVetices, deltaNormals, deltaTangents); Array.Copy(deltaVetices, 0, uDeltaValues, deltaValuesOffset, deltaVetices.Length); deltaValuesOffset += uMesh.vertexCount; Array.Copy(deltaNormals, 0, uDeltaValues, deltaValuesOffset, deltaVetices.Length); deltaValuesOffset += uMesh.vertexCount; Array.Copy(deltaTangents, 0, uDeltaValues, deltaValuesOffset, deltaVetices.Length); deltaValuesOffset += uMesh.vertexCount; uWeights[weightOffset] = uMesh.GetBlendShapeFrameWeight(shapeIndex, frameIndex); weightOffset++; } } deltaValues = new NativeArray <Vector3>(totalDeltaValuesCount, Allocator.TempJob); NativeArray <Vector3> .Copy(uDeltaValues, deltaValues, uDeltaValues.Length); weights = new NativeArray <float>(totalWeightCount, Allocator.TempJob); NativeArray <float> .Copy(uWeights, weights, uWeights.Length); }
static List <TypeObjectData> BuildObjectData() { return(TypeCache.GetTypesDerivedFrom <IComponentData>() .Where(TypeHasUsableComponentFields) .Select(t => { bool isAuthoring = (t.CustomAttributes.Any(a => a.AttributeType == typeof(GenerateAuthoringComponentAttribute))); return new TypeObjectData { Value = new TypeReference { TypeHash = TypeHash.CalculateStableTypeHash(t) }, SearcherTitle = t.Name, Path = isAuthoring ? null : "Advanced" }; }) .ToList()); }
ParseHit(G2PacketH hit, FileLocationFound location) { // for now we dont take into accounts host of partial files if (isPartialFile(hit) && !Settings.ACCEPT_PARTIAL_FILE) { return(null); } string FileName = ""; long size = getNameAndSizeFromHit(hit, out FileName); if (size == 0) { return(null); // no size, no name or bug } List <URN> Hashes = getHashesFromHit(hit); TypeHash type = TypeHash.Md4EDonkey; URN SingleHash = Hashes.Find(FindED2KHash); if (SingleHash == null) { SingleHash = Hashes.Find(FindSHA1Hash); type = TypeHash.Sha1; } // if there is not the hashes we want , we dont want this packet // for now. ActionInnoncence DLL needs to take care of more hashes if (SingleHash == null) { return(null); } // gives a text representation of the hash string strHash = BitConverter.ToString(SingleHash.Digest).Replace("-", string.Empty).ToLower(); string link = getDownloadLink(hit); Metadata meta = Metadata.ParseMetadata(hit.getStringFromChildType(G2PacketType.MD)); G2File f = new G2File(FileName, strHash, SingleHash.Digest, type, size, FileType.Unknow, meta.Codec, location, meta.Length, Settings.PROTOCOL_NAME, link); f.Hashes = Hashes; f.CreationTime = getCreationTimeFromHit(hit); f.Metadata = meta; f.UserComment = hit.getStringFromChildType(G2PacketType.COM); f.PreviewUrl = hit.getStringFromChildType(G2PacketType.PVU); return(f); }
public static string GetHash(TypeHash type, string text, byte[] salt = null) { salt = salt ?? GenerateSalt(); byte[] plain = ASCIIEncoding.UTF8.GetBytes(text); int lenghtPlant = plain.Length, lenghtSalt = salt.Length, lenght = lenghtPlant + lenghtSalt; byte[] bytes = new byte[lenght]; for (int i = 0; i < lenght; ++i) { if (i < lenghtPlant) { bytes[i] = plain[i]; } else { bytes[i] = salt[i - lenghtPlant]; } } byte[] hash = null; switch (type) { case TypeHash.SHA256: SHA256 sha256 = SHA256Managed.Create(); hash = sha256.ComputeHash(bytes); sha256.Dispose(); break; case TypeHash.SHA384: SHA384 sha384 = SHA384Managed.Create(); hash = sha384.ComputeHash(bytes); sha384.Dispose(); break; case TypeHash.SHA512: SHA512 sha512 = SHA512Managed.Create(); hash = sha512.ComputeHash(bytes); sha512.Dispose(); break; } return(GetStringFromHash(hash)); }
void ProcessProperty <TValue>(ref TValue value) { if (m_CurrentPropertyPath.ToString() != m_SearchPropertyPath) { return; } if (TryGetOffsetOfField(m_TargetComponentType, m_CurrentPropertyPath, m_PropertyNameStartIndex, out var offset)) { m_Success = true; m_FieldOffset = (ushort)offset; m_FieldSize = (ushort)UnsafeUtility.SizeOf(value.GetType()); m_StableTypeHash = TypeHash.CalculateStableTypeHash(m_TargetComponentType); } m_OperationComplete = true; }
public void TestSetComponent() { GraphBuilder.VariableHandle varIndex = default; int initialValue = 42; int newValue = 55; SetupTestGraphDefinitionMultipleFrames((b, _) => { var componentTypeRef = new TypeReference { TypeHash = TypeHash.CalculateStableTypeHash(typeof(TestComponent)) }; var onUpdate = b.AddNode(new OnUpdate()); var enabled = b.AddNode(new ConstantBool { Value = true }); var setComponent = b.AddNode(new SetComponent { Type = componentTypeRef, ComponentData = new InputDataMultiPort { DataCount = 2 } }); b.CreateEdge(enabled.ValuePort, onUpdate.Enabled); varIndex = b.BindVariableToDataIndex("a"); b.BindVariableToInput(varIndex, setComponent.ComponentData.SelectPort(0)); b.CreateEdge(onUpdate.Output, setComponent.Set); b.AddReferencedComponent(componentTypeRef); } , (manager, entity, index) => { // don't add the component yet, next frame we can test that "set component" doesn't do anything if no component is attached }, (manager, entity, index) => { LogAssert.NoUnexpectedReceived(); Assert.That(manager.HasComponent <TestComponent>(entity), Is.False); // Set component shouldn't add a component manager.AddComponentData(entity, new TestComponent { Int = initialValue, Float = 12.7f }); GraphInstance instance = GetGraphInstance(entity); instance.WriteValueToDataSlot(varIndex.DataIndex, newValue); }, (manager, entity, index) => { var componentData = manager.GetComponentData <TestComponent>(entity); Assert.That(componentData.Int, Is.EqualTo(newValue)); }); }
public ulong CalculateGhostCollectionHash() { if (!m_GhostTypeCollection.IsCreated) { throw new InvalidOperationException("GhostCollectionSystem.CalculateGhostCollectionHash must be called after the system has configured the ghost collection"); } m_GhostTypeCollectionHash = 0; if (m_GhostTypeCollection.Length > 0) { m_GhostTypeCollectionHash = HashGhostType(m_GhostTypeCollection[0]); for (int i = 1; i < m_GhostTypeCollection.Length; ++i) { var ghotsTypeHash = HashGhostType(m_GhostTypeCollection[i]); m_GhostTypeCollectionHash = TypeHash.CombineFNV1A64(m_GhostTypeCollectionHash, ghotsTypeHash); } } return(m_GhostTypeCollectionHash); }
//Hash requirements: // R0: if components are different or in different order the hash should change // R1: different size, owneroffsets, maskbits, partialcomponents etc must result in a different hash // R2: if a ghost present the same components, with the same fields but different [GhostField] attributes (such as, subType, interpoled, composite) // must result in a different hash, even though the resulting serialization sizes and masks are the same public ulong CalculateComponentCollectionHash() { //Lazy create the component collection if not created when we want to compute the component collection hash if (!m_ComponentCollectionInitialized) { CreateComponentCollection(); } ulong componentCollectionHash = 0; var ghostComponentCollection = EntityManager.GetBuffer <GhostComponentSerializer.State>(m_CollectionSingleton); for (int i = 0; i < ghostComponentCollection.Length; ++i) { var comp = ghostComponentCollection[i]; if (comp.SerializerHash != 0) { componentCollectionHash = TypeHash.CombineFNV1A64(componentCollectionHash, comp.SerializerHash); } } return(componentCollectionHash); }
public void TestGetComponent() { SetupTestGraphDefinitionMultipleFrames((b, _) => { var componentTypeRef = new TypeReference { TypeHash = TypeHash.CalculateStableTypeHash(typeof(TestComponent)) }; var onUpdate = b.AddNode(new OnUpdate()); var enabled = b.AddNode(new ConstantBool { Value = true }); var getComponent = b.AddNode(new GetComponent { Type = componentTypeRef, ComponentData = new OutputDataMultiPort { DataCount = 2 } }); var log = b.AddNode(new Log() { Messages = new InputDataMultiPort { DataCount = 1 } }); b.CreateEdge(enabled.ValuePort, onUpdate.Enabled); b.CreateEdge(onUpdate.Output, log.Input); b.CreateEdge(getComponent.ComponentData.SelectPort(0), log.Messages.SelectPort(0)); b.AddReferencedComponent(componentTypeRef); }, (manager, entity, index) => { // don't add the component yet, next frame we can test that "get component" returns the default value }, (manager, entity, index) => { LogAssert.Expect(LogType.Log, "0"); // no component on entity should give default value manager.AddComponentData(entity, new TestComponent { Int = 42, Float = 12.7f }); }, (manager, entity, index) => { LogAssert.Expect(LogType.Log, "42"); }); }
//Hash requirements: // R0: if components are different or in different order the hash should change // R1: different size, owneroffsets, maskbits, partialcomponents etc must result in a different hash // R2: if a ghost present the same components, with the same fields but different [GhostField] attributes (such as, subType, interpoled, composite) // must result in a different hash, even though the resulting serialization sizes and masks are the same public ulong CalculateComponentCollectionHash() { //Lazy create the component collection if not created when we want to compute the component collection hash if (!m_GhostComponentCollection.IsCreated) { CreateComponentCollection(); } ulong componentCollectionHash = 0; if (m_GhostComponentCollection.Length > 0) { for (int i = 0; i < m_GhostComponentCollection.Length; ++i) { var comp = m_GhostComponentCollection[i]; if (comp.SerializerHash != 0) { componentCollectionHash = TypeHash.CombineFNV1A64(componentCollectionHash, comp.SerializerHash); } } } return(componentCollectionHash); }
public static void RegisterMonoScripts() { if (AssetDatabaseCompatibility.IsAssetImportWorkerProcess() || s_Initialized) { return; } s_Initialized = true; AssetDatabaseCompatibility.UnregisterCustomDependencyPrefixFilter("UnityEngineType/"); var behaviours = TypeCache.GetTypesDerivedFrom <UnityEngine.MonoBehaviour>(); var scripts = TypeCache.GetTypesDerivedFrom <UnityEngine.ScriptableObject>(); for (int i = 0; i != behaviours.Count; i++) { var type = behaviours[i]; if (type.IsGenericType) { continue; } var hash = TypeHash.CalculateStableTypeHash(type); AssetDatabaseCompatibility.RegisterCustomDependency(TypeString(type), new UnityEngine.Hash128(hash, hash)); } for (int i = 0; i != scripts.Count; i++) { var type = scripts[i]; if (type.IsGenericType) { continue; } var hash = TypeHash.CalculateStableTypeHash(type); AssetDatabaseCompatibility.RegisterCustomDependency(TypeString(type), new UnityEngine.Hash128(hash, hash)); } }
public IniTypeAndAlias(TypeHash alias, Type type) { _alias = alias; _type = type; }
public static bool Confirm(TypeHash type, string text, string hash, byte[] salt = null) { return(hash == GetHash(type, text, salt)); }
protected override void OnUpdate() { using (var context = new BlobAssetComputationContext <int, GhostPrefabMetaData>(BlobAssetStore, 16, Allocator.Temp)) { Entities.ForEach((GhostAuthoringComponent ghostAuthoring) => { bool isPrefab = !ghostAuthoring.gameObject.scene.IsValid() || ghostAuthoring.ForcePrefabConversion; var target = GetConversionTarget(this, isPrefab); // Check if the ghost is valid before starting to process if (String.IsNullOrEmpty(ghostAuthoring.prefabId)) { throw new InvalidOperationException($"The ghost {ghostAuthoring.gameObject.name} is not a valid prefab, all ghosts must be the top-level GameObject in a prefab. Ghost instances in scenes must be instances of such prefabs and changes should be made on the prefab asset, not the prefab instance"); } if (!isPrefab && ghostAuthoring.DefaultGhostMode == GhostAuthoringComponent.GhostMode.OwnerPredicted && target != NetcodeConversionTarget.Server) { throw new InvalidOperationException($"Cannot convert a owner predicted ghost {ghostAuthoring.Name} as a scene instance"); } if (!isPrefab && DstEntityManager.World.GetExistingSystem <ClientSimulationSystemGroup>() != null) { throw new InvalidOperationException($"The ghost {ghostAuthoring.gameObject.name} cannot be created on the client, either put it in a sub-scene or spawn it on the server only"); } if (ghostAuthoring.prefabId.Length != 32) { throw new InvalidOperationException("Invalid guid for ghost prefab type"); } // All ghosts should have a linked entity group DeclareLinkedEntityGroup(ghostAuthoring.gameObject); var entity = GetPrimaryEntity(ghostAuthoring); // Generate a ghost type component so the ghost can be identified by mathcing prefab asset guid var ghostType = new GhostTypeComponent(); ghostType.guid0 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(0, 8), 16); ghostType.guid1 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(8, 8), 16); ghostType.guid2 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(16, 8), 16); ghostType.guid3 = Convert.ToUInt32(ghostAuthoring.prefabId.Substring(24, 8), 16); DstEntityManager.AddComponentData(entity, ghostType); // FIXME: maybe stripping should be individual systems running before this to make sure it can be changed in a way that always triggers a reconvert - and to avoid reflection var components = DstEntityManager.GetComponentTypes(entity); if (target != NetcodeConversionTarget.Client) { // If this ghost should be usable on a server we must add a shared ghost type to make sure different ghost types // with the same archetype end up in different chunks. If conversion is client and server the client needs to remove // this at runtime DstEntityManager.AddSharedComponentData(entity, new SharedGhostTypeComponent { SharedValue = ghostType }); } if (target != NetcodeConversionTarget.Server) { // Converting to client or client and server, if client and server this should be stripped from servers at runtime DstEntityManager.AddComponentData(entity, new SnapshotData()); DstEntityManager.AddBuffer <SnapshotDataBuffer>(entity); } // All types have the ghost components DstEntityManager.AddComponentData(entity, new GhostComponent()); // No need to add the predicted ghost component for interpolated only ghosts if the data is only used by the client if (target != NetcodeConversionTarget.Client || ghostAuthoring.SupportedGhostModes != GhostAuthoringComponent.GhostModeMask.Interpolated) { DstEntityManager.AddComponentData(entity, new PredictedGhostComponent()); } if (target == NetcodeConversionTarget.Server) { // If converting server-only data we can remove all components which are not used on the server foreach (var comp in components) { var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>(); if (attr != null && (attr.PrefabType & GhostPrefabType.Server) == 0) { DstEntityManager.RemoveComponent(entity, comp); } } } else if (target == NetcodeConversionTarget.Client) { // If converting client-only data we can remove all components which are not used on the client // If the ghost is interpolated only we can also remove all componens which are not used on interpolated clients, // and if it is predicted only we can remove everything which is not used on predicted clients foreach (var comp in components) { var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>(); if (attr == null) { continue; } if ((attr.PrefabType & GhostPrefabType.Client) == 0) { DstEntityManager.RemoveComponent(entity, comp); } else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated && (attr.PrefabType & GhostPrefabType.InterpolatedClient) == 0) { DstEntityManager.RemoveComponent(entity, comp); } else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted && (attr.PrefabType & GhostPrefabType.PredictedClient) == 0) { DstEntityManager.RemoveComponent(entity, comp); } } } // Even if converting for client and server we can remove components which are only for predicted clients when // the ghost is always interpolated, or components which are only for interpolated clients if the ghost is always // predicted else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated) { foreach (var comp in components) { var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>(); if (attr != null && (attr.PrefabType & (GhostPrefabType.InterpolatedClient | GhostPrefabType.Server)) == 0) { DstEntityManager.RemoveComponent(entity, comp); } } } else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted) { foreach (var comp in components) { var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>(); if (attr != null && (attr.PrefabType & (GhostPrefabType.PredictedClient | GhostPrefabType.Server)) == 0) { DstEntityManager.RemoveComponent(entity, comp); } } } // This logic needs to match the logic creating LinkedEntityGroups, gather a list of all child entities var linkedEntities = new NativeList <Entity>(1, Allocator.Temp); var selfAndChildren = ghostAuthoring.gameObject.GetComponentsInChildren <Transform>(true); foreach (var transform in selfAndChildren) { foreach (var child in GetEntities(transform.gameObject)) { if (DstEntityManager.Exists(child)) { linkedEntities.Add(child); } } } // Mark all child entities as ghost children, entity 0 is the root and hsould not be marked for (int i = 1; i < linkedEntities.Length; ++i) { DstEntityManager.AddComponentData(linkedEntities[i], default(GhostChildEntityComponent)); } if (isPrefab) { var contentHash = TypeHash.FNV1A64(ghostAuthoring.Importance); contentHash = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)ghostAuthoring.SupportedGhostModes)); contentHash = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)ghostAuthoring.DefaultGhostMode)); contentHash = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)ghostAuthoring.OptimizationMode)); contentHash = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64(ghostAuthoring.Name.ToString())); foreach (var comp in components) { contentHash = TypeHash.CombineFNV1A64(contentHash, TypeManager.GetTypeInfo(comp.TypeIndex).StableTypeHash); var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>(); if (attr != null) { contentHash = TypeHash.CombineFNV1A64(contentHash, TypeHash.FNV1A64((int)attr.PrefabType)); } } var blobHash = new Unity.Entities.Hash128(ghostType.guid0 ^ (uint)(contentHash >> 32), ghostType.guid1 ^ (uint)(contentHash), ghostType.guid2, ghostType.guid3); context.AssociateBlobAssetWithUnityObject(blobHash, ghostAuthoring.gameObject); if (context.NeedToComputeBlobAsset(blobHash)) { var builder = new BlobBuilder(Allocator.Temp); ref var root = ref builder.ConstructRoot <GhostPrefabMetaData>(); // Store importance, supported modes, default mode and name in the meta data blob asset root.Importance = ghostAuthoring.Importance; root.SupportedModes = GhostPrefabMetaData.GhostMode.Both; root.DefaultMode = GhostPrefabMetaData.GhostMode.Interpolated; if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated) { root.SupportedModes = GhostPrefabMetaData.GhostMode.Interpolated; } else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted) { root.SupportedModes = GhostPrefabMetaData.GhostMode.Predicted; root.DefaultMode = GhostPrefabMetaData.GhostMode.Predicted; } else if (ghostAuthoring.DefaultGhostMode == GhostAuthoringComponent.GhostMode.OwnerPredicted) { if (!DstEntityManager.HasComponent <GhostOwnerComponent>(entity)) { throw new InvalidOperationException("OwnerPrediction mode can only be used on prefabs which have a GhostOwnerComponent"); } root.DefaultMode = GhostPrefabMetaData.GhostMode.Both; } else if (ghostAuthoring.DefaultGhostMode == GhostAuthoringComponent.GhostMode.Predicted) { root.DefaultMode = GhostPrefabMetaData.GhostMode.Predicted; } root.StaticOptimization = (ghostAuthoring.OptimizationMode == GhostAuthoringComponent.GhostOptimizationMode.Static); builder.AllocateString(ref root.Name, ghostAuthoring.Name); var serverComponents = new NativeList <ulong>(components.Length, Allocator.Temp); var removeOnServer = new NativeList <ulong>(components.Length, Allocator.Temp); var removeOnClient = new NativeList <ulong>(components.Length, Allocator.Temp); var disableOnPredicted = new NativeList <ulong>(components.Length, Allocator.Temp); var disableOnInterpolated = new NativeList <ulong>(components.Length, Allocator.Temp); // Snapshot data buffers should be removed from the server, and shared ghost type from the client removeOnServer.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <SnapshotData>().TypeIndex).StableTypeHash); removeOnServer.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <SnapshotDataBuffer>().TypeIndex).StableTypeHash); removeOnClient.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <SharedGhostTypeComponent>().TypeIndex).StableTypeHash); // If both interpolated and predicted clients are supported the interpolated client needs to disable the prediction component // If the ghost is interpolated only the prediction component can be removed on clients if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.All) { disableOnInterpolated.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <PredictedGhostComponent>().TypeIndex).StableTypeHash); } else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated) { removeOnClient.Add(TypeManager.GetTypeInfo(ComponentType.ReadWrite <PredictedGhostComponent>().TypeIndex).StableTypeHash); } foreach (var comp in components) { var hash = TypeManager.GetTypeInfo(comp.TypeIndex).StableTypeHash; var attr = comp.GetManagedType().GetCustomAttribute <GhostComponentAttribute>(); if (attr == null) { serverComponents.Add(hash); continue; } if ((attr.PrefabType & GhostPrefabType.Server) == 0) { removeOnServer.Add(hash); } else { serverComponents.Add(hash); } // If something is not used on the client, remove it. Make sure to include things that is interpolated only if ghost // is predicted only and the other way around if ((attr.PrefabType & GhostPrefabType.Client) == 0) { removeOnClient.Add(hash); } else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Interpolated && (attr.PrefabType & GhostPrefabType.InterpolatedClient) == 0) { removeOnClient.Add(hash); } else if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.Predicted && (attr.PrefabType & GhostPrefabType.PredictedClient) == 0) { removeOnClient.Add(hash); } // If the prefab only supports a single mode on the client there is no need to enable / disable, if is handled by the // previous loop removing components on the client instead if (ghostAuthoring.SupportedGhostModes == GhostAuthoringComponent.GhostModeMask.All) { // Components available on predicted but not interpolated should be disabled on interpolated clients if ((attr.PrefabType & GhostPrefabType.InterpolatedClient) == 0 && (attr.PrefabType & GhostPrefabType.PredictedClient) != 0) { disableOnInterpolated.Add(hash); } if ((attr.PrefabType & GhostPrefabType.InterpolatedClient) != 0 && (attr.PrefabType & GhostPrefabType.PredictedClient) == 0) { disableOnPredicted.Add(hash); } } } var blobServerComponents = builder.Allocate(ref root.ServerComponentList, serverComponents.Length); for (int i = 0; i < serverComponents.Length; ++i) { blobServerComponents[i] = serverComponents[i]; } // A pre-spawned instance can be created in ClientServer even if the prefab is not, so anything which should // be usable on the server needs to know what to remove from the server version if (target != NetcodeConversionTarget.Client) { // Client only data never needs information about the server var blobRemoveOnServer = builder.Allocate(ref root.RemoveOnServer, removeOnServer.Length); for (int i = 0; i < removeOnServer.Length; ++i) { blobRemoveOnServer[i] = removeOnServer[i]; } } else { builder.Allocate(ref root.RemoveOnServer, 0); } if (target != NetcodeConversionTarget.Server) { var blobRemoveOnClient = builder.Allocate(ref root.RemoveOnClient, removeOnClient.Length); for (int i = 0; i < removeOnClient.Length; ++i) { blobRemoveOnClient[i] = removeOnClient[i]; } } else { builder.Allocate(ref root.RemoveOnClient, 0); } if (target != NetcodeConversionTarget.Server) { // The data for interpolated / predicted diff is required unless this is server-only var blobDisableOnPredicted = builder.Allocate(ref root.DisableOnPredictedClient, disableOnPredicted.Length); for (int i = 0; i < disableOnPredicted.Length; ++i) { blobDisableOnPredicted[i] = disableOnPredicted[i]; } var blobDisableOnInterpolated = builder.Allocate(ref root.DisableOnInterpolatedClient, disableOnInterpolated.Length); for (int i = 0; i < disableOnInterpolated.Length; ++i) { blobDisableOnInterpolated[i] = disableOnInterpolated[i]; } } else { builder.Allocate(ref root.DisableOnPredictedClient, 0); builder.Allocate(ref root.DisableOnInterpolatedClient, 0); } var blobAsset = builder.CreateBlobAssetReference <GhostPrefabMetaData>(Allocator.Persistent); context.AddComputedBlobAsset(blobHash, blobAsset); } context.GetBlobAsset(blobHash, out var blob); DstEntityManager.AddComponentData(entity, new GhostPrefabMetaDataComponent { Value = blob }); } });
public bool Exists(TypeHash type, InstanceHash instance) { if (_lastResult.TypeId == type.TheHash && _lastResult.InstanceId == instance.TheHash) { return true; } for (int idx = 0; idx < _assetEntries.Length; ++idx) { if (_assetEntries[idx].TypeId == type.TheHash && _assetEntries[idx].InstanceId == instance.TheHash) { _lastResult = _assetEntries[idx]; return true; } } return false; }
public AssetEntry GetAsset(TypeHash type, InstanceHash instance) { if (_lastResult.TypeId == type.TheHash && _lastResult.InstanceId == instance.TheHash) { return _lastResult; } for (int idx = 0; idx < _assetEntries.Length; ++idx) { if (_assetEntries[idx].TypeId == type.TheHash && _assetEntries[idx].InstanceId == instance.TheHash) { _lastResult = _assetEntries[idx]; return _lastResult; } } return null; }
public IniTypeDescription(TypeHash name, Type type, IIniDescription[] items) { Name = name; Type = type; Items = items; }