/// <summary> /// Processes a message received from a chat room -- SNAC(0E,06) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(0E,06)</param> internal void ProcessIncomingMessage(DataPacket dp) { UserInfo sender = new UserInfo(); byte[] message; Encoding encoding = Encoding.ASCII; string language = ""; byte[] cookie = dp.Data.ReadByteArray(8); ushort channel = dp.Data.ReadUshort(); using (TlvBlock outerTlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { using (ByteStream userStream = new ByteStream(outerTlvs.ReadByteArray(0x0003))) { sender = userStream.ReadUserInfo(); } using (TlvBlock innerTlvs = new TlvBlock(outerTlvs.ReadByteArray(0x0005))) { message = innerTlvs.ReadByteArray(0x0001); encoding = Marshal.AolMimeToEncoding(innerTlvs.ReadString(0x0002, Encoding.ASCII)); language = innerTlvs.ReadString(0x0003, Encoding.ASCII); } } if (MessageReceived != null) { IM msg = new IM(sender); msg.Message = Encoding.Unicode.GetString(Encoding.Convert(encoding, Encoding.Unicode, message)); msg.Cookie = Cookie.GetReceivedCookie(cookie); MessageReceived(this, new MessageReceivedEventArgs(msg)); } }
private void ProcessMetaInformationResponse(DataPacket dp) { using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { if (tlvs.HasTlv(0x0001)) { ByteStream stream = new ByteStream(tlvs.ReadByteArray(0x0001)); ushort cmdLength = stream.ReadUshortLE(); String uin = stream.ReadUintLE().ToString(); ushort command = stream.ReadUshortLE(); ushort requestId = stream.ReadUshortLE(); MetaResponseType responseType = (MetaResponseType)command; switch (responseType) { case MetaResponseType.OfflineMessage: parent.Messages.ReadIcqOfflineMessage(uin, stream); break; case MetaResponseType.EndOfflineMessage: parent.Messages.EndOfflineMessageSequence(uin, true); break; case MetaResponseType.MetaDataReply: this.ProcessMetaDataReply(uin, dp, stream); break; } } } }
/// <summary> /// Processes requested chat room information -- SNAC(0D,09) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(0D,09)</param> public void ProcessChatRoomInformation(DataPacket dp) { ushort maxRooms = 0xFFFF; ReadOnlyCollection <Tlv> exchangeTlvs = null; ChatRoom newRoom = null; // Parse the response using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { maxRooms = tlvs.ReadByte(0x0002); if (tlvs.HasTlv(0x0003)) { exchangeTlvs = tlvs.ReadAllTlvs(0x0003); } if (tlvs.HasTlv(0x0004)) { newRoom = new ChatRoom(new ByteStream(tlvs.ReadByteArray(0x0004))); } } // If this packet was received in response to a chat room creation request, // request a new chat room connection from the BOS connection if (newRoom != null) { RequestChatRoomConnection(newRoom); } }
/// <summary> /// Processes user information sent by the server -- SNAC(02,06) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(02,06)</param> private void ProcessUserInfo(DataPacket dp) { if (dp.SNAC.Flags != 0) { Logging.DumpFLAP(dp.Data.GetBytes(), "You've got to be s******g me"); } // Apparently, the userinfo block will always be first, // and then possibly TLVs 0x0001 - 0x0005, depending on the request byte[] awaymessage = null; Encoding awaymessageencoding = Encoding.ASCII; byte[] profile = null; Encoding profileencoding = Encoding.ASCII; Capabilities caps = Capabilities.None; UserInfo ui = dp.Data.ReadUserInfo(); using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { profileencoding = Marshal.AolMimeToEncoding(tlvs.ReadString(LOCATION_PROFILE_ENCODING, Encoding.ASCII)); profile = tlvs.ReadByteArray(LOCATION_PROFILE); awaymessageencoding = Marshal.AolMimeToEncoding(tlvs.ReadString(LOCATION_AWAYMESSAGE_ENCODING, Encoding.ASCII)); awaymessage = tlvs.ReadByteArray(LOCATION_AWAYMESSAGE); caps = CapabilityProcessor.ProcessCLSIDList(tlvs.ReadByteArray(LOCATION_CAPABILITIES)); } UserInfoResponse uir = new UserInfoResponse(); uir.Info = ui; if (profile != null) { uir.Profile = profileencoding.GetString(profile, 0, profile.Length); uir.ProfileEncoding = profileencoding; } if (awaymessage != null) { uir.AwayMessage = awaymessageencoding.GetString(awaymessage, 0, awaymessage.Length); uir.AwayMessageEncoding = awaymessageencoding; } uir.ClientCapabilities = caps; if (UserInfoReceived != null) { UserInfoReceived(this, uir); } }
/// <summary> /// Processes the server response to a new family request -- SNAC(01,05) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(01,05)</param> private void ProcessNewServiceResponse(DataPacket dp) { int startIndex = 0; byte[] SNACData = dp.Data.ReadByteArrayToEnd(); if (SNACData[0] == 0x00 && SNACData[1] == 0x06) { startIndex += 2; // What the heck is this...0x0006, some families, some of the time? } using (TlvBlock tlvs = new TlvBlock(SNACData, startIndex)) { ushort family = tlvs.ReadUshort(NEW_SERVICE_FAMILY); string BOSaddress = tlvs.ReadString(NEW_SERVICE_ADDRESS, Encoding.ASCII); byte[] cookie = tlvs.ReadByteArray(NEW_SERVICE_COOKIE); Connection newconn = null; object store = dp.ParentSession.RetrieveRequestID(dp.SNAC.RequestID); if (family != 0x000E) { newconn = dp.ParentSession.Connections.CreateNewConnection(family); } else { ChatRoom roominfo = (ChatRoom)store; newconn = dp.ParentSession.Connections.CreateNewChatConnection(roominfo); } string[] bosinfo = BOSaddress.Split(':'); int port = 0; if (bosinfo.Length == 2) { port = Int32.Parse(bosinfo[1]); } else { port = dp.ParentSession.ServerSettings.LoginPort; } newconn.ServerConnectionCompleted += delegate { newconn.ReadHeader(); }; newconn.Server = bosinfo[0]; newconn.Port = port; newconn.Cookie = new Cookie(cookie); newconn.ConnectToServer(); } // The connection process continues when the server sends SNAC(01,03) }
public void TestChatRoomCreation() { ByteStream dataStream = new ByteStream(Data.SNAC_0D_09); using (TlvBlock tlvs = new TlvBlock(dataStream.ReadByteArrayToEnd())) { Assert.IsTrue(tlvs.HasTlv(0x0004), "TLV 0x0004 missing from data stream"); ChatRoom chatRoom = new ChatRoom(new ByteStream(tlvs.ReadByteArray(0x0004))); Assert.AreEqual(0x0004, chatRoom.Exchange); Assert.AreEqual("!aol://2719:10-4-chat9614646934270543373", chatRoom.FullName); Assert.AreEqual(0x0000, chatRoom.Instance); Assert.AreEqual("Chat 9614646934270543373", chatRoom.DisplayName); Assert.AreEqual(new DateTime(2007, 8, 5, 20, 9, 21, DateTimeKind.Utc), chatRoom.CreationTime); } }
/// <summary> /// Processes a login response -- SNAC(17,03) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object containing SNAC(17,03)</param> internal void ProcessLoginResponse(DataPacket dp) { // Pull apart SNAC(17,03) Cookie cookie; string BOSaddress; using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { if (tlvs.HasTlv(0x0008)) { ushort errorcode = tlvs.ReadUshort(0x0008); parent.OnLoginFailed((LoginErrorCode)errorcode); return; } BOSaddress = tlvs.ReadString(0x0005, Encoding.ASCII); cookie = Cookie.GetReceivedCookie(tlvs.ReadByteArray(0x0006)); } // Shut down the authorization connection // Socket shutdown is initiated by the server parent.OnLoginStatusUpdate("Authorized", 0.33); dp.ParentConnection.DisconnectFromServer(false); // Create a new connection to the BOS server Connection newconn = parent.Connections.CreateNewConnection(0x0001); string[] bosinfo = BOSaddress.Split(':'); newconn.ServerConnectionCompleted += delegate(Connection conn) { conn.ReadyForData = true; conn.ReadHeader(); }; newconn.Server = bosinfo[0]; if (bosinfo.Length == 2) { newconn.Port = Int32.Parse(bosinfo[1]); } else { newconn.Port = dp.ParentConnection.Port; } Logging.WriteString("Connect to Server after auth. Address from dp: {0} - Address to connect: {1}:{2}", BOSaddress, newconn.Server, newconn.Port); newconn.Cookie = cookie; newconn.ConnectToServer(); // The login process continues when the server sends SNAC(01,03) on the new connection }