Пример #1
0
        // local authority client sends sync message to server for broadcasting
        protected virtual void OnClientToServerSync(Vector3?position, Quaternion?rotation, Vector3?scale)
        {
            // only apply if in client authority mode
            if (!clientAuthority)
            {
                return;
            }

            // protect against ever growing buffer size attacks
            if (serverBuffer.Count >= bufferSizeLimit)
            {
                return;
            }

            // only player owned objects (with a connection) can send to
            // server. we can get the timestamp from the connection.
            double timestamp = connectionToClient.remoteTimeStamp;

            // position, rotation, scale can have no value if same as last time.
            // saves bandwidth.
            // but we still need to feed it to snapshot interpolation. we can't
            // just have gaps in there if nothing has changed. for example, if
            //   client sends snapshot at t=0
            //   client sends nothing for 10s because not moved
            //   client sends snapshot at t=10
            // then the server would assume that it's one super slow move and
            // replay it for 10 seconds.
            if (!position.HasValue)
            {
                position = targetComponent.localPosition;
            }
            if (!rotation.HasValue)
            {
                rotation = targetComponent.localRotation;
            }
            if (!scale.HasValue)
            {
                scale = targetComponent.localScale;
            }

            // construct snapshot with batch timestamp to save bandwidth
            NTSnapshot snapshot = new NTSnapshot(
                timestamp,
                NetworkTime.localTime,
                position.Value, rotation.Value, scale.Value
                );

            // add to buffer (or drop if older than first element)
            SnapshotInterpolation.InsertIfNewEnough(snapshot, serverBuffer);
        }
Пример #2
0
        // server broadcasts sync message to all clients
        protected virtual void OnServerToClientSync(Vector3?position, Quaternion?rotation, Vector3?scale)
        {
            // in host mode, the server sends rpcs to all clients.
            // the host client itself will receive them too.
            // -> host server is always the source of truth
            // -> we can ignore any rpc on the host client
            // => otherwise host objects would have ever growing clientBuffers
            // (rpc goes to clients. if isServer is true too then we are host)
            if (isServer)
            {
                return;
            }

            // don't apply for local player with authority
            if (IsClientWithAuthority)
            {
                return;
            }

            // protect against ever growing buffer size attacks
            if (clientBuffer.Count >= bufferSizeLimit)
            {
                return;
            }

            // on the client, we receive rpcs for all entities.
            // not all of them have a connectionToServer.
            // but all of them go through NetworkClient.connection.
            // we can get the timestamp from there.
            double timestamp = NetworkClient.connection.remoteTimeStamp;

            // position, rotation, scale can have no value if same as last time.
            // saves bandwidth.
            // but we still need to feed it to snapshot interpolation. we can't
            // just have gaps in there if nothing has changed. for example, if
            //   client sends snapshot at t=0
            //   client sends nothing for 10s because not moved
            //   client sends snapshot at t=10
            // then the server would assume that it's one super slow move and
            // replay it for 10 seconds.
            if (!position.HasValue)
            {
                position = targetComponent.localPosition;
            }
            if (!rotation.HasValue)
            {
                rotation = targetComponent.localRotation;
            }
            if (!scale.HasValue)
            {
                scale = targetComponent.localScale;
            }

            // construct snapshot with batch timestamp to save bandwidth
            NTSnapshot snapshot = new NTSnapshot(
                timestamp,
                NetworkTime.localTime,
                position.Value, rotation.Value, scale.Value
                );

            // add to buffer (or drop if older than first element)
            SnapshotInterpolation.InsertIfNewEnough(snapshot, clientBuffer);
        }