protected void ProcessAcksForConnection( Context context, Context.ConnectionData connectionData )
    {
        Profiler.BeginSample( "ProcessAcksForConnection" );

        int numAcks = 0;

        connectionData.connection.GetAcks( ref acks, ref numAcks );

        for ( int i = 0; i < numAcks; ++i )
        {
            int packetNumCubeStates;
            int[] packetCubeIds;
            CubeState[] packetCubeState;

            if ( connectionData.sendDeltaBuffer.GetPacketData( acks[i], context.GetResetSequence(), out packetNumCubeStates, out packetCubeIds, out packetCubeState ) )
            {
                for ( int j = 0; j < packetNumCubeStates; ++j )
                {
                    context.UpdateMostRecentAckedState( connectionData, packetCubeIds[j], acks[i], context.GetResetSequence(), ref packetCubeState[j] );
                }
            }
        }

        Profiler.EndSample();
    }
    void ProcessPacketsFromServer()
    {
        Packet packet;

        while ((packet = Net.ReadPacket()) != null)
        {
            if (packet.SenderID != hostUserId)
            {
                continue;
            }

            packet.ReadBytes(readBuffer);

            byte packetType = readBuffer[0];

            if ((state == GuestState.Connecting || state == GuestState.Connected) && packetType == (byte)PacketSerializer.PacketType.ServerInfo)
            {
                ProcessServerInfoPacket(readBuffer);
            }

            if (!IsConnectedToServer())
            {
                continue;
            }

            if (packetType == (byte)PacketSerializer.PacketType.StateUpdate)
            {
                if (enableJitterBuffer)
                {
                    AddStateUpdatePacketToJitterBuffer(context, context.GetClientConnectionData(), readBuffer);
                }
                else
                {
                    ProcessStateUpdatePacket(context.GetClientConnectionData(), readBuffer);
                }
            }

            timeLastPacketReceived = renderTime;
        }

        // process state update from jitter buffer

        if (enableJitterBuffer && IsConnectedToServer())
        {
            ProcessStateUpdateFromJitterBuffer(context, context.GetClientConnectionData(), 0, clientIndex, enableJitterBuffer && renderTime > timeConnected + 0.25);
        }

        // advance remote frame number

        if (IsConnectedToServer())
        {
            Context.ConnectionData connectionData = context.GetClientConnectionData();

            if (!connectionData.firstRemotePacket)
            {
                connectionData.remoteFrameNumber++;
            }
        }
    }
    protected void DetermineNotChangedAndDeltas( Context context, Context.ConnectionData connectionData, ushort currentSequence, int numCubes, ref int[] cubeIds, ref bool[] notChanged, ref bool[] hasDelta, ref ushort[] baselineSequence, ref CubeState[] cubeState, ref CubeDelta[] cubeDelta )
    {
        Profiler.BeginSample( "DeterminedNotChangedAndDeltas" );

#if !DISABLE_DELTA_COMPRESSION
        CubeState baselineCubeState = CubeState.defaults;
#endif // #if !DISABLE_DELTA_COMPRESSION

        for ( int i = 0; i < numCubes; ++i )
        {
            notChanged[i] = false;
            hasDelta[i] = false;

#if !DISABLE_DELTA_COMPRESSION

#if DEBUG_DELTA_COMPRESSION
            cubeDelta[i].absolute_position_x = cubeState[i].position_x;
            cubeDelta[i].absolute_position_y = cubeState[i].position_y;
            cubeDelta[i].absolute_position_z = cubeState[i].position_z;
#endif // #if DEBUG_DELTA_COMPRESSION

            if ( context.GetMostRecentAckedState( connectionData, cubeIds[i], ref baselineSequence[i], context.GetResetSequence(), ref baselineCubeState ) )
            {
                if ( Network.Util.BaselineDifference( currentSequence, baselineSequence[i] ) > Constants.MaxBaselineDifference )
                {
                    // baseline is too far behind => send the cube state absolute.
                    continue;
                }

                if ( baselineCubeState.Equals( cubeState[i] ) )
                {
                    notChanged[i] = true;
                }
                else
                {
                    hasDelta[i] = true;

                    cubeDelta[i].position_delta_x = cubeState[i].position_x - baselineCubeState.position_x;
                    cubeDelta[i].position_delta_y = cubeState[i].position_y - baselineCubeState.position_y;
                    cubeDelta[i].position_delta_z = cubeState[i].position_z - baselineCubeState.position_z;

                    cubeDelta[i].linear_velocity_delta_x = cubeState[i].linear_velocity_x - baselineCubeState.linear_velocity_x;
                    cubeDelta[i].linear_velocity_delta_y = cubeState[i].linear_velocity_y - baselineCubeState.linear_velocity_y;
                    cubeDelta[i].linear_velocity_delta_z = cubeState[i].linear_velocity_z - baselineCubeState.linear_velocity_z;

                    cubeDelta[i].angular_velocity_delta_x = cubeState[i].angular_velocity_x - baselineCubeState.angular_velocity_x;
                    cubeDelta[i].angular_velocity_delta_y = cubeState[i].angular_velocity_y - baselineCubeState.angular_velocity_y;
                    cubeDelta[i].angular_velocity_delta_z = cubeState[i].angular_velocity_z - baselineCubeState.angular_velocity_z;
                }
            }

#endif // #if !DISABLE_DELTA_COMPRESSION
        }

        Profiler.EndSample();
    }
Example #4
0
    void ProcessAcks()
    {
        Profiler.BeginSample("Process Acks");
        {
            Context.ConnectionData connectionData = context.GetClientConnectionData();

            ProcessAcksForConnection(context, connectionData);
        }

        Profiler.EndSample();
    }
        public static void SetContext <T>(this ObservableList <T> ts, IMongoDatabase database, string collection)
        {
            var mc = new Context.ConnectionData {
                Database = database, Collection = collection
            };

            if (ts.Properties.ContainsKey("MongoContext"))
            {
                ts.Properties.Remove("MongoContext");
            }
            ts.Properties.Add("MongoContext", mc);
        }
Example #6
0
    public void ProcessStateUpdatePacket(byte[] packetData, int fromClientIndex)
    {
        int readNumAvatarStates = 0;
        int readNumStateUpdates = 0;

        Context.ConnectionData connectionData = context.GetServerConnectionData(fromClientIndex);

        Network.PacketHeader readPacketHeader;

        if (ReadStateUpdatePacket(packetData, out readPacketHeader, out readNumAvatarStates, ref readAvatarStateQuantized, out readNumStateUpdates, ref readCubeIds, ref readNotChanged, ref readHasDelta, ref readPerfectPrediction, ref readHasPredictionDelta, ref readBaselineSequence, ref readCubeState, ref readCubeDelta, ref readPredictionDelta))
        {
            // unquantize avatar states

            for (int i = 0; i < readNumAvatarStates; ++i)
            {
                AvatarState.Unquantize(ref readAvatarStateQuantized[i], out readAvatarState[i]);
            }

            // ignore any updates from a client with a different reset sequence #

            if (context.GetResetSequence() != readPacketHeader.resetSequence)
            {
                return;
            }

            // decode the predicted cube states from baselines

            DecodePrediction(connectionData.receiveDeltaBuffer, readPacketHeader.sequence, context.GetResetSequence(), readNumStateUpdates, ref readCubeIds, ref readPerfectPrediction, ref readHasPredictionDelta, ref readBaselineSequence, ref readCubeState, ref readPredictionDelta);

            // decode the not changed and delta cube states from baselines

            DecodeNotChangedAndDeltas(connectionData.receiveDeltaBuffer, context.GetResetSequence(), readNumStateUpdates, ref readCubeIds, ref readNotChanged, ref readHasDelta, ref readBaselineSequence, ref readCubeState, ref readCubeDelta);

            // add the cube states to the receive delta buffer

            AddPacketToDeltaBuffer(ref connectionData.receiveDeltaBuffer, readPacketHeader.sequence, context.GetResetSequence(), readNumStateUpdates, ref readCubeIds, ref readCubeState);

            // apply the state updates to cubes

            context.ApplyCubeStateUpdates(readNumStateUpdates, ref readCubeIds, ref readCubeState, fromClientIndex, 0, enableJitterBuffer);

            // apply avatar state updates

            context.ApplyAvatarStateUpdates(readNumAvatarStates, ref readAvatarState, fromClientIndex, 0);

            // process the packet header

            connectionData.connection.ProcessPacketHeader(ref readPacketHeader);
        }
    }
    protected void AddStateUpdatePacketToJitterBuffer( Context context, Context.ConnectionData connectionData, byte[] packetData )
    {
        long packetFrameNumber;

        if ( connectionData.jitterBuffer.AddStateUpdatePacket( packetData, connectionData.receiveDeltaBuffer, context.GetResetSequence(), out packetFrameNumber ) )
        {
            if ( connectionData.firstRemotePacket )
            {
                connectionData.firstRemotePacket = false;
                connectionData.remoteFrameNumber = packetFrameNumber - Constants.NumJitterBufferFrames;
                connectionData.jitterBuffer.Start( connectionData.remoteFrameNumber );
            }
        }
    }
Example #8
0
    void SendPacketToServer()
    {
        if (!IsConnectedToServer())
        {
            return;
        }

        Context.ConnectionData connectionData = context.GetClientConnectionData();

        byte[] packetData = GenerateStateUpdatePacket(connectionData, (float)(physicsTime - renderTime));

        Net.SendPacket(hostUserId, packetData, SendPolicy.Unreliable);

        timeLastPacketSent = renderTime;
    }
Example #9
0
    void ProcessAcks()
    {
        Profiler.BeginSample("Process Acks");
        {
            for (int clientIndex = 1; clientIndex < Constants.MaxClients; ++clientIndex)
            {
                for (int i = 1; i < Constants.MaxClients; ++i)
                {
                    Context.ConnectionData connectionData = context.GetServerConnectionData(i);

                    ProcessAcksForConnection(context, connectionData);
                }
            }
        }

        Profiler.EndSample();
    }
    protected void ProcessStateUpdateFromJitterBuffer( Context context, Context.ConnectionData connectionData, int fromClientIndex, int toClientIndex, bool applySmoothing = true )
    {
        if ( connectionData.remoteFrameNumber < 0 )
            return;

        JitterBufferEntry entry = connectionData.jitterBuffer.GetEntry( (uint) connectionData.remoteFrameNumber );
        if ( entry == null )
            return;

        if ( fromClientIndex == 0 )
        {
            // server -> client

            // Ignore updates from before the last reset.
            if ( Network.Util.SequenceGreaterThan( context.GetResetSequence(), entry.packetHeader.resetSequence ) )
                return;

            // Reset if the server reset sequence is more recent than ours.
            if ( Network.Util.SequenceGreaterThan( entry.packetHeader.resetSequence, context.GetResetSequence() ) )
            {
                context.Reset();
                context.SetResetSequence( entry.packetHeader.resetSequence );
            }
        }
        else
        {
            // client -> server

            // Ignore any updates from the client with a different reset sequence #
            if ( context.GetResetSequence() != entry.packetHeader.resetSequence )
                return;
        }

        // add the cube states to the receive delta buffer

        AddPacketToDeltaBuffer( ref connectionData.receiveDeltaBuffer, entry.packetHeader.sequence, context.GetResetSequence(), entry.numStateUpdates, ref entry.cubeIds, ref entry.cubeState );

        // apply the state updates to cubes

        context.ApplyCubeStateUpdates( entry.numStateUpdates, ref entry.cubeIds, ref entry.cubeState, fromClientIndex, toClientIndex, applySmoothing );

        // process the packet header (handles acks)

        connectionData.connection.ProcessPacketHeader( ref entry.packetHeader );
    }
Example #11
0
    void SendPacketsToConnectedClients()
    {
        for (int clientIndex = 1; clientIndex < Constants.MaxClients; ++clientIndex)
        {
            if (!IsClientConnected(clientIndex))
            {
                continue;
            }

            Context.ConnectionData connectionData = context.GetServerConnectionData(clientIndex);

            byte[] packetData = GenerateStateUpdatePacket(connectionData, clientIndex, (float)(physicsTime - renderTime));

            Net.SendPacket(client[clientIndex].userId, packetData, SendPolicy.Unreliable);

            client[clientIndex].timeLastPacketSent = renderTime;
        }
    }
Example #12
0
    public byte[] GenerateStateUpdatePacket(Context.ConnectionData connectionData, float avatarSampleTimeOffset)
    {
        Profiler.BeginSample("GenerateStateUpdatePacket");

        int maxStateUpdates = Math.Min(Constants.NumCubes, Constants.MaxStateUpdates);

        int numStateUpdates = maxStateUpdates;

        context.UpdateCubePriority();

        context.GetMostImportantCubeStateUpdates(connectionData, ref numStateUpdates, ref cubeIds, ref cubeState);

        Network.PacketHeader writePacketHeader;

        connectionData.connection.GeneratePacketHeader(out writePacketHeader);

        writePacketHeader.resetSequence = context.GetResetSequence();

        writePacketHeader.frameNumber = (uint)frameNumber;

        writePacketHeader.avatarSampleTimeOffset = avatarSampleTimeOffset;

        DetermineNotChangedAndDeltas(context, connectionData, writePacketHeader.sequence, numStateUpdates, ref cubeIds, ref notChanged, ref hasDelta, ref baselineSequence, ref cubeState, ref cubeDelta);

        DeterminePrediction(context, connectionData, writePacketHeader.sequence, numStateUpdates, ref cubeIds, ref notChanged, ref hasDelta, ref perfectPrediction, ref hasPredictionDelta, ref baselineSequence, ref cubeState, ref predictionDelta);

        int numAvatarStates = 1;

        localAvatar.GetComponent <Avatar>().GetAvatarState(out avatarState[0]);

        AvatarState.Quantize(ref avatarState[0], out avatarStateQuantized[0]);

        WriteStateUpdatePacket(ref writePacketHeader, numAvatarStates, ref avatarStateQuantized, numStateUpdates, ref cubeIds, ref notChanged, ref hasDelta, ref perfectPrediction, ref hasPredictionDelta, ref baselineSequence, ref cubeState, ref cubeDelta, ref predictionDelta);

        byte[] packetData = writeStream.GetData();

        AddPacketToDeltaBuffer(ref connectionData.sendDeltaBuffer, writePacketHeader.sequence, context.GetResetSequence(), numStateUpdates, ref cubeIds, ref cubeState);

        context.ResetCubePriority(connectionData, numStateUpdates, cubeIds);

        Profiler.EndSample();

        return(packetData);
    }
Example #13
0
    new void Update()
    {
        base.Update();

        // apply host avatar per-remote client at render time with interpolation

        for (int i = 1; i < Constants.MaxClients; ++i)
        {
            if (client[i].state != ClientState.Connected)
            {
                continue;
            }

            Context.ConnectionData connectionData = context.GetServerConnectionData(i);

            int fromClientIndex = i;
            int toClientIndex   = 0;

            int    numInterpolatedAvatarStates;
            ushort avatarResetSequence;
            if (connectionData.jitterBuffer.GetInterpolatedAvatarState(ref interpolatedAvatarState, out numInterpolatedAvatarStates, out avatarResetSequence))
            {
                if (avatarResetSequence == context.GetResetSequence())
                {
                    context.ApplyAvatarStateUpdates(numInterpolatedAvatarStates, ref interpolatedAvatarState, fromClientIndex, toClientIndex);
                }
            }
        }

        // advance jitter buffer time

        for (int i = 1; i < Constants.MaxClients; ++i)
        {
            if (client[i].state == ClientState.Connected)
            {
                context.GetServerConnectionData(i).jitterBuffer.AdvanceTime(Time.deltaTime);
            }
        }

        // check for timeouts

        CheckForTimeouts();
    }
    void ProcessAcks()
    {
        Profiler.BeginSample("Process Acks");
        {
            // host context
            {
                Context context = GetContext(0);

                if (context)
                {
                    for (int i = 1; i < Constants.MaxClients; ++i)
                    {
                        Context.ConnectionData connectionData = context.GetServerConnectionData(i);

                        ProcessAcksForConnection(context, connectionData);
                    }
                }
            }

            // guest contexts

            for (int clientIndex = 1; clientIndex < Constants.MaxClients; ++clientIndex)
            {
                Context context = GetContext(clientIndex);

                if (!context)
                {
                    continue;
                }

                Context.ConnectionData connectionData = context.GetClientConnectionData();

                ProcessAcksForConnection(context, connectionData);
            }
        }

        Profiler.EndSample();
    }
Example #15
0
    void ProcessPlayerScored(PacketSerializer.GameEvent eventType, ushort senderId, ushort targetId)
    {
        //handle locally
        ScoreManager.HandleScore(senderId, targetId);

        if (targetId == 0)      //server
        {
            SFX.Play(SFXType.SCORED_OTHER);
        }
        else if (senderId == 0)
        {
            SFX.Play(SFXType.SCORED_SELF);
        }
        else
        {
            SFX.Play(SFXType.SCORED_UNRELATED);
        }

        ushort[] perClientScores = ScoreManager.GetScores();

        //send to clients other than myself
        byte[] packetData = GeneratePlayerScoredPacket(eventType, senderId, targetId, perClientScores);

        for (int clientIndex = 1; clientIndex < Constants.MaxClients; ++clientIndex)
        {
            if (!IsClientConnected(clientIndex))
            {
                continue;
            }

            Context.ConnectionData connectionData = context.GetServerConnectionData(clientIndex);

            Net.SendPacket(client[clientIndex].userId, packetData, SendPolicy.Unreliable);

            client[clientIndex].timeLastPacketSent = renderTime;
        }
    }
    new void Update()
    {
        base.Update();

        if (Input.GetKeyDown("return"))
        {
            hostContext.TestSmoothing();
        }

        // apply host avatar state at render time with interpolation

        for (int i = 1; i < Constants.MaxClients; ++i)
        {
            Context context = hostContext;

            Context.ConnectionData connectionData = context.GetServerConnectionData(i);

            int fromClientIndex = i;
            int toClientIndex   = 0;

            int    numInterpolatedAvatarStates;
            ushort avatarResetSequence;
            if (connectionData.jitterBuffer.GetInterpolatedAvatarState(ref interpolatedAvatarState, out numInterpolatedAvatarStates, out avatarResetSequence))
            {
                if (avatarResetSequence == context.GetResetSequence())
                {
                    context.ApplyAvatarStateUpdates(numInterpolatedAvatarStates, ref interpolatedAvatarState, fromClientIndex, toClientIndex);
                }
            }
        }

        // apply guest avatar state at render time with interpolation

        {
            Context context = guestContext;

            Context.ConnectionData connectionData = context.GetClientConnectionData();

            int fromClientIndex = 0;
            int toClientIndex   = 1;

            int    numInterpolatedAvatarStates;
            ushort avatarResetSequence;
            if (connectionData.jitterBuffer.GetInterpolatedAvatarState(ref interpolatedAvatarState, out numInterpolatedAvatarStates, out avatarResetSequence))
            {
                if (avatarResetSequence == context.GetResetSequence())
                {
                    context.ApplyAvatarStateUpdates(numInterpolatedAvatarStates, ref interpolatedAvatarState, fromClientIndex, toClientIndex);
                }
            }
        }

        // advance jitter buffer time

        guestContext.GetClientConnectionData().jitterBuffer.AdvanceTime(Time.deltaTime);

        for (int i = 1; i < Constants.MaxClients; ++i)
        {
            hostContext.GetServerConnectionData(i).jitterBuffer.AdvanceTime(Time.deltaTime);
        }
    }
Example #17
0
    new void Update()
    {
        base.Update();

        if (Input.GetKeyDown("space"))
        {
            Debug.Log("Forcing reconnect");

            successfullyConnected = false;

            RetryUntilConnectedToServer();
        }

        if (state == GuestState.Matchmaking && timeMatchmakingStarted + 30.0 < renderTime)
        {
            Debug.Log("No result from matchmaker");

            RetryUntilConnectedToServer();

            return;
        }

        if (state == GuestState.Connecting && !acceptedConnectionRequest)
        {
            if (hostUserId != 0 && connectionRequests.Contains(hostUserId))
            {
                Debug.Log("Accepting connection request from host");

                Net.Accept(hostUserId);

                acceptedConnectionRequest = true;
            }
        }

        if (state == GuestState.Connected)
        {
            // apply guest avatar state at render time with interpolation

            Context.ConnectionData connectionData = context.GetClientConnectionData();
            int    numInterpolatedAvatarStates;
            ushort avatarResetSequence;
            if (connectionData.jitterBuffer.GetInterpolatedAvatarState(ref interpolatedAvatarState, out numInterpolatedAvatarStates, out avatarResetSequence))
            {
                if (avatarResetSequence == context.GetResetSequence())
                {
                    context.ApplyAvatarStateUpdates(numInterpolatedAvatarStates, ref interpolatedAvatarState, 0, clientIndex);
                }
            }

            // advance jitter buffer time

            context.GetClientConnectionData().jitterBuffer.AdvanceTime(Time.deltaTime);
        }

        if (state == GuestState.WaitingForRetry && timeRetryStarted + RetryTime < renderTime)
        {
            StartMatchmaking();
            return;
        }

        CheckForTimeouts();
    }
Example #18
0
    public void ProcessStateUpdatePacket(Context.ConnectionData connectionData, byte[] packetData)
    {
        Profiler.BeginSample("ProcessStateUpdatePacket");

        int readNumAvatarStates = 0;
        int readNumStateUpdates = 0;

        Network.PacketHeader readPacketHeader;

        if (ReadStateUpdatePacket(packetData, out readPacketHeader, out readNumAvatarStates, ref readAvatarStateQuantized, out readNumStateUpdates, ref readCubeIds, ref readNotChanged, ref readHasDelta, ref readPerfectPrediction, ref readHasPredictionDelta, ref readBaselineSequence, ref readCubeState, ref readCubeDelta, ref readPredictionDelta))
        {
            // unquantize avatar states

            for (int i = 0; i < readNumAvatarStates; ++i)
            {
                AvatarState.Unquantize(ref readAvatarStateQuantized[i], out readAvatarState[i]);
            }

            // ignore updates from before the last server reset

            if (Network.Util.SequenceGreaterThan(context.GetResetSequence(), readPacketHeader.resetSequence))
            {
                return;
            }

            // reset if the server reset sequence is more recent than ours

            if (Network.Util.SequenceGreaterThan(readPacketHeader.resetSequence, context.GetResetSequence()))
            {
                context.Reset();
                context.SetResetSequence(readPacketHeader.resetSequence);
            }

            // decode the predicted cube states from baselines

            DecodePrediction(connectionData.receiveDeltaBuffer, readPacketHeader.sequence, context.GetResetSequence(), readNumStateUpdates, ref readCubeIds, ref readPerfectPrediction, ref readHasPredictionDelta, ref readBaselineSequence, ref readCubeState, ref readPredictionDelta);

            // decode the not changed and delta cube states from baselines

            DecodeNotChangedAndDeltas(connectionData.receiveDeltaBuffer, context.GetResetSequence(), readNumStateUpdates, ref readCubeIds, ref readNotChanged, ref readHasDelta, ref readBaselineSequence, ref readCubeState, ref readCubeDelta);

            // add the cube states to the receive delta buffer

            AddPacketToDeltaBuffer(ref connectionData.receiveDeltaBuffer, readPacketHeader.sequence, context.GetResetSequence(), readNumStateUpdates, ref readCubeIds, ref readCubeState);

            // apply the state updates to cubes

            int fromClientIndex = 0;
            int toClientIndex   = clientIndex;

            context.ApplyCubeStateUpdates(readNumStateUpdates, ref readCubeIds, ref readCubeState, fromClientIndex, toClientIndex, enableJitterBuffer && renderTime > timeConnected + 0.25);

            // apply avatar state updates

            context.ApplyAvatarStateUpdates(readNumAvatarStates, ref readAvatarState, fromClientIndex, toClientIndex);

            // process the packet header

            connectionData.connection.ProcessPacketHeader(ref readPacketHeader);
        }

        Profiler.EndSample();
    }
 protected void UpdateJitterBuffer( Context context, Context.ConnectionData connectionData )
 {
     if ( !connectionData.firstRemotePacket )
         connectionData.remoteFrameNumber++;
 }
    protected void DeterminePrediction( Context context, Context.ConnectionData connectionData, ushort currentSequence, int numCubes, ref int[] cubeIds, ref bool[] notChanged, ref bool[] hasDelta, ref bool[] perfectPrediction, ref bool[] hasPredictionDelta, ref ushort[] baselineSequence, ref CubeState[] cubeState, ref CubeDelta[] predictionDeltas )
    {
        Profiler.BeginSample( "DeterminePrediction" );

        CubeState baselineCubeState = CubeState.defaults;

        for ( int i = 0; i < numCubes; ++i )
        {
            perfectPrediction[i] = false;
            hasPredictionDelta[i] = false;

#if !DISABLE_DELTA_ENCODING

            if ( notChanged[i] )
                continue;

            if ( !hasDelta[i] )
                continue;

            if ( !cubeState[i].active )
                continue;

            if ( context.GetMostRecentAckedState( connectionData, cubeIds[i], ref baselineSequence[i], context.GetResetSequence(), ref baselineCubeState ) )
            {
                if ( Network.Util.BaselineDifference( currentSequence, baselineSequence[i] ) <= Constants.MaxBaselineDifference )
                {
                    // baseline is too far behind. send the cube state absolute
                    continue;
                }

                if ( !baselineCubeState.active )
                {
                    // no point predicting if the cube is at rest.
                    continue;
                }

                int baseline_sequence = baselineSequence[i];
                int current_sequence = currentSequence;

                if ( current_sequence < baseline_sequence )
                    current_sequence += 65536;

                int baseline_position_x = baselineCubeState.position_x;
                int baseline_position_y = baselineCubeState.position_y;
                int baseline_position_z = baselineCubeState.position_z;

                int baseline_linear_velocity_x = baselineCubeState.linear_velocity_x;
                int baseline_linear_velocity_y = baselineCubeState.linear_velocity_y;
                int baseline_linear_velocity_z = baselineCubeState.linear_velocity_z;

                int baseline_angular_velocity_x = baselineCubeState.angular_velocity_x;
                int baseline_angular_velocity_y = baselineCubeState.angular_velocity_y;
                int baseline_angular_velocity_z = baselineCubeState.angular_velocity_z;

                if ( current_sequence < baseline_sequence )
                    current_sequence += 65536;

                int numFrames = current_sequence - baseline_sequence;

                int predicted_position_x;
                int predicted_position_y;
                int predicted_position_z;

                int predicted_linear_velocity_x;
                int predicted_linear_velocity_y;
                int predicted_linear_velocity_z;

                int predicted_angular_velocity_x;
                int predicted_angular_velocity_y;
                int predicted_angular_velocity_z;

                Prediction.PredictBallistic( numFrames,
                                             baseline_position_x, baseline_position_y, baseline_position_z,
                                             baseline_linear_velocity_x, baseline_linear_velocity_y, baseline_linear_velocity_z,
                                             baseline_angular_velocity_x, baseline_angular_velocity_y, baseline_angular_velocity_z,
                                             out predicted_position_x, out predicted_position_y, out predicted_position_z,
                                             out predicted_linear_velocity_x, out predicted_linear_velocity_y, out predicted_linear_velocity_z,
                                             out predicted_angular_velocity_x, out predicted_angular_velocity_y, out predicted_angular_velocity_z );

                int current_position_x = cubeState[i].position_x;
                int current_position_y = cubeState[i].position_y;
                int current_position_z = cubeState[i].position_z;

                int current_linear_velocity_x = cubeState[i].linear_velocity_x;
                int current_linear_velocity_y = cubeState[i].linear_velocity_y;
                int current_linear_velocity_z = cubeState[i].linear_velocity_z;

                int current_angular_velocity_x = cubeState[i].angular_velocity_x;
                int current_angular_velocity_y = cubeState[i].angular_velocity_y;
                int current_angular_velocity_z = cubeState[i].angular_velocity_z;

                int position_error_x = current_position_x - predicted_position_x;
                int position_error_y = current_position_y - predicted_position_y;
                int position_error_z = current_position_z - predicted_position_z;

                int linear_velocity_error_x = current_linear_velocity_x - predicted_linear_velocity_x;
                int linear_velocity_error_y = current_linear_velocity_y - predicted_linear_velocity_y;
                int linear_velocity_error_z = current_linear_velocity_z - predicted_linear_velocity_z;

                int angular_velocity_error_x = current_angular_velocity_x - predicted_angular_velocity_x;
                int angular_velocity_error_y = current_angular_velocity_y - predicted_angular_velocity_y;
                int angular_velocity_error_z = current_angular_velocity_z - predicted_angular_velocity_z;

                if ( position_error_x == 0 &&
                     position_error_y == 0 &&
                     position_error_z == 0 &&
                     linear_velocity_error_x == 0 &&
                     linear_velocity_error_y == 0 &&
                     linear_velocity_error_z == 0 &&
                     angular_velocity_error_x == 0 &&
                     angular_velocity_error_y == 0 &&
                     angular_velocity_error_z == 0 )
                {
                    perfectPrediction[i] = true;
                }
                else
                {
                    int abs_position_error_x = Math.Abs( position_error_x );
                    int abs_position_error_y = Math.Abs( position_error_y );
                    int abs_position_error_z = Math.Abs( position_error_z );

                    int abs_linear_velocity_error_x = Math.Abs( linear_velocity_error_x );
                    int abs_linear_velocity_error_y = Math.Abs( linear_velocity_error_y );
                    int abs_linear_velocity_error_z = Math.Abs( linear_velocity_error_z );

                    int abs_angular_velocity_error_x = Math.Abs( angular_velocity_error_x );
                    int abs_angular_velocity_error_y = Math.Abs( angular_velocity_error_y );
                    int abs_angular_velocity_error_z = Math.Abs( angular_velocity_error_z );

                    int total_prediction_error = abs_position_error_x +
                                                 abs_position_error_y +
                                                 abs_position_error_z +
                                                 linear_velocity_error_x +
                                                 linear_velocity_error_y +
                                                 linear_velocity_error_z +
                                                 angular_velocity_error_x +
                                                 angular_velocity_error_y +
                                                 angular_velocity_error_z;

                    int total_absolute_error = Math.Abs( cubeState[i].position_x - baselineCubeState.position_x ) +
                                               Math.Abs( cubeState[i].position_y - baselineCubeState.position_y ) +
                                               Math.Abs( cubeState[i].position_z - baselineCubeState.position_z ) +
                                               Math.Abs( cubeState[i].linear_velocity_x - baselineCubeState.linear_velocity_x ) +
                                               Math.Abs( cubeState[i].linear_velocity_y - baselineCubeState.linear_velocity_y ) +
                                               Math.Abs( cubeState[i].linear_velocity_z - baselineCubeState.linear_velocity_z ) +
                                               Math.Abs( cubeState[i].angular_velocity_x - baselineCubeState.angular_velocity_x ) +
                                               Math.Abs( cubeState[i].angular_velocity_y - baselineCubeState.angular_velocity_y ) +
                                               Math.Abs( cubeState[i].angular_velocity_z - baselineCubeState.angular_velocity_z );

                    if ( total_prediction_error < total_absolute_error )
                    {
                        int max_position_error = abs_position_error_x;

                        if ( abs_position_error_y > max_position_error )
                            max_position_error = abs_position_error_y;

                        if ( abs_position_error_z > max_position_error )
                            max_position_error = abs_position_error_z;

                        int max_linear_velocity_error = abs_linear_velocity_error_x;

                        if ( abs_linear_velocity_error_y > max_linear_velocity_error )
                            max_linear_velocity_error = abs_linear_velocity_error_y;

                        if ( abs_linear_velocity_error_z > max_linear_velocity_error )
                            max_linear_velocity_error = abs_linear_velocity_error_z;

                        int max_angular_velocity_error = abs_angular_velocity_error_x;

                        if ( abs_angular_velocity_error_y > max_angular_velocity_error )
                            max_angular_velocity_error = abs_angular_velocity_error_y;

                        if ( abs_angular_velocity_error_z > max_angular_velocity_error )
                            max_angular_velocity_error = abs_angular_velocity_error_z;

                        if ( max_position_error <= Constants.PositionDeltaMax &&
                             max_linear_velocity_error <= Constants.LinearVelocityDeltaMax &&
                             max_angular_velocity_error <= Constants.AngularVelocityDeltaMax )
                        {
                            hasPredictionDelta[i] = true;

                            predictionDelta[i].position_delta_x = position_error_x;
                            predictionDelta[i].position_delta_y = position_error_y;
                            predictionDelta[i].position_delta_z = position_error_z;

                            predictionDelta[i].linear_velocity_delta_x = linear_velocity_error_x;
                            predictionDelta[i].linear_velocity_delta_y = linear_velocity_error_y;
                            predictionDelta[i].linear_velocity_delta_z = linear_velocity_error_z;

                            predictionDelta[i].angular_velocity_delta_x = angular_velocity_error_x;
                            predictionDelta[i].angular_velocity_delta_y = angular_velocity_error_y;
                            predictionDelta[i].angular_velocity_delta_z = angular_velocity_error_z;
                        }
                    }
                }
            }
        }

#endif // #if !DISABLE_DELTA_ENCODING

        Profiler.EndSample();
    }
Example #21
0
    public byte[] GenerateStateUpdatePacket(Context.ConnectionData connectionData, int toClientIndex, float avatarSampleTimeOffset)
    {
        int maxStateUpdates = Math.Min(Constants.NumCubes, Constants.MaxStateUpdates);

        int numStateUpdates = maxStateUpdates;

        context.UpdateCubePriority();

        context.GetMostImportantCubeStateUpdates(connectionData, ref numStateUpdates, ref cubeIds, ref cubeState);

        Network.PacketHeader writePacketHeader;

        connectionData.connection.GeneratePacketHeader(out writePacketHeader);

        writePacketHeader.resetSequence = context.GetResetSequence();

        writePacketHeader.frameNumber = (uint)frameNumber;

        writePacketHeader.avatarSampleTimeOffset = avatarSampleTimeOffset;

        DetermineNotChangedAndDeltas(context, connectionData, writePacketHeader.sequence, numStateUpdates, ref cubeIds, ref notChanged, ref hasDelta, ref baselineSequence, ref cubeState, ref cubeDelta);

        DeterminePrediction(context, connectionData, writePacketHeader.sequence, numStateUpdates, ref cubeIds, ref notChanged, ref hasDelta, ref perfectPrediction, ref hasPredictionDelta, ref baselineSequence, ref cubeState, ref predictionDelta);

        int numAvatarStates = 0;

        numAvatarStates = 0;

        for (int i = 0; i < Constants.MaxClients; ++i)
        {
            if (i == toClientIndex)
            {
                continue;
            }

            if (i == 0)
            {
                // grab state from the local avatar.

                localAvatar.GetComponent <Avatar>().GetAvatarState(out avatarState[numAvatarStates]);
                AvatarState.Quantize(ref avatarState[numAvatarStates], out avatarStateQuantized[numAvatarStates]);
                numAvatarStates++;
            }
            else
            {
                // grab state from a remote avatar.

                var remoteAvatar = context.GetRemoteAvatar(i);

                if (remoteAvatar)
                {
                    remoteAvatar.GetAvatarState(out avatarState[numAvatarStates]);
                    AvatarState.Quantize(ref avatarState[numAvatarStates], out avatarStateQuantized[numAvatarStates]);
                    numAvatarStates++;
                }
            }
        }

        WriteStateUpdatePacket(ref writePacketHeader, numAvatarStates, ref avatarStateQuantized, numStateUpdates, ref cubeIds, ref notChanged, ref hasDelta, ref perfectPrediction, ref hasPredictionDelta, ref baselineSequence, ref cubeState, ref cubeDelta, ref predictionDelta);

        byte[] packetData = writeStream.GetData();

        // add the sent cube states to the send delta buffer

        AddPacketToDeltaBuffer(ref connectionData.sendDeltaBuffer, writePacketHeader.sequence, context.GetResetSequence(), numStateUpdates, ref cubeIds, ref cubeState);

        // reset cube priority for the cubes that were included in the packet (so other cubes have a chance to be sent...)

        context.ResetCubePriority(connectionData, numStateUpdates, cubeIds);

        return(packetData);
    }
Example #22
0
    void ProcessPacketsFromConnectedClients()
    {
        Packet packet;

        while ((packet = Net.ReadPacket()) != null)
        {
            int clientIndex = FindClientByUserId(packet.SenderID);
            if (clientIndex == -1)
            {
                continue;
            }

            if (!IsClientConnected(clientIndex))
            {
                continue;
            }

            packet.ReadBytes(readBuffer);

            byte packetType = readBuffer[0];

            if (packetType == (byte)PacketSerializer.PacketType.StateUpdate)
            {
                if (enableJitterBuffer)
                {
                    AddStateUpdatePacketToJitterBuffer(context, context.GetServerConnectionData(clientIndex), readBuffer);
                }
                else
                {
                    ProcessStateUpdatePacket(readBuffer, clientIndex);
                }
            }

            client[clientIndex].timeLastPacketReceived = renderTime;
        }

        ProcessAcks();

        // process client state update from jitter buffer

        if (enableJitterBuffer)
        {
            for (int i = 1; i < Constants.MaxClients; ++i)
            {
                if (client[i].state == ClientState.Connected)
                {
                    ProcessStateUpdateFromJitterBuffer(context, context.GetServerConnectionData(i), i, 0, enableJitterBuffer);
                }
            }
        }

        // advance remote frame number

        for (int i = 1; i < Constants.MaxClients; ++i)
        {
            if (client[i].state == ClientState.Connected)
            {
                Context.ConnectionData connectionData = context.GetServerConnectionData(i);

                if (!connectionData.firstRemotePacket)
                {
                    connectionData.remoteFrameNumber++;
                }
            }
        }
    }
    new void FixedUpdate()
    {
        var avatar = localAvatar.GetComponent <Avatar>();

        bool reset = Input.GetKey("space") || (avatar.IsPressingIndex() && avatar.IsPressingX());

        if (reset)
        {
            hostContext.Reset();
            hostContext.IncreaseResetSequence();
        }

        if (Input.GetKey("1") || avatar.IsPressingX())
        {
            SwitchToHostContext();
        }
        else if (Input.GetKey("2") || avatar.IsPressingY())
        {
            SwitchToGuestContext();
        }

        MirrorLocalAvatarToRemote();

        hostContext.CheckForAtRestObjects();
        guestContext.CheckForAtRestObjects();

        byte[] serverToClientPacketData = GenerateStateUpdatePacket(hostContext, hostContext.GetServerConnectionData(1), 0, 1, (float)(physicsTime - renderTime));

        networkSimulator.SendPacket(0, 1, serverToClientPacketData);

        byte[] clientToServerPacketData = GenerateStateUpdatePacket(guestContext, guestContext.GetClientConnectionData(), 1, 0, (float)(physicsTime - renderTime));

        networkSimulator.SendPacket(1, 0, clientToServerPacketData);

        networkSimulator.AdvanceTime(frameNumber * 1.0 / Constants.PhysicsFrameRate);

        while (true)
        {
            int from, to;

            byte[] packetData = networkSimulator.ReceivePacket(out from, out to);

            if (packetData == null)
            {
                break;
            }

            Context context = GetContext(to);

            if (to == 0)
            {
                Assert.IsTrue(from >= 1);
                Assert.IsTrue(from < Constants.MaxClients);

                if (enableJitterBuffer)
                {
                    AddStateUpdatePacketToJitterBuffer(context, context.GetServerConnectionData(from), packetData);
                }
                else
                {
                    ProcessStateUpdatePacket(context, context.GetServerConnectionData(from), packetData, from, to);
                }
            }
            else
            {
                Assert.IsTrue(from == 0);

                if (enableJitterBuffer)
                {
                    AddStateUpdatePacketToJitterBuffer(context, context.GetClientConnectionData(), packetData);
                }
                else
                {
                    ProcessStateUpdatePacket(context, context.GetClientConnectionData(), packetData, from, to);
                }
            }
        }

        // process packet from host jitter buffer

        for (int from = 1; from < Constants.MaxClients; ++from)
        {
            const int to = 0;

            Context context = GetContext(to);

            ProcessStateUpdateFromJitterBuffer(context, context.GetServerConnectionData(from), from, to, enableJitterBuffer);
        }

        // process packet from guest jitter buffer

        if (enableJitterBuffer)
        {
            const int from = 0;
            const int to   = 1;

            Context context = GetContext(to);

            ProcessStateUpdateFromJitterBuffer(context, context.GetClientConnectionData(), from, to, enableJitterBuffer);
        }

        // advance host remote frame number for each connected client

        for (int i = 1; i < Constants.MaxClients; ++i)
        {
            Context context = GetContext(0);

            Context.ConnectionData connectionData = context.GetServerConnectionData(i);

            if (!connectionData.firstRemotePacket)
            {
                connectionData.remoteFrameNumber++;
            }
        }

        // advance guest remote frame number
        {
            Context context = GetContext(1);

            Context.ConnectionData connectionData = context.GetClientConnectionData();

            if (!connectionData.firstRemotePacket)
            {
                connectionData.remoteFrameNumber++;
            }
        }

        hostContext.CheckForAtRestObjects();
        guestContext.CheckForAtRestObjects();

        ProcessAcks();

        base.FixedUpdate();
    }