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); } } } }
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); }
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); } }
void SendPrivateMessage(XmppPersonModel person, string text) { SendPrivateMessage(person, null, text); }
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); } }
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); } }
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; }
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); } }
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; } }