Exemplo n.º 1
0
        /// <summary>
        /// thx to Hitman for this implementation ;)
        /// </summary>
        /// <param name="stream"></param>
        private async void OnReceive(MemoryStream stream)
        {
            if (_reader is null)
            {
                _reader = new BigEndianReader();
            }
            if (stream.Length > 0)
            {
                _reader.Add(stream.ToArray(), 0, (int)stream.Length);
            }

            byte[] full_data = _reader.Data;
            while (_position < full_data.Length && full_data.Length - _position >= 2)
            {
                long start_pos = _position;
                _current_header = (ushort)((full_data[_position] * 256) + full_data[_position + 1]);
                _position      += sizeof(ushort);

                _instance_id = (uint)((full_data[_position] * 256 * 256 * 256) + (full_data[_position + 1] * 256 * 256) + (full_data[_position + 2] * 256) + full_data[_position + 3]);
                _position   += sizeof(uint);


                if (full_data.Length - _position < _static_header)
                {
                    break;
                }

                switch (_static_header)
                {
                case 0: _length = 0; break;

                case 1: _length = full_data[_position]; break;

                case 2: _length = (ushort)((full_data[_position] * 256) + full_data[_position + 1]); break;

                case 3: _length = (full_data[_position] * 256 * 256) + (full_data[_position + 1] * 256) + full_data[_position + 2]; break;
                }

                _position += _static_header;

                long _current_data_len = full_data.Length - _position;
                if (_current_data_len >= _length)
                {
                    NetworkElement _element = BotofuProtocolManager.Protocol[ProtocolKeyEnum.Messages, x => x.protocolID == _message_id];
                    _data = new byte[_current_data_len];

                    byte[] packet_data = new byte[(int)(_position - start_pos) + _length.Value];
                    Array.Copy(full_data, start_pos, packet_data, 0, packet_data.Length);
                    Array.Copy(full_data, _position, _data, 0, _length.Value);

                    if (_element != null)
                    {
                        logger.Info($"[{_tag}] {_element.BasicString}");
                        _data_buffer_reader = new MessageDataBufferReader(_element);
                        using (BigEndianReader big_data_reader = new BigEndianReader(_data))
                        {
                            await _handler.Handle(this, _element, _data_buffer_reader.Parse(big_data_reader));
                        }
                    }

                    _position += _length.Value;

                    if (_current_data_len == _length)
                    {
                        _clear();

                        _reader.Dispose();
                        _reader   = new BigEndianReader();
                        _position = 0;
                        break;
                    }
                    _clear();
                }
                else
                {
                    _position = start_pos;
                    break;
                }
            }
        }
        /// <summary>
        /// thx to Hitman for this implementation made by ToOnS
        /// </summary>
        /// <param name="stream"></param>
        protected virtual void OnReceive(MemoryStream stream)
        {
            if (_reader is null)
            {
                _reader = new BigEndianReader();
            }
            if (stream.Length > 0)
            {
                _reader.Add(stream.ToArray(), 0, (int)stream.Length);
            }

            byte[] full_data = _reader.Data;
            while (_position < full_data.Length && full_data.Length - _position >= 2)
            {
                long start_pos = _position;
                _current_header = (ushort)((full_data[_position] * 256) + full_data[_position + 1]);
                _position      += sizeof(ushort);

                if (_tag == ProxyTagEnum.Client)
                {
                    _instance_id = (uint)((full_data[_position] * 256 * 256 * 256) + (full_data[_position + 1] * 256 * 256) + (full_data[_position + 2] * 256) + full_data[_position + 3]);
                    _position   += sizeof(uint);
                }

                if (full_data.Length - _position < _static_header)
                {
                    break;
                }

                switch (_static_header)
                {
                case 0: _length = 0; break;

                case 1: _length = full_data[_position]; break;

                case 2: _length = (ushort)((full_data[_position] * 256) + full_data[_position + 1]); break;

                case 3: _length = (full_data[_position] * 256 * 256) + (full_data[_position + 1] * 256) + full_data[_position + 2]; break;
                }

                _position += _static_header;

                long _current_data_len = full_data.Length - _position;
                if (_current_data_len >= _length)
                {
                    NetworkElement _element = BotofuProtocolManager.Protocol[ProtocolKeyEnum.Messages, x => x.protocolID == _message_id];
                    _data = new byte[_current_data_len];

                    if (_tag == ProxyTagEnum.Client)
                    {
                        // rmv element from not game socket
                        if (_instance_id > _proxy.GLOBAL_INSTANCE_ID * 2)
                        {
                            _element = null;
                        }
                        else
                        {
                            _proxy.LAST_CLIENT_INSTANCE_ID    = _instance_id.Value;
                            _proxy.MESSAGE_RECEIVED_FROM_LAST = 0;
                        }
                    }
                    else
                    {
                        if (_message_id == StaticValues.RAW_DATA_MSG_RCV_ID) // rdm
                        {
                            _element = BotofuProtocolManager.Protocol[ProtocolKeyEnum.Messages, x => x.name == "RawDataMessage"];
                        }
                        _proxy.MESSAGE_RECEIVED_FROM_LAST++;
                    }

                    byte[] packet_data = new byte[(int)(_position - start_pos) + _length.Value];
                    Array.Copy(full_data, start_pos, packet_data, 0, packet_data.Length);
                    Array.Copy(full_data, _position, _data, 0, _length.Value);

                    if (_element != null)
                    {
                        logger.Info($"[{_tag}] {_element.BasicString} n°{_proxy.GLOBAL_INSTANCE_ID}");
                        _data_buffer_reader = new MessageDataBufferReader(_element);

                        using (BigEndianReader big_data_reader = new BigEndianReader(_data))
                        {
                            if (_handler.Handle(this, _element, _data_buffer_reader.Parse(big_data_reader)).Result)
                            {
                                _client_sender.Handle(_remote, packet_data);
                            }
                        }
                    }
                    else
                    {
                        _client_sender.Handle(_remote, packet_data);
                    }

                    _position += _length.Value;

                    if (_current_data_len == _length)
                    {
                        _clear();

                        _reader.Dispose();
                        _reader   = new BigEndianReader();
                        _position = 0;
                        break;
                    }
                    _clear();
                }
                else
                {
                    _position = start_pos;
                    break;
                }
            }
        }