private MultiMimeMessage ParseSDGTextPayloadMessage(MultiMimeMessage multiMimeMessage) { TextPayloadMessage textPayloadMessage = new TextPayloadMessage(); textPayloadMessage.CreateFromParentMessage(multiMimeMessage); return(multiMimeMessage); }
private MultiMimeMessage ParseSDGP2PSignalMessage(MultiMimeMessage multiMimeMessage) { SLPMessage slpMessage = SLPMessage.Parse(multiMimeMessage.InnerBody); slpMessage.CreateFromParentMessage(multiMimeMessage); return(multiMimeMessage); }
private MultiMimeMessage ParseSDGCustomEmoticonMessage(MultiMimeMessage multiMimeMessage) { EmoticonMessage emoticonMessage = new EmoticonMessage(); emoticonMessage.CreateFromParentMessage(multiMimeMessage); emoticonMessage.EmoticonType = multiMimeMessage.ContentHeaders[MIMEContentHeaders.ContentType] == "text/x-mms-animemoticon" ? EmoticonType.AnimEmoticon : EmoticonType.StaticEmoticon; return(multiMimeMessage); }
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); }
/// <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); }
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> /// 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); }
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)); } }
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); }
private void OnSDGWinkReceived(MultiMimeMessage multiMimeMessage, Contact sender, Contact originalSender, RoutingInfo routingInfo) { Wink wink = new Wink(); wink.SetContext((multiMimeMessage.InnerMessage as TextPayloadMessage).Text); OnWinkDefinitionReceived(new WinkEventArgs(originalSender, wink, 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()); } }
private MultiMimeMessage ParseSDGTextPayloadMessage(MultiMimeMessage multiMimeMessage) { TextPayloadMessage textPayloadMessage = new TextPayloadMessage(); textPayloadMessage.CreateFromParentMessage(multiMimeMessage); return multiMimeMessage; }
private MultiMimeMessage ParseSDGP2PSignalMessage(MultiMimeMessage multiMimeMessage) { SLPMessage slpMessage = SLPMessage.Parse(multiMimeMessage.InnerBody); slpMessage.CreateFromParentMessage(multiMimeMessage); return multiMimeMessage; }
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 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); }
private void OnSDGTextMessageReceived(MultiMimeMessage multiMimeMessage, Contact sender, Contact by, RoutingInfo routingInfo) { TextMessage txtMessage = multiMimeMessage.InnerMessage as TextMessage; OnTextMessageReceived(new TextMessageArrivedEventArgs(sender, txtMessage, by, routingInfo)); }
internal static RoutingInfo FromMultiMimeMessage(MultiMimeMessage multiMimeMessage, NSMessageHandler nsMessageHandler) { IMAddressInfoType senderAccountAddressType; string senderAccount = string.Empty; IMAddressInfoType senderGatewayAccountAddressType; string senderGatewayAccount = string.Empty; IMAddressInfoType receiverAccountAddressType; string receiverAccount = string.Empty; IMAddressInfoType receiverGatewayAccountAddressType; string receiverGatewayAccount = string.Empty; if ((false == Contact.ParseFullAccount(multiMimeMessage.From.ToString(), out senderAccountAddressType, out senderAccount, out senderGatewayAccountAddressType, out senderGatewayAccount)) || (false == Contact.ParseFullAccount(multiMimeMessage.To.ToString(), out receiverAccountAddressType, out receiverAccount, out receiverGatewayAccountAddressType, out receiverGatewayAccount))) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "Cannot parse sender or receiver from message: " + multiMimeMessage.From.ToString() + "|" + multiMimeMessage.To.ToString()); return null; } Contact sender = null; Contact senderGateway = null; Contact receiver = null; Contact receiverGateway = null; if (multiMimeMessage.From.HasAttribute("via")) senderGateway = GetGatewayFromAccountString(multiMimeMessage.From["via"], nsMessageHandler); if (senderGateway == null && multiMimeMessage.RoutingHeaders.ContainsKey(MIMERoutingHeaders.Via)) //The gateway is sender gateway senderGateway = GetGatewayFromAccountString(multiMimeMessage.RoutingHeaders[MIMERoutingHeaders.Via], nsMessageHandler); if (multiMimeMessage.To.HasAttribute("via")) receiverGateway = GetGatewayFromAccountString(multiMimeMessage.To["via"], nsMessageHandler); bool fromMyself = (senderAccount == nsMessageHandler.Owner.Account && senderAccountAddressType == IMAddressInfoType.WindowsLive); if (!Contact.IsSpecialGatewayType(senderAccountAddressType)) { if (senderGateway == null) sender = fromMyself ? nsMessageHandler.Owner : nsMessageHandler.ContactList.GetContactWithCreate(senderAccount, senderAccountAddressType); else { // For facebook, we might need to use GetContact instead of GetContactWithCreate, // that's the official client's behavior. Actually we will get all status notification from // our facebook contacts, however, WLM only display those guys who are also our windows live // contact. For now, those facebook contact doesn't add us as an WLM contact will also show up // in MSNPSharp, their name is the same with the account - all are numbers. I think it doesn't // harm so far, so keep it like this is reasonable, but might change in the future. sender = senderGateway.ContactList.GetContactWithCreate(senderAccount, senderAccountAddressType); } } else { sender = GetGateway(senderAccount, senderAccountAddressType, nsMessageHandler); } bool sentToMe = (receiverAccount == nsMessageHandler.Owner.Account && receiverAccountAddressType == IMAddressInfoType.WindowsLive); if (!Contact.IsSpecialGatewayType(receiverAccountAddressType)) { if (receiverGateway == null) receiver = sentToMe ? nsMessageHandler.Owner : nsMessageHandler.ContactList.GetContactWithCreate(receiverAccount, receiverAccountAddressType); else { receiver = receiverGateway.ContactList.GetContactWithCreate(receiverAccount, receiverAccountAddressType); } } else { receiver = GetGateway(receiverAccount, receiverAccountAddressType, nsMessageHandler); } RoutingInfo routingInfo = new RoutingInfo(sender, senderGateway, receiver, receiverGateway, nsMessageHandler); routingInfo.SenderEndPointID = GetEPID(multiMimeMessage.From); routingInfo.SenderAccount = senderAccount; routingInfo.SenderType = senderAccountAddressType; routingInfo.ReceiverEndPointID = GetEPID(multiMimeMessage.To); routingInfo.ReceiverAccount = receiverAccount; routingInfo.ReceiverType = receiverAccountAddressType; return routingInfo; }
private MultiMimeMessage ParseSDGDataMessage(MultiMimeMessage multiMimeMessage, Contact sender, Contact by) { return multiMimeMessage; }
private void OnNFYPUTReceived(MultiMimeMessage multiMimeMessage, RoutingInfo routingInfo) { switch (multiMimeMessage.ContentHeaders[MIMEContentHeaders.ContentType].Value) { #region user xml case "application/user+xml": { if (multiMimeMessage.ContentHeaders[MIMEHeaderStrings.NotifType].Value == "Sync") { if (routingInfo.SenderGateway != null && routingInfo.SenderGateway.ClientType == IMAddressInfoType.Circle) { JoinMultiparty(routingInfo.SenderGateway); } //Sync the contact in contact list with the contact in gateway. // TODO: Set the NSMessagehandler.ContactList contact to the gateway // TODO: triger the ContactOnline event for the gateway contact. //Just wait for my fix. } if (multiMimeMessage.InnerBody == null || multiMimeMessage.InnerBody.Length == 0) return; //No xml content. if (multiMimeMessage.ContentHeaders[MIMEHeaderStrings.NotifType].Value == "Full") { //This is an initial NFY } XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(Encoding.UTF8.GetString(multiMimeMessage.InnerBody)); XmlNodeList services = xmlDoc.SelectNodes("//user/s"); XmlNodeList serviceEndPoints = xmlDoc.SelectNodes("//user/sep"); if (services.Count > 0) { foreach (XmlNode service in services) { ServiceShortNames serviceEnum = (ServiceShortNames)Enum.Parse(typeof(ServiceShortNames), service.Attributes["n"].Value); switch (serviceEnum) { case ServiceShortNames.IM: { foreach (XmlNode node in service.ChildNodes) { switch (node.Name) { case "Status": if (routingInfo.FromOwner && IsSignedIn == false) { // We have already signed in another place, but not here... // Don't set status... This place will set the status later. return; } PresenceStatus oldStatus = routingInfo.Sender.Status; PresenceStatus newStatus = ParseStatus(node.InnerText); routingInfo.Sender.SetStatus(newStatus); OnContactStatusChanged(new ContactStatusChangedEventArgs(routingInfo.Sender, routingInfo.SenderGateway, oldStatus, newStatus)); OnContactOnline(new ContactStatusChangedEventArgs(routingInfo.Sender, routingInfo.SenderGateway, oldStatus, newStatus)); break; case "CurrentMedia": //MSNP21TODO: UBX implementation break; } } break; } case ServiceShortNames.PE: { // Create a new reference to fire PersonalMessageChanged event. PersonalMessage personalMessage = new PersonalMessage(service.ChildNodes); if (!String.IsNullOrEmpty(personalMessage.Payload) && routingInfo.Sender.PersonalMessage != personalMessage) { // FriendlyName if (!String.IsNullOrEmpty(personalMessage.FriendlyName)) { //Only Windows Live Messenger Contact has friendly name. routingInfo.Sender.SetName(personalMessage.FriendlyName); } // UserTileLocation if (!String.IsNullOrEmpty(personalMessage.UserTileLocation) && routingInfo.Sender.UserTileLocation != personalMessage.UserTileLocation) { routingInfo.Sender.UserTileLocation = personalMessage.UserTileLocation; routingInfo.Sender.FireDisplayImageContextChangedEvent(personalMessage.UserTileLocation); } // Scene if (!String.IsNullOrEmpty(personalMessage.Scene)) { if (routingInfo.Sender.SceneContext != personalMessage.Scene) { routingInfo.Sender.SceneContext = personalMessage.Scene; routingInfo.Sender.FireSceneImageContextChangedEvent(personalMessage.Scene); } } // ColorScheme if (personalMessage.ColorScheme != Color.Empty) { if (routingInfo.Sender.ColorScheme != personalMessage.ColorScheme) { routingInfo.Sender.ColorScheme = personalMessage.ColorScheme; routingInfo.Sender.OnColorSchemeChanged(); } } // This must be final... routingInfo.Sender.PersonalMessage = personalMessage; } break; } case ServiceShortNames.PF: { // Profile Annotation, it is AB.Me.annotations/Live.Profile.Expression.LastChanged // <user><s n="PF" ts="2011-04-16T06:00:58Z"></s></user> if (routingInfo.FromOwner) { DateTime ts = WebServiceDateTimeConverter.ConvertToDateTime(service.Attributes["ts"].Value); } break; } } } } if (serviceEndPoints.Count > 0) { foreach (XmlNode serviceEndPoint in serviceEndPoints) { ServiceShortNames serviceEnum = (ServiceShortNames)Enum.Parse(typeof(ServiceShortNames), serviceEndPoint.Attributes["n"].Value); Guid epid = serviceEndPoint.Attributes["epid"] == null ? Guid.Empty : new Guid(serviceEndPoint.Attributes["epid"].Value); if (!routingInfo.Sender.EndPointData.ContainsKey(epid)) { lock (routingInfo.Sender.SyncObject) routingInfo.Sender.EndPointData.Add(epid, routingInfo.FromOwner ? new PrivateEndPointData(routingInfo.Sender.Account, epid) : new EndPointData(routingInfo.Sender.Account, epid)); } switch (serviceEnum) { case ServiceShortNames.IM: { foreach (XmlNode node in serviceEndPoint.ChildNodes) { switch (node.Name) { case "Capabilities": ClientCapabilities cap = ClientCapabilities.None; ClientCapabilitiesEx capEx = ClientCapabilitiesEx.None; string[] caps = node.InnerText.Split(':'); if (caps.Length > 1) { capEx = (ClientCapabilitiesEx)long.Parse(caps[1]); } cap = (ClientCapabilities)long.Parse(caps[0]); routingInfo.Sender.EndPointData[epid].IMCapabilities = cap; routingInfo.Sender.EndPointData[epid].IMCapabilitiesEx = capEx; break; } } break; } case ServiceShortNames.PE: { foreach (XmlNode node in serviceEndPoint.ChildNodes) { switch (node.Name) { case "Capabilities": ClientCapabilities cap = ClientCapabilities.None; ClientCapabilitiesEx capEx = ClientCapabilitiesEx.None; string[] caps = node.InnerText.Split(':'); if (caps.Length > 1) { capEx = (ClientCapabilitiesEx)long.Parse(caps[1]); } cap = (ClientCapabilities)long.Parse(caps[0]); routingInfo.Sender.EndPointData[epid].PECapabilities = cap; routingInfo.Sender.EndPointData[epid].PECapabilitiesEx = capEx; break; } } routingInfo.Sender.SetChangedPlace(new PlaceChangedEventArgs(routingInfo.Sender.EndPointData[epid], PlaceChangedReason.SignedIn)); break; } case ServiceShortNames.PD: { PrivateEndPointData privateEndPoint = routingInfo.Sender.EndPointData[epid] as PrivateEndPointData; foreach (XmlNode node in serviceEndPoint.ChildNodes) { switch (node.Name) { case "ClientType": privateEndPoint.ClientType = node.InnerText; break; case "EpName": privateEndPoint.Name = node.InnerText; break; case "Idle": privateEndPoint.Idle = bool.Parse(node.InnerText); break; case "State": privateEndPoint.State = ParseStatus(node.InnerText); break; } } Owner.SetChangedPlace(new PlaceChangedEventArgs(privateEndPoint, PlaceChangedReason.SignedIn)); break; } } } } } break; #endregion #region circles xml case "application/circles+xml": { if (routingInfo.SenderType == IMAddressInfoType.Circle) { Contact circle = ContactList.GetCircle(routingInfo.SenderAccount); if (circle == null) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[OnNFYReceived] Cannot complete the operation since circle not found: " + multiMimeMessage.From.ToString()); return; } if (multiMimeMessage.InnerBody == null || multiMimeMessage.InnerBody.Length == 0 || "<circle></circle>" == Encoding.UTF8.GetString(multiMimeMessage.InnerBody)) { // No xml content and full notify... Circle goes online... if (multiMimeMessage.ContentHeaders[MIMEHeaderStrings.NotifType].Value == "Full") { PresenceStatus oldStatus = circle.Status; PresenceStatus newStatus = PresenceStatus.Online; circle.SetStatus(newStatus); // The contact changed status OnContactStatusChanged(new ContactStatusChangedEventArgs(circle, oldStatus, newStatus)); // The contact goes online OnContactOnline(new ContactStatusChangedEventArgs(circle, oldStatus, newStatus)); } return; } XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(Encoding.UTF8.GetString(multiMimeMessage.InnerBody)); XmlNodeList ids = xmlDoc.SelectNodes("//circle/roster/user/id"); if (ids.Count == 0) { return; //I hate indent. } foreach (XmlNode node in ids) { IMAddressInfoType accountAddressType; string account; IMAddressInfoType viaAccountAddressType; string viaAccount; string fullAccount = node.InnerText; if (false == Contact.ParseFullAccount(fullAccount, out accountAddressType, out account, out viaAccountAddressType, out viaAccount)) { continue; } if (account == Owner.Account) continue; if (circle.ContactList.HasContact(account, accountAddressType)) { Contact contact = circle.ContactList.GetContact(account, accountAddressType); OnJoinedGroupChat(new GroupChatParticipationEventArgs(contact, circle)); } } } else if (routingInfo.SenderType == IMAddressInfoType.TemporaryGroup) { MultipartyObject mpo = GetMultipartyObject(routingInfo.SenderAccount); Contact group = null; if (mpo == null) { // Created remotely. NSMessageProcessor nsmp = (NSMessageProcessor)MessageProcessor; int transId = nsmp.IncreaseTransactionID(); group = new Contact(routingInfo.SenderAccount, IMAddressInfoType.TemporaryGroup, this); group.ContactList = new ContactList(new Guid(routingInfo.SenderAccount.Split('@')[0]), null, group, this); mpo = new MultipartyObject(transId, new List<string>(), group, null); lock (multiParties) multiParties[transId] = mpo; OnMultipartyCreatedRemotely(new MultipartyCreatedEventArgs(group)); group.SetStatus(PresenceStatus.Online); } else { group = mpo.MultiParty; } if (multiMimeMessage.InnerBody == null || multiMimeMessage.InnerBody.Length == 0) { // No xml content and full notify... Circle goes online... if (multiMimeMessage.ContentHeaders[MIMEHeaderStrings.NotifType].Value == "Full") { PresenceStatus oldStatus = group.Status; PresenceStatus newStatus = PresenceStatus.Online; group.SetStatus(newStatus); // The contact changed status OnContactStatusChanged(new ContactStatusChangedEventArgs(group, oldStatus, newStatus)); // The contact goes online OnContactOnline(new ContactStatusChangedEventArgs(group, oldStatus, newStatus)); } return; } // Join multiparty if state is Pending XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(Encoding.UTF8.GetString(multiMimeMessage.InnerBody)); XmlNodeList rosters = xmlDoc.SelectNodes("//circle/roster/user"); foreach (XmlNode roster in rosters) { string state = (roster["state"] == null) ? string.Empty : roster["state"].InnerText; string[] fullAccount = roster["id"].InnerText.Split(':'); IMAddressInfoType addressType = (IMAddressInfoType)int.Parse(fullAccount[0]); string memberAccount = fullAccount[1].ToLowerInvariant(); // Me contact if ("pending" == state.ToLowerInvariant() && addressType == Owner.ClientType && memberAccount == Owner.Account) { JoinMultiparty(group); } else { Contact part = group.ContactList.GetContactWithCreate(memberAccount, addressType); Contact real = ContactList.GetContactWithCreate(memberAccount, addressType); part.SetStatus(real.Status); OnJoinedGroupChat(new GroupChatParticipationEventArgs(part, group)); if (mpo.InviteQueueHash.Contains(part.SiblingString)) mpo.InviteQueueHash.Remove(part.SiblingString); } } } } break; #endregion #region network xml case "application/network+xml": { if (routingInfo.Sender.ClientType == IMAddressInfoType.RemoteNetwork && routingInfo.Sender.Account == RemoteNetworkGateways.FaceBookGatewayAccount) { string status = Encoding.UTF8.GetString(multiMimeMessage.InnerBody); PresenceStatus oldStatus = routingInfo.Sender.Status; PresenceStatus newStatus = PresenceStatus.Unknown; if (status.Contains("SignedIn")) newStatus = PresenceStatus.Online; else if (status.Contains("SignedOut")) newStatus = PresenceStatus.Offline; if (newStatus != PresenceStatus.Unknown) { routingInfo.Sender.SetStatus(newStatus); // The contact changed status OnContactStatusChanged(new ContactStatusChangedEventArgs(routingInfo.Sender, routingInfo.SenderGateway, oldStatus, newStatus)); if (newStatus == PresenceStatus.Online) OnContactOnline(new ContactStatusChangedEventArgs(routingInfo.Sender, routingInfo.SenderGateway, oldStatus, newStatus)); else OnContactOffline(new ContactStatusChangedEventArgs(routingInfo.Sender, routingInfo.SenderGateway, oldStatus, newStatus)); } } } break; #endregion } }
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); } }
/// <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; }
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); }
private void OnSDGCloseIMWindowReceived(MultiMimeMessage multiMimeMessage, RoutingInfo routingInfo) { string partiesString = (multiMimeMessage.InnerMessage as TextPayloadMessage).Text; if (string.IsNullOrEmpty(partiesString)) return; string[] parties = partiesString.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries); IMAddressInfoType addressInfo = IMAddressInfoType.None; string account = string.Empty; List<Contact> partiesList = new List<Contact>(0); for (int i = 0; i < parties.Length; i++) { Contact.ParseFullAccount(parties[i], out addressInfo, out account); Contact party = ContactList.GetContact(account, addressInfo); if (party != null) partiesList.Add(party); } EndPointData senderEndPoint = null; EndPointData receiverEndPoint = null; if (routingInfo.Sender != null) { if (routingInfo.Sender.EndPointData.ContainsKey(routingInfo.SenderEndPointID)) senderEndPoint = routingInfo.Sender.EndPointData[routingInfo.SenderEndPointID]; } if (routingInfo.Receiver != null) { if (routingInfo.Receiver.EndPointData.ContainsKey(routingInfo.ReceiverEndPointID)) receiverEndPoint = routingInfo.Receiver.EndPointData[routingInfo.ReceiverEndPointID]; } OnRemoteEndPointCloseIMWindow(new CloseIMWindowEventArgs(routingInfo.Sender, senderEndPoint, routingInfo.Receiver, receiverEndPoint, partiesList.ToArray())); }
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); }
private void OnSDGCustomEmoticonReceived(MultiMimeMessage multiMimeMessage, Contact sender, Contact originalSender, RoutingInfo routingInfo) { EmoticonMessage emoticonMessage = multiMimeMessage.InnerMessage as EmoticonMessage; foreach (Emoticon emoticon in emoticonMessage.Emoticons) { OnEmoticonDefinitionReceived(new EmoticonDefinitionEventArgs(originalSender, originalSender, routingInfo, emoticon)); } }
/// <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); } } }
private void OnSDGDataMessageReceived(MultiMimeMessage multiMimeMessage, Contact sender, Contact by, RoutingInfo routingInfo) { Guid senderEPID = routingInfo.SenderEndPointID; P2PVersion p2pVer = senderEPID == Guid.Empty ? P2PVersion.P2PV1 : P2PVersion.P2PV2; string[] offsets = multiMimeMessage.ContentHeaders.ContainsKey(MIMEContentHeaders.BridgingOffsets) ? multiMimeMessage.ContentHeaders[MIMEContentHeaders.BridgingOffsets].ToString().Split(',') : new string[] { "0" }; List<long> offsetList = new List<long>(); foreach (string os in offsets) { offsetList.Add(long.Parse(os)); } P2PMessage p2pData = new P2PMessage(p2pVer); P2PMessage[] p2pDatas = p2pData.CreateFromOffsets(offsetList.ToArray(), multiMimeMessage.InnerBody); if (multiMimeMessage.ContentHeaders.ContainsKey(MIMEContentHeaders.Pipe)) { SDGBridge.PackageNo = ushort.Parse(multiMimeMessage.ContentHeaders[MIMEContentHeaders.Pipe]); } foreach (P2PMessage m in p2pDatas) { SDGBridge.ProcessP2PMessage(sender, senderEPID, m); } }
/// <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); } }
private void OnSDGP2PSignalReceived(MultiMimeMessage multiMimeMessage, Contact sender, Contact by, RoutingInfo routingInfo) { //SLPMessage slpMessage = SLPMessage.Parse(multiMimeMessage.InnerBody); SLPMessage slpMessage = multiMimeMessage.InnerMessage as SLPMessage; if (slpMessage != null) { if (slpMessage.ContentType == "application/x-msnmsgr-transreqbody" || slpMessage.ContentType == "application/x-msnmsgr-transrespbody" || slpMessage.ContentType == "application/x-msnmsgr-transdestaddrupdate") { P2PSession.ProcessDirectInvite(slpMessage, this, null); } } }
private void OnNFYDELReceived(MultiMimeMessage multiMimeMessage, RoutingInfo routingInfo) { switch (multiMimeMessage.ContentHeaders[MIMEContentHeaders.ContentType].Value) { #region user xml case "application/user+xml": { if (multiMimeMessage.InnerBody == null || multiMimeMessage.InnerBody.Length == 0) return; //No xml content. if (multiMimeMessage.ContentHeaders[MIMEHeaderStrings.NotifType].Value == "Full") { //This is an initial NFY } XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(Encoding.UTF8.GetString(multiMimeMessage.InnerBody)); XmlNodeList services = xmlDoc.SelectNodes("//user/s"); XmlNodeList serviceEndPoints = xmlDoc.SelectNodes("//user/sep"); if (serviceEndPoints.Count > 0) { foreach (XmlNode serviceEndPoint in serviceEndPoints) { ServiceShortNames serviceEnum = (ServiceShortNames)Enum.Parse(typeof(ServiceShortNames), serviceEndPoint.Attributes["n"].Value); Guid epid = serviceEndPoint.Attributes["epid"] == null ? Guid.Empty : new Guid(serviceEndPoint.Attributes["epid"].Value); switch (serviceEnum) { case ServiceShortNames.IM: case ServiceShortNames.PD: { if (routingInfo.Sender.EndPointData.ContainsKey(epid)) { routingInfo.Sender.SetChangedPlace(new PlaceChangedEventArgs(routingInfo.Sender.EndPointData[epid], PlaceChangedReason.SignedOut)); } if (routingInfo.FromOwner && epid == MachineGuid && messageProcessor != null) { SignoutFrom(epid); } break; } } } } if (services.Count > 0) { foreach (XmlNode service in services) { ServiceShortNames serviceEnum = (ServiceShortNames)Enum.Parse(typeof(ServiceShortNames), service.Attributes["n"].Value); switch (serviceEnum) { case ServiceShortNames.IM: { PresenceStatus oldStatus = routingInfo.Sender.Status; PresenceStatus newStatus = PresenceStatus.Offline; routingInfo.Sender.SetStatus(newStatus); OnContactStatusChanged(new ContactStatusChangedEventArgs(routingInfo.Sender, routingInfo.SenderGateway, oldStatus, newStatus)); OnContactOffline(new ContactStatusChangedEventArgs(routingInfo.Sender, routingInfo.SenderGateway, oldStatus, newStatus)); break; } } } } } break; #endregion #region circles xml case "application/circles+xml": { Contact circle = null; Contact group = null; if (routingInfo.SenderType == IMAddressInfoType.Circle) { circle = ContactList.GetCircle(routingInfo.SenderAccount); if (circle == null) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[OnNFYReceived] Cannot complete the operation since circle not found: " + multiMimeMessage.From.ToString()); return; } } else if (routingInfo.SenderType == IMAddressInfoType.TemporaryGroup) { group = GetMultiparty(routingInfo.SenderAccount); if (group == null) { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[OnNFYReceived] temp group not found: " + multiMimeMessage.From.ToString()); return; } } else { Trace.WriteLineIf(Settings.TraceSwitch.TraceError, "[OnNFYReceived] sender is not circle nor temp group: " + multiMimeMessage.From.ToString()); return; } if (multiMimeMessage.ContentHeaders.ContainsKey(MIMEHeaderStrings.Uri)) { string xpathUri = multiMimeMessage.ContentHeaders[MIMEHeaderStrings.Uri].ToString(); if (xpathUri.Contains("/circle/roster(IM)/user")) { string typeAccount = xpathUri.Substring("/circle/roster(IM)/user".Length); typeAccount = typeAccount.Substring(typeAccount.IndexOf("(") + 1); typeAccount = typeAccount.Substring(0, typeAccount.IndexOf(")")); string[] member = typeAccount.Split(':'); string memberAccount = member[1]; IMAddressInfoType memberNetwork = (IMAddressInfoType)int.Parse(member[0]); Contact c = null; if (circle != null) { if (!circle.ContactList.HasContact(memberAccount, memberNetwork)) return; c = circle.ContactList.GetContact(memberAccount, memberNetwork); OnLeftGroupChat(new GroupChatParticipationEventArgs(c, circle)); } if (group != null) { if (!group.ContactList.HasContact(memberAccount, memberNetwork)) return; c = group.ContactList.GetContact(memberAccount, memberNetwork); group.ContactList.Remove(memberAccount, memberNetwork); OnLeftGroupChat(new GroupChatParticipationEventArgs(c, group)); } } else { Contact goesOfflineGroup = null; if (circle != null) goesOfflineGroup = circle; else if (group != null) goesOfflineGroup = group; // Group goes offline... if (goesOfflineGroup != null) { PresenceStatus oldStatus = goesOfflineGroup.Status; PresenceStatus newStatus = PresenceStatus.Offline; goesOfflineGroup.SetStatus(newStatus); // the contact changed status OnContactStatusChanged(new ContactStatusChangedEventArgs(goesOfflineGroup, routingInfo.SenderGateway, oldStatus, newStatus)); // the contact goes offline OnContactOffline(new ContactStatusChangedEventArgs(goesOfflineGroup, routingInfo.SenderGateway, oldStatus, newStatus)); } } } } break; #endregion #region network xml case "application/network+xml": { } break; #endregion } }
private MultiMimeMessage ParseSDGCustomEmoticonMessage(MultiMimeMessage multiMimeMessage) { EmoticonMessage emoticonMessage = new EmoticonMessage(); emoticonMessage.CreateFromParentMessage(multiMimeMessage); emoticonMessage.EmoticonType = multiMimeMessage.ContentHeaders[MIMEContentHeaders.ContentType] == "text/x-mms-animemoticon" ? EmoticonType.AnimEmoticon : EmoticonType.StaticEmoticon; return multiMimeMessage; }