/// <summary> /// /// </summary> /// <param name="buffer"></param> /// <returns></returns> public static ProtocolVersion GetProtocolVersion(byte[] buffer) { using (MemoryStream stream = new MemoryStream(buffer)) { using (BinaryBitReader reader = new BinaryBitReader((Stream)stream)) { if (!CheckSignature(reader.ReadByte())) { throw new FormatException("Invalid signature!"); } reader.ReadBoolean(); reader.ReadBoolean(); return((ProtocolVersion)reader.ReadUInt(3)); } } }
/// <summary> /// /// </summary> /// <param name="payload"></param> protected override void unpack(BinaryBitReader reader) { ReadLocation(reader); if (this.Version >= ProtocolVersion.v4__WeatherExtension) { if (reader.ReadBoolean()) { RequestLat = reader.ReadFloat(true, 7, 13); RequestLon = reader.ReadFloat(true, 8, 13); PointKey = (byte)reader.ReadUInt(4); } } }
protected override void unpack(BinaryBitReader reader) { Time = START.AddDays(reader.ReadUInt(14)); Time = Time.AddHours(reader.ReadUInt(5)); Time = Time.AddMinutes(reader.ReadUInt(2) * 15); if (reader.ReadBoolean()) { MonthlyBegin = START.AddDays(reader.ReadUInt(14)); MonthlyNext = START.AddDays(reader.ReadUInt(14)); } Balance = (int?)reader.ReadIntNullable(15); Units = (int?)reader.ReadIntNullable(15); Usages = (int?)reader.ReadIntNullable(15); }
/// <summary> /// /// </summary> /// <param name="reader"></param> protected void ReadLocation(BinaryBitReader reader) { if (Version >= ProtocolVersion.v2__LocationFix) { Lat = reader.ReadFloat(true, 7, 13); Lon = reader.ReadFloat(true, 8, 13); } else { Lat = reader.ReadFloat(true, 7, 9); Lon = reader.ReadFloat(true, 8, 9); } bool hasAlt = reader.ReadBoolean(); if (hasAlt) { Alt = (int)reader.ReadUInt(14); } }
/// <summary> /// /// </summary> /// <param name="direction"></param> /// <param name="buffer"></param> /// <returns></returns> public static Message Unpack(byte[] buffer, IPacketBuffer packetBuffer = null) { if (packetBuffer == null) { packetBuffer = new RealmPacketBuffer(); } using (MemoryStream stream = new MemoryStream(buffer)) { using (BinaryBitReader reader = new BinaryBitReader((Stream)stream)) { if (!CheckSignature(reader.ReadByte())) { throw new FormatException("Invalid signature!"); } var direction = reader.ReadBoolean() ? Direction.MO : Direction.MT; var composite = reader.ReadBoolean() ? Composite.Complex : Composite.Simple; var version = reader.ReadUInt(3); var length = (0 + (reader.ReadBoolean() ? ((ushort)0x400) : ((ushort)0))) + (reader.ReadBoolean() ? ((ushort)0x200) : ((ushort)0)) + (reader.ReadBoolean() ? ((ushort)0x100) : ((ushort)0)); int parts = 1; int part = 0; int group = 0; if (composite == Composite.Complex) { group = reader.ReadByte(); parts = reader.ReadByte(); part = reader.ReadByte(); } MessageType messageType = (MessageType)reader.ReadByte(); length += reader.ReadByte(); byte[] payload = reader.ReadBytes(length); byte sum = reader.ReadByte(); int index = 0; while (true) { if (index >= (stream.Length - 1L)) { if (sum != 0) { throw new FormatException("Invalid checksum!"); } var types = direction == Direction.MT ? KnownMTTypes : KnownMOTypes; var type = types.Where(t => t.Key == messageType).FirstOrDefault(); Message message = (Message)Activator.CreateInstance(type.Value, true); message.Version = (ProtocolVersion)version; message.Composite = composite; message.Group = (byte)group; message.Index = (byte)part; message.TotalParts = (byte)parts; message.Payload = payload; var packet = new Packet() { Direction = direction == Direction.MO ? PacketDirection.Outbound : PacketDirection.Inbound, Index = message.Index, Group = message.Group, TotalParts = message.TotalParts, Payload = message.Payload, }; packetBuffer.SavePacket(packet); message.ReadyParts = (byte)packetBuffer.GetPacketCount(message.Group, packet.Direction); if (message.Complete) { var __parts = packetBuffer .GetPackets(message.Group, packet.Direction) .OrderBy(x => x.Index) .Select(x => x.Payload) .ToList(); message.Payload = ByteArrayHelper.Merge(__parts); using (MemoryStream stream2 = new MemoryStream(message.Payload)) { using (BinaryBitReader reader2 = new BinaryBitReader((Stream)stream2)) { message.unpack(reader2); } } packetBuffer.DeletePackets(message.Group, packet.Direction); } return(message); } sum -= buffer[index]; index++; } } } }
/// <summary> /// /// </summary> /// <param name="payload"></param> protected override void unpack(BinaryBitReader reader) { Forecast = new i360PointForecast(); bool extended = false; if (this.Version >= ProtocolVersion.v3__WeatherExtension) { extended = reader.ReadBoolean(); } Forecast.TimeOffset = (int)reader.ReadUInt(5) - 12; var dates = new int[16]; var forecasts = new List <i360Forecast>(); int month = 0; for (int j = 0; j < 16; j++) { try { var forecast = new i360Forecast(); ///-> ///Дата не изменилась? bool sameDay = reader.ReadBoolean(); ///Если изменилась - сохраняем день от начала месяца if (!sameDay) { dates[j] = (int)reader.ReadUInt(5); } else { dates[j] = dates[j - 1]; } if (j > 0 && dates[j] < dates[j - 1]) { month++; } int hourOffset = (int)reader.ReadUInt(5); forecast.Date = new DateTime(DateTime.Now.Year, DateTime.Now.Month + month, dates[j], hourOffset, 0, 0, DateTimeKind.Utc); ///-> forecast.Temperature = (int)reader.ReadUInt(7) - 70; ///-> uint?_pressure = reader.ReadUIntNullable(8); if (_pressure != null) { forecast.Pressure = (int)_pressure + 580; } ///-> uint?_cloud = reader.ReadUIntNullable(4); if (_cloud != null) { forecast.Cloud = Math.Min(100, (int)_cloud * 15); } ///-> /// uint?_precipitation = reader.ReadUIntNullable(8); if (_precipitation != null) { forecast.Precipitation = _precipitation / 4d; } ///-> uint?_windDirection = reader.ReadUIntNullable(4); if (_windDirection != null) { forecast.WindDirection = (int)Math.Round(_windDirection.Value * 45d); } ///--> forecast.WindSpeed = reader.ReadUIntNullable(6); ///-> forecast.SnowRisk = reader.ReadBoolean(); ///-> if (this.Version >= ProtocolVersion.v3__WeatherExtension && extended) { ///-> uint?_cloudHeight = reader.ReadUIntNullable(8); if (_cloudHeight != null) { forecast.CloudHeight = (int)(_cloudHeight.Value * 70d); } ///-> uint?_visibility = reader.ReadUIntNullable(10); if (_visibility != null) { forecast.Visibility = (int)(_visibility.Value * 10d); } ///-> forecast.WindGust = reader.ReadUIntNullable(6); ///-> } forecasts.Add(forecast); } catch (Exception e) { Debugger.Break(); } } Forecast.DayInfos = forecasts.GroupBy(x => x.Date.Date).Select(x => new i360DayInfo() { Date = x.Key }).ToList(); Forecast.Forecasts = forecasts; if (this.Version >= ProtocolVersion.v4__WeatherExtension) { if (reader.ReadBoolean()) { PointKey = (byte)reader.ReadUInt(4); } } }
protected static string Read(BinaryBitReader reader) { Page? page = null; StringBuilder builder = new StringBuilder(); byte[] bytes = new byte[] { }; while (true) { try { if (page == Page.UNICODE_FORCE) { var b = reader.ReadByte(); if (b == (byte)Page.END) { break; } Array.Resize(ref bytes, bytes.Length + 1); bytes[bytes.Length - 1] = b; } else { int num = (((((0 + (reader.ReadBoolean() ? 1 : 0)) + ((reader.ReadBoolean() ? 1 : 0) << 1)) + ((reader.ReadBoolean() ? 1 : 0) << 2)) + ((reader.ReadBoolean() ? 1 : 0) << 3)) + ((reader.ReadBoolean() ? 1 : 0) << 4)) + ((reader.ReadBoolean() ? 1 : 0) << 5); if (num < 8) { page = (Page?)num; if (page == Page.END) { break; } } else { switch (page) { case Page.SYM: builder.Append(page_sym[num - 8]); break; case Page.EN: builder.Append(page_en[num - 8]); break; case Page.RU: builder.Append(page_ru[num - 8]); break; case Page.RU_EXT: builder.Append(page_ru_ext[num - 8]); break; default: throw new NotSupportedException(); } } } } catch (EndOfStreamException) { break; } catch (Exception) { Debugger.Break(); } } var bb = Encoding.UTF8.GetString(bytes); builder.Append(bb); return(builder.ToString()); }