Example #1
0
 private void OnServerRpcReply(INetworkPlayer player, ServerRpcReply reply)
 {
     // find the callback that was waiting for this and invoke it.
     if (callbacks.TryGetValue(reply.replyId, out Action <NetworkReader> action))
     {
         callbacks.Remove(replyId);
         using (PooledNetworkReader reader = NetworkReaderPool.GetReader(reply.payload))
         {
             reader.ObjectLocator = Client.World;
             action(reader);
         }
     }
     else
     {
         throw new MethodAccessException("Received reply but no handler was registered");
     }
 }
Example #2
0
        void ApplySpawnPayload(NetworkIdentity identity, SpawnMessage msg)
        {
            if (msg.assetId != Guid.Empty)
            {
                identity.AssetId = msg.assetId;
            }

            if (!identity.gameObject.activeSelf)
            {
                identity.gameObject.SetActive(true);
            }

            // apply local values for VR support
            identity.transform.localPosition = msg.position;
            identity.transform.localRotation = msg.rotation;
            identity.transform.localScale    = msg.scale;
            identity.HasAuthority            = msg.isOwner;
            identity.NetId  = msg.netId;
            identity.Client = Client;
            identity.ClientObjectManager = this;

            if (msg.isLocalPlayer)
            {
                InternalAddPlayer(identity);
            }

            // deserialize components if any payload
            // (Count is 0 if there were no components)
            if (msg.payload.Count > 0)
            {
                using (PooledNetworkReader payloadReader = NetworkReaderPool.GetReader(msg.payload))
                {
                    identity.OnDeserializeAllSafely(payloadReader, true);
                }
            }

            SpawnedObjects[msg.netId] = identity;

            // objects spawned as part of initial state are started on a second pass
            identity.NotifyAuthority();
            identity.StartClient();
            CheckForLocalPlayer(identity);
        }
Example #3
0
        private void OnServerRpc(INetworkPlayer player, uint netId, int componentIndex, int functionIndex, ArraySegment <byte> payload, int replyId)
        {
            if (!Server.World.TryGetIdentity(netId, out var identity))
            {
                if (logger.WarnEnabled())
                {
                    logger.LogWarning($"Spawned object not found when handling ServerRpc message [netId={netId}]");
                }
                return;
            }

            var behaviour = identity.NetworkBehaviours[componentIndex];

            var remoteCall = behaviour.remoteCallCollection.Get(functionIndex);

            if (remoteCall.InvokeType != RpcInvokeType.ServerRpc)
            {
                throw new MethodInvocationException($"Invalid ServerRpc for index {functionIndex}");
            }

            // ServerRpcs can be for player objects, OR other objects with client-authority
            // -> so if this connection's controller has a different netId then
            //    only allow the ServerRpc if clientAuthorityOwner
            if (remoteCall.RequireAuthority && identity.Owner != player)
            {
                if (logger.WarnEnabled())
                {
                    logger.LogWarning($"ServerRpc for object without authority [netId={netId}]");
                }
                return;
            }

            if (logger.LogEnabled())
            {
                logger.Log($"OnServerRpcMessage for netId={netId} conn={player}");
            }

            using (var reader = NetworkReaderPool.GetReader(payload, Server.World))
            {
                remoteCall.Invoke(reader, behaviour, player, replyId);
            }
        }
Example #4
0
        void CmdOnAnimationServerMessage(int stateHash, float normalizedTime, int layerId, float weight, byte[] parameters)
        {
            // Ignore messages from client if not in client authority mode
            if (!ClientAuthority)
            {
                return;
            }

            if (logger.LogEnabled())
            {
                logger.Log("OnAnimationMessage for netId=" + NetId);
            }

            // handle and broadcast
            using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters))
            {
                HandleAnimMsg(stateHash, normalizedTime, layerId, weight, networkReader);
                RpcOnAnimationClientMessage(stateHash, normalizedTime, layerId, weight, parameters);
            }
        }
Example #5
0
        void OnUpdateVarsMessage(UpdateVarsMessage msg)
        {
            if (logger.LogEnabled())
            {
                logger.Log("ClientScene.OnUpdateVarsMessage " + msg.netId);
            }

            if (objectLocator.TryGetIdentity(msg.netId, out NetworkIdentity localObject))
            {
                using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
                    localObject.OnDeserializeAll(networkReader, false);
            }
            else
            {
                if (logger.WarnEnabled())
                {
                    logger.LogWarning("Did not find target for sync message for " + msg.netId + " . Note: this can be completely normal because UDP messages may arrive out of order, so this message might have arrived after a Destroy message.");
                }
            }
        }
Example #6
0
        public void ReadBytesCountTooBigTest()
        {
            // calling ReadBytes with a count bigger than what is in Reader
            // should throw an exception
            byte[] bytes = { 0x00, 0x01 };

            using (PooledNetworkReader reader = NetworkReaderPool.GetReader(bytes))
            {
                try
                {
                    reader.ReadBytes(bytes, bytes.Length + 1);
                    // BAD: IF WE GOT HERE, THEN NO EXCEPTION WAS THROWN
                    Assert.Fail();
                }
                catch (EndOfStreamException)
                {
                    // GOOD
                }
            }
        }
Example #7
0
        public void ShrinkCapacity()
        {
            NetworkReaderPool.Capacity = 2;

            // get Reader and recycle so we have 2 in there, hence 'next' is at limit
            PooledNetworkReader a = NetworkReaderPool.GetReader(default(ArraySegment <byte>));
            PooledNetworkReader b = NetworkReaderPool.GetReader(default(ArraySegment <byte>));

            NetworkReaderPool.Recycle(a);
            NetworkReaderPool.Recycle(b);

            // shrink
            NetworkReaderPool.Capacity = 1;

            // get one. should return the only one which is still in there.
            PooledNetworkReader c = NetworkReaderPool.GetReader(default(ArraySegment <byte>));

            Assert.That(c, !Is.Null);
            Assert.That(c == a || c == b);
        }
Example #8
0
        /// <summary>
        /// Handle ServerRpc from specific player, this could be one of multiple players on a single client
        /// </summary>
        /// <param name="conn"></param>
        /// <param name="msg"></param>
        void OnServerRpcMessage(INetworkConnection conn, ServerRpcMessage msg)
        {
            if (!SpawnedObjects.TryGetValue(msg.netId, out NetworkIdentity identity) || identity is null)
            {
                if (logger.WarnEnabled())
                {
                    logger.LogWarning("Spawned object not found when handling ServerRpc message [netId=" + msg.netId + "]");
                }
                return;
            }
            Skeleton skeleton = RemoteCallHelper.GetSkeleton(msg.functionHash);

            if (skeleton.invokeType != MirageInvokeType.ServerRpc)
            {
                throw new MethodInvocationException($"Invalid ServerRpc for id {msg.functionHash}");
            }

            // ServerRpcs can be for player objects, OR other objects with client-authority
            // -> so if this connection's controller has a different netId then
            //    only allow the ServerRpc if clientAuthorityOwner
            if (skeleton.cmdRequireAuthority && identity.ConnectionToClient != conn)
            {
                if (logger.WarnEnabled())
                {
                    logger.LogWarning("ServerRpc for object without authority [netId=" + msg.netId + "]");
                }
                return;
            }

            if (logger.LogEnabled())
            {
                logger.Log("OnServerRpcMessage for netId=" + msg.netId + " conn=" + conn);
            }

            using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
            {
                networkReader.ObjectLocator = this;
                identity.HandleRemoteCall(skeleton, msg.componentIndex, networkReader, conn, msg.replyId);
            }
        }
Example #9
0
        internal void OnRpcMessage(RpcMessage msg)
        {
            if (logger.LogEnabled())
            {
                logger.Log("ClientScene.OnRPCMessage hash:" + msg.functionHash + " netId:" + msg.netId);
            }

            Skeleton skeleton = RemoteCallHelper.GetSkeleton(msg.functionHash);

            if (skeleton.invokeType != RpcInvokeType.ClientRpc)
            {
                throw new MethodInvocationException($"Invalid RPC call with id {msg.functionHash}");
            }
            if (Client.World.TryGetIdentity(msg.netId, out NetworkIdentity identity))
            {
                using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(msg.payload))
                {
                    networkReader.ObjectLocator = Client.World;
                    identity.HandleRemoteCall(skeleton, msg.componentIndex, networkReader);
                }
            }
        }
Example #10
0
        void CmdClientToServerSync(byte[] payload)
        {
            // Ignore messages from client if not in client authority mode
            if (!ClientAuthority)
            {
                return;
            }

            // deserialize payload
            using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(payload))
                DeserializeFromReader(networkReader);

            // server-only mode does no interpolation to save computations,
            // but let's set the position directly
            if (IsServer && !IsClient)
            {
                ApplyPositionRotationScale(goal.LocalPosition, goal.LocalRotation, goal.LocalScale);
            }

            // set dirty so that OnSerialize broadcasts it
            SetDirtyBit(1UL);
        }
Example #11
0
        public void PoolReUsesReadersUpToSizeLimit()
        {
            NetworkReaderPool.Capacity = 1;

            // get 2 Readers
            PooledNetworkReader a = NetworkReaderPool.GetReader(default(ArraySegment <byte>));
            PooledNetworkReader b = NetworkReaderPool.GetReader(default(ArraySegment <byte>));

            // recycle all
            NetworkReaderPool.Recycle(a);
            NetworkReaderPool.Recycle(b);

            // get 2 new ones
            PooledNetworkReader c = NetworkReaderPool.GetReader(default(ArraySegment <byte>));
            PooledNetworkReader d = NetworkReaderPool.GetReader(default(ArraySegment <byte>));

            // exactly one should be reused, one should be new
            bool cReused = c == a || c == b;
            bool dReused = d == a || d == b;

            Assert.That((cReused && !dReused) ||
                        (!cReused && dReused));
        }
Example #12
0
 void RpcOnAnimationParametersClientMessage(byte[] parameters)
 {
     using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters))
         HandleAnimParamsMsg(networkReader);
 }
Example #13
0
 void RpcOnAnimationClientMessage(int stateHash, float normalizedTime, int layerId, float weight, byte[] parameters)
 {
     using (PooledNetworkReader networkReader = NetworkReaderPool.GetReader(parameters))
         HandleAnimMsg(stateHash, normalizedTime, layerId, weight, networkReader);
 }
Example #14
0
 private void RpcOnAnimationParametersClientMessage(ArraySegment <byte> parameters)
 {
     using (var networkReader = NetworkReaderPool.GetReader(parameters, null))
         HandleAnimParamsMsg(networkReader);
 }
Example #15
0
 private void RpcOnAnimationClientMessage(int stateHash, float normalizedTime, int layerId, float weight, ArraySegment <byte> parameters)
 {
     using (var networkReader = NetworkReaderPool.GetReader(parameters, null))
         HandleAnimMsg(stateHash, normalizedTime, layerId, weight, networkReader);
 }
Example #16
0
 public void Dispose()
 {
     NetworkReaderPool.Recycle(this);
 }