コード例 #1
0
        private static void InvokeExecute(ref RpcExecutor.Parameters parameters)
        {
            var rpcData = default(RpcSetNetworkId);

            rpcData.Deserialize(ref parameters.Reader);

            parameters.CommandBuffer.AddComponent(parameters.JobIndex, parameters.Connection, new NetworkIdComponent {
                Value = rpcData.nid
            });
            var ent = parameters.CommandBuffer.CreateEntity(parameters.JobIndex);

            parameters.CommandBuffer.AddComponent(parameters.JobIndex, ent, new ClientServerTickRate
            {
                MaxSimulationStepsPerFrame = rpcData.simMaxSteps,
                NetworkTickRate            = rpcData.netTickRate,
                SimulationTickRate         = rpcData.simTickRate
            });
        }
コード例 #2
0
 private static void InvokeExecute(ref RpcExecutor.Parameters parameters)
 {
     RpcExecutor.ExecuteCreateRequestComponent <HeartbeatComponent>(ref parameters);
 }
コード例 #3
0
            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);
                var deserializeState = new RpcDeserializerState {
                    ghostMap = ghostMap
                };

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

                    var dynArray   = rpcInBuffer[i];
                    var parameters = new RpcExecutor.Parameters
                    {
                        Reader        = dynArray.AsDataStreamReader(),
                        CommandBuffer = commandBuffer,
                        State         = (IntPtr)UnsafeUtility.AddressOf(ref deserializeState),
                        Connection    = entities[i],
                        JobIndex      = chunkIndex
                    };
                    int msgHeaderLen = dynamicAssemblyList ? 10 : 4;
                    while (parameters.Reader.GetBytesRead() < parameters.Reader.Length)
                    {
                        int rpcIndex = 0;
                        if (dynamicAssemblyList)
                        {
                            ulong rpcHash = parameters.Reader.ReadULong();
                            if (rpcHash == 0)
                            {
                                rpcIndex = ushort.MaxValue;
                                protocolVersion.RpcCollectionVersion       = 0;
                                protocolVersion.ComponentCollectionVersion = 0;
                            }
                            else if (rpcHash != 0 && !hashToIndex.TryGetValue(rpcHash, out rpcIndex))
                            {
                                errors.Enqueue(new RpcReceiveError
                                {
                                    connection = entities[i],
                                    error      = ErrorCodes.InvalidRpc
                                });
                                break;
                            }
                        }
                        else
                        {
                            rpcIndex = parameters.Reader.ReadUShort();
                        }

                        var rpcSize = parameters.Reader.ReadUShort();
                        if (rpcIndex == ushort.MaxValue)
                        {
                            // Special value for NetworkProtocolVersion
                            var netCodeVersion   = parameters.Reader.ReadInt();
                            var gameVersion      = parameters.Reader.ReadInt();
                            var rpcVersion       = parameters.Reader.ReadULong();
                            var componentVersion = parameters.Reader.ReadULong();
                            if (netCodeVersion != protocolVersion.NetCodeVersion ||
                                gameVersion != protocolVersion.GameVersion ||
                                rpcVersion != protocolVersion.RpcCollectionVersion ||
                                componentVersion != protocolVersion.ComponentCollectionVersion)
                            {
                                errors.Enqueue(new RpcReceiveError
                                {
                                    connection = entities[i],
                                    error      = ErrorCodes.ProtocolMismatch
                                });
                                break;
                            }
                            //The connection has received the version. RpcSystem can't accept any rpc's if the NetworkProtocolVersion
                            //has not been received first.
                            var connection = connections[i];
                            connection.ProtocolVersionReceived = 1;
                            connections[i] = connection;
                        }
                        else if (rpcIndex >= execute.Length)
                        {
                            //If this is the server, we must disconnect the connection
                            errors.Enqueue(new RpcReceiveError
                            {
                                connection = entities[i],
                                error      = ErrorCodes.InvalidRpc
                            });
                            break;
                        }
                        else if (connections[i].ProtocolVersionReceived == 0)
                        {
                            errors.Enqueue(new RpcReceiveError
                            {
                                connection = entities[i],
                                error      = ErrorCodes.VersionNotReceived
                            });
                            break;
                        }
                        else
                        {
                            execute[rpcIndex].Execute.Ptr.Invoke(ref parameters);
                        }
                    }

                    dynArray.Clear();

                    var sendBuffer = rpcOutBuffer[i];
                    while (sendBuffer.Length > 0)
                    {
                        if (driver.BeginSend(reliablePipeline, connections[i].Value, out var tmp) == 0)
                        {
                            // If sending failed we stop and wait until next frame
                            if (sendBuffer.Length > tmp.Capacity)
                            {
                                var sendArray = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(sendBuffer.GetUnsafePtr(), sendBuffer.Length, Allocator.Invalid);
    #if ENABLE_UNITY_COLLECTIONS_CHECKS
                                var safety = NativeArrayUnsafeUtility.GetAtomicSafetyHandle(sendBuffer.AsNativeArray());
                                NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref sendArray, safety);
    #endif
                                var reader = new DataStreamReader(sendArray);
                                reader.ReadByte();
                                reader.ReadUShort();
                                var len = reader.ReadUShort() + msgHeaderLen + 1;
                                if (len > tmp.Capacity)
                                {
                                    sendBuffer.Clear();
                                    // Could not fit a single message in the packet, this is a serious error
                                    throw new InvalidOperationException("An RPC was too big to be sent, reduce the size of your RPCs");
                                }
                                tmp.WriteBytes((byte *)sendBuffer.GetUnsafePtr(), len);
                                // Try to fit a few more messages in this packet
                                while (true)
                                {
                                    var subArray = sendArray.GetSubArray(tmp.Length, sendArray.Length - tmp.Length);
                                    reader = new DataStreamReader(subArray);
                                    reader.ReadUShort();
                                    len = reader.ReadUShort() + msgHeaderLen;
                                    if (tmp.Length + len > tmp.Capacity)
                                    {
                                        break;
                                    }
                                    tmp.WriteBytes((byte *)subArray.GetUnsafeReadOnlyPtr(), len);
                                }
                            }
                            else
                            {
                                tmp.WriteBytes((byte *)sendBuffer.GetUnsafePtr(), sendBuffer.Length);
                            }
                            // If sending failed we stop and wait until next frame
                            var result = 0;
                            if ((result = driver.EndSend(tmp)) <= 0)
                            {
                                UnityEngine.Debug.LogWarning($"An error occured during EndSend. ErrorCode: {result}");
                                break;
                            }
                            if (tmp.Length < sendBuffer.Length)
                            {
                                // Compact the buffer, removing the rpcs we did send
                                for (int cpy = tmp.Length; cpy < sendBuffer.Length; ++cpy)
                                {
                                    sendBuffer[1 + cpy - tmp.Length] = sendBuffer[cpy];
                                }
                                // Remove all but the first byte of the data we sent, first byte is identifying the packet as an rpc
                                sendBuffer.ResizeUninitialized(1 + sendBuffer.Length - tmp.Length);
                            }
                            else
                            {
                                sendBuffer.Clear();
                            }
                        }
                    }
                }
            }
コード例 #4
0
            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();
                    }
                }
            }
コード例 #5
0
            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);
                var errors       = new NativeArray <RpcReceiveError>(rpcInBuffer.Length, Allocator.Temp);
                var errorCount   = 0;

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

                    var dynArray   = rpcInBuffer[i];
                    var parameters = new RpcExecutor.Parameters
                    {
                        Reader        = dynArray.AsDataStreamReader(),
                        CommandBuffer = commandBuffer,
                        Connection    = entities[i],
                        JobIndex      = chunkIndex
                    };
                    while (parameters.Reader.GetBytesRead() < parameters.Reader.Length)
                    {
                        var rpcIndex = parameters.Reader.ReadUShort();
                        if (rpcIndex == ushort.MaxValue)
                        {
                            // Special value for NetworkProtocolVersion
                            var netCodeVersion = parameters.Reader.ReadInt();
                            var gameVersion    = parameters.Reader.ReadInt();
                            var rpcVersion     = parameters.Reader.ReadULong();
                            if (netCodeVersion != protocolVersion.NetCodeVersion ||
                                gameVersion != protocolVersion.GameVersion ||
                                rpcVersion != protocolVersion.RpcCollectionVersion)
                            {
                                commandBuffer.AddComponent(chunkIndex, entities[i], new NetworkStreamRequestDisconnect {
                                    Reason = NetworkStreamDisconnectReason.BadProtocolVersion
                                });
                                errors[errorCount++] = new RpcReceiveError
                                {
                                    connection = entities[i],
                                    error      = ErrorCodes.ProtocolMismatch
                                };
                                break;
                            }
                        }
                        else if (rpcIndex >= execute.Length)
                        {
                            errors[errorCount++] = new RpcReceiveError
                            {
                                connection = entities[i],
                                error      = ErrorCodes.InvalidRpc
                            };
                            break;
                        }
                        else
                        {
                            execute[rpcIndex].Execute.Ptr.Invoke(ref parameters);
                        }
                    }

                    dynArray.Clear();

                    var sendBuffer = rpcOutBuffer[i];
                    if (sendBuffer.Length > 0)
                    {
                        DataStreamWriter tmp = driver.BeginSend(reliablePipeline, connections[i].Value);
                        if (!tmp.IsCreated)
                        {
                            continue;
                        }
                        tmp.WriteBytes((byte *)sendBuffer.GetUnsafePtr(), sendBuffer.Length);
                        driver.EndSend(tmp);
                        sendBuffer.Clear();
                    }
                }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
// TODO: we need to report the errors produced.
                if (errorCount > 0)
                {
                    throw new InvalidOperationException("RpcSystem received malformed packets or packets with the wrong version");
                }
#endif
            }