Ejemplo n.º 1
0
        public unsafe void Schedule(DynamicBuffer <OutgoingRpcDataStreamBufferComponent> buffer, T data)
        {
            DataStreamWriter writer = new DataStreamWriter(128, Allocator.Temp);

            if (buffer.Length == 0)
            {
                writer.Write((byte)NetworkStreamProtocol.Rpc);
            }
            writer.Write(rpcType);
            data.Serialize(writer);
            var prevLen = buffer.Length;

            buffer.ResizeUninitialized(buffer.Length + writer.Length);
            byte *ptr = (byte *)buffer.GetUnsafePtr();

            ptr += prevLen;
            UnsafeUtility.MemCpy(ptr, writer.GetUnsafeReadOnlyPtr(), writer.Length);
        }
        public static unsafe void SendProtocolVersion(DynamicBuffer <OutgoingRpcDataStreamBufferComponent> buffer, NetworkProtocolVersion version)
        {
            DataStreamWriter writer = new DataStreamWriter(UnsafeUtility.SizeOf <NetworkProtocolVersion>() + 2 + 1, Allocator.Temp);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (buffer.Length != 0)
            {
                throw new InvalidOperationException("Protocol version must be the very first RPC sent");
            }
#endif
            writer.Write((byte)NetworkStreamProtocol.Rpc);
            writer.Write(ushort.MaxValue);
            writer.Write(version.NetCodeVersion);
            writer.Write(version.GameVersion);
            writer.Write(version.RpcCollectionVersion);
            var prevLen = buffer.Length;
            buffer.ResizeUninitialized(buffer.Length + writer.Length);
            byte *ptr = (byte *)buffer.GetUnsafePtr();
            ptr += prevLen;
            UnsafeUtility.MemCpy(ptr, writer.GetUnsafeReadOnlyPtr(), writer.Length);
        }
Ejemplo n.º 3
0
            public unsafe void Execute(Entity entity, int index, [ReadOnly] ref PlayerStateComponentData state)
            {
                // FIXME: ack and sending command stream should be handled by a different system
                DataStreamWriter writer = new DataStreamWriter(128, Allocator.Temp);
                var buffer = cmdBuffer[entity];
                var ack    = ackSnapshot[entity];

                writer.Write((byte)NetworkStreamProtocol.Command);
                writer.Write(ack.LastReceivedSnapshotByLocal);
                writer.Write(ack.ReceivedSnapshotByLocalMask);
                writer.Write(localTime);
                writer.Write(ack.LastReceivedRemoteTime - (localTime - ack.LastReceiveTimestamp));
                if (state.PlayerShip == Entity.Null)
                {
                    if (shoot != 0)
                    {
                        rpcQueue.Schedule(rpcBuffer[entity], new RpcSpawn());
                    }
                }
                else
                {
                    writer.Write(inputTargetTick);
                    writer.Write(left);
                    writer.Write(right);
                    writer.Write(thrust);
                    writer.Write(shoot);

                    // If ship, store commands in network command buffer
                    /*input = new PlayerInputComponentData(left, right, thrust, shoot);*/
                    // FIXME: when destroying the ship is in a command buffer this no longer works
                    if (shipState.Exists(state.PlayerShip)) // There might be a pending set to null
                    {
                        shipState[state.PlayerShip] = new ShipStateComponentData(thrust, true);
                    }
                }
                buffer.ResizeUninitialized(writer.Length);
                byte *ptr = (byte *)buffer.GetUnsafePtr();

                UnsafeUtility.MemCpy(buffer.GetUnsafePtr(), writer.GetUnsafeReadOnlyPtr(), writer.Length);
            }
Ejemplo n.º 4
0
        public unsafe void Schedule(DynamicBuffer <OutgoingRpcDataStreamBufferComponent> buffer, T data)
        {
            DataStreamWriter writer = new DataStreamWriter(UnsafeUtility.SizeOf <T>() + 2 + 1, Allocator.Temp);

            if (buffer.Length == 0)
            {
                writer.Write((byte)NetworkStreamProtocol.Rpc);
            }
            if (!rpcTypeHashToIndex.TryGetValue(rpcType, out var rpcIndex))
            {
                throw new InvalidOperationException("Could not find RPC index for type");
            }
            writer.Write((ushort)rpcIndex);
            data.Serialize(writer);
            var prevLen = buffer.Length;

            buffer.ResizeUninitialized(buffer.Length + writer.Length);
            byte *ptr = (byte *)buffer.GetUnsafePtr();

            ptr += prevLen;
            UnsafeUtility.MemCpy(ptr, writer.GetUnsafeReadOnlyPtr(), writer.Length);
        }
Ejemplo n.º 5
0
            public void Execute()
            {
                DataStreamReader stream;

                NetworkEvent.Type cmd;

                //前フレームで解決できなかったbufferedからuncheckedに登録.
                if (!savedUncheckedReliableDataStream.IsCreated)
                {
                    stream = new DataStreamReader(savedUncheckedReliableDataStream, 0, savedUncheckedReliableDataStream.Length);
                    int offset = 0;
                    while (offset < savedUncheckedReliableDataStream.Length)
                    {
                        var    readerCtx = default(DataStreamReader.Context);
                        ushort length    = stream.ReadUShort(ref readerCtx);
                        if (0 < length && length <= savedUncheckedReliableDataStream.Length - offset - 2)
                        {
                            uncheckedreliableStreams.Add(
                                new DataStreamReader(savedUncheckedReliableDataStream, offset + 2, length));
                            offset += length + 2;
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                while ((cmd = connection.PopEvent(driver, out stream)) != NetworkEvent.Type.Empty)
                {
                    if (cmd == NetworkEvent.Type.Connect)
                    {
                        flags[(int)FlagDef.IsConnected] = 1;
                        Debug.Log("Connect : " + connection.InternalId);
                    }
                    else if (cmd == NetworkEvent.Type.Disconnect)
                    {
                        flags[(int)FlagDef.IsDisconnected] = 1;
                        Debug.Log("Disconnect : " + connection.InternalId);
                    }
                    else if (cmd == NetworkEvent.Type.Data)
                    {
                        if (!stream.IsCreated)
                        {
                            continue;
                        }

                        var    readerCtx = default(DataStreamReader.Context);
                        byte   qosType   = stream.ReadByte(ref readerCtx);
                        ushort seqNum    = stream.ReadUShort(ref readerCtx);
                        ushort ackNum    = stream.ReadUShort(ref readerCtx);

                        //if (qosType != (byte)QosType.MeasureLatency) {
                        //	Debug.Log ("Recieve Data Len=" + stream.Length + ",QoS=" + qosType + ",Seq=" + seqNum + ",Ack=" + ackNum);
                        //}
                        //最初のregister packetはseqNumに

                        bool isInitialUpdate = flags[(int)FlagDef.IsNotInitialUpdate] == 0;

                        //ackNumの更新
                        if (seqNumbers[(int)SeqNumberDef.OtherAck] != ackNum)
                        {
                            seqNumbers[(int)SeqNumberDef.OtherAck] = ackNum;
                            //Debug.Log ("update OtherAck = " + ackNum + " first=" + isInitialUpdate);
                        }

                        switch ((QosType)qosType)
                        {
                        case QosType.MeasureLatency:
                            long currentUnixTime = System.DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                            long otherUnixTime   = stream.ReadLong(ref readerCtx);
                            seqNumbers[(int)SeqNumberDef.Latency] = (ushort)(currentUnixTime - otherUnixTime);
                            break;

                        case QosType.Unreliable:
                            dataStreams.Add(stream);
                            break;

                        case QosType.Reliable:
                            int seqNumberDiff = (int)seqNum - seqNumbers[(int)SeqNumberDef.OtherSeq];
                            if (!isInitialUpdate && seqNumberDiff > 1)
                            {
                                //Debug.Log ("Reliable seqNumberDiff > 1 recieve");
                                //順番が入れ替わってるからバッファに貯める
                                if (seqNumberDiff - 2 < uncheckedreliableStreams.Length)
                                {
                                    if (uncheckedreliableStreams[seqNumberDiff - 2].IsCreated)
                                    {
                                        uncheckedreliableStreams[seqNumberDiff - 2] = stream;
                                    }
                                }
                                else
                                {
                                    uncheckedreliableStreams.Add(stream);
                                }
                            }
                            else if (isInitialUpdate || (seqNumberDiff == 1 || seqNumberDiff == -ushort.MaxValue))
                            {
                                flags[(int)FlagDef.IsNotInitialUpdate] = 1;
                                //次の順のパケットなら確定する
                                seqNumbers[(int)SeqNumberDef.OtherSeq] = seqNum;
                                //Debug.Log ("update OtherSeq = " + seqNumbers[(int)SeqNumberDef.OtherSeq] + " first=" + isInitialUpdate);
                                //AddChunksInDataStream (stream, ref readerCtx);
                                dataStreams.Add(stream);

                                //順番待ちのパケットを確定する
                                while (uncheckedreliableStreams.Length != 0)
                                {
                                    if (!uncheckedreliableStreams[0].IsCreated)
                                    {
                                        IncrementSequenceNumber(SeqNumberDef.OtherSeq);
                                        //Debug.Log ("update OtherSeq = " + seqNumbers[(int)SeqNumberDef.OtherSeq]);
                                        //AddChunksInDataStream (uncheckedreliableStreams[0], ref readerCtx);
                                        dataStreams.Add(uncheckedreliableStreams[0]);
                                        uncheckedreliableStreams.RemoveAtSwapBack(0);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                            else
                            {
                                //受信済みのSeqNumのパケットなら無視
                                //Debug.Log ("Reliable same recieve");
                            }
                            break;
                        }
                    }
                }

                //uncheckedreliableStreamsに残ったパケットはnetworkdriverから実態が消される前にコピーしておく
                unsafe {
                    //uncheckedreliableStreamsはsavedUncheckedReliableDataStreamに実態を持つ場合があるので
                    //直接savedUncheckedReliableDataStream書き込むと実態が消えてしまうのでtempまず書く
                    tempUncheckedReliableDataStream.Clear();
                    for (int i = 0; i < uncheckedreliableStreams.Length; i++)
                    {
                        int dataLength = uncheckedreliableStreams[i].Length;
                        if (tempUncheckedReliableDataStream.Capacity - tempUncheckedReliableDataStream.Length < dataLength + 2)
                        {
                            tempUncheckedReliableDataStream.Capacity *= 2;
                        }
                        byte *dataPtr = DataStreamUnsafeUtility.GetUnsafeReadOnlyPtr(uncheckedreliableStreams[i]);
                        tempUncheckedReliableDataStream.Write(dataLength);
                        tempUncheckedReliableDataStream.WriteBytes(dataPtr, dataLength);
                    }
                    savedUncheckedReliableDataStream.Clear();
                    if (savedUncheckedReliableDataStream.Capacity < tempUncheckedReliableDataStream.Capacity)
                    {
                        savedUncheckedReliableDataStream.Capacity *= tempUncheckedReliableDataStream.Capacity;
                    }
                    savedUncheckedReliableDataStream.WriteBytes(
                        tempUncheckedReliableDataStream.GetUnsafeReadOnlyPtr(), tempUncheckedReliableDataStream.Length);
                }

                //次に自分が送るパケットでどこまで受け取ったか伝える.
                seqNumbers[(int)SeqNumberDef.SelfAck] = seqNumbers[(int)SeqNumberDef.OtherSeq];
            }