void FXmppPresenceJingle::OnSignalMucPresenceUpdate(const class FXmppMucPresenceStatus& MucStatus)
{
	FXmppUserJid MucJid;
	FXmppJingle::ConvertToJid(MucJid, MucStatus.jid());

	UE_LOG(LogXmpp, Verbose, TEXT("Received MUC presence from [%s]"), *MucJid.GetFullPath());

	FXmppMucPresence MucPresence;
	ConvertToMucPresence(MucPresence, MucStatus, MucJid);
	Connection.MultiUserChat()->HandleMucPresence(MucPresence);
}
void FXmppPresenceJingle::OnSignalPresenceUpdate(const buzz::PresenceStatus& InStatus)
{	
	// ignore muc presence
	FString Domain(UTF8_TO_TCHAR(InStatus.jid().domain().c_str()));
	if (!Domain.Equals(Connection.GetMucDomain(), ESearchCase::IgnoreCase))
	{
		FXmppUserJid UserJid;
		FXmppJingle::ConvertToJid(UserJid, InStatus.jid());
		// Don't keep presence entries missing a resource, this comes in when a new friend is added but will never get updated when user logs off
		if (UserJid.IsValid() && !UserJid.Resource.IsEmpty())
		{
			FScopeLock Lock(&RosterLock);
		
			FXmppUserPresenceJingle& RosterEntry = RosterPresence.FindOrAdd(UserJid.GetFullPath());
			ConvertToPresence(*RosterEntry.Presence, InStatus, UserJid);
			FXmppJingle::ConvertToJid(RosterEntry.UserJid, InStatus.jid());

			UE_LOG(LogXmpp, Verbose, TEXT("Received presence for user [%s]"), *UserJid.GetFullPath());
			DebugPrintPresence(*RosterEntry.Presence);

			RosterUpdates.Enqueue(UserJid.GetFullPath());
		}
		else if (UserJid.IsValid() && UserJid.Resource.IsEmpty())
		{
			UE_LOG(LogXmpp, Warning, TEXT("Ignoring presence update with empty resource. StatusJid = %s, JidFullPath = %s"), UTF8_TO_TCHAR(InStatus.jid().Str().c_str()), *UserJid.GetFullPath());
		}
	}
}
void FXmppPresenceJingle::ConvertToPresence(FXmppUserPresence& OutPresence, const buzz::PresenceStatus& InStatus, const FXmppUserJid& InJid)
{
	OutPresence.UserJid = InJid;
	OutPresence.bIsAvailable = InStatus.available();
	OutPresence.StatusStr = UTF8_TO_TCHAR(InStatus.status().c_str());
	if (!InStatus.sent_time().empty())
	{
		//@todo samz - fix legacy time usage
		FString SentTime = UTF8_TO_TCHAR(InStatus.sent_time().c_str());
		// convert from "20141115T19:43:17" time to "2014-11-15T19:43:17" Iso8601 compatible format
		if (!SentTime.Contains(TEXT("-")) && SentTime.Len() >= 8)
		{
			SentTime.InsertAt(6, TEXT("-"));
			SentTime.InsertAt(4, TEXT("-"));
		}
		FDateTime::ParseIso8601(*SentTime, OutPresence.SentTime);
	}
	
	OutPresence.Status = EXmppPresenceStatus::Offline;
	if (InStatus.available())
	{
		switch (InStatus.show())
		{
		case buzz::PresenceStatus::SHOW_ONLINE:
			OutPresence.Status = EXmppPresenceStatus::Online;
			break;
		case buzz::PresenceStatus::SHOW_NONE:
		case buzz::PresenceStatus::SHOW_OFFLINE:
			OutPresence.Status = EXmppPresenceStatus::Offline;
			break;
		case buzz::PresenceStatus::SHOW_AWAY:
			OutPresence.Status = EXmppPresenceStatus::Away;
			break;
		case buzz::PresenceStatus::SHOW_XA:
			OutPresence.Status = EXmppPresenceStatus::ExtendedAway;
			break;
		case buzz::PresenceStatus::SHOW_DND:
			OutPresence.Status = EXmppPresenceStatus::DoNotDisturb;
			break;
		case buzz::PresenceStatus::SHOW_CHAT:
			OutPresence.Status = EXmppPresenceStatus::Chat;
			break;
		}
	}
	
	InJid.ParseResource(OutPresence.AppId, OutPresence.Platform);
}