static NetworkingService()
        {
#if UNITY_EDITOR
            if (!EditorApplication.isPlaying)
            {
                return;
            }
#endif

            settings = Resources.Load <NetworkingSettings>("NetworkingSettings");

            matchmakingHandler = new MatchmakingHandler();
            serialization      = new SerializableTypes();
            eventHandler       = new MultiplayerEventHandler(serialization);
            clientHandler      = new ClientHandler();
            roomHandler        = new RoomHandler();
            callbackHandler    = new CallbackHandler(clientHandler, roomHandler);
            resourceHandler    = new ResourceHandler(settings, eventHandler);

            serialization.RegisterCustomTypesInternal();

            PhotonNetwork.SerializationRate      = settings.SerializationRate;
            PhotonNetwork.SendRate               = settings.SendRate;
            PhotonNetwork.AutomaticallySyncScene = settings.SynchronizeClientScenes;

            PhotonNetwork.AddCallbackTarget(callbackHandler);
            PhotonNetwork.AddCallbackTarget(eventHandler);
        }
示例#2
0
        public void AddSerializableType(TypeReference dataType, SerializableTypeInfo serializableTypeInfo, string profile = "Default")
        {
            SerializableTypeInfo currentValue;

            // Check if declaring type is generics
            var resolvedType = dataType.Resolve();

            if (resolvedType != null && resolvedType.DeclaringType != null && (resolvedType.HasGenericParameters || resolvedType.DeclaringType.HasGenericParameters))
            {
                throw new NotSupportedException(String.Format("Serialization of nested types referencing parent's generic parameters is not currently supported. " +
                                                              "[Nested type={0} Parent={1}]", resolvedType.FullName, resolvedType.DeclaringType));
            }

            var profileInfo = GetSerializableTypes(profile);

            if (profileInfo.TryGetSerializableTypeInfo(dataType, serializableTypeInfo.Mode != DataSerializerGenericMode.None, out currentValue))
            {
                // TODO: Doesn't work in some generic case
                if (//currentValue.SerializerType.ConvertCSharp() != serializableTypeInfo.SerializerType.ConvertCSharp() ||
                    currentValue.Mode != serializableTypeInfo.Mode)
                {
                    throw new InvalidOperationException(string.Format("Incompatible serializer found for same type in different assemblies for {0}", dataType.ConvertCSharp()));
                }
                return;
            }

            // Check that we don't simply try to add the same serializer than Default profile (optimized)
            SerializableTypeInfo defaultValue;

            if (profile != "Default" && SerializableTypes.TryGetSerializableTypeInfo(dataType, serializableTypeInfo.Mode != DataSerializerGenericMode.None, out defaultValue))
            {
                if (defaultValue.SerializerType.FullName == serializableTypeInfo.SerializerType.FullName)
                {
                    // Already added in default profile, early exit
                    return;
                }
            }

            profileInfo.AddSerializableTypeInfo(dataType, serializableTypeInfo);

            // Scan and add dependencies (stored in EnumerateGenericInstantiations() functions).
            if (serializableTypeInfo.Local && serializableTypeInfo.SerializerType != null)
            {
                var resolvedSerializerType = serializableTypeInfo.SerializerType.Resolve();
                if (resolvedSerializerType != null)
                {
                    var enumerateGenericInstantiationsMethod = resolvedSerializerType.Methods.FirstOrDefault(x => x.Name == "EnumerateGenericInstantiations");
                    if (enumerateGenericInstantiationsMethod != null)
                    {
                        // Detect all ldtoken (attributes would have been better, but unfortunately C# doesn't allow generics in attributes)
                        foreach (var inst in enumerateGenericInstantiationsMethod.Body.Instructions)
                        {
                            if (inst.OpCode.Code == Code.Ldtoken)
                            {
                                var type = (TypeReference)inst.Operand;

                                // Try to "close" generics type with serializer type as a context
                                var dependentType = ResolveGenericsVisitor.Process(serializableTypeInfo.SerializerType, type);
                                if (!dependentType.ContainsGenericParameter())
                                {
                                    // Import type so that it becomes local to the assembly
                                    // (otherwise SerializableTypeInfo.Local will be false and it won't be instantiated)
                                    var importedType = Assembly.MainModule.ImportReference(dependentType);
                                    if (GenerateSerializer(importedType) == null)
                                    {
                                        throw new InvalidOperationException(string.Format("Could not find serializer for generic dependent type {0} when processing {1}", dependentType, dataType));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }