Esempio n. 1
0
        public unsafe void Execute(Entity entity, int index, [ReadOnly] ref CommandTargetComponent commandTarget)
        {
            if (commandTarget.targetEntity == Entity.Null)
            {
                return;
            }

            var buffer = cmdBuffer[entity];

            if (buffer.Length == 0)
            {
                return;
            }
            DataStreamReader reader = DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)buffer.GetUnsafePtr(), buffer.Length);
            var ctx             = default(DataStreamReader.Context);
            var tick            = reader.ReadUInt(ref ctx);
            var receivedCommand = default(TCommandData);

            receivedCommand.Deserialize(tick, reader, ref ctx);
            buffer.Clear();

            // Store received commands in the network command buffer
            var command = commandData[commandTarget.targetEntity];

            command.AddCommandData(receivedCommand);
        }
Esempio n. 2
0
        protected unsafe override void OnUpdate()
        {
            // TODO: LZ:
            //      not use Allocator.Persistent
            var ents = m_RpcBufferQuery.ToEntityArray(Allocator.TempJob);

            for (var i = 0; i < ents.Length; ++i)
            {
                var ent    = ents[i];
                var rpcBuf = EntityManager.GetBuffer <IncomingRpcDataStreamBufferComponent>(ent);

                DataStreamReader reader = DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)rpcBuf.GetUnsafePtr(), rpcBuf.Length);

                var ctx = default(DataStreamReader.Context);
                while (reader.GetBytesRead(ref ctx) < reader.Length)
                {
                    int type = reader.ReadInt(ref ctx);
                    if (type < m_InternalRpcCollectionLength)
                    {
                        m_InternalRpcCollection.ExecuteRpc(type, reader, ref ctx, ent, PostUpdateCommands);
                    }
                    else
                    {
                        m_RpcCollection.ExecuteRpc(type - m_InternalRpcCollectionLength, reader, ref ctx, ent, PostUpdateCommands);
                    }
                }

                rpcBuf.Clear();
            }
            ents.Dispose();
        }
Esempio n. 3
0
        public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var entities     = chunk.GetNativeArray(entityType);
            var bufferAccess = chunk.GetBufferAccessor(bufferType);

            for (int i = 0; i < bufferAccess.Length; ++i)
            {
                var dynArray            = bufferAccess[i];
                DataStreamReader reader = DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)dynArray.GetUnsafePtr(), dynArray.Length);
                var ctx = default(DataStreamReader.Context);
                while (reader.GetBytesRead(ref ctx) < reader.Length)
                {
                    int type = reader.ReadInt(ref ctx);
                    if (type < internalRpcCollectionLength)
                    {
                        internalRpcCollection.ExecuteRpc(type, reader, ref ctx, entities[i], commandBuffer, chunkIndex);
                    }
                    else
                    {
                        rpcCollection.ExecuteRpc(type - internalRpcCollectionLength, reader, ref ctx, entities[i], commandBuffer, chunkIndex);
                    }
                }

                dynArray.Clear();
            }
        }
            public unsafe void Execute(Entity entity, int index, [ReadOnly] ref PlayerStateComponentData playerState)
            {
                if (playerState.PlayerShip == Entity.Null)
                {
                    return;
                }

                var buffer = cmdBuffer[entity];

                if (buffer.Length == 0)
                {
                    return;
                }
                DataStreamReader reader = DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)buffer.GetUnsafePtr(), buffer.Length);
                var ctx       = default(DataStreamReader.Context);
                var inputTick = reader.ReadUInt(ref ctx);
                var left      = reader.ReadByte(ref ctx);
                var right     = reader.ReadByte(ref ctx);
                var thrust    = reader.ReadByte(ref ctx);
                var shoot     = reader.ReadByte(ref ctx);

                buffer.Clear();
                //Debug.Log("Input delay: " + (int)(currentTick - inputTick));

                // If ship, store commands in network command buffer
                var input = shipInput[playerState.PlayerShip];

                input.mostRecentPos               = (input.mostRecentPos + 1) % 32;
                input.tick[input.mostRecentPos]   = inputTick;
                input.left[input.mostRecentPos]   = left;
                input.right[input.mostRecentPos]  = right;
                input.thrust[input.mostRecentPos] = thrust;
                input.shoot[input.mostRecentPos]  = shoot;
                shipInput[playerState.PlayerShip] = input;
            }
Esempio n. 5
0
        public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
        {
            var entities     = chunk.GetNativeArray(entityType);
            var bufferAccess = chunk.GetBufferAccessor(bufferType);

            for (int i = 0; i < bufferAccess.Length; ++i)
            {
                var dynArray            = bufferAccess[i];
                DataStreamReader reader = DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)dynArray.GetUnsafePtr(), dynArray.Length);
                var ctx = default(DataStreamReader.Context);
                while (reader.GetBytesRead(ref ctx) < reader.Length)
                {
                    int type = reader.ReadInt(ref ctx);
                    switch (type)
                    {
                    case 0:
                    {
                        var tmp = new RpcSetNetworkId();
                        tmp.Deserialize(reader, ref ctx);
                        tmp.Execute(entities[i], commandBuffer, chunkIndex);
                        break;
                    }

                    case 1:
                    {
                        var tmp = new RpcLoadLevel();
                        tmp.Deserialize(reader, ref ctx);
                        tmp.Execute(entities[i], commandBuffer, chunkIndex);
                        break;
                    }

                    case 2:
                    {
                        var tmp = new RpcLevelLoaded();
                        tmp.Deserialize(reader, ref ctx);
                        tmp.Execute(entities[i], commandBuffer, chunkIndex);
                        break;
                    }

                    case 3:
                    {
                        var tmp = new RpcSpawn();
                        tmp.Deserialize(reader, ref ctx);
                        tmp.Execute(entities[i], commandBuffer, chunkIndex);
                        break;
                    }
                    }
                }

                dynArray.Clear();
            }
        }
            public unsafe void Execute(Entity entity, int index, [ReadOnly] ref CommandTargetComponent commandTarget,
                                       ref NetworkSnapshotAckComponent snapshotAck)
            {
                if (typeof(TCommandData) == typeof(NullCommandData) && commandTarget.targetEntity != Entity.Null)
                {
                    return;
                }
                if (typeof(TCommandData) != typeof(NullCommandData) && !commandData.Exists(commandTarget.targetEntity))
                {
                    return;
                }

                var buffer = cmdBuffer[entity];

                if (buffer.Length < 4)
                {
                    return;
                }
                DataStreamReader reader =
                    DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)buffer.GetUnsafePtr(), buffer.Length);
                var ctx  = default(DataStreamReader.Context);
                var tick = reader.ReadUInt(ref ctx);

                int age = (int)(serverTick - tick);

                age *= 256;
                snapshotAck.ServerCommandAge = (snapshotAck.ServerCommandAge * 7 + age) / 8;

                if (commandTarget.targetEntity != Entity.Null && buffer.Length > 4)
                {
                    var command = commandData[commandTarget.targetEntity];
                    var baselineReceivedCommand = default(TCommandData);
                    baselineReceivedCommand.Deserialize(tick, reader, ref ctx);
                    // Store received commands in the network command buffer
                    command.AddCommandData(baselineReceivedCommand);
                    for (uint i = 1; i < CommandSendSystem <TCommandData> .k_InputBufferSendSize; ++i)
                    {
                        var receivedCommand = default(TCommandData);
                        receivedCommand.Deserialize(tick - i, reader, ref ctx, baselineReceivedCommand,
                                                    compressionModel);
                        // Store received commands in the network command buffer
                        command.AddCommandData(receivedCommand);
                    }
                }
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                netStats[0]  = serverTick;
                netStats[1] += (uint)buffer.Length + 16u; // 16 is the ack fields which are already processed
#endif
                buffer.Clear();
            }
        private unsafe void OnArrayProcess(NativeArray <Entity> entities, NativeArray <CommandTargetComponent> targetArray)
        {
            var serverTick = World.GetExistingSystem <ServerSimulationSystemGroup>().ServerTick;

            for (var ent = 0; ent < entities.Length; ent++)
            {
                var target = targetArray[ent];
                if (target.targetEntity == default)
                {
                    continue;
                }

                var buffer = EntityManager.GetBuffer <IncomingCommandDataStreamBufferComponent>(entities[ent]);
                if (buffer.Length <= 0)
                {
                    continue;
                }

                var reader = DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)buffer.GetUnsafePtr(), buffer.Length);
                var ctx    = default(DataStreamReader.Context);

                var tick = reader.ReadUInt(ref ctx);
                var age  = (int)(serverTick - tick);
                age *= 256;

                var snapshotAck = EntityManager.GetComponentData <NetworkSnapshotAckComponent>(entities[ent]);
                snapshotAck.ServerCommandAge = (snapshotAck.ServerCommandAge * 7 + age) / 8;
                EntityManager.SetComponentData(entities[ent], snapshotAck);

                while (reader.GetBytesRead(ref ctx) < reader.Length)
                {
                    var type = reader.ReadByte(ref ctx);
                    if (!m_CommandCollectionSystem.SystemProcessors.TryGetValue(type, out var processor))
                    {
                        throw new KeyNotFoundException($"No processor with type '{type}' found!");
                    }

                    processor.BeginDeserialize(target.targetEntity, type);
                    processor.ProcessReceive(serverTick, reader, ref ctx, m_NetworkCompressionModel);
                }

                buffer.Clear();
            }
        }
Esempio n. 8
0
            public unsafe void Execute()
            {
                // FIXME: should handle any number of connections with individual ghost mappings for each
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (players.Length > 1)
                {
                    throw new InvalidOperationException("Ghost receive system only supports a single connection");
                }
#endif
                while (delayedDespawnQueue.Count > 0 &&
                       !SequenceHelpers.IsNewer(delayedDespawnQueue.Peek().tick, targetTick))
                {
                    commandBuffer.RemoveComponent(delayedDespawnQueue.Dequeue().ghost, replicatedEntityType);
                }

                var snapshot = snapshotFromEntity[players[0]];
                if (snapshot.Length == 0)
                {
                    return;
                }

                var dataStream =
                    DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)snapshot.GetUnsafePtr(), snapshot.Length);
                // Read the ghost stream
                // find entities to spawn or destroy
                var readCtx    = new DataStreamReader.Context();
                var serverTick = dataStream.ReadUInt(ref readCtx);
                var ack        = snapshotAckFromEntity[players[0]];
                if (ack.LastReceivedSnapshotByLocal != 0 && !SequenceHelpers.IsNewer(serverTick, ack.LastReceivedSnapshotByLocal))
                {
                    return;
                }
                if (ack.LastReceivedSnapshotByLocal != 0)
                {
                    ack.ReceivedSnapshotByLocalMask <<= (int)(serverTick - ack.LastReceivedSnapshotByLocal);
                }
                ack.ReceivedSnapshotByLocalMask  |= 1;
                ack.LastReceivedSnapshotByLocal   = serverTick;
                snapshotAckFromEntity[players[0]] = ack;

                uint despawnLen = dataStream.ReadUInt(ref readCtx);
                uint updateLen  = dataStream.ReadUInt(ref readCtx);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                int startPos = dataStream.GetBitsRead(ref readCtx);
#endif
                for (var i = 0; i < despawnLen; ++i)
                {
                    int         ghostId = (int)dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                    GhostEntity ent;
                    if (!ghostEntityMap.TryGetValue(ghostId, out ent))
                    {
                        continue;
                    }

                    ghostEntityMap.Remove(ghostId);
                    // if predicted, despawn now, otherwise wait
                    if (predictedFromEntity.Exists(ent.entity))
                    {
                        commandBuffer.RemoveComponent(ent.entity, replicatedEntityType);
                    }
                    else
                    {
                        delayedDespawnQueue.Enqueue(new DelayedDespawnGhost {
                            ghost = ent.entity, tick = serverTick
                        });
                    }
                }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                netStats[0] = despawnLen;
                netStats[1] = (uint)(dataStream.GetBitsRead(ref readCtx) - startPos);
                netStats[2] = 0;
                for (int i = 0; i < serializers.Length; ++i)
                {
                    netStats[i * 3 + 3] = 0;
                    netStats[i * 3 + 4] = 0;
                    netStats[i * 3 + 5] = 0;
                }
                uint statCount         = 0;
                uint uncompressedCount = 0;
#endif

                uint targetArch    = 0;
                uint targetArchLen = 0;
                uint baselineTick  = 0;
                uint baselineTick2 = 0;
                uint baselineTick3 = 0;
                uint baselineLen   = 0;
                int  newGhosts     = 0;
                for (var i = 0; i < updateLen; ++i)
                {
                    if (targetArchLen == 0)
                    {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                        int curPos = dataStream.GetBitsRead(ref readCtx);
                        if (statCount > 0)
                        {
                            int statType = (int)targetArch;
                            netStats[statType * 3 + 3] = netStats[statType * 3 + 3] + statCount;
                            netStats[statType * 3 + 4] = netStats[statType * 3 + 4] + (uint)(curPos - startPos);
                            netStats[statType * 3 + 5] = netStats[statType * 3 + 5] + uncompressedCount;
                        }

                        startPos          = curPos;
                        statCount         = 0;
                        uncompressedCount = 0;
#endif
                        targetArch    = dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                        targetArchLen = dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                    }
                    --targetArchLen;

                    if (baselineLen == 0)
                    {
                        baselineTick  = serverTick - dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                        baselineTick2 = serverTick - dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                        baselineTick3 = serverTick - dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                        baselineLen   = dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                    }
                    --baselineLen;

                    int         ghostId = (int)dataStream.ReadPackedUInt(ref readCtx, compressionModel);
                    GhostEntity gent;
                    if (ghostEntityMap.TryGetValue(ghostId, out gent))
                    {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                        if (gent.ghostType != targetArch)
                        {
                            throw new InvalidOperationException("Received a ghost with an invalid ghost type");
                        }
                        //throw new InvalidOperationException("Received a ghost with an invalid ghost type " + targetArch + ", expected " + gent.ghostType);
#endif
                        serializers.Deserialize((int)targetArch, gent.entity, serverTick, baselineTick, baselineTick2, baselineTick3,
                                                dataStream, ref readCtx, compressionModel);
                    }
                    else
                    {
                        ++newGhosts;
                        serializers.Spawn((int)targetArch, ghostId, serverTick, dataStream, ref readCtx, compressionModel);
                    }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    ++statCount;
                    if (baselineTick == serverTick)
                    {
                        ++uncompressedCount;
                    }
#endif
                }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                if (statCount > 0)
                {
                    int curPos   = dataStream.GetBitsRead(ref readCtx);
                    int statType = (int)targetArch;
                    netStats[statType * 3 + 3] = netStats[statType * 3 + 3] + statCount;
                    netStats[statType * 3 + 4] = netStats[statType * 3 + 4] + (uint)(curPos - startPos);
                    netStats[statType * 3 + 5] = netStats[statType * 3 + 5] + uncompressedCount;
                }
#endif
                while (ghostEntityMap.Capacity < ghostEntityMap.Length + newGhosts)
                {
                    ghostEntityMap.Capacity += 1024;
                }
            }
            public unsafe void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex)
            {
                var entities     = chunk.GetNativeArray(entityType);
                var rpcInBuffer  = chunk.GetBufferAccessor(inBufferType);
                var rpcOutBuffer = chunk.GetBufferAccessor(outBufferType);
                var connections  = chunk.GetNativeArray(connectionType);

                for (int i = 0; i < rpcInBuffer.Length; ++i)
                {
                    if (driver.GetConnectionState(connections[i].Value) != NetworkConnection.State.Connected)
                    {
                        continue;
                    }

                    var dynArray = rpcInBuffer[i];
                    var reader   = DataStreamUnsafeUtility.CreateReaderFromExistingData((byte *)dynArray.GetUnsafePtr(),
                                                                                        dynArray.Length);
                    var parameters = new RpcExecutor.Parameters
                    {
                        Reader        = reader,
                        ReaderContext = default(DataStreamReader.Context),
                        CommandBuffer = commandBuffer,
                        Connection    = entities[i],
                        JobIndex      = chunkIndex
                    };
                    while (reader.GetBytesRead(ref parameters.ReaderContext) < reader.Length)
                    {
                        var rpcIndex = reader.ReadUShort(ref parameters.ReaderContext);
                        if (rpcIndex == ushort.MaxValue)
                        {
                            // Special value for NetworkProtocolVersion
                            var netCodeVersion = reader.ReadInt(ref parameters.ReaderContext);
                            var gameVersion    = reader.ReadInt(ref parameters.ReaderContext);
                            var rpcVersion     = reader.ReadULong(ref parameters.ReaderContext);
                            if (netCodeVersion != protocolVersion.NetCodeVersion ||
                                gameVersion != protocolVersion.GameVersion ||
                                rpcVersion != protocolVersion.RpcCollectionVersion)
                            {
                                commandBuffer.AddComponent(chunkIndex, entities[i], new NetworkStreamRequestDisconnect {
                                    Reason = NetworkStreamDisconnectReason.BadProtocolVersion
                                });
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                                throw new InvalidOperationException("Network protocol mismatch");
#else
                                return;
#endif
                            }
                        }
                        else if (rpcIndex >= execute.Length)
                        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                            throw new InvalidOperationException("Received an invalid RPC");
#else
                            return;
#endif
                        }
                        else
                        {
                            execute[rpcIndex].Execute.Ptr.Invoke(ref parameters);
                        }
                    }

                    dynArray.Clear();

                    var sendBuffer = rpcOutBuffer[i];
                    if (sendBuffer.Length > 0)
                    {
                        DataStreamWriter tmp = new DataStreamWriter(sendBuffer.Length, Allocator.Temp);
                        tmp.WriteBytes((byte *)sendBuffer.GetUnsafePtr(), sendBuffer.Length);
                        driver.Send(reliablePipeline, connections[i].Value, tmp);
                        sendBuffer.Clear();
                    }
                }
            }