using namespace std;
-#include <string>
-#include <map>
-#include <sstream>
-#include <vector>
-#include <deque>
#include <stdarg.h>
#include "configreader.h"
#include "inspircd.h"
-#include "hash_map.h"
#include "users.h"
-#include "ctables.h"
-#include "globals.h"
#include "modules.h"
-#include "dynamic.h"
-#include "commands.h"
#include "wildcard.h"
#include "mode.h"
-#include "xline.h"
-#include "inspstring.h"
-#include "helperfuncs.h"
-#include "typedefs.h"
chanrec::chanrec(InspIRCd* Instance) : ServerInstance(Instance)
{
void chanrec::SetModeParam(char mode,const char* parameter,bool mode_on)
{
- log(DEBUG,"SetModeParam called");
+ ServerInstance->Log(DEBUG,"SetModeParam called");
CustomModeList::iterator n = custom_mode_params.find(mode);
if (n == custom_mode_params.end())
{
custom_mode_params[mode] = strdup(parameter);
- log(DEBUG,"Custom mode parameter %c %s added",mode,parameter);
+ ServerInstance->Log(DEBUG,"Custom mode parameter %c %s added",mode,parameter);
}
else
{
- log(DEBUG, "Tried to set custom mode parameter for %c '%s' when it was already '%s'", mode, parameter, n->second);
+ ServerInstance->Log(DEBUG, "Tried to set custom mode parameter for %c '%s' when it was already '%s'", mode, parameter, n->second);
}
}
else
if (!Ptr)
{
- if (user->fd > -1)
+ if (IS_LOCAL(user))
{
MOD_RESULT = 0;
FOREACH_RESULT_I(Instance,I_OnUserPreJoin,OnUserPreJoin(user,NULL,cname));
*Ptr->topic = 0;
strlcpy(Ptr->setby, user->nick,NICKMAX-1);
Ptr->topicset = 0;
- ilog(Instance,DEBUG,"chanrec::JoinUser(): created: %s",cname);
+ Instance->Log(DEBUG,"chanrec::JoinUser(): created: %s",cname);
/*
* set created to 2 to indicate user
* is the first in the channel
{
if (!key)
{
- ilog(Instance,DEBUG,"chanrec::JoinUser(): no key given in JOIN");
+ Instance->Log(DEBUG,"chanrec::JoinUser(): no key given in JOIN");
user->WriteServ("475 %s %s :Cannot join channel (Requires key)",user->nick, Ptr->name);
return NULL;
}
{
if (strcmp(key,Ptr->key))
{
- ilog(Instance,DEBUG,"chanrec::JoinUser(): bad key given in JOIN");
+ Instance->Log(DEBUG,"chanrec::JoinUser(): bad key given in JOIN");
user->WriteServ("475 %s %s :Cannot join channel (Incorrect key)",user->nick, Ptr->name);
return NULL;
}
sprintf(mask,"%s!%s@%s",user->nick, user->ident, user->GetIPString());
if (!MOD_RESULT)
{
- for (BanList::iterator i = Ptr->bans.begin(); i != Ptr->bans.end(); i++)
+ if (Ptr->IsBanned(user))
{
- /* This allows CIDR ban matching
- *
- * Full masked host Full unmasked host IP with/without CIDR
- */
- if ((match(user->GetFullHost(),i->data)) || (match(user->GetFullRealHost(),i->data)) || (match(mask, i->data, true)))
- {
- user->WriteServ("474 %s %s :Cannot join channel (You're banned)",user->nick, Ptr->name);
- return NULL;
- }
+ user->WriteServ("474 %s %s :Cannot join channel (You're banned)",user->nick, Ptr->name);
+ return NULL;
}
}
}
}
else
{
- ilog(Instance,DEBUG,"chanrec::JoinUser(): Overridden checks");
+ Instance->Log(DEBUG,"chanrec::JoinUser(): Overridden checks");
}
created = 1;
}
if (created == 2)
{
- ilog(Instance,DEBUG,"BLAMMO, Whacking channel.");
+ Instance->Log(DEBUG,"BLAMMO, Whacking channel.");
/* Things went seriously pear shaped, so take this away. bwahaha. */
chan_hash::iterator n = Instance->chanlist.find(cname);
if (n != Instance->chanlist.end())
/* first user in is given ops */
a->uc_modes = UCMODE_OP;
Ptr->AddOppedUser(user);
+ Ptr->SetPrefix(user, '@', OP_VALUE, true);
}
else
{
a->channel = Ptr;
Ptr->AddUser(user);
+ user->ModChannelCount(1);
Ptr->WriteChannel(user,"JOIN :%s",Ptr->name);
/* Major improvement by Brain - we dont need to be calculating all this pointlessly for remote users */
user->WriteServ("333 %s %s %s %lu", user->nick, Ptr->name, Ptr->setby, (unsigned long)Ptr->topicset);
}
Ptr->UserList(user);
- user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, Ptr->name);
}
FOREACH_MOD_I(Instance,I_OnUserJoin,OnUserJoin(user,Ptr));
return Ptr;
}
+bool chanrec::IsBanned(userrec* user)
+{
+ char mask[MAXBUF];
+ sprintf(mask,"%s!%s@%s",user->nick, user->ident, user->GetIPString());
+ for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++)
+ {
+ /* This allows CIDR ban matching
+ *
+ * Full masked host Full unmasked host IP with/without CIDR
+ */
+ if ((match(user->GetFullHost(),i->data)) || (match(user->GetFullRealHost(),i->data)) || (match(mask, i->data, true)))
+ {
+ return true;
+ }
+
+ }
+ return false;
+}
+
/* chanrec::PartUser
* remove a channel from a users record, and remove the record from the hash
* if the channel has become empty
}
user->chans[i]->uc_modes = 0;
user->chans[i]->channel = NULL;
+ user->ModChannelCount(-1);
+ this->RemoveAllPrefixes(user);
break;
}
}
/* kill the record */
if (iter != ServerInstance->chanlist.end())
{
- log(DEBUG,"del_channel: destroyed: %s", this->name);
+ ServerInstance->Log(DEBUG,"del_channel: destroyed: %s", this->name);
FOREACH_MOD(I_OnChannelDelete,OnChannelDelete(this));
ServerInstance->chanlist.erase(iter);
}
this->WriteChannelWithServ(ServerInstance->Config->ServerName, "KICK %s %s :%s", this->name, user->nick, reason);
user->chans[i]->uc_modes = 0;
user->chans[i]->channel = NULL;
+ this->RemoveAllPrefixes(user);
break;
}
}
src->WriteServ("441 %s %s %s :They are not on that channel",src->nick, user->nick, this->name);
return this->GetUserCounter();
}
- if ((is_uline(user->server)) && (!is_uline(src->server)))
+ if ((ServerInstance->ULine(user->server)) && (!ServerInstance->ULine(src->server)))
{
src->WriteServ("482 %s %s :Only a u-line may kick a u-line from a channel.",src->nick, this->name);
return this->GetUserCounter();
}
int MOD_RESULT = 0;
- if (!is_uline(src->server))
+ if (!ServerInstance->ULine(src->server))
{
MOD_RESULT = 0;
FOREACH_RESULT(I_OnUserPreKick,OnUserPreKick(src,user,this,reason));
if (MOD_RESULT != -1)
{
FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(src,user,this,AC_KICK));
- if ((MOD_RESULT == ACR_DENY) && (!is_uline(src->server)))
+ if ((MOD_RESULT == ACR_DENY) && (!ServerInstance->ULine(src->server)))
return this->GetUserCounter();
- if ((MOD_RESULT == ACR_DEFAULT) || (!is_uline(src->server)))
+ if ((MOD_RESULT == ACR_DEFAULT) || (!ServerInstance->ULine(src->server)))
{
int them = this->GetStatus(src);
int us = this->GetStatus(user);
this->WriteChannel(src, "KICK %s %s :%s", this->name, user->nick, reason);
(*i)->uc_modes = 0;
(*i)->channel = NULL;
+ this->RemoveAllPrefixes(user);
break;
}
}
for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++)
{
- if (i->second->fd != FD_MAGIC_NUMBER)
+ if (IS_LOCAL(i->second))
user->WriteTo(i->second,text);
}
}
{
char list[MAXBUF];
size_t dlen, curlen;
+ int MOD_RESULT = 0;
+
+ FOREACH_RESULT(I_OnUserList,OnUserList(user, this));
+ ServerInstance->Log(DEBUG,"MOD_RESULT for UserList = %d",MOD_RESULT);
+ if (MOD_RESULT == 1)
+ return;
+
+ ServerInstance->Log(DEBUG,"Using builtin NAMES list generation");
dlen = curlen = snprintf(list,MAXBUF,"353 %s = %s :", user->nick, this->name);
continue;
}
- size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", this->GetStatusChar(i->second), i->second->nick);
+ size_t ptrlen = snprintf(ptr, MAXBUF, "%s%s ", this->GetPrefixChar(i->second), i->second->nick);
curlen += ptrlen;
ptr += ptrlen;
if (curlen > (480-NICKMAX))
{
/* list overflowed into multiple numerics */
- user->WriteServ(list);
+ user->WriteServ(std::string(list));
/* reset our lengths */
dlen = curlen = snprintf(list,MAXBUF,"353 %s = %s :", user->nick, this->name);
/* if whats left in the list isnt empty, send it */
if (numusers)
{
- user->WriteServ(list);
+ user->WriteServ(std::string(list));
}
+
+ user->WriteServ("366 %s %s :End of /NAMES list.", user->nick, this->name);
}
long chanrec::GetMaxBans()
/* returns the status character for a given user on a channel, e.g. @ for op,
* % for halfop etc. If the user has several modes set, the highest mode
- * the user has must be returned. */
-
-const char* chanrec::GetStatusChar(userrec *user)
+ * the user has must be returned.
+ */
+const char* chanrec::GetPrefixChar(userrec *user)
{
- for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
+ static char px[2];
+ unsigned int mx = 0;
+
+ *px = 0;
+ *(px+1) = 0;
+
+ prefixlist::iterator n = prefixes.find(user);
+ if (n != prefixes.end())
{
- if ((*i)->channel == this)
+ for (std::vector<prefixtype>::iterator x = n->second.begin(); x != n->second.end(); x++)
{
- if (((*i)->uc_modes & UCMODE_OP) > 0)
- {
- return "@";
- }
- if (((*i)->uc_modes & UCMODE_HOP) > 0)
+ if (x->second > mx)
{
- return "%";
+ *px = x->first;
+ mx = x->second;
}
- if (((*i)->uc_modes & UCMODE_VOICE) > 0)
- {
- return "+";
- }
- return "";
}
}
- return "";
+
+ return px;
+}
+
+const char* chanrec::GetAllPrefixChars(userrec* user)
+{
+ static char prefix[MAXBUF];
+ int ctr = 0;
+ *prefix = 0;
+
+ prefixlist::iterator n = prefixes.find(user);
+ if (n != prefixes.end())
+ {
+ for (std::vector<prefixtype>::iterator x = n->second.begin(); x != n->second.end(); x++)
+ {
+ prefix[ctr++] = x->first;
+ }
+ }
+
+ prefix[ctr] = 0;
+
+ return prefix;
+}
+
+unsigned int chanrec::GetPrefixValue(userrec* user)
+{
+ unsigned int mx = 0;
+
+ prefixlist::iterator n = prefixes.find(user);
+ if (n != prefixes.end())
+ {
+ for (std::vector<prefixtype>::iterator x = n->second.begin(); x != n->second.end(); x++)
+ {
+ if (x->second > mx)
+ mx = x->second;
+ }
+ }
+
+ return mx;
}
}
-
int chanrec::GetStatus(userrec *user)
{
- if (is_uline(user->server))
+ if (ServerInstance->ULine(user->server))
return STATUS_OP;
for (std::vector<ucrec*>::const_iterator i = user->chans.begin(); i != user->chans.end(); i++)
return STATUS_NORMAL;
}
+/*bool ModeParser::PrefixComparison(const prefixtype one, const prefixtype two)
+{
+ return one.second > two.second;
+}*/
+
+void chanrec::SetPrefix(userrec* user, char prefix, unsigned int prefix_value, bool adding)
+{
+ prefixlist::iterator n = prefixes.find(user);
+ prefixtype pfx = std::make_pair(prefix,prefix_value);
+ if (adding)
+ {
+ if (n != prefixes.end())
+ {
+ if (std::find(n->second.begin(), n->second.end(), pfx) == n->second.end())
+ {
+ n->second.push_back(pfx);
+ std::sort(n->second.begin(), n->second.end(), ModeParser::PrefixComparison);
+ }
+ }
+ else
+ {
+ pfxcontainer one;
+ one.push_back(pfx);
+ prefixes.insert(std::make_pair<userrec*,pfxcontainer>(user, one));
+ }
+ }
+ else
+ {
+ if (n != prefixes.end())
+ {
+ pfxcontainer::iterator x = std::find(n->second.begin(), n->second.end(), pfx);
+ if (x != n->second.end())
+ n->second.erase(x);
+ }
+ }
+}
+
+void chanrec::RemoveAllPrefixes(userrec* user)
+{
+ prefixlist::iterator n = prefixes.find(user);
+ if (n != prefixes.end())
+ prefixes.erase(n);
+}