diff --git a/src/XMPPThread/Stanzas/Presence.c b/src/XMPPThread/Stanzas/Presence.c index b72f988..dc825f3 100644 --- a/src/XMPPThread/Stanzas/Presence.c +++ b/src/XMPPThread/Stanzas/Presence.c @@ -56,6 +56,60 @@ GuessStatus(XMLElement *stanza) } return USER_STATUS_ONLINE; } + +static Array * +GetStatuses(XMLElement *info) +{ + XMLElement *child; + Array *ret; + size_t i; + if (!info) + { + return NULL; + } + + ret = ArrayCreate(); + for (i = 0; i < ArraySize(info->children); i++) + { + child = ArrayGet(info->children, i); + if (StrEquals(child->name, "status")) + { + ArrayAdd(ret, HashMapGet(child->attrs, "code")); + } + } + + return ret; +} + +static void +FreeStatuses(Array *statuses) +{ + if (!statuses) + { + return; + } + + ArrayFree(statuses); +} +static bool +HasStatus(Array *statuses, const char *code) +{ + size_t i; + if (!statuses || !code) + { + return false; + } + + for (i = 0; i < ArraySize(statuses); i++) + { + if (StrEquals(ArrayGet(statuses, i), code)) + { + return true; + } + } + + return false; +} void PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr) { @@ -96,9 +150,8 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr) if ((user_info = XMLookForTKV(stanza, "x", "xmlns", MUC_USER_NS))) { XMLElement *item = XMLookForUnique(user_info, "item"); - XMLElement *status = XMLookForUnique(user_info, "status"); -#define IsStatus(code) (status && \ - StrEquals(HashMapGet(status->attrs, "code"), #code)) + Array *statuses = GetStatuses(user_info); +#define IsStatus(code) (HasStatus(statuses, #code)) char *jid = item ? HashMapGet(item->attrs, "jid") : NULL; char *trim = ParseeTrimJID(jid); char *from = NULL; @@ -197,7 +250,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr) { ASBan(args->config, room, real_matrix); } - else if (IsStatus(307)) + else if (IsStatus(307) && !IsStatus(333)) { ASKick(args->config, room, real_matrix); } @@ -235,6 +288,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza, XMPPThread *thr) Free(parsee_j); Free(parsee); Free(room); + FreeStatuses(statuses); } if (status) {