/// <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; } } }