public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(IOwned <TService> serviceInstance)
            where TService : class
        {
            if (serviceInstance is null)
            {
                throw new ArgumentNullException(nameof(serviceInstance));
            }
            var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.Value.GetType(), true);

            this.TryRegisterServiceDefinitions(allServices, null);

            var connectionInfo = this.RetrieveConnectionInfo();

            lock (this.syncRoot)
            {
                var serviceInstanceId = RpcObjectId.NewId();

                var publishedServices = this.PublishInstanceCore_Locked(allServices, serviceInstance, serviceInstanceId, false);

                Func <ValueTask> disposeAction = () => this.UnpublishInstanceAsync(serviceInstanceId);

                return(OwnedObject.Create(new RpcObjectRef <TService>(
                                              connectionInfo, serviceInstanceId, publishedServices.ToArray()), disposeAction));
            }
        }
예제 #2
0
    private void ScrubOwnedObject(OwnedObject ownedObject)
    {
        //remove any children that don't need to exist on the server
        foreach (Transform child in ownedObject.transform)
        {
            if (child.CompareTag(CLIENT_ANY_TAG) || child.CompareTag(CLIENT_SELF_TAG))
            {
                Destroy(child.gameObject);
            }
        }

        //destroy any remaining visibility togglers
        foreach (VisibilityToggle visibilityToggle in ownedObject.GetComponentsInChildren <VisibilityToggle>())
        {
            Destroy(visibilityToggle);
        }

        //destroy any remaining animators
        foreach (Animator animator in ownedObject.GetComponentsInChildren <Animator>())
        {
            Destroy(animator);
        }

        //destroy any remaining audio sources
        foreach (AudioSource audioSource in ownedObject.GetComponents <AudioSource>())
        {
            Destroy(audioSource);
        }
    }
예제 #3
0
 public static IOwned <RpcObjectRef <TService> > PublishInstance <TService>(this IRpcServer server, TService serviceInstance, bool takeOwnership = false) where TService : class
 {
     if (server is null)
     {
         throw new ArgumentNullException(nameof(server));
     }
     return(server.ServicePublisher.PublishInstance(takeOwnership ? OwnedObject.Create(serviceInstance) : OwnedObject.CreateUnowned(serviceInstance)));
 }
    protected void ColorizeOwnedObject(OwnedObject ownedObject)
    {
        Color teamColor = clientGameManager.GameState.teams[ownedObject.teamId].color;

        foreach (Colorable colorable in ownedObject.GetComponentsInChildren <Colorable>())
        {
            colorable.SetColor(teamColor);
        }
    }
        public IOwned <RpcSingletonRef <TService> > PublishSingleton <TService>(Func <IServiceProvider?, IOwned <TService> > factory)
            where TService : class
        {
            this.PublishSingletonFactoryCore(factory);

            return(OwnedObject.Create(new RpcSingletonRef <TService>(
                                          this.RetrieveConnectionInfo()),
                                      () => this.UnpublishSingletonAsync <TService>()));
        }
예제 #6
0
        [Test] public void CircularOwnership()
        {
            OwnedObject data = new OwnedObject();

            data.TestProperty = new OwnedObject();
            data.TestProperty.TestProperty = data;

            OwnedObject dataResult = data.DeepClone();

            Assert.IsTrue(dataResult.TestProperty.TestProperty == dataResult);
        }
        public static IOwned <RpcSingletonRef <TService> > PublishSingleton <TService>(this IRpcServicePublisher servicePublisher, Func <TService> factory)
            where TService : class
        {
            if (servicePublisher is null)
            {
                throw new ArgumentNullException(nameof(servicePublisher));
            }

            IOwned <TService> CreateActivatedService(IServiceProvider?_) => OwnedObject.Create(factory());

            return(servicePublisher.PublishSingleton(CreateActivatedService));
        }
예제 #8
0
        [Test] public void CloneRecursiveGraphs()
        {
            // Make sure that object referencing themselves can be cloned without problems
            OwnedObject source = new OwnedObject();

            source.TestData     = 42;
            source.TestProperty = source;
            OwnedObject target = source.DeepClone();

            Assert.AreNotSame(source, target);
            Assert.AreEqual(source.TestData, target.TestData);
            Assert.AreSame(target, target.TestProperty);
        }
        /// <summary>
        /// Publishes an RPC service instance using an instance factory.
        /// </summary>
        /// <typeparam name="TService">The type of the published instance.</typeparam>
        /// <param name="factory">A factory function that should create the service instance specified by the <see cref="RpcObjectId"/>. If the created
        /// instance implements <see cref="IDisposable"/> the instance will be disposed when the RPC call has finished.
        /// </param>
        /// <returns>A scoped object including the <see cref="RpcObjectRef"/> identifying the published instance. The scoped object will unpublish
        /// the service instance when disposed.</returns>
        public static IOwned <RpcObjectRef <TService> > PublishInstance <TService>(this IRpcServicePublisher servicePublisher, Func <RpcObjectId, TService> factory)
            where TService : class
        {
            if (servicePublisher is null)
            {
                throw new ArgumentNullException(nameof(servicePublisher));
            }

            IOwned <TService> CreateActivatedService(IServiceProvider?services, RpcObjectId objectId)
            {
                return(OwnedObject.Create(factory(objectId)));
            }

            return(servicePublisher.PublishInstance(CreateActivatedService));
        }
 private void SetTargeting(GameObject targetingObject, int resourceCost, OwnedObject referencedObject = null, Entity targetingEntity = null)
 {
     if (targetingObject == null && currentTargetingObject != null)
     {
         Destroy(currentTargetingObject);
     }
     currentTargetingObject       = targetingObject;
     currentTargetingResourceCost = resourceCost;
     currentTargetingReference    = referencedObject;
     currentTargetingEntity       = targetingEntity;
     if (currentTargetingObject != null)
     {
         currentTargetingCollider = currentTargetingObject.GetComponentInChildren <Collider>();
     }
     isTargetingValid = false;
 }
            internal static IOwned <TService> CreateActivatedService(IServiceProvider?services)
            {
                if (services == null)
                {
                    throw new RpcFailureException(RpcFailure.RemoteDefinitionError, "An IServiceProvider must be supplied when services are published using IServiceProvider factories.");
                }

                TService service = services.GetService <TServiceImpl>();

                if (service != null)
                {
                    return(OwnedObject.CreateUnowned(service));
                }

                service = (TService)Factory.Value(services, Array.Empty <object>());
                return(OwnedObject.Create(service));
            }
        public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(Func <IServiceProvider?, RpcObjectId, IOwned <TService> > factory)
            where TService : class
        {
            var allServices = RpcBuilderUtil.GetAllServices(typeof(TService), RpcServiceDefinitionSide.Server, true);

            this.TryRegisterServiceDefinitions(allServices, null);

            var connectionInfo = this.RetrieveConnectionInfo();

            lock (this.syncRoot)
            {
                var objectId = RpcObjectId.NewId();

                var publishedServices = this.PublishInstanceFactoryCore_Locked(allServices, objectId, factory);

                return(OwnedObject.Create(new RpcObjectRef <TService>(
                                              connectionInfo, objectId, publishedServices.ToArray()),
                                          () => this.UnpublishInstanceAsync(objectId)));
            }
        }
        /// <summary>
        /// Publishes an RPC service instance with the help of a service provider factory.
        /// </summary>
        /// <typeparam name="TService">The type of the published instance.</typeparam>
        /// <param name="factory">A factory function that should create the service instance specified by the <see cref="RpcObjectId"/>
        /// with the help of the provided <see cref="IServiceProvider"/>.</param>
        /// <returns>A scoped object including the <see cref="RpcObjectRef"/> identifying the published instance. The scoped object will unpublish
        /// the service instance when disposed.</returns>
        public static IOwned <RpcObjectRef <TService> > PublishInstance <TService>(this IRpcServicePublisher servicePublisher, Func <IServiceProvider, RpcObjectId, TService> factory)
            where TService : class
        {
            if (servicePublisher is null)
            {
                throw new ArgumentNullException(nameof(servicePublisher));
            }

            IOwned <TService> CreateActivatedService(IServiceProvider?services, RpcObjectId objectId)
            {
                if (services == null)
                {
                    throw new RpcDefinitionException("An IServiceProvider must be supplied when services are published using IServiceProvider factories.");
                }

                return(OwnedObject.CreateUnowned(factory(services, objectId)));
            }

            return(servicePublisher.PublishInstance(CreateActivatedService));
        }
        public IOwned <RpcSingletonRef <TService> > PublishSingleton <TService>(IOwned <TService> singletonService) where TService : class
        {
            if (singletonService == null)
            {
                throw new ArgumentNullException(nameof(singletonService));
            }

            var allServices = RpcBuilderUtil.GetAllServices(typeof(TService), false);

            this.TryRegisterServiceDefinitions(allServices, null);

            var publishedServices = this.VerifyPublishedServices(allServices);

            var connectionInfo = this.RetrieveConnectionInfo();

            lock (this.syncRoot)
            {
                var instanceKey = new InstanceKey(singletonService.Value);

                foreach (var serviceType in publishedServices.ServiceTypes)
                {
                    if (this.singletonServiceTypeToServiceImpl.ContainsKey(serviceType) || this.singletonServiceTypeToFactory.ContainsKey(serviceType))
                    {
                        throw new RpcDefinitionException($"A singleton for the type '{serviceType}' has already been published.");
                    }
                }

                this.singletonTypeToPublishedServices.Add(typeof(TService), publishedServices);
                var publishedInstance = new PublishedInstance(singletonService);
                foreach (var serviceType in publishedServices.ServiceTypes)
                {
                    this.singletonServiceTypeToServiceImpl.Add(serviceType, publishedInstance);
                }
            }

            return(OwnedObject.Create(new RpcSingletonRef <TService>(
                                          connectionInfo),
                                      () => this.UnpublishSingletonAsync <TService>()));
        }
    private void ScrubOwnedObject(OwnedObject ownedObject)
    {
        if (ownedObject is Entity)
        {
            Entity entity = ownedObject as Entity;
            if (ownedObject.teamId == clientGameManager.MyPlayer.teamId)
            {
                //disable visibility updates for teammates since they will always be visible
                entity.updateVisibility = false;
            }
            else
            {
                //immediately send visibility=false update to ensure everything starts hidden
                entity.VisibilityTargetDispatch(null);
            }
        }

        //remove any children that don't need to exist on a client
        foreach (Transform child in ownedObject.transform)
        {
            if (child.CompareTag(CLIENT_SELF_TAG) && ownedObject.playerId != clientGameManager.MyPlayer.id)
            {
                Destroy(child.gameObject);
            }
            else if (child.CompareTag(CLIENT_TEAM_OR_AUTHORITY_TAG) && ownedObject.teamId != clientGameManager.MyPlayer.teamId)
            {
                Destroy(child.gameObject);
            }
        }

        //disable nav mesh agents since they can cause "jiggling" on the client screen
        if (ownedObject.GetComponent <NavMeshAgent>() != null)
        {
            ownedObject.GetComponent <NavMeshAgent>().enabled = false;
        }
    }
        public RpcObjectRef <TService> GetOrPublishInstance <TService>(TService serviceInstance) where TService : class
        {
            if (serviceInstance is null)
            {
                throw new ArgumentNullException(nameof(serviceInstance));
            }

            InstanceKey key;

            lock (this.syncRoot)
            {
                key = new InstanceKey(serviceInstance);
                if (this.serviceImplToId.TryGetValue(key, out var instanceId))
                {
                    return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray()));
                }
            }

            // Not published, so we try to register the serviceInstance's service definitions
            // and then publish it.

            var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.GetType(), true);

            this.TryRegisterServiceDefinitions(allServices, null);

            var connectionInfo = this.RetrieveConnectionInfo();

            lock (this.syncRoot)
            {
                // Let's try again.
                if (this.serviceImplToId.TryGetValue(key, out var instanceId))
                {
                    // Somebody beat us to it.
                    return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray()));
                }

                var objectId             = RpcObjectId.NewId();
                var newPublishedServices = this.PublishInstanceCore_Locked(allServices, OwnedObject.CreateUnowned(serviceInstance), objectId, true);
                return(new RpcObjectRef <TService>(connectionInfo, objectId, newPublishedServices.ToArray()));
            }
        }