You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvilib/irc/kvi_ircuserdb.cpp

286 lines
7.6 KiB

//=============================================================================
//
// File : kvi_ircuserdb.cpp
// Creation date : Mon Jul 31 2000 21:23:22 by Szymon Stefanek
//
// This file is part of the KVirc irc client distribution
// Copyright (C) 2000-2004 Szymon Stefanek (pragma at kvirc dot net)
//
// This program is FREE software. You can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your opinion) any later version.
//
// This program is distributed in the HOPE that it will be USEFUL,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, write to the Free Software Foundation,
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#define __KVILIB__
#include "kvi_debug.h"
#include "kvi_ircuserdb.h"
#include "kvi_mirccntrl.h"
#include "kvi_qstring.h"
#include "kvi_stringconversion.h"
//static int cacheHit = 0;
//static int cacheMiss = 0;
KviIrcUserEntry::KviIrcUserEntry(const TQString &user,const TQString &host)
{
m_szUser = user;
m_szHost = host;
m_pAvatar = 0;
m_nRefs = 1;
m_iHops = -1;
m_bAway = false;
m_eGender = Unknown;
m_bBot = false;
m_bNotFoundRegUserLoockup=false;
m_bUseCustomColor=false;
}
void KviIrcUserEntry::setRealName(const TQString &rn)
{
m_szRealName = rn;
m_szRealName = KviTQString::trimmed(m_szRealName);
if(m_szRealName.length()>=3)
{
if( (m_szRealName[0].unicode()==KVI_TEXT_COLOR) && (m_szRealName[2].unicode()==KVI_TEXT_RESET) )
{
switch(m_szRealName[1].unicode())
{
case '1': // hum.. encoded as hidden color code eh ? publish is somewhere, so others might implement this...
setGender(Male);
break;
case '2':
setGender(Female);
break;
case '3':
setBot(true);
break;
}
m_szRealName.remove(0,3);
}
}
}
KviIrcUserEntry::~KviIrcUserEntry()
{
if(m_pAvatar)delete m_pAvatar;
}
void KviIrcUserEntry::setAvatar(KviAvatar * av)
{
if(m_pAvatar)delete m_pAvatar;
m_pAvatar = av;
}
KviAvatar * KviIrcUserEntry::forgetAvatar()
{
KviAvatar * ret = m_pAvatar;
m_pAvatar = 0;
return ret;
}
KviIrcUserDataBase::KviIrcUserDataBase()
: TQObject()
{
// we expect a maximum of ~4000 users (= ~16 KB array on a 32 bit machine)
// ...after that we will loose in performance
// ... well...4000 users is a really big number...say 6-7 really big channels
// (4001 is prime)
// up to 12000 users we will have a reasonably fast access.
// the performance increase since kvirc versions < 3.0.0
// is really big anyway (there was a linear list instead of a hash!!!)
m_pDict = new KviPointerHashTable<TQString,KviIrcUserEntry>(4001,false);
m_pDict->setAutoDelete(true);
setupConnectionWithReguserDb();
}
KviIrcUserDataBase::~KviIrcUserDataBase()
{
delete m_pDict;
}
bool KviIrcUserDataBase::haveCustomColor(const TQString & nick)
{
KviIrcUserEntry *u = find(nick);
if(!u) return false;
if( u->m_szLastRegisteredMatchNick!=nick)
registeredUser(nick);
if(!u->m_bNotFoundRegUserLoockup)
{
return u->m_bUseCustomColor;
}
return false;
}
TQColor* KviIrcUserDataBase::customColor(const TQString & nick)
{
KviIrcUserEntry *u = find(nick);
if(!u) return 0;
if( u->m_szLastRegisteredMatchNick!=nick)
registeredUser(nick);
if(!u->m_bNotFoundRegUserLoockup)
{
return &(u->m_cachedColor);
}
return 0;
}
KviRegisteredUser* KviIrcUserDataBase::registeredUser(const TQString & nick,const TQString & user,const TQString & host)
{
if(nick.isEmpty()) return 0;
KviIrcUserEntry *u = find(nick);
if(!u) return g_pRegisteredUserDataBase->findMatchingUser(nick,user,host);
KviRegisteredUser* pUser=0;
if(u->m_bNotFoundRegUserLoockup && u->m_szLastRegisteredMatchNick==nick)
{
//cacheHit++;
//debug("cache hits/miss = %i/%i",cacheHit,cacheMiss);
return 0;
}
if(!u->m_szRegisteredUserName.isEmpty() && u->m_szLastRegisteredMatchNick==nick)
{
pUser = g_pRegisteredUserDataBase->getUser(u->m_szRegisteredUserName);
//if(pUser) cacheHit++;
}
if(!pUser) {
//user renamed or it is a first loockup
if(u->hasHost() && u->hasUser())
{
pUser=g_pRegisteredUserDataBase->findMatchingUser(nick,u->user(),u->host());
//cacheMiss++;
if(pUser) {
u->m_szLastRegisteredMatchNick=nick;
u->m_szRegisteredUserName=pUser->name();
u->m_bUseCustomColor=pUser->getBoolProperty("useCustomColor");
TQString szTmp=pUser->getProperty("customColor");
KviStringConversion::fromString(szTmp,u->m_cachedColor);
u->m_bNotFoundRegUserLoockup=false; //to be shure
} else {
u->m_szLastRegisteredMatchNick=nick;
u->m_bNotFoundRegUserLoockup=true;
}
}
}
// debug("cache hits/miss = %i/%i",cacheHit,cacheMiss);
return pUser;
}
KviRegisteredUser* KviIrcUserDataBase::registeredUser(const TQString & nick)
{
if(nick.isEmpty()) return 0;
KviIrcUserEntry *u = find(nick);
if(!u) return 0;
return registeredUser(nick,u->user(),u->host());
}
void KviIrcUserDataBase::clear()
{
delete m_pDict;
m_pDict = new KviPointerHashTable<TQString,KviIrcUserEntry>(4001,false);
m_pDict->setAutoDelete(true);
}
KviIrcUserEntry * KviIrcUserDataBase::insertUser(const TQString &nick,const TQString &user,const TQString &hostname)
{
KviIrcUserEntry * e = m_pDict->find(nick);
if(e)
{
e->m_nRefs++;
if(e->m_szUser.isEmpty())
{
e->m_szUser = user;
e->m_szHost = hostname;
}
} else {
e = new KviIrcUserEntry(user,hostname);
m_pDict->insert(nick,e);
}
return e;
}
void KviIrcUserDataBase::removeUser(const TQString &nick,KviIrcUserEntry * e)
{
e->m_nRefs--;
if(e->m_nRefs == 0)m_pDict->remove(nick);
}
void KviIrcUserDataBase::setupConnectionWithReguserDb()
{
connect(g_pRegisteredUserDataBase,TQT_SIGNAL(userRemoved(const TQString&)),this,TQT_SLOT(registeredUserRemoved(const TQString&)));
connect(g_pRegisteredUserDataBase,TQT_SIGNAL(userChanged(const TQString&)),this,TQT_SLOT(registeredUserChanged(const TQString&)));
connect(g_pRegisteredUserDataBase,TQT_SIGNAL(userAdded(const TQString&)),this,TQT_SLOT(registeredUserAdded(const TQString&)));
connect(g_pRegisteredUserDataBase,TQT_SIGNAL(databaseCleared()),this,TQT_SLOT(registeredDatabaseCleared()));
}
void KviIrcUserDataBase::registeredUserRemoved(const TQString& user)
{
KviPointerHashTableIterator<TQString,KviIrcUserEntry> it( *m_pDict );
for( ; it.current(); ++it )
{
if(it.current()->m_szRegisteredUserName==user)
{
it.current()->m_szRegisteredUserName="";
it.current()->m_bNotFoundRegUserLoockup=false;
}
}
}
void KviIrcUserDataBase::registeredUserChanged(const TQString& user)
{
//the same as above
KviPointerHashTableIterator<TQString,KviIrcUserEntry> it( *m_pDict );
for( ; it.current(); ++it )
{
if(it.current()->m_szRegisteredUserName==user)
{
it.current()->m_szRegisteredUserName="";
it.current()->m_bNotFoundRegUserLoockup=false;
}
}
}
void KviIrcUserDataBase::registeredUserAdded(const TQString& user)
{
KviPointerHashTableIterator<TQString,KviIrcUserEntry> it( *m_pDict );
for( ; it.current(); ++it )
{
if(it.current()->m_szRegisteredUserName.isEmpty())
{
it.current()->m_bNotFoundRegUserLoockup=false;
}
}
}
void KviIrcUserDataBase::registeredDatabaseCleared()
{
KviPointerHashTableIterator<TQString,KviIrcUserEntry> it( *m_pDict );
for( ; it.current(); ++it )
{
it.current()->m_szRegisteredUserName="";
it.current()->m_bNotFoundRegUserLoockup=false;
}
}