Пример #1
0
        public void Read(NetPacketReader reader, int frame, bool discardOutOfOrderPackets)
        {
            NetDebug.Log($"Receiving packet with remote frame <b>{frame}</b> at local frame <b>{world.Frame}</b>", LogType.Packet);

            if (!arbiter)
            {
                world.Frame = frame;

                int inputLength     = reader.GetInt();
                int statefulsLength = reader.GetInt();
                int fieldsLength    = reader.GetInt();

                ReadInput(reader, inputLength);
                ReadStateful(reader, statefulsLength, frame, discardOutOfOrderPackets);
                ReadFields(reader, fieldsLength, frame, discardOutOfOrderPackets);
            }
            else
            {
                int inputLength = reader.GetInt();
                ReadInput(reader, inputLength);
            }

            if (!reader.EndOfData)
            {
                NetDebug.LogError($"ReadState method did not read all bytes from the NetPacketReader; it is intended to always consume all bytes, regardless of whether the data is applied to the StatefulWorld.");
            }
        }
Пример #2
0
        protected override void OnReceiveNonStatePacket(PacketType packetType, NetPeer peer, NetPacketReader reader, DeliveryMethod deliveryMethod)
        {
            base.OnReceiveNonStatePacket(packetType, peer, reader, deliveryMethod);

            if (packetType == PacketType.Join)
            {
                jitterBuffersByPeerId[peer.Id + 1] = new JitterBuffer(settings.JitterBufferDelayFrames);

                int remoteID = reader.GetInt();

                int frame = reader.GetInt();

                StatefulWorld.Instance.Frame = frame;

                NetDebug.Log($"Local client assigned id <b>{remoteID}</b>", LogType.Connection);
            }
            else if (packetType == PacketType.Ownership)
            {
                int id = reader.GetInt();

                if (role == Role.ListenClient)
                {
                    StatefulWorld.Instance.statefulObjects[id].GetComponent <IInputController>().SetEnabled(true, true);
                }
                else
                {
                    Remote.ClaimOwnership(id);
                }

                NetDebug.Log($"Local client assigned ownership of object id <b>{id}</b>", LogType.Ownership);
            }
        }
Пример #3
0
        public IEnumerable <Packet> StepBuffer()
        {
            DecrementBufferFrames();

            outputPackets.Clear();

            // If the buffer is too large, it is better to flush multiple packets all at once
            // to catch up to the sender. This will cause popping, but is preferable to perpetually
            // lagging behind.
            // If this is happening too frequently, the buffer delayFrames should be increased.
            while (buffer.Count > delayFrames)
            {
                Packet output = buffer[buffer.Count - 1];

                outputPackets.Add(output);

                NetDebug.Log($"Buffer is size {buffer.Count}; <b><color=orange>Flushing</color></b> packet with remote frame <b>{output.StatePacket.Frame}</b>. " +
                             $"<i>(Buffer is now size {buffer.Count - 1}.)</i>", LogType.JitterBuffer);

                buffer.RemoveAt(buffer.Count - 1);
                DecrementBufferFrames();
            }

            if (buffer.Count > 0 && buffer[buffer.Count - 1].BufferFramesRemaining <= 0)
            {
                Packet output = buffer[buffer.Count - 1];
                outputPackets.Add(output);
                buffer.RemoveAt(buffer.Count - 1);

                NetDebug.Log($"<b><color=cyan>Removing</color></b> packet with remote frame <b>{output.StatePacket.Frame}</b> from jitter buffer. " +
                             $"<i>(Buffer is now size {buffer.Count}.)</i>", LogType.JitterBuffer);
            }

            return(outputPackets);
        }
Пример #4
0
        public void Insert(Peer.StatePacket statePacket)
        {
            Packet packet = new Packet()
            {
                StatePacket           = statePacket,
                BufferFramesRemaining = buffer.Count > 0 ? buffer[0].BufferFramesRemaining + 1 : delayFrames
            };

            // Iterate through the buffer to determine where the new packet should be placed.
            for (int i = 0; i < buffer.Count + 1; i++)
            {
                // If the packet has arrived in order with respect to all elements in the buffer, its
                // remote frame should be larger than all other elements in the buffer, and it will
                // be inserted at the front of the buffer.
                if (i == buffer.Count || packet.StatePacket.Frame > buffer[i].StatePacket.Frame)
                {
                    buffer.Insert(i, packet);
                    break;
                }
                // If the packet arrived out of order with respect to the next packet in the buffer,
                // swap arrival frames with the next packet. This allows the buffer to more accurately represent
                // the cadence that the packets were sent.
                else
                {
                    int tempArrivalFrame = packet.BufferFramesRemaining;
                    packet.BufferFramesRemaining    = buffer[i].BufferFramesRemaining;
                    buffer[i].BufferFramesRemaining = tempArrivalFrame;
                }
            }

            NetDebug.Log($"<color=yellow><b>Inserting</b></color> packet with remote frame <b>{packet.StatePacket.Frame}</b> into jitter buffer. " +
                         $"<i>(Buffer is now size {buffer.Count}.)</i>", LogType.JitterBuffer);
        }
Пример #5
0
        private void Listener_PeerDisconnectedEvent(NetPeer peer, DisconnectInfo disconnectInfo)
        {
            int id = peer.Id + 1;

            jitterBuffersByPeerId.Remove(id);

            NetDebug.Log($"Peer index <b>{peer.Id}</b> global ID {id} disconnected. Reason: {disconnectInfo.Reason}", LogType.Connection);
            OnPeerDisconnected?.Invoke(id);
        }
Пример #6
0
        public void WriteStateFields(NetDataWriter writer, bool writeEvenIfNotDirty = false)
        {
            bool objectHeaderWritten, behaviourHeaderWritten;

            objectHeaderWritten = false;

            for (int i = 0; i < stateFieldsByMonoBehaviour.Count; i++)
            {
                behaviourHeaderWritten = false;

                var kvp = stateFieldsByMonoBehaviour[i];

                for (int j = 0; j < kvp.Value.Count; j++)
                {
                    PropertyInfo info = kvp.Value[j];

                    IStateField field = (IStateField)info.GetValue(kvp.Key);

                    if (field.IsDirty || writeEvenIfNotDirty)
                    {
                        // If this is the first field written for this object,
                        // we need to write in this object's ID.
                        if (!objectHeaderWritten)
                        {
                            writer.Put((byte)DataType.Object);
                            writer.Put(ID);
                            writer.Put(Identity.GUID);
                            objectHeaderWritten = true;
                        }

                        // Same as above, but per-behaviour.
                        if (!behaviourHeaderWritten)
                        {
                            writer.Put((byte)DataType.Behaviour);
                            writer.Put(i);
                            behaviourHeaderWritten = true;
                        }

                        writer.Put((byte)DataType.Field);
                        writer.Put(j);
                        field.Write(writer);

                        field.IsDirty = false;

                        NetDebug.Log($"Writing IStateField <b>{info.Name}</b>.", ID, LogType.Property);
                    }
                }
            }
        }
Пример #7
0
        private void Listener_PeerConnectedEvent(NetPeer peer)
        {
            int id = peer.Id + 1;

            jitterBuffersByPeerId[id] = new JitterBuffer(settings.JitterBufferDelayFrames);

            NetDataWriter writer = new NetDataWriter();

            writer.Put((byte)PacketType.Join);
            writer.Put(id);
            writer.Put(StatefulWorld.Instance.Frame);
            peer.Send(writer, DeliveryMethod.ReliableOrdered);
            writer.Reset();

            Remote.SynchronizeAll();

            NetDebug.Log($"Peer index <b>{peer.Id}</b> connected. Assigned global ID {id}.", LogType.Connection);

            OnPeerConnected?.Invoke(id);
        }
Пример #8
0
        private void Listener_ConnectionRequestEvent(ConnectionRequest request)
        {
            request.Accept();

            NetDebug.Log($"Connection requested", LogType.Connection);
        }