Пример #1
0
        private bool UpdateSpeakerStates(ReceivingState state, bool allClosing, bool forceReset, int channelSession, ushort sequenceNumber, ushort senderId, string playerName)
        {
            if (forceReset || state.ExpectedChannelSession != channelSession)
            {
                state.ExpectedChannelSession = channelSession;
                Log.Trace(
                    state.Open
                        ? "Channel Session has changed: {0} => {1} (Triggering forced playback reset)"
                        : "Channel Session has changed: {0} => {1}",
                    state.ExpectedChannelSession, channelSession
                    );

                //If there is an open session force it closed (we will re-open it instantly)
                if (state.Open)
                {
                    _client.OnPlayerStoppedSpeaking(playerName);
                    state.Open = false;
                }
            }

            //If this player does not currently have an open channel, open it (and reset sequence numbers etc)
            if (!state.Open)
            {
                // check for old sequence numbers and discard
                if (state.BaseSequenceNumber.WrappedDelta(sequenceNumber) < 0)
                {
                    return(false);
                }

                state.PlayerId            = senderId;
                state.BaseSequenceNumber  = sequenceNumber;
                state.LocalSequenceNumber = 0;
                state.LastReceiptTicks    = DateTime.Now.Ticks;
                state.Open = true;

                _client.OnPlayerStartedSpeaking(playerName);
            }

            var sequenceDelta = state.BaseSequenceNumber.WrappedDelta(sequenceNumber);

            if (state.LocalSequenceNumber + sequenceDelta < 0)
            {
                // we must have received our first packet out of order
                // this "old" packet will give us a negative local sequence number, which will wrap when cast into the uint
                // discard the packet
                return(false);
            }

            state.LastReceiptTicks    = DateTime.Now.Ticks;
            state.LocalSequenceNumber = (uint)(state.LocalSequenceNumber + sequenceDelta);
            state.BaseSequenceNumber  = sequenceNumber;
            state.Open = !allClosing;

            return(true);
        }
Пример #2
0
        private static void Receive(Socket clientSocket)
        {
            // Создаем объект для callback.
            ReceivingState receivingState = new ReceivingState();

            receivingState.ClientSocket = clientSocket;
            // Начинаем асинхронно получать данные от клиента.
            // Передаем буфер, куда будут складываться полученные байты.
            clientSocket.BeginReceive(receivingState.Buffer, 0, ReceivingState.BufferSize, SocketFlags.None,
                                      ReceiveCallback, receivingState);
        }
Пример #3
0
        private void ReadChannelStates(ref PacketReader reader, ReceivingState state, ushort numChannels, out bool positional, out bool allClosing, out bool forceReset, out ChannelPriority priority)
        {
            positional = true;
            allClosing = true;
            int forcingReset = 0;

            priority = ChannelPriority.None;

            for (var i = 0; i < numChannels; i++)
            {
                byte   channelBitfield;
                ushort channelRecipient;
                reader.ReadVoicePacketChannel(out channelBitfield, out channelRecipient);
                var channel = new ChannelBitField(channelBitfield);

                var compositeId = (int)(channel.Type) | channelRecipient << 8;
                _tmpCompositeIdBuffer.Add(compositeId);

                int previousSession;
                if (state.ExpectedPerChannelSessions.TryGetValue(compositeId, out previousSession))
                {
                    if (previousSession != channel.SessionId)
                    {
                        forcingReset++;
                    }
                }
                state.ExpectedPerChannelSessions[compositeId] = channel.SessionId;

                if (ChannelAddressesUs(channel, channelRecipient))
                {
                    if (!channel.IsPositional)
                    {
                        positional = false;
                    }

                    if (!channel.IsClosing)
                    {
                        allClosing = false;
                    }

                    if (channel.Priority > priority)
                    {
                        priority = channel.Priority;
                    }
                }
            }

            forceReset = forcingReset == numChannels;
            state.ClearChannels(_tmpCompositeIdBuffer);
            _tmpCompositeIdBuffer.Clear();
        }
Пример #4
0
        private void ProcessCommands(string messageType, int BytesRead)
        {
            switch (messageType)
            {
            case "IMG":
                Debug.Assert(state == ReceivingState.NONE, "Connector.cs: state should be NONE, was " + state.ToString() + ", bytes read: " + BytesRead);
                state = ReceivingState.IMG;

                // If packet came with "IMG|" + data, handle below
                if (BytesRead > 4)
                {
                    for (int i = 4; i < BytesRead; i++)
                    {
                        imgBuffer[imgByteOffset + i - 4] = readBuffer[i];
                    }
                    imgByteOffset += (BytesRead - 4);

                    if (imgByteOffset >= IMG_SIZE)
                    {
                        imgByteOffset = 0;
                        state         = ReceivingState.NONE;
                    }
                }
                break;

            case "":     // string.Empty
                if (state == ReceivingState.IMG)
                {
                    for (int i = 0; i < BytesRead; i++)
                    {
                        imgBuffer[imgByteOffset + i] = readBuffer[i];
                    }
                    imgByteOffset += BytesRead;

                    if (imgByteOffset >= IMG_SIZE)
                    {
                        imgByteOffset = 0;
                        state         = ReceivingState.NONE;
                    }
                }
                break;

            default:
                Debug.Assert(false, "Connector.cs: messageType (" + messageType + ") was not valid");
                break;
            }
        }
Пример #5
0
        private ReceivingState FindState(ushort senderId, bool reset = false)
        {
            if (senderId < _receiving.Count)
            {
                if (reset)
                {
                    _receiving[senderId] = new ReceivingState();
                }
            }
            else
            {
                while (_receiving.Count <= senderId)
                {
                    _receiving.Add(new ReceivingState());
                }
            }

            return(_receiving[senderId]);
        }
Пример #6
0
        private static void ReceiveCallback(IAsyncResult asyncResult)
        {
            // Достаем клиентский сокет из параметра callback.
            ReceivingState receivingState = (ReceivingState)asyncResult.AsyncState;
            Socket         clientSocket   = receivingState.ClientSocket;

            // Читаем данные из клиентского сокета.
            int bytesReceived = clientSocket.EndReceive(asyncResult);

            if (bytesReceived > 0)
            {
                // В буфер могли поместиться не все данные.
                // Все данные от клиента складываем в другой буфер - ReceivedData.
                receivingState.ReceivedData.AddRange(receivingState.Buffer.Take(bytesReceived));

                // Пытаемся распарсить Request из полученных данных.
                byte[]  receivedBytes = receivingState.ReceivedData.ToArray();
                Request request       = Request.StupidParse(receivedBytes);
                if (request == null)
                {
                    // request не распарсился, значит получили не все данные.
                    // Запрашиваем еще.
                    clientSocket.BeginReceive(receivingState.Buffer, 0, ReceivingState.BufferSize, SocketFlags.None,
                                              ReceiveCallback, receivingState);
                }
                else
                {
                    // Все данные были получены от клиента.
                    // Для удобства выведем их на консоль.
                    Console.WriteLine(
                        $">>> Received {receivedBytes.Length} bytes from {clientSocket.RemoteEndPoint}. Data:\n" +
                        Encoding.ASCII.GetString(receivedBytes));

                    // Сформируем ответ.
                    byte[] responseBytes = ProcessRequest(request);

                    // Отправим ответ клиенту.
                    Send(clientSocket, responseBytes);
                }
            }
        }
Пример #7
0
 public StateChangedEventArgs(RunningState runningState, ReceivingState receivingState)
 {
     RunningState = runningState;
     ReceivingState = receivingState;
 }