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 void OnSDGTextMessageReceived(MultiMimeMessage multiMimeMessage, Contact sender, Contact by, RoutingInfo routingInfo)
        {
            TextMessage txtMessage = multiMimeMessage.InnerMessage as TextMessage;

            OnTextMessageReceived(new TextMessageArrivedEventArgs(sender, txtMessage, by, routingInfo));
        }
        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));
        }
        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);
            }
        }
        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 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()));
        }
        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));
            }
        }
Example #8
0
        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 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
            }
        }
Example #10
0
 public EmoticonArrivedEventArgs(Contact sender, Emoticon emoticon, Contact circle, RoutingInfo routingInfo)
     : base(sender, circle, routingInfo)
 {
     this.emoticon = emoticon;
 }
Example #11
0
 public WinkEventArgs(Contact contact, Wink wink, RoutingInfo routingInfo)
     : base(contact, null, routingInfo)
 {
     this.wink = wink;
 }
Example #12
0
 public TextMessageArrivedEventArgs(Contact sender, TextMessage textMessage, Contact originalSender, RoutingInfo routingInfo)
     : base(sender, originalSender, routingInfo)
 {
     this.textMessage = textMessage;
 }
Example #13
0
 public TypingArrivedEventArgs(Contact contact, Contact originalSender, RoutingInfo routingInfo)
     : base(contact, originalSender, routingInfo)
 {
 }
Example #14
0
 protected MessageArrivedEventArgs(Contact contact, Contact originalSender, RoutingInfo routingInfo)
 {
     this.sender         = contact;
     this.originalSender = originalSender;
     this.routingInfo    = routingInfo;
 }
Example #15
0
 public EmoticonDefinitionEventArgs(Contact contact, Contact originalSender, RoutingInfo routingInfo, Emoticon emoticon)
     : base(contact, originalSender, routingInfo)
 {
     this.emoticon = emoticon;
 }
Example #16
0
        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);
        }