Beispiel #1
0
 void SendPrivateMessage(XmppPersonModel person, Jid jid, string text)
 {
     if (jid == null) {
         jid = person.Jid;
     }
     if ((jid.Server == "gmail.com") ||
         (jid.Server == "googlemail.com")) {
         // don't send to all high prio resources or to specific resources
         // because gtalk clones any message to all resources anyway
         _SendPrivateMessage(person, jid.Bare, text);
     } else if (!String.IsNullOrEmpty(jid.Resource)) {
         _SendPrivateMessage(person, jid, text);
     } else {
         var resources = person.GetResourcesWithHighestPriority();
         if (resources.Count == 0) {
             // no connected resource, send to bare jid
             _SendPrivateMessage(person, jid.Bare, text);
         } else {
             foreach (var res in resources) {
                 if (String.IsNullOrEmpty(res.Name)) {
                     // don't send messages to empty resources
                     continue;
                 }
                 Jid j = new Jid(jid);
                 j.Resource = res.Name;
                 _SendPrivateMessage(person, j, text);
             }
         }
     }
 }
Beispiel #2
0
 void _SendPrivateMessage(XmppPersonModel person, Jid jid, string text)
 {
     var mesg = new Message(jid, XmppMessageType.chat, text);
     XmppResourceModel res;
     if (person.Resources.TryGetValue(jid.Resource ?? "", out res)) {
         if (res.NicknameContactKnowsFromMe != Nicknames[0]) {
             res.NicknameContactKnowsFromMe = Nicknames[0];
             mesg.Nickname = new Nickname(Nicknames[0]);
         }
     }
     JabberClient.Send(mesg);
 }
Beispiel #3
0
 void ProcessNickname(XmppPersonModel person, Nickname nick)
 {
     if (String.IsNullOrEmpty(nick.Value)) {
         return;
     }
     // only rename person if it doesn't have a preset name
     if (person.IdentityName == person.ID) {
         var oldIdentityNameColored = person.IdentityNameColored;
         var oldIdentityName = person.IdentityName;
         person.IdentityName = nick.Value;
         ProcessIdentityNameChanged(person, oldIdentityNameColored, oldIdentityName);
     }
 }
Beispiel #4
0
 void SendPrivateMessage(XmppPersonModel person, string text)
 {
     SendPrivateMessage(person, null, text);
 }
Beispiel #5
0
        void ProcessIdentityNameChanged(XmppPersonModel contact, TextMessagePartModel oldIdentityNameColored, string oldIdentityName)
        {
            var builder = CreateMessageBuilder();
            builder.AppendEventPrefix();
            string idstring = (oldIdentityName == contact.Jid.Bare)?"":GenerateIdString(contact);
            oldIdentityNameColored.BackgroundColor = TextColor.None;
            builder.AppendFormat("{2}{1} is now known as {0}", contact, idstring, oldIdentityNameColored);

            if (ContactChat != null) {
                PersonModel oldp = ContactChat.GetPerson(contact.ID);
                if (oldp != null) {
                    Session.UpdatePersonInGroupChat(ContactChat, oldp, contact.ToPersonModel());
                    Session.AddMessageToChat(ContactChat, new MessageModel(builder.ToMessage()));
                }
            }

            var chat = Session.GetChat(contact.ID, ChatType.Person, this) as PersonChatModel;
            if (chat != null) {
                chat.Name = contact.IdentityName;
                builder.MessageType = MessageType.ChatNameChanged;
                var msg = builder.ToMessage();
                Session.AddMessageToChat(chat, msg);

                chat.Person = contact.ToPersonModel();
                var msg2 = new MessageModel(msg);
                msg2.MessageType = MessageType.PersonChatPersonChanged;
                Session.AddMessageToChat(chat, msg2);
            }
        }
Beispiel #6
0
 void PrintPrivateChatPresence(XmppPersonModel person, Presence pres)
 {
     Jid jid = pres.From;
     XmppResourceModel resource;
     if (person.Resources.TryGetValue(jid.Resource??"", out resource)) {
         if (resource.Presence.Show == pres.Show
             && resource.Presence.Status == pres.Status
             && resource.Presence.Last == pres.Last
             && resource.Presence.XDelay == pres.XDelay
             && resource.Presence.Priority == pres.Priority
             && resource.Presence.Type == pres.Type
             ) {
             // presence didn't change enough to warrent a display message -> abort
             return;
         }
     }
     MessageModel msg = CreatePresenceUpdateMessage(jid, person, pres);
     if (!String.IsNullOrEmpty(jid.Resource)) {
         var directchat = Session.GetChat(jid, ChatType.Person, this);
         if (directchat != null) {
             // in case of direct chat we still send this message
             Session.AddMessageToChat(directchat, msg);
         }
     }
     // a nonexisting resource going offline?
     if (pres.Type == PresenceType.unavailable) {
         if (!person.Resources.ContainsKey(jid.Resource??"")) {
             return;
         }
     }
     var res = person.GetOrCreateResource(jid);
     var oldpres = res.Presence;
     res.Presence = pres;
     // highest pres
     Jid hjid = jid;
     Jid nextjid = jid;
     // 2nd highest pres
     Presence hpres = pres;
     Presence nextpres = null;
     bool amHighest = true;
     bool wasHighest = true;
     foreach (var pair in person.Resources) {
         if (pair.Value == res) continue;
         if (nextpres == null || pair.Value.Presence.Priority > nextpres.Priority) {
             nextjid.Resource = pair.Key;
             nextpres = pair.Value.Presence;
         }
         if (pair.Value.Presence.Priority > hpres.Priority) {
             // someone has a higher priority than I do
             // print the status of that resource
             hjid.Resource = pair.Key;
             hpres = pair.Value.Presence;
             amHighest = false;
         }
         if (oldpres != null && pair.Value.Presence.Priority > oldpres.Priority) {
             wasHighest = false;
         }
     }
     if (pres.Type == PresenceType.available) {
         // wasn't and isn't highiest prio -> ignore
         if (!wasHighest && !amHighest) return;
         // just another below zero prio -> ignore
         if (amHighest && pres.Priority < 0) return;
         // was highest, isn't anymore -> show presence of new highest
         if (wasHighest && !amHighest) {
             msg = CreatePresenceUpdateMessage(hjid, person, hpres);
         }
     } else if (pres.Type == PresenceType.unavailable) {
         // still a resource left with positive priority
         if (nextpres != null && nextpres.Priority >= 0) {
             msg = CreatePresenceUpdateMessage(nextjid, person, nextpres);
         }
     }
     var chat = Session.GetChat(jid.Bare, ChatType.Person, this);
     if (chat != null) {
         Session.AddMessageToChat(chat, msg);
     }
     if (ContactChat != null) {
         Session.AddMessageToChat(ContactChat, msg);
     }
 }
Beispiel #7
0
 XmppPersonModel GetOrCreateContact(Jid jid, string name)
 {
     XmppPersonModel p;
     if (!Contacts.TryGetValue(jid.Bare, out p)) {
         p = new XmppPersonModel(jid, name, this);
         Contacts[jid.Bare] = p;
     }
     return p;
 }
Beispiel #8
0
        void PrintGroupChatPresence(XmppGroupChatModel chat, XmppPersonModel person, Presence pres)
        {
            Jid jid = pres.From;
            XmppResourceModel resource;
            if (person.MucResources.TryGetValue(jid.Resource??"", out resource)) {
                if (resource.Presence.Show == pres.Show
                    && resource.Presence.Status == pres.Status
                    && resource.Presence.Last == pres.Last
                    && resource.Presence.XDelay == pres.XDelay
                    && resource.Presence.Priority == pres.Priority
                    && resource.Presence.Nickname == pres.Nickname
                    && resource.Presence.Type == pres.Type
                    ) {
                    // presence didn't change enough to warrent a display message -> abort
                    return;
                }
            }

            var msg = CreatePresenceUpdateMessage(person.Jid, person, pres);
            Session.AddMessageToChat(chat, msg);
            // clone directly to muc person chat
            // don't care about real jid, that has its own presence packets
            var personChat = Session.GetChat(jid, ChatType.Person, this);
            if (personChat != null) {
                Session.AddMessageToChat(personChat, msg);
            }
        }
Beispiel #9
0
        void OnGroupChatPresence(XmppGroupChatModel chat, Presence pres)
        {
            Jid jid = pres.From;
            XmppPersonModel person;
            // check whether we know the real jid of this muc user
            if (pres.MucUser != null &&
                pres.MucUser.Item != null &&
                pres.MucUser.Item.Jid != null ) {
                string nick = pres.From.Resource;
                if (!string.IsNullOrEmpty(pres.MucUser.Item.Nickname)) {
                    nick = pres.MucUser.Item.Nickname;
                }
                person = GetOrCreateContact(pres.MucUser.Item.Jid.Bare, nick);
            } else {
                // we do not know the real jid of this user, don't add it to our local roster
                // BUG? pres.From.Resource can be null?
                person = new XmppPersonModel(jid, pres.From.Resource, this);
            }
            person.GetOrCreateMucResource(jid).Presence = pres;
            PrintGroupChatPresence(chat, person, pres);
            switch (pres.Type) {
                case PresenceType.available:
                    // don't do anything if the contact already exists
                    if (chat.UnsafePersons.ContainsKey(person.ID)) {
                        return;
                    }
                    // is the chat synced? add the new contact the regular way
                    if (chat.IsSynced) {
                        Session.AddPersonToGroupChat(chat, person.ToPersonModel());
                        return;
                    }

                    chat.UnsafePersons.Add(person.ID, person.ToPersonModel());

                    // did I join? then the chat roster is fully received
                    if (pres.From.Resource == chat.OwnNickname) {
                        // HACK: lower probability of sync race condition swallowing messages
                        ThreadPool.QueueUserWorkItem(delegate {
                            Thread.Sleep(1000);
                            lock (this) {
                                if (IsDisposed) {
                                    return;
                                }
                                chat.IsSynced = true;
                                Session.SyncChat(chat);
                                Session.EnableChat(chat);
                            }
                        });
                    }
                    break;
                case PresenceType.unavailable:
                    Session.RemovePersonFromGroupChat(chat, person.ToPersonModel());
                    // did I leave? then I "probably" left the room
                    if (pres.From.Resource == chat.OwnNickname) {
                        Session.RemoveChat(chat);
                    }
                    break;
                case PresenceType.error:
                    if (pres.Error == null) break;
                    switch (pres.Error.Type) {
                        case ErrorType.cancel:
                            switch (pres.Error.Condition) {
                                case ErrorCondition.Conflict:
                                    // nickname already in use
                                    // autorejoin with _ appended to nickname
                                    JoinRoom(chat.ID, chat.OwnNickname + "_", chat.Password);
                                    break;
                            }
                            break;
                    }
                    break;
            }
        }