private NetworkMessage ParseTextPayloadMessage(NSMessage message) { TextPayloadMessage txtPayLoad = new TextPayloadMessage(string.Empty); txtPayLoad.CreateFromParentMessage(message); return(message); }
object ICloneable.Clone() { NSMessage messageClone = new NSMessage(); messageClone.ParseBytes(GetBytes()); if (messageClone.InnerBody == null && InnerBody != null) { messageClone.InnerBody = new byte[InnerBody.Length]; Buffer.BlockCopy(InnerBody, 0, messageClone.InnerBody, 0, InnerBody.Length); } return(messageClone); }
private NetworkMessage ParseSDGMessage(NSMessage nsMessage) { MultiMimeMessage multiMimeMessage = new MultiMimeMessage(); multiMimeMessage.CreateFromParentMessage(nsMessage); if (multiMimeMessage.ContentHeaders.ContainsKey(MIMEContentHeaders.MessageType)) { switch (multiMimeMessage.ContentHeaders[MIMEContentHeaders.MessageType].ToString()) { default: Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "[ParseSDGMessage] Cannot parse this type of SDG message: \r\n" + multiMimeMessage.ContentHeaders[MIMEContentHeaders.MessageType].ToString() + "\r\n\r\nMessage Body: \r\n\r\n" + multiMimeMessage.ToDebugString()); break; case MessageTypes.Nudge: case MessageTypes.ControlTyping: case MessageTypes.Wink: case MessageTypes.SignalCloseIMWindow: // Pure Text body, nothing to parse. ParseSDGTextPayloadMessage(multiMimeMessage); break; case MessageTypes.Text: // Set the TextMessage as its InnerMessage. ParseSDGTextMessage(multiMimeMessage); break; case MessageTypes.CustomEmoticon: // Set the EmoticonMessage as its InnerMessage. ParseSDGCustomEmoticonMessage(multiMimeMessage); break; case MessageTypes.SignalP2P: // Add the SLPMessage as its InnerMessage. ParseSDGP2PSignalMessage(multiMimeMessage); break; case MessageTypes.Data: //OnSDGDataMessageReceived(multiMimeMessage, sender, by, routingInfo); break; } } return(nsMessage); }
protected virtual void On801Received(NSMessage message) { /******* 801 45 5 0 6 6 *******/ if (message.InnerBody == null || message.InnerBody.Length == 0) return; string payload = Encoding.UTF8.GetString(message.InnerBody); int transID = message.TransactionID; Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "SDG message with TransId: " + transID + " couldn't be delivered. PIPE(SB) closed?" + "\r\rPayload:" + payload, GetType().Name); }
private NetworkMessage ParseMSGMessage(NSMessage message) { MimeMessage mimeMessage = new MimeMessage(); mimeMessage.CreateFromParentMessage(message); string mime = mimeMessage.MimeHeader[MIMEContentHeaders.ContentType].ToString(); if (mime.IndexOf("text/x-msmsgsprofile") >= 0) { //This is profile, the content is nothing. } else { MimeMessage innerMimeMessage = new MimeMessage(false); innerMimeMessage.CreateFromParentMessage(mimeMessage); } return(message); }
protected override void SendOnePacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage p2pMessage) { if (remote == null) return; string to = ((int)remote.ClientType).ToString() + ":" + remote.Account; string from = ((int)NSMessageHandler.Owner.ClientType).ToString() + ":" + NSMessageHandler.Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = NSMessageHandler.MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.To][MIMERoutingHeaders.EPID] = remoteGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.ServiceChannel] = "PE"; mmMessage.RoutingHeaders[MIMERoutingHeaders.Options] = "0"; mmMessage.ContentKeyVersion = "2.0"; SLPMessage slpMessage = p2pMessage.IsSLPData ? p2pMessage.InnerMessage as SLPMessage : null; if (slpMessage != null && ((slpMessage.ContentType == "application/x-msnmsgr-transreqbody" || slpMessage.ContentType == "application/x-msnmsgr-transrespbody" || slpMessage.ContentType == "application/x-msnmsgr-transdestaddrupdate"))) { mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.SignalP2P; mmMessage.InnerBody = slpMessage.GetBytes(false); mmMessage.InnerMessage = slpMessage; } else { mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/x-msnmsgrp2p"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentTransferEncoding] = "binary"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.Data; //mmMessage.ContentHeaders[MIMEContentHeaders.Pipe] = PackageNo.ToString(); mmMessage.ContentHeaders[MIMEContentHeaders.BridgingOffsets] = "0"; mmMessage.InnerBody = p2pMessage.GetBytes(true); mmMessage.InnerMessage = p2pMessage; } NSMessageProcessor nsmp = (NSMessageProcessor)NSMessageHandler.MessageProcessor; int transId = nsmp.IncreaseTransactionID(); lock (p2pAckMessages) p2pAckMessages[transId] = new P2PMessageSessionEventArgs(p2pMessage, session); NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.TransactionID = transId; sdgPayload.InnerMessage = mmMessage; nsmp.SendMessage(sdgPayload, sdgPayload.TransactionID); }
/// <summary> /// Called when a GCF command has been received. /// </summary> /// <remarks>Indicates that the server has send bad words for messaging.</remarks> /// <param name="message"></param> protected virtual void OnGCFReceived(NSMessage message) { NetworkMessage networkMessage = message as NetworkMessage; if (networkMessage.InnerBody != null) { censorWords.Clear(); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(new MemoryStream(networkMessage.InnerBody)); XmlNodeList imtexts = xmlDoc.GetElementsByTagName("imtext"); foreach (XmlNode imtextNode in imtexts) { string censor = Encoding.UTF8.GetString(Convert.FromBase64String(imtextNode.Attributes["value"].Value)); censorWords.Add(new Regex(censor)); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Censor: " + censor, GetType().Name); } } }
/// <summary> /// Called when a RML command has been received. /// </summary> /// <remarks>Indicates that someone was removed from a list by local user (RML [Trans-ID] OK) /// or local user was removed from someone's reverse list (RML 0 [Trans-ID]\r\n[payload]).</remarks> /// <param name="nsMessage"></param> protected virtual void OnRMLReceived(NSMessage nsMessage) { NetworkMessage networkMessage = nsMessage as NetworkMessage; if (networkMessage.InnerBody != null) //Payload RML command. { ContactService.msRequest(PartnerScenario.Initial, null); if (Settings.TraceSwitch.TraceVerbose) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(new MemoryStream(networkMessage.InnerBody)); XmlNodeList domains = xmlDoc.GetElementsByTagName("d"); string domain = String.Empty; foreach (XmlNode domainNode in domains) { domain = domainNode.Attributes["n"].Value; XmlNode contactNode = domainNode.FirstChild; do { string account = contactNode.Attributes["n"].Value + "@" + domain; IMAddressInfoType type = (IMAddressInfoType)int.Parse(contactNode.Attributes["t"].Value); RoleLists list = (RoleLists)int.Parse(contactNode.Attributes["l"].Value); account = account.ToLower(CultureInfo.InvariantCulture); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, account + ":" + type + " has removed you from his/her " + list.ToString(), GetType().Name); } while (contactNode.NextSibling != null); } } } }
/// <summary> /// Called when a NOT command has been received. /// </summary> /// <remarks> /// Indicates that a notification message has been received. /// <code>NOT [body length]</code> /// </remarks> /// <param name="message"></param> protected virtual void OnNOTReceived(NSMessage message) { // build a notification message NotificationMessage notification = new NotificationMessage(message); Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "Notification received : " + notification.BodyPayload); if (notification.NotificationTypeSpecified == false && notification.Id == 0 && notification.SiteId == 45705 && notification.MessageId == 0 && notification.SendDevice == "messenger" && notification.ReceiverAccount.ToLowerInvariant() == Owner.Account) { string xmlString = notification.BodyPayload; XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlString); XmlNode node = xmlDoc.SelectSingleNode(@"//NotificationData"); if (node == null) return; node = xmlDoc.SelectSingleNode(@"//NotificationData/Service"); if (node != null) { if (node.InnerText != "ABCHInternal") return; node = xmlDoc.SelectSingleNode(@"//NotificationData/CID"); if (node == null) return; if (node.InnerText != Owner.CID.ToString()) return; ContactService.ServerNotificationRequest(PartnerScenario.ABChangeNotifyAlert, null, null); } else { node = xmlDoc.SelectSingleNode(@"//NotificationData/CircleId"); if (node == null) return; string abId = node.InnerText; node = xmlDoc.SelectSingleNode(@"//NotificationData/Role"); RoleId role = RoleId.Member; if (node != null) { role = (RoleId)Enum.Parse(typeof(RoleId), node.InnerText); } object[] param = new object[] { abId, role }; ContactService.ServerNotificationRequest(PartnerScenario.CircleIdAlert, param, null); } } }
protected internal virtual void SendTextMessage(Contact remoteContact, TextMessage textMessage) { textMessage.PrepareMessage(); string to = ((int)remoteContact.ClientType).ToString() + ":" + remoteContact.Account; string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = NSMessageHandler.MachineGuid.ToString("B").ToLowerInvariant(); if (remoteContact.ClientType == IMAddressInfoType.Circle) { mmMessage.RoutingHeaders[MIMERoutingHeaders.To][MIMERoutingHeaders.Path] = "IM"; } else if (remoteContact.Online) { mmMessage.RoutingHeaders[MIMERoutingHeaders.ServiceChannel] = "IM/Online"; } else { mmMessage.RoutingHeaders[MIMERoutingHeaders.ServiceChannel] = "IM/Offline"; } if (remoteContact.Via != null) { mmMessage.RoutingHeaders[MIMERoutingHeaders.To]["via"] = ((int)remoteContact.Via.ClientType).ToString() + ":" + remoteContact.Via.Account; } mmMessage.ContentKeyVersion = "2.0"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.Text; mmMessage.ContentHeaders[MIMEHeaderStrings.X_MMS_IM_Format] = textMessage.GetStyleString(); mmMessage.InnerBody = Encoding.UTF8.GetBytes(textMessage.Text); NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(sdgPayload); }
/// <summary> /// Set the status of the contact list owner (the client). /// </summary> /// <remarks>You can only set the status _after_ SignedIn event. Otherwise you won't receive online notifications from other clients or the connection is closed by the server.</remarks> internal void SetPresenceStatus( PresenceStatus newStatus, ClientCapabilities newLocalIMCaps, ClientCapabilitiesEx newLocalIMCapsex, ClientCapabilities newLocalPECaps, ClientCapabilitiesEx newLocalPECapsex, string newEPName, PersonalMessage newPSM, bool forcePEservice) { if (IsSignedIn == false) throw new MSNPSharpException("Can't set status. You must wait for the SignedIn event before you can set an initial status."); if (newStatus == PresenceStatus.Offline) { SignoutFrom(MachineGuid); return; } bool setAll = (Owner.Status == PresenceStatus.Offline); if (setAll || forcePEservice || newStatus != Owner.Status || newLocalIMCaps != Owner.LocalEndPointIMCapabilities || newLocalIMCapsex != Owner.LocalEndPointIMCapabilitiesEx || newLocalPECaps != Owner.LocalEndPointPECapabilities || newLocalPECapsex != Owner.LocalEndPointPECapabilitiesEx || newEPName != Owner.EpName) { XmlDocument xmlDoc = new XmlDocument(); XmlElement userElement = xmlDoc.CreateElement("user"); // s.IM (Status, CurrentMedia) if (setAll || forcePEservice || newStatus != Owner.Status) { XmlElement service = xmlDoc.CreateElement("s"); service.SetAttribute("n", ServiceShortNames.IM.ToString()); service.InnerXml = "<Status>" + ParseStatus(newStatus) + "</Status>" + "<CurrentMedia>" + MSNHttpUtility.XmlEncode(newPSM.CurrentMedia) + "</CurrentMedia>"; userElement.AppendChild(service); // Don't call Owner.Status = newStatus. } // s.PE (UserTileLocation, FriendlyName, PSM, Scene, ColorScheme) if (setAll || forcePEservice) { XmlElement service = xmlDoc.CreateElement("s"); service.SetAttribute("n", ServiceShortNames.PE.ToString()); service.InnerXml = newPSM.Payload; userElement.AppendChild(service); // Don't set owner.PersonalMessage here. It is replaced (with a new reference) when NFY PUT received. } // sep.IM (Capabilities) if (setAll || newLocalIMCaps != Owner.LocalEndPointIMCapabilities || newLocalIMCapsex != Owner.LocalEndPointIMCapabilitiesEx) { ClientCapabilities localIMCaps = setAll ? ClientCapabilities.DefaultIM : newLocalIMCaps; ClientCapabilitiesEx localIMCapsEx = setAll ? ClientCapabilitiesEx.DefaultIM : newLocalIMCapsex; XmlElement sep = xmlDoc.CreateElement("sep"); sep.SetAttribute("n", ServiceShortNames.IM.ToString()); XmlElement capabilities = xmlDoc.CreateElement("Capabilities"); capabilities.InnerText = ((long)localIMCaps).ToString() + ":" + ((long)localIMCapsEx).ToString(); sep.AppendChild(capabilities); userElement.AppendChild(sep); // Don't call Owner.LocalEndPointIMCapabilities. It is recursive call to this method. } // sep.PE (Capabilities) if (setAll || newLocalPECaps != Owner.LocalEndPointPECapabilities || newLocalPECapsex != Owner.LocalEndPointPECapabilitiesEx) { ClientCapabilities localPECaps = setAll ? ClientCapabilities.DefaultPE : newLocalPECaps; ClientCapabilitiesEx localPECapsEx = setAll ? ClientCapabilitiesEx.DefaultPE : newLocalPECapsex; XmlElement sep = xmlDoc.CreateElement("sep"); sep.SetAttribute("n", ServiceShortNames.PE.ToString()); XmlElement VER = xmlDoc.CreateElement("VER"); VER.InnerText = Credentials.ClientInfo.MessengerClientName + ":" + Credentials.ClientInfo.MessengerClientBuildVer; sep.AppendChild(VER); XmlElement TYP = xmlDoc.CreateElement("TYP"); TYP.InnerText = "1"; sep.AppendChild(TYP); XmlElement capabilities = xmlDoc.CreateElement("Capabilities"); capabilities.InnerText = ((long)localPECaps).ToString() + ":" + ((long)localPECapsEx).ToString(); sep.AppendChild(capabilities); userElement.AppendChild(sep); // Don't call Owner.LocalEndPointPECapabilities. It is recursive call to this method. } // sep.PD (EpName, State) if (setAll || newEPName != Owner.EpName || newStatus != Owner.Status) { XmlElement sep = xmlDoc.CreateElement("sep"); sep.SetAttribute("n", ServiceShortNames.PD.ToString()); XmlElement clientType = xmlDoc.CreateElement("ClientType"); clientType.InnerText = "1"; sep.AppendChild(clientType); XmlElement epName = xmlDoc.CreateElement("EpName"); epName.InnerText = MSNHttpUtility.XmlEncode(newEPName); sep.AppendChild(epName); XmlElement idle = xmlDoc.CreateElement("Idle"); idle.InnerText = ((newStatus == PresenceStatus.Idle) ? "true" : "false"); sep.AppendChild(idle); XmlElement state = xmlDoc.CreateElement("State"); state.InnerText = ParseStatus(newStatus); sep.AppendChild(state); userElement.AppendChild(sep); // Don't set Owner.EpName. It is recursive call to this method. } if (userElement.HasChildNodes) { string xml = userElement.OuterXml; string me = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(me, me); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = NSMessageHandler.MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.Stream = 1; mmMessage.ReliabilityHeaders[MIMEReliabilityHeaders.Flags] = "ACK"; mmMessage.ContentKey = MIMEContentHeaders.Publication; mmMessage.ContentHeaders[MIMEContentHeaders.URI] = "/user"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/user+xml"; mmMessage.InnerBody = System.Text.Encoding.UTF8.GetBytes(xml); NSMessage nsMessage = new NSMessage("PUT"); nsMessage.InnerMessage = mmMessage; MessageProcessor.SendMessage(nsMessage); } } }
public void LeaveMultiparty(Contact group) { string to = ((int)group.ClientType).ToString() + ":" + group.Account; string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.ContentKey = MIMEContentHeaders.Publication; mmMessage.ContentHeaders[MIMEContentHeaders.URI] = "/circle/roster(IM)/user(" + from + ")"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/circles+xml"; mmMessage.InnerBody = new byte[0]; NSMessage delPayload = new NSMessage("DEL"); delPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(delPayload); lock (multiParties) { int delTransId = 0; foreach (MultipartyObject g in multiParties.Values) { if (g.MultiParty != null && g.MultiParty.Account == group.Account) { delTransId = g.TransactionID; break; } } if (delTransId != 0) multiParties.Remove(delTransId); } }
protected internal virtual void SendEmoticonDefinitions(Contact remoteContact, List<Emoticon> emoticons, EmoticonType icontype) { EmoticonMessage emoticonMessage = new EmoticonMessage(emoticons, icontype); string to = ((int)remoteContact.ClientType).ToString() + ":" + remoteContact.Account; string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.ContentKeyVersion = "2.0"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.CustomEmoticon; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = icontype == EmoticonType.AnimEmoticon ? "text/x-mms-animemoticon" : "text/x-mms-emoticon"; mmMessage.InnerBody = emoticonMessage.GetBytes(); NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(sdgPayload); }
/// <summary> /// Called when a CVR command has been received. /// </summary> /// <remarks> /// Indicates that the server has approved our client details. This function will send the USR command. /// <code>CVR [Transaction] [Recommended version] [Recommended version] [Minimum version] [Download url] [Info url]</code> /// </remarks> /// <param name="message"></param> protected virtual void OnCVRReceived(NSMessage message) { }
/// <summary> /// Creates a new multiparty (Group chat) /// </summary> /// <param name="inviteQueue">Contacts to be invited (don't add yourself)</param> /// <param name="onCreated">The handler to be executed when multiparty created (must be provided)</param> /// <exception cref="ArgumentNullException">inviteQueue or event handler is null</exception> /// <exception cref="InvalidOperationException">At least 2 contacts is required except you and contacts must support multiparty</exception> /// <returns>Transaction ID</returns> public int CreateMultiparty(List<Contact> inviteQueue, EventHandler<MultipartyCreatedEventArgs> onCreated) { if (inviteQueue == null || inviteQueue.Count == 0) throw new ArgumentNullException("inviteQueue"); if (onCreated == null) throw new ArgumentNullException("onCreated"); List<string> newQueue = new List<string>(); foreach (Contact c in inviteQueue) { if (c != null && !c.IsSibling(Owner) && !newQueue.Contains(c.SiblingString) && c.SupportsMultiparty) { newQueue.Add(c.SiblingString); } } if (newQueue.Count < 2) throw new InvalidOperationException("At least 2 contacts is required except you and contacts must support multiparty."); NSMessageProcessor nsmp = (NSMessageProcessor)MessageProcessor; int transId = nsmp.IncreaseTransactionID(); lock (multiParties) multiParties[transId] = new MultipartyObject(transId, newQueue, null, onCreated); string to = ((int)IMAddressInfoType.TemporaryGroup).ToString() + ":" + Guid.Empty.ToString("D").ToLowerInvariant() + "@" + Contact.DefaultHostDomain; string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.ContentKey = MIMEContentHeaders.Publication; mmMessage.ContentHeaders[MIMEContentHeaders.URI] = "/circle"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/multiparty+xml"; mmMessage.InnerBody = new byte[0]; NSMessage putPayload = new NSMessage("PUT"); putPayload.InnerMessage = mmMessage; nsmp.SendMessage(putPayload, transId); return transId; }
/// <summary> /// Called when a CHL (challenge) command message has been received. /// </summary> /// <param name="message"></param> protected virtual void OnCHLReceived(NSMessage message) { if (Credentials == null) throw new MSNPSharpException("No credentials available for the NSMSNP15 handler. No challenge answer could be send."); string payload = QRYFactory.CreateQRY(Credentials.ClientID, Credentials.ClientCode, message.CommandValues[0].ToString()); MessageProcessor.SendMessage(new NSPayLoadMessage("QRY", new string[] { Credentials.ClientID }, payload)); }
/// <summary> /// Called when a ADL command has been received. /// ADL [TransactionID] [OK] /// </summary> /// <param name="message"></param> protected virtual void OnADLReceived(NSMessage message) { if (message.TransactionID != 0 && message.CommandValues[0].ToString() == "OK") { if (ProcessADL(message.TransactionID)) { } } else { NetworkMessage networkMessage = message as NetworkMessage; if (networkMessage.InnerBody != null) //Payload ADL command { // ALL CHANGES WILL BE MADE BY msRequest() ContactService.msRequest(PartnerScenario.MessengerPendingList, null); } } }
protected virtual bool ProcessNetworkMessage(NSMessage nsMessage) { bool isUnknownMessage = false; switch (nsMessage.Command) { // Most used CMDs case "NFY": OnNFYReceived(nsMessage); break; case "SDG": OnSDGReceived(nsMessage); break; case "MSG": OnMSGReceived(nsMessage); break; case "QNG": OnQNGReceived(nsMessage); break; case "ADL": OnADLReceived(nsMessage); break; case "RML": OnRMLReceived(nsMessage); break; case "PUT": OnPUTReceived(nsMessage); break; case "DEL": OnDELReceived(nsMessage); break; // Other CMDs case "CHL": OnCHLReceived(nsMessage); break; case "NOT": OnNOTReceived(nsMessage); break; case "OUT": OnOUTReceived(nsMessage); break; case "QRY": OnQRYReceived(nsMessage); break; case "SBS": OnSBSReceived(nsMessage); break; case "VER": OnVERReceived(nsMessage); break; case "CVR": OnCVRReceived(nsMessage); break; case "USR": OnUSRReceived(nsMessage); break; case "XFR": OnXFRReceived(nsMessage); break; case "GCF": OnGCFReceived(nsMessage); break; // Error codes case "801": On801Received(nsMessage); break; default: isUnknownMessage = true; break; } return !isUnknownMessage; }
/// <summary> /// Called when a XFR command has been received. /// </summary> /// <remarks> /// Indicates that the notification server has send us the location that we must switch to a new notification server. /// <code>XFR 0 [NS] [*.gateway.edge.messenger.live.com:Port] [G] [D] [HopString]</code> /// <code>XFR [Transaction] [NS] [IP:Port] [U] [D] [HopString]</code> /// </remarks> /// <param name="message"></param> protected virtual void OnXFRReceived(NSMessage message) { if ((string)message.CommandValues[0] == "NS") { // switch to a new notification server. That means reconnecting our current message processor. NSMessageProcessor processor = (NSMessageProcessor)MessageProcessor; // set new connectivity settings ConnectivitySettings newSettings = new ConnectivitySettings(processor.ConnectivitySettings); // disconnect first processor.Disconnect(); processor = null; string[] hostAndPort = ((string)message.CommandValues[1]).Split(new char[] { ':' }); bool isGateway = message.CommandValues[2].ToString() == "G"; // Get hop count. Version: 1\r\nXfrCount: 2\r\n if (message.CommandValues.Count >= 5) { string hopString = Encoding.ASCII.GetString(Convert.FromBase64String((string)message.CommandValues[4])); Match m = Regex.Match(hopString, @"(\d+)").NextMatch(); if (m.Success) { hopCount = Convert.ToInt32(m.Value); } } if (Settings.DisableHttpPolling && isGateway) { newSettings.HttpPoll = false; newSettings.Host = ConnectivitySettings.DefaultHost; newSettings.Port = ConnectivitySettings.DefaultPort; } else { newSettings.HttpPoll = isGateway; newSettings.Host = hostAndPort[0]; newSettings.Port = int.Parse(hostAndPort[1], System.Globalization.CultureInfo.InvariantCulture); } // Register events and handler, NSMessageProcessor mp = new NSMessageProcessor(newSettings); this.MessageProcessor = mp; mp.Connect(); // then reconnect. The login procedure will now start over again. } }
/// <summary> /// Called when a USR command has been received. /// </summary> /// <remarks> /// /// <code>USR [Transaction] [SSO|OK] [Account] [Policy|Verified] [Nonce]</code> /// </remarks> /// <param name="message"></param> protected virtual void OnUSRReceived(NSMessage message) { //single-sign-on stuff if ((string)message.CommandValues[0] == "SSO") { string policy = (string)message.CommandValues[2]; string nonce = (string)message.CommandValues[3]; try { SingleSignOnManager.Authenticate( this, policy, delegate(object sender, EventArgs e) { if (messageProcessor != null && messageProcessor.Connected) { MBI mbi = new MBI(); string response = MSNTicket.SSOTickets[SSOTicketType.Clear].Ticket + " " + mbi.Encrypt(MSNTicket.SSOTickets[SSOTicketType.Clear].BinarySecret, nonce); MessageProcessor.SendMessage(new NSMessage("USR", new string[] { "SSO", "S", response, MachineGuid.ToString("B") })); } }, delegate(object sender, ExceptionEventArgs e) { if (messageProcessor != null) messageProcessor.Disconnect(); OnAuthenticationError(e); } ); } catch (Exception exception) { if (messageProcessor != null) messageProcessor.Disconnect(); OnAuthenticationError(new ExceptionEventArgs(exception)); return; } } else if ((string)message.CommandValues[0] == "OK") { // we sucesfully logged in if (Owner == null) { // set the owner's name and CID ContactList.SetOwner(new Owner(WebServiceConstants.MessengerIndividualAddressBookId, message.CommandValues[1].ToString(), msnTicket.OwnerCID, this)); Owner.GetCoreProfile( delegate(object sender1, EventArgs arg) { OnOwnerVerified(EventArgs.Empty); }, delegate(object sender2, ExceptionEventArgs exceptionArgs) { OnOwnerVerified(EventArgs.Empty); } ); pong = new System.Timers.Timer(1000); pong.Elapsed += new System.Timers.ElapsedEventHandler(pong_Elapsed); SendPing(); } Owner.PassportVerified = message.CommandValues[2].Equals("1"); } }
public void InviteContactToMultiparty(Contact contact, Contact group) { string to = ((int)group.ClientType).ToString() + ":" + group.Account; string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.To][MIMERoutingHeaders.Path] = "IM"; mmMessage.ContentKey = MIMEContentHeaders.Publication; mmMessage.ContentHeaders[MIMEContentHeaders.URI] = "/circle"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/multiparty+xml"; string xml = "<circle><roster><id>IM</id><user><id>" + ((int)contact.ClientType).ToString() + ":" + contact.Account + "</id></user></roster></circle>"; mmMessage.InnerBody = Encoding.UTF8.GetBytes(xml); NSMessage putPayload = new NSMessage("PUT"); putPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(putPayload); }
/// <summary> /// Called when a MSG command has been received. /// </summary> /// <remarks> /// Indicates that the notification server has send us a MSG. /// This is usually a MSG from the 'HOTMAIL' user (account is also 'HOTMAIL') which includes notifications /// about the contact list owner's profile, new mail, number of unread mails in the inbox, offline messages, etc. /// <code>MSG [Account] [Name] [Length]</code> /// </remarks> /// <param name="message"></param> protected virtual void OnMSGReceived(NSMessage message) { MimeMessage mimeMessage = message.InnerMessage as MimeMessage; string mime = mimeMessage.MimeHeader[MIMEContentHeaders.ContentType].ToString(); if (mime.IndexOf("text/x-msmsgsprofile") >= 0) { StrDictionary hdr = mimeMessage.MimeHeader; int clientPort = 0; if (hdr.ContainsKey("ClientPort")) { clientPort = int.Parse(mimeMessage.MimeHeader["ClientPort"].Replace('.', ' '), System.Globalization.CultureInfo.InvariantCulture); clientPort = ((clientPort & 255) * 256) + ((clientPort & 65280) / 256); } IPAddress ip = hdr.ContainsKey("ClientIP") ? IPAddress.Parse(hdr["ClientIP"]) : IPAddress.None; if (IPAddress.None != ip) { // set the external end point. This can be used in file transfer connectivity determing externalEndPoint = new IPEndPoint(ip, clientPort); } Owner.UpdateProfile(hdr); ContactService.SynchronizeContactList(); } else if (mime.IndexOf("x-msmsgsemailnotification") >= 0) { MimeMessage mimeEmailNotificationMessage = mimeMessage.InnerMessage as MimeMessage; OnNewMailReceived(new NewMailEventArgs( mimeMessage.MimeHeader[MIMEHeaderStrings.From], mimeEmailNotificationMessage.MimeHeader["Message-URL"], mimeEmailNotificationMessage.MimeHeader["Post-URL"], mimeEmailNotificationMessage.MimeHeader["Subject"], mimeEmailNotificationMessage.MimeHeader["Dest-Folder"], mimeEmailNotificationMessage.MimeHeader["From-Addr"], mimeEmailNotificationMessage.MimeHeader.ContainsKey("id") ? int.Parse(mimeEmailNotificationMessage.MimeHeader["id"], System.Globalization.CultureInfo.InvariantCulture) : 0 )); } else if (mime.IndexOf("x-msmsgsactivemailnotification") >= 0) { //Now this is the unread OIM info, not the new mail. MimeMessage mimeActiveEmailNotificationMessage = mimeMessage.InnerMessage as MimeMessage; OnMailboxChanged(new MailChangedEventArgs( mimeActiveEmailNotificationMessage.MimeHeader["Src-Folder"], mimeActiveEmailNotificationMessage.MimeHeader["Dest-Folder"], mimeActiveEmailNotificationMessage.MimeHeader.ContainsKey("Message-Delta") ? int.Parse(mimeActiveEmailNotificationMessage.MimeHeader["Message-Delta"], System.Globalization.CultureInfo.InvariantCulture) : 0 )); } else if (mime.IndexOf("x-msmsgsinitialemailnotification") >= 0) { MimeMessage mimeInitialEmailNotificationMessage = mimeMessage.InnerMessage as MimeMessage; OnMailboxStatusReceived(new MailboxStatusEventArgs( mimeInitialEmailNotificationMessage.MimeHeader.ContainsKey("Inbox-Unread") ? int.Parse(mimeInitialEmailNotificationMessage.MimeHeader["Inbox-Unread"], System.Globalization.CultureInfo.InvariantCulture) : 0, mimeInitialEmailNotificationMessage.MimeHeader.ContainsKey("Folders-Unread") ? int.Parse(mimeInitialEmailNotificationMessage.MimeHeader["Folders-Unread"], System.Globalization.CultureInfo.InvariantCulture) : 0, mimeInitialEmailNotificationMessage.MimeHeader["Inbox-URL"], mimeInitialEmailNotificationMessage.MimeHeader["Folders-URL"], mimeInitialEmailNotificationMessage.MimeHeader["Post-URL"] )); } else if (mime.IndexOf("x-msmsgsinitialmdatanotification") >= 0 || mime.IndexOf("x-msmsgsoimnotification") >= 0) { MimeMessage innerMimeMessage = mimeMessage.InnerMessage as MimeMessage; /* * <MD> * <E> * <I>884</I> Inbox total * <IU>0</IU> Inbox unread mail * <O>222</O> Sent + Junk + Drafts * <OU>15</OU> Junk unread mail * </E> * <Q> * <QTM>409600</QTM> * <QNM>204800</QNM> * </Q> * <M> * <!-- OIM Nodes --> * </M> * <M> * <!-- OIM Nodes --> * </M> * </MD> */ string xmlstr = innerMimeMessage.MimeHeader["Mail-Data"]; try { XmlDocument xdoc = new XmlDocument(); xdoc.LoadXml(xmlstr); XmlNodeList mdnodelist = xdoc.GetElementsByTagName("MD"); if (mdnodelist.Count > 0) { foreach (XmlNode node in mdnodelist[0]) { if (node.Name.ToLowerInvariant() == "e" && node.HasChildNodes) { int iu = 0; int ou = 0; foreach (XmlNode cnode in node.ChildNodes) { if (cnode.Name.ToLowerInvariant() == "iu") { int.TryParse(cnode.InnerText, out iu); break; } } foreach (XmlNode cnode in node.ChildNodes) { if (cnode.Name.ToLowerInvariant() == "ou") { int.TryParse(cnode.InnerText, out ou); break; } } OnMailboxStatusReceived(new MailboxStatusEventArgs( iu, ou, innerMimeMessage.MimeHeader["Inbox-URL"], innerMimeMessage.MimeHeader["Folders-URL"], innerMimeMessage.MimeHeader["Post-URL"] )); break; } } } } catch (Exception ex) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, ex.Message, GetType().Name); } } }
internal void JoinMultiparty(Contact group) { if (group.ClientType == IMAddressInfoType.Circle || group.ClientType == IMAddressInfoType.TemporaryGroup) { string to = ((int)group.ClientType).ToString() + ":" + group.Account; string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.ContentKey = MIMEContentHeaders.Publication; mmMessage.ContentHeaders[MIMEContentHeaders.URI] = "/circle"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/circles+xml"; string xml = "<circle><roster><id>IM</id><user><id>1:" + Owner.Account + "</id></user></roster></circle>"; mmMessage.InnerBody = Encoding.UTF8.GetBytes(xml); NSMessage putPayload = new NSMessage("PUT"); putPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(putPayload); OnJoinedGroupChat(new GroupChatParticipationEventArgs(Owner, group)); } }
/// <summary> /// Called when an OUT command has been received. /// </summary> /// <remarks> /// Indicates that the server has signed off the user. /// <code>OUT [Reason]</code> /// </remarks> /// <param name="message"></param> protected virtual void OnOUTReceived(NSMessage message) { if (message.CommandValues.Count == 1) { switch (message.CommandValues[0].ToString().ToUpper(System.Globalization.CultureInfo.InvariantCulture)) { case "OTH": OnSignedOff(new SignedOffEventArgs(SignedOffReason.OtherClient)); break; case "SSD": OnSignedOff(new SignedOffEventArgs(SignedOffReason.ServerDown)); break; default: OnSignedOff(new SignedOffEventArgs(SignedOffReason.None)); break; } } else OnSignedOff(new SignedOffEventArgs(SignedOffReason.None)); }
/// <summary> /// Sends a mobile message to the specified remote contact. This only works when /// the remote contact has it's mobile device enabled and has MSN-direct enabled. /// </summary> /// <param name="receiver"></param> /// <param name="text"></param> protected internal virtual void SendMobileMessage(Contact receiver, string text) { TextMessage txtMsg = new TextMessage(text); string to = ((int)receiver.ClientType).ToString() + ":" + ((receiver.ClientType == IMAddressInfoType.Telephone) ? "tel:" + receiver.Account : receiver.Account); string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.ServiceChannel] = "IM/Mobile"; mmMessage.ContentKeyVersion = "2.0"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.Text; mmMessage.ContentHeaders[MIMEContentHeaders.MSIMFormat] = txtMsg.GetStyleString(); mmMessage.InnerBody = Encoding.UTF8.GetBytes(txtMsg.Text); NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(sdgPayload); }
/// <summary> /// Called when a DEL command message has been received. /// </summary> /// <param name="message"></param> protected virtual void OnDELReceived(NSMessage message) { bool ok = message.CommandValues.Count > 0 && message.CommandValues[0].ToString() == "OK"; if (ok) { Trace.WriteLineIf(Settings.TraceSwitch.TraceVerbose, "DEL command accepted", GetType().Name); } }
protected internal virtual void SendTypingMessage(Contact remoteContact) { string to = ((int)remoteContact.ClientType).ToString() + ":" + remoteContact.Account; string from = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = NSMessageHandler.MachineGuid.ToString("B").ToLowerInvariant(); if (remoteContact.ClientType == IMAddressInfoType.Circle) { mmMessage.RoutingHeaders[MIMERoutingHeaders.To][MIMERoutingHeaders.Path] = "IM"; } if (remoteContact.Via != null) { mmMessage.RoutingHeaders[MIMERoutingHeaders.To]["via"] = ((int)remoteContact.Via.ClientType).ToString() + ":" + remoteContact.Via.Account; } mmMessage.ContentKeyVersion = "2.0"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.ControlTyping; mmMessage.InnerBody = new byte[0]; NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(sdgPayload); }
/// <summary> /// Called when a PUT command message has been received. /// </summary> /// <param name="message"></param> protected virtual void OnPUTReceived(NSMessage message) { bool ok = message.CommandValues.Count > 0 && message.CommandValues[0].ToString() == "OK"; if (multiParties.ContainsKey(message.TransactionID)) { if (ok == false || message.InnerBody == null || message.InnerBody.Length == 0) { lock (multiParties) multiParties.Remove(message.TransactionID); return; } MultiMimeMessage mmMessage = new MultiMimeMessage(message.InnerBody); string[] tempGroup = mmMessage.From.Value.Split(':'); IMAddressInfoType addressType = (IMAddressInfoType)int.Parse(tempGroup[0]); if (addressType == IMAddressInfoType.TemporaryGroup) { Contact group = new Contact(tempGroup[1].ToLowerInvariant(), IMAddressInfoType.TemporaryGroup, this); group.ContactList = new ContactList(new Guid(tempGroup[1].ToLowerInvariant().Split('@')[0]), null, group, this); MultipartyObject mpo = multiParties[message.TransactionID]; mpo.TransactionID = message.TransactionID; mpo.MultiParty = group; JoinMultiparty(group); List<string> copy = new List<string>(mpo.InviteQueueHash); foreach (string siblingHash in copy) { string[] addressTypeAndAccount = siblingHash.Split(new char[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries); Contact contact = ContactList.GetContactWithCreate(addressTypeAndAccount[1], (IMAddressInfoType)Enum.Parse(typeof(IMAddressInfoType), addressTypeAndAccount[0].ToString())); InviteContactToMultiparty(contact, group); } mpo.OnMultipartyCreatedLocally(this, new MultipartyCreatedEventArgs(group)); group.SetStatus(PresenceStatus.Online); Trace.WriteLineIf(Settings.TraceSwitch.TraceInfo, "MultipartyCreated: " + group.Account); } else { lock (multiParties) multiParties.Remove(message.TransactionID); } } }
internal void SignoutFrom(Guid endPointID) { if (messageProcessor == null || messageProcessor.Connected == false) return; if (endPointID == MachineGuid) { messageProcessor.Disconnect(); return; } string me = ((int)Owner.ClientType).ToString() + ":" + Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(me, me); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.ContentKey = MIMEContentHeaders.Publication; mmMessage.ContentHeaders[MIMEContentHeaders.URI] = "/user"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/user+xml"; string xml = "<user><sep n=\"IM\" epid=\"" + endPointID.ToString("B").ToLowerInvariant() + "\"/></user>"; mmMessage.InnerBody = Encoding.UTF8.GetBytes(xml); NSMessage delPayload = new NSMessage("DEL"); delPayload.InnerMessage = mmMessage; MessageProcessor.SendMessage(delPayload); }
/// <summary> /// Called when a QNG command has been received. /// </summary> /// <remarks> /// Indicates a ping answer. The number of seconds indicates the timespan in which another ping must be send. /// <code>QNG [Seconds]</code> /// </remarks> /// <param name="message"></param> protected virtual void OnQNGReceived(NSMessage message) { if (pong != null) { int seconds = int.Parse((string)message.CommandValues[0], System.Globalization.CultureInfo.InvariantCulture); if (seconds > 1) { try { pong.Interval = 1000 * (seconds - 1); pong.Enabled = true; } catch (ObjectDisposedException) { pong = null; } } } }
/// <summary> /// Called when a NFY command has been received. /// <code> /// NFY [TransactionID] [Operation: PUT|DEL] [Payload Length]\r\n[Payload Data] /// </code> /// </summary> /// <param name="message"></param> protected virtual void OnNFYReceived(NSMessage message) { NetworkMessage networkMessage = message as NetworkMessage; if (networkMessage.InnerBody == null || networkMessage.InnerBody.Length == 0) return; //PUT or DEL string command = message.CommandValues[0].ToString(); MultiMimeMessage multiMimeMessage = new MultiMimeMessage(networkMessage.InnerBody); if (!(multiMimeMessage.ContentHeaders.ContainsKey(MIMEContentHeaders.ContentType))) return; RoutingInfo routingInfo = RoutingInfo.FromMultiMimeMessage(multiMimeMessage, this); if (routingInfo == null) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[OnNFYReceived] Get Rounting Info Error."); return; } if (command == "PUT") { OnNFYPUTReceived(multiMimeMessage, routingInfo); } else if (command == "DEL") { OnNFYDELReceived(multiMimeMessage, routingInfo); } }
protected override void SendMultiPacket(P2PSession session, Contact remote, Guid remoteGuid, P2PMessage[] sendList) { if (remote == null) return; NSMessageProcessor nsmp = (NSMessageProcessor)NSMessageHandler.MessageProcessor; string to = ((int)remote.ClientType).ToString() + ":" + remote.Account; string from = ((int)NSMessageHandler.Owner.ClientType).ToString() + ":" + NSMessageHandler.Owner.Account; MultiMimeMessage mmMessage = new MultiMimeMessage(to, from); mmMessage.RoutingHeaders[MIMERoutingHeaders.From][MIMERoutingHeaders.EPID] = NSMessageHandler.MachineGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.To][MIMERoutingHeaders.EPID] = remoteGuid.ToString("B").ToLowerInvariant(); mmMessage.RoutingHeaders[MIMERoutingHeaders.ServiceChannel] = "PE"; mmMessage.RoutingHeaders[MIMERoutingHeaders.Options] = "0"; mmMessage.ContentKeyVersion = "2.0"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentType] = "application/x-msnmsgrp2p"; mmMessage.ContentHeaders[MIMEContentHeaders.ContentTransferEncoding] = "binary"; mmMessage.ContentHeaders[MIMEContentHeaders.MessageType] = MessageTypes.Data; List<string> bridgingOffsets = new List<string>(); List<object> userStates = new List<object>(); byte[] buffer = new byte[0]; foreach (P2PMessage p2pMessage in sendList) { SLPMessage slpMessage = p2pMessage.IsSLPData ? p2pMessage.InnerMessage as SLPMessage : null; if (slpMessage != null && ((slpMessage.ContentType == "application/x-msnmsgr-transreqbody" || slpMessage.ContentType == "application/x-msnmsgr-transrespbody" || slpMessage.ContentType == "application/x-msnmsgr-transdestaddrupdate"))) { SendOnePacket(session, remote, remoteGuid, p2pMessage); } else { bridgingOffsets.Add(buffer.Length.ToString()); buffer = NetworkMessage.AppendArray(buffer, p2pMessage.GetBytes(true)); int transId = nsmp.IncreaseTransactionID(); userStates.Add(transId); lock (p2pAckMessages) p2pAckMessages[transId] = new P2PMessageSessionEventArgs(p2pMessage, session); //mmMessage.ContentHeaders[MIMEContentHeaders.Pipe] = PackageNo.ToString(); } } if (buffer.Length > 0) { mmMessage.ContentHeaders[MIMEContentHeaders.BridgingOffsets] = String.Join(",", bridgingOffsets.ToArray()); mmMessage.InnerBody = buffer; int transId2 = nsmp.IncreaseTransactionID(); userStates.Add(transId2); NSMessage sdgPayload = new NSMessage("SDG"); sdgPayload.TransactionID = transId2; sdgPayload.InnerMessage = mmMessage; nsmp.Processor.Send(sdgPayload.GetBytes(), userStates.ToArray()); } }
//This is actually another OnMSGxxx /// <summary> /// Called when a SDG command has been received. /// <remarks>Indicates that someone send us a message.</remarks> /// <code> /// SDG 0 [Payload Length]\r\n[Payload Data] /// </code> /// </summary> /// <param name="message"></param> protected virtual void OnSDGReceived(NSMessage message) { if (message.InnerBody == null || (message.InnerMessage is MultiMimeMessage) == false) { // This is not an SDG MultiMimeMessage message return; } MultiMimeMessage multiMimeMessage = message.InnerMessage as MultiMimeMessage; #region Get the Routing Info RoutingInfo routingInfo = RoutingInfo.FromMultiMimeMessage(multiMimeMessage, this); if (routingInfo == null) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[OnSDGReceived] Get Rounting Info Error."); return; } Contact sender = null; // via=fb, circle or temporary group Contact originalSender = null; // invidiual sender, 1 on 1 chat if (routingInfo.ReceiverType == IMAddressInfoType.Circle || routingInfo.ReceiverType == IMAddressInfoType.TemporaryGroup) { sender = routingInfo.Receiver; if (sender == null) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[OnSDGReceived] Error: Cannot find group: " + multiMimeMessage.To.ToString()); return; } originalSender = routingInfo.Sender; } // External Network if (originalSender == null && routingInfo.SenderGateway != null) { originalSender = routingInfo.SenderGateway; sender = routingInfo.Sender; } if (originalSender == null) { sender = routingInfo.Sender; originalSender = sender; } #endregion if (multiMimeMessage.ContentHeaders.ContainsKey(MIMEContentHeaders.MessageType)) { switch (multiMimeMessage.ContentHeaders[MIMEContentHeaders.MessageType].ToString()) { default: Trace.WriteLineIf(Settings.TraceSwitch.TraceWarning, "[OnSDGReceived] UNHANDLED MESSAGE TYPE: \r\n" + multiMimeMessage.ContentHeaders[MIMEContentHeaders.MessageType].ToString() + "\r\n\r\nMessage Body: \r\n\r\n" + multiMimeMessage.ToDebugString()); break; case MessageTypes.Nudge: OnNudgeReceived(new NudgeArrivedEventArgs(sender, originalSender, routingInfo)); break; case MessageTypes.ControlTyping: OnTypingMessageReceived(new TypingArrivedEventArgs(sender, originalSender, routingInfo)); break; case MessageTypes.Text: OnSDGTextMessageReceived(multiMimeMessage, sender, originalSender, routingInfo); break; case MessageTypes.CustomEmoticon: OnSDGCustomEmoticonReceived(multiMimeMessage, sender, originalSender, routingInfo); break; case MessageTypes.Wink: OnSDGWinkReceived(multiMimeMessage, sender, originalSender, routingInfo); break; case MessageTypes.SignalP2P: OnSDGP2PSignalReceived(multiMimeMessage, sender, originalSender, routingInfo); break; case MessageTypes.SignalCloseIMWindow: OnSDGCloseIMWindowReceived(multiMimeMessage, routingInfo); break; case MessageTypes.Data: OnSDGDataMessageReceived(multiMimeMessage, sender, originalSender, routingInfo); break; } } }
public NSMessageEventArgs(NSMessage nsMessage) { this.nsMessage = nsMessage; }