summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/channels.h3
-rw-r--r--include/users.h2
-rw-r--r--src/channels.cpp55
-rw-r--r--src/helperfuncs.cpp50
-rw-r--r--src/modules/m_spanningtree.cpp5
-rw-r--r--src/users.cpp15
6 files changed, 57 insertions, 73 deletions
diff --git a/include/channels.h b/include/channels.h
index c7a0a8777..e14c81f27 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -213,8 +213,9 @@ class chanrec : public Extensible
/** Delete a user pointer to the internal reference list
* @param user The user to delete
+ * @return number of users left on the channel
*/
- void DelUser(userrec* user);
+ unsigned long DelUser(userrec* user);
void DelOppedUser(userrec* user);
void DelHalfoppedUser(userrec* user);
void DelVoicedUser(userrec* user);
diff --git a/include/users.h b/include/users.h
index 71563abfa..294bc1e1f 100644
--- a/include/users.h
+++ b/include/users.h
@@ -151,7 +151,7 @@ class userrec : public connection
*/
char modes[54];
- std::vector<ucrec> chans;
+ std::vector<ucrec*> chans;
/** The server the user is connected to.
*/
diff --git a/src/channels.cpp b/src/channels.cpp
index 95e511156..1574ffc0b 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -66,7 +66,7 @@ extern chan_hash chanlist;
using namespace std;
-chanrec* ForceChan(chanrec* Ptr,ucrec &a,userrec* user, int created);
+chanrec* ForceChan(chanrec* Ptr,ucrec *a,userrec* user, int created);
chanrec::chanrec()
{
@@ -133,7 +133,7 @@ void chanrec::AddUser(userrec* user)
internal_userlist[user] = user;
}
-void chanrec::DelUser(userrec* user)
+unsigned long chanrec::DelUser(userrec* user)
{
CUList::iterator a = internal_userlist.find(user);
if (a != internal_userlist.end())
@@ -143,8 +143,9 @@ void chanrec::DelUser(userrec* user)
DelOppedUser(user);
DelHalfoppedUser(user);
DelVoicedUser(user);
- return;
+ return internal_userlist.size();
}
+ return internal_userlist.size();
}
bool chanrec::HasUser(userrec* user)
@@ -387,7 +388,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
*/
if (!IS_LOCAL(user)) /* was a check on fd < 0 */
{
- ucrec a;
+ ucrec* a = new ucrec();
chanrec* c = ForceChan(Ptr,a,user,created);
user->chans.push_back(a);
return c;
@@ -397,7 +398,7 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
/* Oper allows extension up to the OPERMAXCHANS value */
if (user->chans.size() < OPERMAXCHANS)
{
- ucrec a;
+ ucrec* a = new ucrec();
chanrec* c = ForceChan(Ptr,a,user,created);
user->chans.push_back(a);
return c;
@@ -419,10 +420,10 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
chanlist.erase(n);
for (unsigned int index =0; index < user->chans.size(); index++)
{
- if (user->chans[index].channel == Ptr)
+ if (user->chans[index]->channel == Ptr)
{
- user->chans[index].channel = NULL;
- user->chans[index].uc_modes = 0;
+ user->chans[index]->channel = NULL;
+ user->chans[index]->uc_modes = 0;
}
}
}
@@ -430,17 +431,17 @@ chanrec* add_channel(userrec *user, const char* cn, const char* key, bool overri
return NULL;
}
-chanrec* ForceChan(chanrec* Ptr,ucrec &a,userrec* user, int created)
+chanrec* ForceChan(chanrec* Ptr,ucrec *a,userrec* user, int created)
{
if (created == 2)
{
/* first user in is given ops */
- a.uc_modes = UCMODE_OP;
+ a->uc_modes = UCMODE_OP;
Ptr->AddOppedUser(user);
}
else
{
- a.uc_modes = 0;
+ a->uc_modes = 0;
}
a.channel = Ptr;
@@ -483,7 +484,7 @@ chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool
for (unsigned int i =0; i < user->chans.size(); i++)
{
/* zap it from the channel list of the user */
- if (user->chans[i].channel == Ptr)
+ if (user->chans[i]->channel == Ptr)
{
if (reason)
{
@@ -495,8 +496,8 @@ chanrec* del_channel(userrec *user, const char* cname, const char* reason, bool
FOREACH_MOD(I_OnUserPart,OnUserPart(user,Ptr,""));
WriteChannel(Ptr,user,"PART :%s",Ptr->name);
}
- user->chans[i].uc_modes = 0;
- user->chans[i].channel = NULL;
+ user->chans[i]->uc_modes = 0;
+ user->chans[i]->channel = NULL;
log(DEBUG,"del_channel: unlinked: %s %s",user->nick,Ptr->name);
break;
}
@@ -547,12 +548,11 @@ void server_kick_channel(userrec* user, chanrec* Ptr, char* reason, bool trigger
for (unsigned int i =0; i < user->chans.size(); i++)
{
- if (user->chans[i].channel)
- if (!strcasecmp(user->chans[i].channel->name,Ptr->name))
+ if ((user->chans[i]->channel) && (user->chans[i]->channel->name == Ptr))
{
WriteChannelWithServ(Config->ServerName,Ptr,"KICK %s %s :%s",Ptr->name, user->nick, reason);
- user->chans[i].uc_modes = 0;
- user->chans[i].channel = NULL;
+ user->chans[i]->uc_modes = 0;
+ user->chans[i]->channel = NULL;
break;
}
}
@@ -631,23 +631,18 @@ void kick_channel(userrec *src,userrec *user, chanrec *Ptr, char* reason)
for (unsigned int i =0; i < user->chans.size(); i++)
{
/* zap it from the channel list of the user */
- if (user->chans[i].channel)
+ if ((user->chans[i].channel) && (user->chans[i].channel == Ptr->name))
{
- if (!strcasecmp(user->chans[i].channel->name,Ptr->name))
- {
- WriteChannel(Ptr,src,"KICK %s %s :%s",Ptr->name, user->nick, reason);
- user->chans[i].uc_modes = 0;
- user->chans[i].channel = NULL;
- log(DEBUG,"del_channel: unlinked: %s %s",user->nick,Ptr->name);
- break;
- }
+ WriteChannel(Ptr,src,"KICK %s %s :%s",Ptr->name, user->nick, reason);
+ user->chans[i].uc_modes = 0;
+ user->chans[i].channel = NULL;
+ log(DEBUG,"del_channel: unlinked: %s %s",user->nick,Ptr->name);
+ break;
}
}
- Ptr->DelUser(user);
-
+ if (!Ptr->DelUser(user))
/* if there are no users left on the channel */
- if (!usercount(Ptr))
{
chan_hash::iterator iter = chanlist.find(Ptr->name);
diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp
index d2ec1f7d0..f728516f9 100644
--- a/src/helperfuncs.cpp
+++ b/src/helperfuncs.cpp
@@ -1219,49 +1219,37 @@ long GetMaxBans(char* name)
void purge_empty_chans(userrec* u)
{
int purge = 0;
+ std::vector<chanrec*> to_delete;
// firstly decrement the count on each channel
- for (unsigned int f = 0; f < u->chans.size(); f++)
+ for (std::vector<ucrec*>::iterator f = u->chans.begin(); f != u->chans.end(); f++)
{
- if (u->chans[f].channel)
+ ucrec* (ucrec*)*f;
+ if (f->channel)
{
- u->chans[f].channel->DelUser(u);
+ if (f->channel->DelUser(u) == 0)
+ {
+ /* No users left in here, mark it for deletion */
+ to_delete.push_back(f->channel);
+ f->channel = NULL;
+ }
}
}
- for (unsigned int i = 0; i < u->chans.size(); i++)
+ for (std::vector<chanrec*>::iterator n = to_delete.begin(); n != to_delete.end(); n++)
{
- if (u->chans[i].channel)
+ chanrec* thischan = (chanrec*)*n;
+ chan_hash::iterator i2 = chanlist.find(thischan->name);
+ if (i2 != chanlist.end())
{
- if (!usercount(u->chans[i].channel))
- {
- chan_hash::iterator i2 = chanlist.find(u->chans[i].channel->name);
-
- /* kill the record */
- if (i2 != chanlist.end())
- {
- log(DEBUG,"del_channel: destroyed: %s",i2->second->name);
-
- if (i2->second)
- {
- FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second));
- delete i2->second;
- }
-
- chanlist.erase(i2);
- purge++;
- u->chans[i].channel = NULL;
- }
- }
- else
- {
- log(DEBUG,"skipped purge for %s",u->chans[i].channel->name);
- }
+ FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(i2->second));
+ delete i2->second;
+ chanlist.erase(i2);
}
}
- log(DEBUG,"completed channel purge, killed %lu",(unsigned long)purge);
- DeleteOper(u);
+ if (*u->oper)
+ DeleteOper(u);
}
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index bb97d2b05..e99bd814d 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -1111,11 +1111,6 @@ class TreeSocket : public InspSocket
strlcpy(clientlist[tempnick]->modes, modes.c_str(),53);
inet_aton(params[6].c_str(),&clientlist[tempnick]->ip4);
- ucrec a;
- a.channel = NULL;
- a.uc_modes = 0;
- clientlist[tempnick]->chans.resize(MAXCHANS);
-
WriteOpers("*** Client connecting at %s: %s!%s@%s [%s]",clientlist[tempnick]->server,clientlist[tempnick]->nick,clientlist[tempnick]->ident,clientlist[tempnick]->host,(char*)inet_ntoa(clientlist[tempnick]->ip4));
params[7] = ":" + params[7];
diff --git a/src/users.cpp b/src/users.cpp
index 94ed97d93..9bc006bbc 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -113,10 +113,20 @@ userrec::userrec()
sendq = "";
chans.clear();
invites.clear();
+ clientlist[tempnick]->chans.resize(MAXCHANS);
+ for (unsigned int n = 0; n < MAXCHANS; n++)
+ {
+ clientlist[tempnick]->chans[n] = new ucrec();
+ }
}
userrec::~userrec()
{
+ for (std::vector<ucrec*>::iterator n = clientlist[tempnick]->chans.begin(); n != clientlist[tempnick]->chans.end(); n++)
+ {
+ ucrec* x = (ucrec*)*n;
+ delete x;
+ }
}
void userrec::MakeHost(char* nhost)
@@ -616,11 +626,6 @@ void AddClient(int socket, int port, bool iscached, in_addr ip4)
clientlist[tempnick]->sendqmax = class_sqmax;
clientlist[tempnick]->recvqmax = class_rqmax;
- ucrec a;
- a.channel = NULL;
- a.uc_modes = 0;
- clientlist[tempnick]->chans.resize(MAXCHANS);
-
fd_ref_table[socket] = clientlist[tempnick];
local_users.push_back(clientlist[tempnick]);