summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/access.h2
-rw-r--r--include/anope.h17
-rw-r--r--include/channels.h19
-rw-r--r--include/hashcomp.h4
-rw-r--r--include/logger.h27
-rw-r--r--include/modes.h29
-rw-r--r--include/protocol.h2
-rw-r--r--include/servers.h8
-rw-r--r--include/users.h4
-rw-r--r--modules/commands/bs_kick.cpp4
-rw-r--r--modules/commands/cs_access.cpp4
-rw-r--r--modules/commands/cs_akick.cpp5
-rw-r--r--modules/commands/cs_ban.cpp3
-rw-r--r--modules/commands/cs_enforce.cpp12
-rw-r--r--modules/commands/cs_kick.cpp3
-rw-r--r--modules/commands/cs_mode.cpp11
-rw-r--r--modules/commands/cs_seen.cpp15
-rw-r--r--modules/commands/cs_set.cpp3
-rw-r--r--modules/commands/cs_suspend.cpp2
-rw-r--r--modules/commands/cs_sync.cpp2
-rw-r--r--modules/commands/cs_updown.cpp15
-rw-r--r--modules/commands/ns_recover.cpp6
-rw-r--r--modules/commands/os_chankill.cpp2
-rw-r--r--modules/commands/os_dns.cpp10
-rw-r--r--modules/commands/os_forbid.cpp62
-rw-r--r--modules/commands/os_forbid.h6
-rw-r--r--modules/commands/os_jupe.cpp2
-rw-r--r--modules/commands/os_list.cpp4
-rw-r--r--modules/commands/os_mode.cpp6
-rw-r--r--modules/commands/os_noop.cpp2
-rw-r--r--modules/commands/os_session.cpp174
-rw-r--r--modules/commands/os_session.h6
-rw-r--r--modules/commands/os_sxline.cpp2
-rw-r--r--modules/extra/cs_statusupdate.cpp4
-rw-r--r--modules/extra/m_xmlrpc_main.cpp4
-rw-r--r--modules/protocol/bahamut.cpp34
-rw-r--r--modules/protocol/charybdis.cpp2
-rw-r--r--modules/protocol/hybrid.cpp30
-rw-r--r--modules/protocol/inspircd11.cpp27
-rw-r--r--modules/protocol/inspircd12.cpp41
-rw-r--r--modules/protocol/inspircd20.cpp6
-rw-r--r--modules/protocol/ngircd.cpp24
-rw-r--r--modules/protocol/plexus.cpp9
-rw-r--r--modules/protocol/ratbox.cpp2
-rw-r--r--modules/protocol/unreal.cpp38
-rw-r--r--modules/pseudoclients/chanserv.cpp4
-rw-r--r--modules/pseudoclients/memoserv.cpp4
-rw-r--r--modules/pseudoclients/nickserv.cpp4
-rw-r--r--modules/pseudoclients/operserv.cpp18
-rw-r--r--src/access.cpp10
-rw-r--r--src/bots.cpp4
-rw-r--r--src/channels.cpp115
-rw-r--r--src/config.cpp11
-rw-r--r--src/hashcomp.cpp80
-rw-r--r--src/logger.cpp209
-rw-r--r--src/main.cpp3
-rw-r--r--src/messages.cpp15
-rw-r--r--src/misc.cpp6
-rw-r--r--src/modes.cpp219
-rw-r--r--src/process.cpp29
-rw-r--r--src/protocol.cpp2
-rw-r--r--src/regchannel.cpp31
-rw-r--r--src/servers.cpp56
-rw-r--r--src/users.cpp24
64 files changed, 752 insertions, 786 deletions
diff --git a/include/access.h b/include/access.h
index ea2667774..f60625ad9 100644
--- a/include/access.h
+++ b/include/access.h
@@ -79,6 +79,8 @@ class CoreExport ChanAccess : public Serializable
AccessProvider *provider;
/* Channel this access entry is on */
Serialize::Reference<ChannelInfo> ci;
+ /* account this access entry is for, if any */
+ Serialize::Reference<NickCore> nc;
Anope::string mask;
Anope::string creator;
time_t last_seen;
diff --git a/include/anope.h b/include/anope.h
index 9bf0f982d..8e24d12da 100644
--- a/include/anope.h
+++ b/include/anope.h
@@ -255,7 +255,7 @@ namespace Anope
{
Anope::string new_string = *this;
for (size_type i = 0; i < new_string.length(); ++i)
- new_string[i] = std::tolower(new_string[i], Anope::casemap);
+ new_string[i] = Anope::tolower(new_string[i]);
return new_string;
}
@@ -266,7 +266,7 @@ namespace Anope
{
Anope::string new_string = *this;
for (size_type i = 0; i < new_string.length(); ++i)
- new_string[i] = std::toupper(new_string[i], Anope::casemap);
+ new_string[i] = Anope::toupper(new_string[i]);
return new_string;
}
@@ -547,15 +547,12 @@ class CoreExport sepstream
/** Original string.
*/
Anope::string tokens;
- /** Last position of a seperator token
- */
- Anope::string::iterator last_starting_position;
- /** Current string position
- */
- Anope::string::iterator n;
/** Seperator value
*/
char sep;
+ /** Current string position
+ */
+ size_t pos;
public:
/** Create a sepstream and fill it with the provided data
*/
@@ -570,7 +567,7 @@ class CoreExport sepstream
/** Gets token number 'num' from the stream
* @param token The token is placed here
* @param num The token number to featch
- * @return True if the token was able to be detched
+ * @return True if the token was able to be fetched
*/
bool GetToken(Anope::string &token, int num);
@@ -588,7 +585,7 @@ class CoreExport sepstream
/** Gets token number 'num' from the stream and all remaining tokens.
* @param token The token is placed here
* @param num The token number to featch
- * @return True if the token was able to be detched
+ * @return True if the token was able to be fetched
*/
bool GetTokenRemainder(Anope::string &token, int num);
diff --git a/include/channels.h b/include/channels.h
index 18ef65a7c..118864c8a 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -54,7 +54,7 @@ class CoreExport Channel : public Base, public Extensible
time_t creation_time;
/* Users in the channel */
- typedef std::list<ChanUserContainer *> ChanUserList;
+ typedef std::map<User *, ChanUserContainer *> ChanUserList;
ChanUserList users;
/* Current topic of the channel */
@@ -75,12 +75,14 @@ class CoreExport Channel : public Base, public Extensible
int16_t chanserv_modecount; /* Number of check_mode()'s this sec */
int16_t bouncy_modes; /* Did we fail to set modes here? */
+ private:
/** Constructor
* @param name The channel name
* @param ts The time the channel was created
*/
Channel(const Anope::string &nname, time_t ts = Anope::CurTime);
+ public:
/** Destructor
*/
~Channel();
@@ -113,14 +115,14 @@ class CoreExport Channel : public Base, public Extensible
* @param u The user
* @return A user container if found, else NULL
*/
- ChanUserContainer *FindUser(const User *u) const;
+ ChanUserContainer *FindUser(User *u) const;
/** Check if a user has a status on a channel
* @param u The user
* @param cms The status mode, or NULL to represent no status
* @return true or false
*/
- bool HasUserStatus(const User *u, ChannelModeStatus *cms) const;
+ bool HasUserStatus(User *u, ChannelModeStatus *cms);
/** Check if a user has a status on a channel
* Use the overloaded function for ChannelModeStatus* to check for no status
@@ -128,7 +130,7 @@ class CoreExport Channel : public Base, public Extensible
* @param name The mode name, eg CMODE_OP, CMODE_VOICE
* @return true or false
*/
- bool HasUserStatus(const User *u, const Anope::string &name) const;
+ bool HasUserStatus(User *u, const Anope::string &name);
/** See if a channel has a mode
* @param name The mode name
@@ -279,13 +281,20 @@ class CoreExport Channel : public Base, public Extensible
* @param full Whether or not to match using the user's real host and IP
* @return whether or not a ban was removed
*/
- bool Unban(const User *u, bool full = false);
+ bool Unban(User *u, bool full = false);
/** Finds a channel
* @param name The channel to find
* @return The channel, if found
*/
static Channel* Find(const Anope::string &name);
+
+ /** Finds or creates a channel
+ * @param name The channel name
+ * @param created Set to true if the channel was just created
+ * @param ts The time the channel was created
+ */
+ static Channel *FindOrCreate(const Anope::string &name, bool &created, time_t ts = Anope::CurTime);
};
#endif // CHANNELS_H
diff --git a/include/hashcomp.h b/include/hashcomp.h
index 9ebc7ae81..38c0e3833 100644
--- a/include/hashcomp.h
+++ b/include/hashcomp.h
@@ -28,6 +28,10 @@ namespace Anope
/* Casemap in use by Anope. ci::string's comparation functions use this (and thus Anope::string) */
extern std::locale casemap;
+ extern void CaseMapRebuild();
+ extern unsigned char tolower(unsigned char);
+ extern unsigned char toupper(unsigned char);
+
/* ASCII case insensitive ctype. */
template<typename char_type>
class ascii_ctype : public std::ctype<char_type>
diff --git a/include/logger.h b/include/logger.h
index 5050c22ce..afa874ca3 100644
--- a/include/logger.h
+++ b/include/logger.h
@@ -45,7 +45,8 @@ struct LogFile
std::ofstream stream;
LogFile(const Anope::string &name);
- Anope::string GetName() const;
+ ~LogFile();
+ const Anope::string &GetName() const;
};
/* Represents a single log message */
@@ -72,7 +73,6 @@ class CoreExport Log
Module *m;
LogType type;
Anope::string category;
- std::list<Anope::string> sources;
std::stringstream buf;
@@ -109,17 +109,18 @@ class CoreExport Log
class CoreExport LogInfo
{
public:
- std::list<Anope::string> targets;
- std::map<Anope::string, LogFile *> logfiles;
- std::list<Anope::string> sources;
+ std::vector<Anope::string> targets;
+ std::vector<LogFile *> logfiles;
+ int last_day;
+ std::vector<Anope::string> sources;
int log_age;
- std::list<Anope::string> admin;
- std::list<Anope::string> override;
- std::list<Anope::string> commands;
- std::list<Anope::string> servers;
- std::list<Anope::string> users;
- std::list<Anope::string> channels;
- std::list<Anope::string> normal;
+ std::vector<Anope::string> admin;
+ std::vector<Anope::string> override;
+ std::vector<Anope::string> commands;
+ std::vector<Anope::string> servers;
+ std::vector<Anope::string> users;
+ std::vector<Anope::string> channels;
+ std::vector<Anope::string> normal;
bool raw_io;
bool debug;
@@ -127,7 +128,7 @@ class CoreExport LogInfo
~LogInfo();
- void AddType(std::list<Anope::string> &list, const Anope::string &type);
+ void OpenLogFiles();
bool HasType(LogType ltype, const Anope::string &type) const;
diff --git a/include/modes.h b/include/modes.h
index bb329b5b4..6a39393bb 100644
--- a/include/modes.h
+++ b/include/modes.h
@@ -134,7 +134,7 @@ class CoreExport ChannelModeList : public ChannelMode
* @param e The entry to match against
* @return true on match
*/
- virtual bool Matches(const User *u, const Entry *e) { return false; }
+ virtual bool Matches(User *u, const Entry *e) { return false; }
/** Called when a mask is added to a channel
* @param chan The channel
@@ -181,7 +181,7 @@ class CoreExport ChannelModeStatus : public ChannelMode
{
public:
/* The symbol, eg @ % + */
- char Symbol;
+ char symbol;
/* The "level" of the mode, used to compare with other modes.
* Used so we know op > halfop > voice etc.
*/
@@ -190,10 +190,10 @@ class CoreExport ChannelModeStatus : public ChannelMode
/** constructor
* @param name The mode name
* @param mc The mode char
- * @param mSymbol The symbol for the mode, eg @ %
+ * @param msymbol The symbol for the mode, eg @ %
* @param mlevel A level for the mode, which is usually determined by the PREFIX capab
*/
- ChannelModeStatus(const Anope::string &name, char mc, char mSymbol, short mlevel = 0);
+ ChannelModeStatus(const Anope::string &name, char mc, char msymbol, short mlevel = 0);
/** destructor
*/
@@ -203,9 +203,14 @@ class CoreExport ChannelModeStatus : public ChannelMode
/* The status a user has on a channel (+v, +h, +o) etc */
class CoreExport ChannelStatus
{
+ Anope::string modes;
public:
- std::set<Anope::string> modes;
- Anope::string BuildCharPrefixList() const;
+ void AddMode(char c);
+ void DelMode(char c);
+ bool HasMode(char c) const;
+ bool Empty() const;
+ void Clear();
+ const Anope::string &Modes() const;
Anope::string BuildModePrefixList() const;
};
@@ -292,11 +297,14 @@ class CoreExport ModeManager
*/
static std::list<Anope::string> BuildModeStrings(StackerInfo *info);
- public:
- /* List of all modes Anope knows about */
+ /* Array of all modes Anope knows about. Modes are in this array at position
+ * modechar. Additionally, status modes are in this array (again) at statuschar.
+ */
static std::vector<ChannelMode *> ChannelModes;
static std::vector<UserMode *> UserModes;
+ public:
+
/* Number of generic channel and user modes we are tracking */
static unsigned GenericChannelModes;
static unsigned GenericUserModes;
@@ -358,6 +366,9 @@ class CoreExport ModeManager
*/
static char GetStatusChar(char symbol);
+ static const std::vector<ChannelMode *> &GetChannelModes();
+ static const std::vector<UserMode *> &GetUserModes();
+
/** Add a mode to the stacker to be set on a channel
* @param bi The client to set the modes from
* @param c The channel
@@ -419,7 +430,7 @@ class CoreExport Entry
* @param full True to match against a users real host and IP
* @return true on match
*/
- bool Matches(const User *u, bool full = false) const;
+ bool Matches(User *u, bool full = false) const;
};
#endif // MODES_H
diff --git a/include/protocol.h b/include/protocol.h
index 8953d25e5..23bed3003 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -148,7 +148,7 @@ class CoreExport IRCDProto : public Service
* be set on the user. This may include the modes in the join, but will usually place them on the mode
* stacker to be set "soon".
*/
- virtual void SendJoin(const User *u, Channel *c, const ChannelStatus *status) = 0;
+ virtual void SendJoin(User *u, Channel *c, const ChannelStatus *status) = 0;
virtual void SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...);
/** Force joins a user that isn't ours to a channel.
diff --git a/include/servers.h b/include/servers.h
index d8b01626f..bf0acb523 100644
--- a/include/servers.h
+++ b/include/servers.h
@@ -33,6 +33,10 @@ namespace Servers
*/
extern CoreExport Server* GetUplink();
+ /* Server maps by name and id */
+ extern CoreExport Anope::map<Server *> ByName;
+ extern CoreExport Anope::map<Server *> ByID;
+
/* CAPAB/PROTOCTL given by the uplink */
extern CoreExport std::set<Anope::string> Capab;
}
@@ -169,10 +173,10 @@ class CoreExport Server : public Extensible
/** Find a server
* @param name The name or SID/numeric
- * @param s The server list to search for this server on, defaults to our Uplink
+ * @param name_only set to true to only look up by name, not SID
* @return The server
*/
- static Server *Find(const Anope::string &name, Server *s = NULL);
+ static Server *Find(const Anope::string &name, bool name_only = false);
};
#endif // SERVERS_H
diff --git a/include/users.h b/include/users.h
index 4110ad211..5bcd61f95 100644
--- a/include/users.h
+++ b/include/users.h
@@ -79,7 +79,7 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
bool super_admin;
/* Channels the user is in */
- typedef std::list<ChanUserContainer *> ChanUserList;
+ typedef std::map<Channel *, ChanUserContainer *> ChanUserList;
ChanUserList chans;
/* Last time this user sent a memo command used */
@@ -312,7 +312,7 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
* @param c The channel
* @return The channel container, or NULL
*/
- ChanUserContainer *FindChannel(const Channel *c) const;
+ ChanUserContainer *FindChannel(Channel *c) const;
/** Check if the user is protected from kicks and negative mode changes
* @return true or false
diff --git a/modules/commands/bs_kick.cpp b/modules/commands/bs_kick.cpp
index 3f7cc16c2..97f6b6035 100644
--- a/modules/commands/bs_kick.cpp
+++ b/modules/commands/bs_kick.cpp
@@ -808,7 +808,7 @@ class BSKick : public Module
{
Channel *c = cit->second;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
- (*it)->Shrink("bs_main_userdata");
+ it->second->Shrink("bs_main_userdata");
c->Shrink("bs_main_bandata");
}
}
@@ -1033,7 +1033,7 @@ class BSKick : public Module
{
for (User::ChanUserList::iterator it = u->chans.begin(); it != u->chans.end();)
{
- Channel *chan = (*it)->chan;
+ Channel *chan = it->second->chan;
++it;
if (chan->ci && chan->ci->HasExt("BS_KICK_AMSGS") && !chan->ci->AccessFor(u).HasPriv("NOKICK"))
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp
index 239c344ab..3a4bdff54 100644
--- a/modules/commands/cs_access.cpp
+++ b/modules/commands/cs_access.cpp
@@ -326,7 +326,7 @@ class CommandCSAccess : public Command
Anope::string timebuf;
if (ci->c)
for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
- if (access->Matches((*cit)->user, (*cit)->user->Account()))
+ if (access->Matches(cit->second->user, cit->second->user->Account()))
timebuf = "Now";
if (timebuf.empty())
{
@@ -360,7 +360,7 @@ class CommandCSAccess : public Command
Anope::string timebuf;
if (ci->c)
for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit)
- if (access->Matches((*cit)->user, (*cit)->user->Account()))
+ if (access->Matches(cit->second->user, cit->second->user->Account()))
timebuf = "Now";
if (timebuf.empty())
{
diff --git a/modules/commands/cs_akick.cpp b/modules/commands/cs_akick.cpp
index a3133b8e9..f2bd603f9 100644
--- a/modules/commands/cs_akick.cpp
+++ b/modules/commands/cs_akick.cpp
@@ -390,9 +390,10 @@ class CommandCSAKick : public Command
return;
}
- for (User::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
+ for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
{
- ChanUserContainer *uc = *it++;
+ ChanUserContainer *uc = it->second;
+ ++it;
if (ci->CheckKick(uc->user))
++count;
diff --git a/modules/commands/cs_ban.cpp b/modules/commands/cs_ban.cpp
index 06c8de95a..5aad394a3 100644
--- a/modules/commands/cs_ban.cpp
+++ b/modules/commands/cs_ban.cpp
@@ -160,7 +160,8 @@ class CommandCSBan : public Command
int matched = 0, kicked = 0;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
{
- ChanUserContainer *uc = *it++;
+ ChanUserContainer *uc = it->second;
+ ++it;
if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
{
diff --git a/modules/commands/cs_enforce.cpp b/modules/commands/cs_enforce.cpp
index 4d5ba0242..fd5caf613 100644
--- a/modules/commands/cs_enforce.cpp
+++ b/modules/commands/cs_enforce.cpp
@@ -31,7 +31,7 @@ class CommandCSEnforce : public Command
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
ci->c->SetCorrectModes(uc->user, false, false);
}
@@ -50,7 +50,7 @@ class CommandCSEnforce : public Command
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
User *user = uc->user;
if (user->IsProtected())
@@ -81,7 +81,7 @@ class CommandCSEnforce : public Command
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
User *user = uc->user;
if (user->IsProtected())
@@ -113,7 +113,7 @@ class CommandCSEnforce : public Command
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
User *user = uc->user;
if (user->IsProtected())
@@ -145,7 +145,7 @@ class CommandCSEnforce : public Command
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
User *user = uc->user;
if (user->IsProtected())
@@ -195,7 +195,7 @@ class CommandCSEnforce : public Command
/* The newer users are at the end of the list, so kick users starting from the end */
for (Channel::ChanUserList::reverse_iterator it = ci->c->users.rbegin(), it_end = ci->c->users.rend(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
User *user = uc->user;
if (user->IsProtected())
diff --git a/modules/commands/cs_kick.cpp b/modules/commands/cs_kick.cpp
index 03beaf0a8..870c18f0c 100644
--- a/modules/commands/cs_kick.cpp
+++ b/modules/commands/cs_kick.cpp
@@ -79,7 +79,8 @@ class CommandCSKick : public Command
int matched = 0, kicked = 0;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
{
- ChanUserContainer *uc = *it++;
+ ChanUserContainer *uc = it->second;
+ ++it;
if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
{
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
index 7edc4eddc..1d0f0985b 100644
--- a/modules/commands/cs_mode.cpp
+++ b/modules/commands/cs_mode.cpp
@@ -253,9 +253,11 @@ class CommandCSMode : public Command
case '*':
if (adding == -1 || !has_access)
break;
- for (unsigned j = 0; j < ModeManager::ChannelModes.size(); ++j)
+ for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j)
{
- ChannelMode *cm = ModeManager::ChannelModes[j];
+ ChannelMode *cm = ModeManager::GetChannelModes()[j];
+ if (!cm)
+ continue;
if (!u || cm->CanSet(u))
{
if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM))
@@ -309,9 +311,10 @@ class CommandCSMode : public Command
break;
}
- for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
+ for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
+ ++it;
AccessGroup targ_access = ci->AccessFor(uc->user);
diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp
index 10c23dd53..66706c8fb 100644
--- a/modules/commands/cs_seen.cpp
+++ b/modules/commands/cs_seen.cpp
@@ -60,10 +60,10 @@ struct SeenInfo : Serializable
s = anope_dynamic_static_cast<SeenInfo *>(obj);
else
{
- /* ignore duplicate entries in the db, created by an old bug */
- s = FindInfo(snick);
- if (!s)
- s = new SeenInfo();
+ SeenInfo* &info = database[snick];
+ if (!info)
+ info = new SeenInfo();
+ s = info;
}
data["nick"] >> s->nick;
@@ -388,12 +388,9 @@ class CSSeen : public Module
if (!u->server->IsSynced())
return;
- SeenInfo *info = FindInfo(nick);
+ SeenInfo* &info = database[nick];
if (!info)
- {
- info = new SeenInfo;
- database.insert(std::pair<Anope::string, SeenInfo *>(nick, info));
- }
+ info = new SeenInfo();
info->nick = nick;
info->vhost = u->GetVIdent() + "@" + u->GetDisplayedHost();
info->type = Type;
diff --git a/modules/commands/cs_set.cpp b/modules/commands/cs_set.cpp
index cfc2c4767..67d024c9f 100644
--- a/modules/commands/cs_set.cpp
+++ b/modules/commands/cs_set.cpp
@@ -544,7 +544,8 @@ class CommandCSSetPersist : public Command
/* Channel doesn't exist, create it */
if (!ci->c)
{
- Channel *c = new Channel(ci->name);
+ bool created;
+ Channel *c = Channel::FindOrCreate(ci->name, created);
if (ci->bi)
ci->bi->Join(c);
}
diff --git a/modules/commands/cs_suspend.cpp b/modules/commands/cs_suspend.cpp
index fdfd2d55a..0ea54879e 100644
--- a/modules/commands/cs_suspend.cpp
+++ b/modules/commands/cs_suspend.cpp
@@ -66,7 +66,7 @@ class CommandCSSuspend : public Command
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
User *user = uc->user;
if (!user->HasMode("OPER") && user->server != Me)
users.push_back(user);
diff --git a/modules/commands/cs_sync.cpp b/modules/commands/cs_sync.cpp
index 1a02c813c..3983a52d1 100644
--- a/modules/commands/cs_sync.cpp
+++ b/modules/commands/cs_sync.cpp
@@ -35,7 +35,7 @@ class CommandCSSync : public Command
Log(LOG_COMMAND, source, this, ci);
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
- ci->c->SetCorrectModes((*it)->user, true, false);
+ ci->c->SetCorrectModes(it->second->user, true, false);
source.Reply(_("All user modes on \002%s\002 have been synced."), ci->name.c_str());
}
diff --git a/modules/commands/cs_updown.cpp b/modules/commands/cs_updown.cpp
index 27e1984d1..ecce1e51d 100644
--- a/modules/commands/cs_updown.cpp
+++ b/modules/commands/cs_updown.cpp
@@ -30,7 +30,7 @@ class CommandCSUp : public Command
return;
for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
{
- Channel *c = (*it)->chan;
+ Channel *c = it->second->chan;
c->SetCorrectModes(source.GetUser(), true, false);
}
}
@@ -87,13 +87,10 @@ class CommandCSDown : public Command
{
void RemoveAll(User *u, Channel *c)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
-
- if (cm != NULL && cm->type == MODE_STATUS)
- c->RemoveMode(NULL, cm, u->nick);
- }
+ ChanUserContainer *cu = c->FindUser(u);
+ if (cu != NULL)
+ for (size_t i = 0; i < cu->status.Modes().length(); ++i)
+ c->RemoveMode(NULL, ModeManager::FindChannelModeByChar(cu->status.Modes()[i]), u->GetUID());
}
public:
@@ -111,7 +108,7 @@ class CommandCSDown : public Command
return;
for (User::ChanUserList::iterator it = source.GetUser()->chans.begin(); it != source.GetUser()->chans.end(); ++it)
{
- Channel *c = (*it)->chan;
+ Channel *c = it->second->chan;
RemoveAll(source.GetUser(), c);
}
}
diff --git a/modules/commands/ns_recover.cpp b/modules/commands/ns_recover.cpp
index 33a97646c..ee54f3b3f 100644
--- a/modules/commands/ns_recover.cpp
+++ b/modules/commands/ns_recover.cpp
@@ -62,7 +62,7 @@ class NSRecoverRequest : public IdentifyRequest
{
NSRecoverExtensibleInfo *ei = new NSRecoverExtensibleInfo;
for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
- (*ei)[(*it)->chan->name] = (*it)->status;
+ (*ei)[it->first->name] = it->second->status;
source.GetUser()->Extend("ns_recover_info", ei);
}
@@ -265,8 +265,8 @@ class NSRecover : public Module
std::map<Anope::string, ChannelStatus>::iterator it = ei->find(c->name);
if (it != ei->end())
{
- for (std::set<Anope::string>::iterator it2 = it->second.modes.begin(), it2_end = it->second.modes.end(); it2 != it2_end; ++it2)
- c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByName(*it2), u->GetUID());
+ for (size_t i = 0; i < it->second.Modes().length(); ++i)
+ c->SetMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(it->second.Modes()[i]), u->GetUID());
ei->erase(it);
if (ei->empty())
diff --git a/modules/commands/os_chankill.cpp b/modules/commands/os_chankill.cpp
index 3fea40043..c88011b5b 100644
--- a/modules/commands/os_chankill.cpp
+++ b/modules/commands/os_chankill.cpp
@@ -74,7 +74,7 @@ class CommandOSChanKill : public Command
{
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
{
- ChanUserContainer *uc = *it++;
+ ChanUserContainer *uc = it->second;
if (uc->user->server == Me || uc->user->HasMode("OPER"))
continue;
diff --git a/modules/commands/os_dns.cpp b/modules/commands/os_dns.cpp
index d690ae55a..666baefdf 100644
--- a/modules/commands/os_dns.cpp
+++ b/modules/commands/os_dns.cpp
@@ -214,7 +214,7 @@ class CommandOSDNS : public Command
for (unsigned i = 0; i < dns_servers->size(); ++i)
{
DNSServer *s = dns_servers->at(i);
- Server *srv = Server::Find(s->GetName());
+ Server *srv = Server::Find(s->GetName(), true);
ListFormatter::ListEntry entry;
entry["Server"] = s->GetName();
@@ -351,7 +351,7 @@ class CommandOSDNS : public Command
return;
}
- Server *serv = Server::Find(params[1]);
+ Server *serv = Server::Find(params[1], true);
if (!serv || serv == Me || serv->IsJuped())
{
source.Reply(_("Server %s is not linked to the network."), params[1].c_str());
@@ -411,7 +411,7 @@ class CommandOSDNS : public Command
source.Reply(_("Removed server %s from zone %s."), s->GetName().c_str(), z->name.c_str());
return;
}
- else if (Server::Find(s->GetName()))
+ else if (Server::Find(s->GetName(), true))
{
source.Reply(_("Server %s must be quit before it can be deleted."), s->GetName().c_str());
return;
@@ -543,7 +543,7 @@ class CommandOSDNS : public Command
source.Reply(_("Server %s does not exist."), params[1].c_str());
return;
}
- else if (!Server::Find(s->GetName()))
+ else if (!Server::Find(s->GetName(), true))
{
source.Reply(_("Server %s is not currently linked."), s->GetName().c_str());
return;
@@ -676,7 +676,7 @@ class ModuleDNS : public Module
for (unsigned j = 0; j < dns_servers->size(); ++j)
{
DNSServer *s = dns_servers->at(j);
- if (s->Pooled() && Server::Find(s->GetName()))
+ if (s->Pooled() && Server::Find(s->GetName(), true))
s->SetActive(true);
}
}
diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp
index e3a0c42b8..a33ef66f2 100644
--- a/modules/commands/os_forbid.cpp
+++ b/modules/commands/os_forbid.cpp
@@ -16,60 +16,64 @@
class MyForbidService : public ForbidService
{
- Serialize::Checker<std::vector<ForbidData *> > forbid_data;
+ Serialize::Checker<std::vector<ForbidData *>[FT_SIZE]> forbid_data;
public:
MyForbidService(Module *m) : ForbidService(m), forbid_data("ForbidData") { }
void AddForbid(ForbidData *d) anope_override
{
- this->forbid_data->push_back(d);
+ this->forbid_data[d->type].push_back(d);
}
void RemoveForbid(ForbidData *d) anope_override
{
- std::vector<ForbidData *>::iterator it = std::find(this->forbid_data->begin(), this->forbid_data->end(), d);
- if (it != this->forbid_data->end())
- this->forbid_data->erase(it);
+ std::vector<ForbidData *>::iterator it = std::find(this->forbid_data[d->type].begin(), this->forbid_data[d->type].end(), d);
+ if (it != this->forbid_data[d->type].end())
+ this->forbid_data[d->type].erase(it);
delete d;
}
ForbidData *FindForbid(const Anope::string &mask, ForbidType ftype) anope_override
{
- const std::vector<ForbidData *> &forbids = this->GetForbids();
+ const std::vector<ForbidData *> &forbids = this->forbid_data[ftype];
for (unsigned i = forbids.size(); i > 0; --i)
{
ForbidData *d = forbids[i - 1];
- if ((ftype == FT_NONE || ftype == d->type) && Anope::Match(mask, d->mask, false, true))
+ if (Anope::Match(mask, d->mask, false, true))
return d;
}
return NULL;
}
- const std::vector<ForbidData *> &GetForbids() anope_override
+ std::vector<ForbidData *> GetForbids() anope_override
{
- for (unsigned i = this->forbid_data->size(); i > 0; --i)
- {
- ForbidData *d = this->forbid_data->at(i - 1);
-
- if (d->expires && Anope::CurTime >= d->expires)
+ std::vector<ForbidData *> forbids;
+ for (unsigned j = 0; j < FT_SIZE; ++j)
+ for (unsigned i = this->forbid_data[j].size(); i > 0; --i)
{
- Anope::string ftype = "none";
- if (d->type == FT_NICK)
- ftype = "nick";
- else if (d->type == FT_CHAN)
- ftype = "chan";
- else if (d->type == FT_EMAIL)
- ftype = "email";
-
- Log(LOG_NORMAL, "expire/forbid") << "Expiring forbid for " << d->mask << " type " << ftype;
- this->forbid_data->erase(this->forbid_data->begin() + i - 1);
- delete d;
+ ForbidData *d = this->forbid_data[j].at(i - 1);
+
+ if (d->expires && Anope::CurTime >= d->expires)
+ {
+ Anope::string ftype = "none";
+ if (d->type == FT_NICK)
+ ftype = "nick";
+ else if (d->type == FT_CHAN)
+ ftype = "chan";
+ else if (d->type == FT_EMAIL)
+ ftype = "email";
+
+ Log(LOG_NORMAL, "expire/forbid") << "Expiring forbid for " << d->mask << " type " << ftype;
+ this->forbid_data[j].erase(this->forbid_data[j].begin() + i - 1);
+ delete d;
+ }
+ else
+ forbids.push_back(d);
}
- }
- return this->forbid_data;
+ return forbids;
}
};
@@ -93,7 +97,7 @@ class CommandOSForbid : public Command
const Anope::string &command = params[0];
const Anope::string &subcommand = params.size() > 1 ? params[1] : "";
- ForbidType ftype = FT_NONE;
+ ForbidType ftype = FT_SIZE;
if (subcommand.equals_ci("NICK"))
ftype = FT_NICK;
else if (subcommand.equals_ci("CHAN"))
@@ -103,7 +107,7 @@ class CommandOSForbid : public Command
else if (subcommand.equals_ci("REGISTER"))
ftype = FT_REGISTER;
- if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_NONE)
+ if (command.equals_ci("ADD") && params.size() > 3 && ftype != FT_SIZE)
{
const Anope::string &expiry = params[2][0] == '+' ? params[2] : "";
const Anope::string &entry = !expiry.empty() ? params[3] : params[2];
@@ -156,7 +160,7 @@ class CommandOSForbid : public Command
Log(LOG_ADMIN, source, this) << "to add a forbid on " << entry << " of type " << subcommand;
source.Reply(_("Added a forbid on %s to expire on %s."), entry.c_str(), d->expires ? Anope::strftime(d->expires).c_str() : "never");
}
- else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_NONE)
+ else if (command.equals_ci("DEL") && params.size() > 2 && ftype != FT_SIZE)
{
const Anope::string &entry = params[2];
diff --git a/modules/commands/os_forbid.h b/modules/commands/os_forbid.h
index b4d1ce7ce..00827c559 100644
--- a/modules/commands/os_forbid.h
+++ b/modules/commands/os_forbid.h
@@ -3,11 +3,11 @@
enum ForbidType
{
- FT_NONE,
FT_NICK,
FT_CHAN,
FT_EMAIL,
- FT_REGISTER
+ FT_REGISTER,
+ FT_SIZE
};
struct ForbidData : Serializable
@@ -35,7 +35,7 @@ class ForbidService : public Service
virtual ForbidData *FindForbid(const Anope::string &mask, ForbidType type) = 0;
- virtual const std::vector<ForbidData *> &GetForbids() = 0;
+ virtual std::vector<ForbidData *> GetForbids() = 0;
};
static ServiceReference<ForbidService> forbid_service("ForbidService", "forbid");
diff --git a/modules/commands/os_jupe.cpp b/modules/commands/os_jupe.cpp
index fa79c9098..fbe5bac12 100644
--- a/modules/commands/os_jupe.cpp
+++ b/modules/commands/os_jupe.cpp
@@ -26,7 +26,7 @@ class CommandOSJupe : public Command
{
const Anope::string &jserver = params[0];
const Anope::string &reason = params.size() > 1 ? params[1] : "";
- Server *server = Server::Find(jserver);
+ Server *server = Server::Find(jserver, true);
if (!IRCD->IsHostValid(jserver) || jserver.find('.') == Anope::string::npos)
source.Reply(_("Please use a valid server name when juping."));
diff --git a/modules/commands/os_list.cpp b/modules/commands/os_list.cpp
index f4de45203..6880bbbc0 100644
--- a/modules/commands/os_list.cpp
+++ b/modules/commands/os_list.cpp
@@ -44,7 +44,7 @@ class CommandOSChanList : public Command
for (User::ChanUserList::iterator uit = u2->chans.begin(), uit_end = u2->chans.end(); uit != uit_end; ++uit)
{
- ChanUserContainer *cc = *uit;
+ ChanUserContainer *cc = uit->second;
if (!modes.empty())
for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
@@ -142,7 +142,7 @@ class CommandOSUserList : public Command
for (Channel::ChanUserList::iterator cuit = c->users.begin(), cuit_end = c->users.end(); cuit != cuit_end; ++cuit)
{
- ChanUserContainer *uc = *cuit;
+ ChanUserContainer *uc = cuit->second;
if (!modes.empty())
for (std::set<Anope::string>::iterator it = modes.begin(), it_end = modes.end(); it != it_end; ++it)
diff --git a/modules/commands/os_mode.cpp b/modules/commands/os_mode.cpp
index 33387bff6..db0ac73b5 100644
--- a/modules/commands/os_mode.cpp
+++ b/modules/commands/os_mode.cpp
@@ -45,13 +45,13 @@ class CommandOSMode : public Command
{
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
if (uc->user->HasMode("OPER"))
continue;
- for (std::set<Anope::string>::iterator it2 = uc->status.modes.begin(), it2_end = uc->status.modes.end(); it2 != it2_end; ++it2)
- c->RemoveMode(c->ci->WhoSends(), *it2, uc->user->GetUID(), false);
+ for (size_t i = 0; i < uc->status.Modes().length(); ++i)
+ c->RemoveMode(c->ci->WhoSends(), ModeManager::FindChannelModeByChar(uc->status.Modes()[i]), uc->user->GetUID(), false);
}
source.Reply(_("All modes cleared on %s."), c->name.c_str());
diff --git a/modules/commands/os_noop.cpp b/modules/commands/os_noop.cpp
index 9e9af1398..082294f22 100644
--- a/modules/commands/os_noop.cpp
+++ b/modules/commands/os_noop.cpp
@@ -28,7 +28,7 @@ class CommandOSNOOP : public Command
const Anope::string &cmd = params[0];
const Anope::string &server = params[1];
- Server *s = Server::Find(server);
+ Server *s = Server::Find(server, true);
if (s == NULL)
source.Reply(_("Server %s does not exist."), server.c_str());
else if (s == Me || s->IsJuped())
diff --git a/modules/commands/os_session.cpp b/modules/commands/os_session.cpp
index 1edda00d6..31846c9db 100644
--- a/modules/commands/os_session.cpp
+++ b/modules/commands/os_session.cpp
@@ -61,11 +61,6 @@ class MySessionService : public SessionService
return this->Exceptions;
}
- void AddSession(Session *s) anope_override
- {
- this->Sessions[s->addr] = s;
- }
-
void DelSession(Session *s) anope_override
{
this->Sessions.erase(s->addr);
@@ -80,6 +75,18 @@ class MySessionService : public SessionService
return NULL;
}
+ SessionMap::iterator FindSessionIterator(const Anope::string &ip)
+ {
+ cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
+ return this->Sessions.find(c);
+ }
+
+ Session* &FindOrCreateSession(const Anope::string &ip)
+ {
+ cidr c(ip, ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
+ return this->Sessions[c];
+ }
+
SessionMap &GetSessions() anope_override
{
return this->Sessions;
@@ -611,124 +618,117 @@ class OSSession : public Module
CommandOSException commandosexception;
ServiceReference<XLineManager> akills;
- void AddSession(User *u, bool exempt)
+ public:
+ OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
+ exception_type("Exception", Exception::Unserialize), ss(this), commandossession(this), commandosexception(this), akills("XLineManager", "xlinemanager/sgline")
{
- Session *session;
- try
- {
- session = this->ss.FindSession(u->ip);
- }
- catch (const SocketException &)
- {
+ this->SetAuthor("Anope");
+ this->SetPermanent(true);
+
+ Implementation i[] = { I_OnUserConnect, I_OnPreUserLogoff };
+ ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
+ ModuleManager::SetPriority(this, PRIORITY_FIRST);
+ }
+
+ void OnUserConnect(User *u, bool &exempt) anope_override
+ {
+ if (u->Quitting() || !Config->LimitSessions || exempt || !u->server || u->server->IsULined())
return;
- }
- if (session)
+ try
{
- bool kill = false;
- if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit)
+ Session* &session = this->ss.FindOrCreateSession(u->ip);
+
+ if (session)
{
- kill = true;
- Exception *exception = this->ss.FindException(u);
- if (exception)
+ bool kill = false;
+ if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit)
{
- kill = false;
- if (exception->limit && session->count >= exception->limit)
- kill = true;
+ kill = true;
+ Exception *exception = this->ss.FindException(u);
+ if (exception)
+ {
+ kill = false;
+ if (exception->limit && session->count >= exception->limit)
+ kill = true;
+ }
}
- }
- /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
- * decremented in do_quit, which caused problems and fixed here
- *
- * Now, we create the user struture before calling this to fix some user tracking issues,
- * so we must increment this here no matter what because it will either be
- * decremented in do_kill or in do_quit - Adam
- */
- ++session->count;
+ /* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
+ * decremented in do_quit, which caused problems and fixed here
+ *
+ * Now, we create the user struture before calling this to fix some user tracking issues,
+ * so we must increment this here no matter what because it will either be
+ * decremented in do_kill or in do_quit - Adam
+ */
+ ++session->count;
- if (kill && !exempt)
- {
- if (OperServ)
+ if (kill && !exempt)
{
- if (!Config->SessionLimitExceeded.empty())
- u->SendMessage(OperServ, Config->SessionLimitExceeded.c_str(), u->ip.c_str());
- if (!Config->SessionLimitDetailsLoc.empty())
- u->SendMessage(OperServ, "%s", Config->SessionLimitDetailsLoc.c_str());
- }
+ if (OperServ)
+ {
+ if (!Config->SessionLimitExceeded.empty())
+ u->SendMessage(OperServ, Config->SessionLimitExceeded.c_str(), u->ip.c_str());
+ if (!Config->SessionLimitDetailsLoc.empty())
+ u->SendMessage(OperServ, "%s", Config->SessionLimitDetailsLoc.c_str());
+ }
- ++session->hits;
- if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills)
- {
- const Anope::string &akillmask = "*@" + u->ip;
- XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID());
- akills->AddXLine(x);
- akills->Send(NULL, x);
- Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
- }
- else
- {
- u->Kill(Config->OperServ, "Session limit exceeded");
- u = NULL; /* No guarentee u still exists */
+ ++session->hits;
+ if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills)
+ {
+ const Anope::string &akillmask = "*@" + u->ip;
+ XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID());
+ akills->AddXLine(x);
+ akills->Send(NULL, x);
+ Log(OperServ, "akill/session") << "Added a temporary AKILL for \002" << akillmask << "\002 due to excessive connections";
+ }
+ else
+ {
+ u->Kill(Config->OperServ, "Session limit exceeded");
+ }
}
}
+ else
+ {
+ session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
+ }
}
- else
- {
- session = new Session(u->ip, u->ip.find(':') != Anope::string::npos ? Config->SessionIPv6CIDR : Config->SessionIPv4CIDR);
- this->ss.AddSession(session);
- }
+ catch (const SocketException &) { }
}
- void DelSession(User *u)
+ void OnPreUserLogoff(User *u) anope_override
{
- Session *session;
+ if (!Config->LimitSessions || !u->server || u->server->IsULined())
+ return;
+
+ SessionService::SessionMap::iterator sit;
try
{
- session = this->ss.FindSession(u->ip);
+ sit = this->ss.FindSessionIterator(u->ip);
}
catch (const SocketException &)
{
return;
}
- if (!session)
+
+ SessionService::SessionMap &sessions = this->ss.GetSessions();
+
+ if (sit == sessions.end())
{
Log(LOG_DEBUG) << "Tried to delete non-existant session: " << u->ip;
return;
}
+ Session *session = sit->second;
+
if (session->count > 1)
{
--session->count;
return;
}
- this->ss.DelSession(session);
delete session;
- }
-
- public:
- OSSession(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
- exception_type("Exception", Exception::Unserialize), ss(this), commandossession(this), commandosexception(this), akills("XLineManager", "xlinemanager/sgline")
- {
- this->SetAuthor("Anope");
- this->SetPermanent(true);
-
- Implementation i[] = { I_OnUserConnect, I_OnPreUserLogoff };
- ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
- ModuleManager::SetPriority(this, PRIORITY_FIRST);
- }
-
- void OnUserConnect(User *user, bool &exempt) anope_override
- {
- if (!user->Quitting() && Config->LimitSessions)
- this->AddSession(user, exempt);
- }
-
- void OnPreUserLogoff(User *u) anope_override
- {
- if (Config->LimitSessions && (!u->server || !u->server->IsULined()))
- this->DelSession(u);
+ sessions.erase(sit);
}
};
diff --git a/modules/commands/os_session.h b/modules/commands/os_session.h
index 6d1dd917d..f3077d0ac 100644
--- a/modules/commands/os_session.h
+++ b/modules/commands/os_session.h
@@ -42,11 +42,7 @@ class SessionService : public Service
virtual ExceptionVector &GetExceptions() = 0;
- virtual void AddSession(Session *s) = 0;
-
- virtual void DelSession(Session *s) = 0;
-
- virtual Session *FindSession(const Anope::string &mask) = 0;
+ virtual Session *FindSession(const Anope::string &ip) = 0;
virtual SessionMap &GetSessions() = 0;
};
diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp
index 2a98edf1d..e76a611db 100644
--- a/modules/commands/os_sxline.cpp
+++ b/modules/commands/os_sxline.cpp
@@ -599,7 +599,7 @@ class CommandOSSQLine : public CommandOSSXLineBase
std::vector<User *> users;
for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
User *user = uc->user;
if (!user->HasMode("OPER") && user->server != Me)
diff --git a/modules/extra/cs_statusupdate.cpp b/modules/extra/cs_statusupdate.cpp
index 97faae851..4a53956d7 100644
--- a/modules/extra/cs_statusupdate.cpp
+++ b/modules/extra/cs_statusupdate.cpp
@@ -36,7 +36,7 @@ class StatusUpdate : public Module
if (ci->c)
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- User *user = (*it)->user;
+ User *user = it->second->user;
if (access->Matches(user, user->Account()))
{
@@ -53,7 +53,7 @@ class StatusUpdate : public Module
if (ci->c)
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- User *user = (*it)->user;
+ User *user = it->second->user;
if (access->Matches(user, user->Account()))
{
diff --git a/modules/extra/m_xmlrpc_main.cpp b/modules/extra/m_xmlrpc_main.cpp
index e4b761cc7..9166f27df 100644
--- a/modules/extra/m_xmlrpc_main.cpp
+++ b/modules/extra/m_xmlrpc_main.cpp
@@ -174,7 +174,7 @@ class MyXMLRPCEvent : public XMLRPCEvent
Anope::string users;
for (Channel::ChanUserList::const_iterator it = c->users.begin(); it != c->users.end(); ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
users += uc->status.BuildModePrefixList() + uc->user->nick + " ";
}
if (!users.empty())
@@ -226,7 +226,7 @@ class MyXMLRPCEvent : public XMLRPCEvent
Anope::string channels;
for (User::ChanUserList::const_iterator it = u->chans.begin(); it != u->chans.end(); ++it)
{
- ChanUserContainer *cc = *it;
+ ChanUserContainer *cc = it->second;
channels += cc->status.BuildModePrefixList() + cc->chan->name + " ";
}
if (!channels.empty())
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp
index 8c2c131a6..1f15e3c06 100644
--- a/modules/protocol/bahamut.cpp
+++ b/modules/protocol/bahamut.cpp
@@ -143,16 +143,14 @@ class BahamutIRCdProto : public IRCDProto
return;
/* ZLine if we can instead */
- try
- {
- if (x->GetUser() == "*")
+ if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
+ try
{
sockaddrs(x->GetHost());
IRCD->SendSZLineDel(x);
return;
}
- }
- catch (const SocketException &) { }
+ catch (const SocketException &) { }
UplinkSocket::Message() << "RAKILL " << x->GetHost() << " " << x->GetUser();
}
@@ -170,7 +168,7 @@ class BahamutIRCdProto : public IRCDProto
}
/* JOIN - SJOIN */
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
UplinkSocket::Message(user) << "SJOIN " << c->creation_time << " " << c->name;
if (status)
@@ -182,12 +180,11 @@ class BahamutIRCdProto : public IRCDProto
*/
ChanUserContainer *uc = c->FindUser(user);
if (uc != NULL)
- uc->status.modes.clear();
+ uc->status.Clear();
BotInfo *setter = BotInfo::Find(user->nick);
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- if (cs.modes.count(ModeManager::ChannelModes[i]->name))
- c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
}
}
@@ -217,16 +214,14 @@ class BahamutIRCdProto : public IRCDProto
}
/* ZLine if we can instead */
- try
- {
- if (x->GetUser() == "*")
+ if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
+ try
{
sockaddrs(x->GetHost());
IRCD->SendSZLine(u, x);
return;
}
- }
- catch (const SocketException &) { }
+ catch (const SocketException &) { }
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->expires - Anope::CurTime;
@@ -448,14 +443,7 @@ struct IRCDMessageSJoin : IRCDMessage
for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
{
buf.erase(buf.begin());
- ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
- if (!cm)
- {
- Log() << "Received unknown mode prefix " << cm << " in SJOIN string";
- continue;
- }
-
- sju.first.modes.insert(cm->name);
+ sju.first.AddMode(ch);
}
sju.second = User::Find(buf);
diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp
index 6f41abcc5..e91478c7f 100644
--- a/modules/protocol/charybdis.cpp
+++ b/modules/protocol/charybdis.cpp
@@ -52,7 +52,7 @@ class CharybdisProto : public IRCDProto
void SendAkill(User *u, XLine *x) anope_override { ratbox->SendAkill(u, x); }
void SendAkillDel(const XLine *x) anope_override { ratbox->SendAkillDel(x); }
void SendSQLineDel(const XLine *x) anope_override { ratbox->SendSQLineDel(x); }
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override { ratbox->SendJoin(user, c, status); }
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { ratbox->SendJoin(user, c, status); }
void SendServer(const Server *server) anope_override { ratbox->SendServer(server); }
void SendChannel(Channel *c) anope_override { ratbox->SendChannel(c); }
void SendTopic(BotInfo *bi, Channel *c) anope_override { ratbox->SendTopic(bi, c); }
diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp
index ac3f88c41..3247787f1 100644
--- a/modules/protocol/hybrid.cpp
+++ b/modules/protocol/hybrid.cpp
@@ -88,7 +88,7 @@ class HybridProto : public IRCDProto
UplinkSocket::Message(OperServ) << "UNRESV * " << x->mask;
}
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
/*
* Note that we must send our modes with the SJOIN and
@@ -234,7 +234,7 @@ class HybridProto : public IRCDProto
{
ChannelStatus status;
- status.modes.insert("OP");
+ status.AddMode('o');
bi->Join(c, &status);
}
@@ -271,24 +271,14 @@ struct IRCDMessageBMask : IRCDMessage
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
Channel *c = Channel::Find(params[1]);
+ ChannelMode *mode = ModeManager::FindChannelModeByChar(params[2][0]);
- if (c)
+ if (c && mode)
{
- ChannelMode *ban = ModeManager::FindChannelModeByName("BAN"),
- *except = ModeManager::FindChannelModeByName("EXCEPT"),
- *invex = ModeManager::FindChannelModeByName("INVITEOVERRIDE");
-
spacesepstream bans(params[3]);
Anope::string token;
while (bans.GetToken(token))
- {
- if (ban && params[2].equals_cs("b"))
- c->SetModeInternal(source, ban, token);
- else if (except && params[2].equals_cs("e"))
- c->SetModeInternal(source, except, token);
- else if (invex && params[2].equals_cs("I"))
- c->SetModeInternal(source, invex, token);
- }
+ c->SetModeInternal(source, mode, token);
}
}
};
@@ -412,15 +402,7 @@ struct IRCDMessageSJoin : IRCDMessage
for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
{
buf.erase(buf.begin());
- ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
-
- if (!cm)
- {
- Log() << "Received unknown mode prefix " << ch << " in SJOIN string";
- continue;
- }
-
- sju.first.modes.insert(cm->name);
+ sju.first.AddMode(ch);
}
sju.second = User::Find(buf);
diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp
index 0761f478c..b6cb905c2 100644
--- a/modules/protocol/inspircd11.cpp
+++ b/modules/protocol/inspircd11.cpp
@@ -80,16 +80,14 @@ class InspIRCdProto : public IRCDProto
return;
/* ZLine if we can instead */
- try
- {
- if (x->GetUser() == "*")
+ if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
+ try
{
sockaddrs(x->GetHost());
IRCD->SendSZLineDel(x);
return;
}
- }
- catch (const SocketException &) { }
+ catch (const SocketException &) { }
UplinkSocket::Message(OperServ) << "GLINE " << x->mask;
}
@@ -136,16 +134,14 @@ class InspIRCdProto : public IRCDProto
}
/* ZLine if we can instead */
- try
- {
- if (x->GetUser() == "*")
+ if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
+ try
{
sockaddrs(x->GetHost());
IRCD->SendSZLine(u, x);
return;
}
- }
- catch (const SocketException &) { }
+ catch (const SocketException &) { }
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->expires - Anope::CurTime;
@@ -203,7 +199,7 @@ class InspIRCdProto : public IRCDProto
}
/* JOIN */
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
UplinkSocket::Message(user) << "JOIN " << c->name << " " << c->creation_time;
if (status)
@@ -215,12 +211,11 @@ class InspIRCdProto : public IRCDProto
*/
ChanUserContainer *uc = c->FindUser(user);
if (uc != NULL)
- uc->status.modes.clear();
+ uc->status.Clear();
BotInfo *setter = BotInfo::Find(user->nick);
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- if (cs.modes.count(ModeManager::ChannelModes[i]->name))
- c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
}
}
@@ -653,7 +648,7 @@ struct IRCDMessageFJoin : IRCDMessage
continue;
}
- sju.first.modes.insert(cm->name);
+ sju.first.AddMode(cm->mchar);
}
/* Erase the , */
buf.erase(buf.begin());
diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp
index a79edf291..deb7bbbf1 100644
--- a/modules/protocol/inspircd12.cpp
+++ b/modules/protocol/inspircd12.cpp
@@ -180,16 +180,15 @@ class InspIRCd12Proto : public IRCDProto
}
/* ZLine if we can instead */
- try
- {
- if (x->GetUser() == "*")
+ if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
+ try
{
sockaddrs(x->GetHost());
IRCD->SendSZLine(u, x);
return;
}
- }
- catch (const SocketException &) { }
+ catch (const SocketException &) { }
+
SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->by, x->GetReason());
}
@@ -221,7 +220,7 @@ class InspIRCd12Proto : public IRCDProto
}
/* JOIN */
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
UplinkSocket::Message(Me) << "FJOIN " << c->name << " " << c->creation_time << " +" << c->GetModes(true, true) << " :," << user->GetUID();
/* Note that we can send this with the FJOIN but choose not to
@@ -237,19 +236,11 @@ class InspIRCd12Proto : public IRCDProto
*/
ChanUserContainer *uc = c->FindUser(user);
if (uc != NULL)
- uc->status.modes.clear();
+ uc->status.Clear();
BotInfo *setter = BotInfo::Find(user->nick);
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
-
- if (cs.modes.count(cm->name) || cs.modes.count(cm->mchar))
- {
- c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
- cs.modes.insert(cm->name);
- }
- }
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
}
}
@@ -386,7 +377,7 @@ class InspIRCdExtBan : public ChannelModeList
public:
InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { }
- bool Matches(const User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) anope_override
{
const Anope::string &mask = e->GetMask();
@@ -839,20 +830,14 @@ struct IRCDMessageFJoin : IRCDMessage
Message::Join::SJoinUser sju;
/* Loop through prefixes and find modes for them */
- for (char c; (c = buf[0]) != ',';)
+ for (char c; (c = buf[0]) != ',' && c;)
{
buf.erase(buf.begin());
- ChannelMode *cm = ModeManager::FindChannelModeByChar(c);
- if (!cm)
- {
- Log() << "Received unknown mode prefix " << c << " in FJOIN string";
- continue;
- }
-
- sju.first.modes.insert(cm->name);
+ sju.first.AddMode(c);
}
/* Erase the , */
- buf.erase(buf.begin());
+ if (!buf.empty())
+ buf.erase(buf.begin());
sju.second = User::Find(buf);
if (!sju.second)
diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp
index bbe069466..0af696bf0 100644
--- a/modules/protocol/inspircd20.cpp
+++ b/modules/protocol/inspircd20.cpp
@@ -55,7 +55,7 @@ class InspIRCd20Proto : public IRCDProto
void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override { insp12->SendModeInternal(bi, u, buf); }
void SendClientIntroduction(const User *u) anope_override { insp12->SendClientIntroduction(u); }
void SendServer(const Server *server) anope_override { insp12->SendServer(server); }
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override { insp12->SendJoin(user, c, status); }
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { insp12->SendJoin(user, c, status); }
void SendSQLineDel(const XLine *x) anope_override { insp12->SendSQLineDel(x); }
void SendSQLine(User *u, const XLine *x) anope_override { insp12->SendSQLine(u, x); }
void SendVhost(User *u, const Anope::string &vident, const Anope::string &vhost) anope_override { insp12->SendVhost(u, vident, vhost); }
@@ -80,7 +80,7 @@ class InspIRCdExtBan : public ChannelModeList
public:
InspIRCdExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { }
- bool Matches(const User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) anope_override
{
const Anope::string &mask = e->GetMask();
@@ -111,7 +111,7 @@ class InspIRCdExtBan : public ChannelModeList
{
ChanUserContainer *uc = c->FindUser(u);
if (uc != NULL)
- if (cm == NULL || uc->status.modes.count(cm->name))
+ if (cm == NULL || uc->status.HasMode(cm->mchar))
return true;
}
}
diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp
index e54a4f8f7..ef226f87e 100644
--- a/modules/protocol/ngircd.cpp
+++ b/modules/protocol/ngircd.cpp
@@ -83,7 +83,7 @@ class ngIRCdProto : public IRCDProto
UplinkSocket::Message(Me) << "WALLOPS :" << buf;
}
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
UplinkSocket::Message(user) << "JOIN " << c->name;
if (status)
@@ -95,12 +95,11 @@ class ngIRCdProto : public IRCDProto
*/
ChanUserContainer *uc = c->FindUser(user);
if (uc != NULL)
- uc->status.modes.clear();
+ uc->status.Clear();
BotInfo *setter = BotInfo::Find(user->nick);
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- if (cs.modes.count(ModeManager::ChannelModes[i]->name))
- c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
}
}
@@ -245,10 +244,8 @@ struct IRCDMessageChaninfo : IRCDMessage
*/
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
-
- Channel *c = Channel::Find(params[0]);
- if (!c)
- c = new Channel(params[0]);
+ bool created;
+ Channel *c = Channel::FindOrCreate(params[0], created);
Anope::string modes = params[1];
@@ -470,15 +467,8 @@ struct IRCDMessageNJoin : IRCDMessage
/* Get prefixes from the nick */
for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
{
- ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
buf.erase(buf.begin());
- if (!cm)
- {
- Log(LOG_DEBUG) << "Received unknown mode prefix " << ch << " in NJOIN string.";
- continue;
- }
-
- sju.first.modes.insert(cm->name);
+ sju.first.AddMode(ch);
}
sju.second = User::Find(buf);
diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp
index d117389e7..c22c43192 100644
--- a/modules/protocol/plexus.cpp
+++ b/modules/protocol/plexus.cpp
@@ -48,7 +48,7 @@ class PlexusProto : public IRCDProto
void SendSVSHold(const Anope::string &nick) anope_override { hybrid->SendSVSHold(nick); }
void SendSVSHoldDel(const Anope::string &nick) anope_override { hybrid->SendSVSHoldDel(nick); }
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " +" << c->GetModes(true, true) << " :" << user->GetUID();
if (status)
@@ -60,12 +60,11 @@ class PlexusProto : public IRCDProto
*/
ChanUserContainer *uc = c->FindUser(user);
if (uc != NULL)
- uc->status.modes.clear();
+ uc->status.Clear();
BotInfo *setter = BotInfo::Find(user->nick);
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- if (cs.modes.count(ModeManager::ChannelModes[i]->name))
- c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
}
}
diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp
index 247b8777a..129752c06 100644
--- a/modules/protocol/ratbox.cpp
+++ b/modules/protocol/ratbox.cpp
@@ -37,7 +37,7 @@ class RatboxProto : public IRCDProto
void SendAkill(User *u, XLine *x) anope_override { hybrid->SendAkill(u, x); }
void SendAkillDel(const XLine *x) anope_override { hybrid->SendAkillDel(x); }
void SendSQLineDel(const XLine *x) anope_override { hybrid->SendSQLineDel(x); }
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override { hybrid->SendJoin(user, c, status); }
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override { hybrid->SendJoin(user, c, status); }
void SendServer(const Server *server) anope_override { hybrid->SendServer(server); }
void SendModeInternal(const BotInfo *bi, const User *u, const Anope::string &buf) anope_override { hybrid->SendModeInternal(bi, u, buf); }
void SendChannel(Channel *c) anope_override { hybrid->SendChannel(c); }
diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp
index 984277c14..25094a24d 100644
--- a/modules/protocol/unreal.cpp
+++ b/modules/protocol/unreal.cpp
@@ -44,16 +44,14 @@ class UnrealIRCdProto : public IRCDProto
return;
/* ZLine if we can instead */
- try
- {
- if (x->GetUser() == "*")
+ if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
+ try
{
sockaddrs(x->GetHost());
IRCD->SendSZLineDel(x);
return;
}
- }
- catch (const SocketException &) { }
+ catch (const SocketException &) { }
UplinkSocket::Message() << "TKL - G " << x->GetUser() << " " << x->GetHost() << " " << Config->OperServ;
}
@@ -108,16 +106,14 @@ class UnrealIRCdProto : public IRCDProto
}
/* ZLine if we can instead */
- try
- {
- if (x->GetUser() == "*")
+ if (x->GetUser() == "*" && x->GetHost().find_first_not_of("0123456789:.") == Anope::string::npos)
+ try
{
sockaddrs(x->GetHost());
IRCD->SendSZLine(u, x);
return;
}
- }
- catch (const SocketException &) { }
+ catch (const SocketException &) { }
// Calculate the time left before this would expire, capping it at 2 days
time_t timeleft = x->expires - Anope::CurTime;
@@ -154,7 +150,7 @@ class UnrealIRCdProto : public IRCDProto
}
/* JOIN */
- void SendJoin(const User *user, Channel *c, const ChannelStatus *status) anope_override
+ void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override
{
UplinkSocket::Message(Me) << "SJOIN " << c->creation_time << " " << c->name << " :" << user->nick;
if (status)
@@ -166,12 +162,11 @@ class UnrealIRCdProto : public IRCDProto
*/
ChanUserContainer *uc = c->FindUser(user);
if (uc != NULL)
- uc->status.modes.clear();
+ uc->status.Clear();
BotInfo *setter = BotInfo::Find(user->nick);
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- if (cs.modes.count(ModeManager::ChannelModes[i]->name))
- c->SetMode(setter, ModeManager::ChannelModes[i], user->GetUID(), false);
+ for (size_t i = 0; i < cs.Modes().length(); ++i)
+ c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false);
}
}
@@ -384,7 +379,7 @@ class UnrealExtBan : public ChannelModeList
public:
UnrealExtBan(const Anope::string &mname, char modeChar) : ChannelModeList(mname, modeChar) { }
- bool Matches(const User *u, const Entry *e) anope_override
+ bool Matches(User *u, const Entry *e) anope_override
{
const Anope::string &mask = e->GetMask();
@@ -407,7 +402,7 @@ class UnrealExtBan : public ChannelModeList
{
ChanUserContainer *uc = c->FindUser(u);
if (uc != NULL)
- if (cm == NULL || uc->status.modes.count(cm->name))
+ if (cm == NULL || uc->status.HasMode(cm->mchar))
return true;
}
}
@@ -1050,15 +1045,8 @@ struct IRCDMessageSJoin : IRCDMessage
/* Get prefixes from the nick */
for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));)
{
+ sju.first.AddMode(ch);
buf.erase(buf.begin());
- ChannelMode *cm = ModeManager::FindChannelModeByChar(ch);
- if (!cm)
- {
- Log(LOG_DEBUG) << "Received unknown mode prefix " << ch << " in SJOIN string";
- continue;
- }
-
- sju.first.modes.insert(cm->name);
}
sju.second = User::Find(buf);
diff --git a/modules/pseudoclients/chanserv.cpp b/modules/pseudoclients/chanserv.cpp
index 7b59c0597..21a2f75f7 100644
--- a/modules/pseudoclients/chanserv.cpp
+++ b/modules/pseudoclients/chanserv.cpp
@@ -35,8 +35,8 @@ class ExpireCallback : public Timer
if (ci->c)
{
time_t last_used = ci->last_used;
- for (User::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit)
- ci->AccessFor((*cit)->user);
+ for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end && last_used == ci->last_used; ++cit)
+ ci->AccessFor(cit->second->user);
expire = last_used == ci->last_used;
}
else
diff --git a/modules/pseudoclients/memoserv.cpp b/modules/pseudoclients/memoserv.cpp
index 73dd48b94..d28774e34 100644
--- a/modules/pseudoclients/memoserv.cpp
+++ b/modules/pseudoclients/memoserv.cpp
@@ -81,7 +81,7 @@ class MyMemoServService : public MemoServService
{
for (Channel::ChanUserList::iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it)
{
- ChanUserContainer *cu = *it;
+ ChanUserContainer *cu = it->second;
if (ci->AccessFor(cu->user).HasPriv("MEMO"))
{
@@ -171,7 +171,7 @@ class MemoServCore : public Module
void OnJoinChannel(User *u, Channel *c) anope_override
{
- if (c->ci && c->ci->AccessFor(u).HasPriv("MEMO") && c->ci->memos.memos->size() > 0)
+ if (c->ci && !c->ci->memos.memos->empty() && c->ci->AccessFor(u).HasPriv("MEMO"))
{
if (c->ci->memos.memos->size() == 1)
u->SendMessage(MemoServ, _("There is \002%d\002 memo on channel %s."), c->ci->memos.memos->size(), c->ci->name.c_str());
diff --git a/modules/pseudoclients/nickserv.cpp b/modules/pseudoclients/nickserv.cpp
index e221c19c0..35319e552 100644
--- a/modules/pseudoclients/nickserv.cpp
+++ b/modules/pseudoclients/nickserv.cpp
@@ -257,7 +257,7 @@ class NickServCore : public Module
if (Config->NSModeOnID)
for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
{
- ChanUserContainer *cc = *it;
+ ChanUserContainer *cc = it->second;
Channel *c = cc->chan;
if (c)
c->SetCorrectModes(u, true, true);
@@ -296,7 +296,7 @@ class NickServCore : public Module
{
for (User::ChanUserList::iterator it = u->chans.begin(), it_end = u->chans.end(); it != it_end; ++it)
{
- ChanUserContainer *cc = *it;
+ ChanUserContainer *cc = it->second;
Channel *c = cc->chan;
if (c)
c->SetCorrectModes(u, true, true);
diff --git a/modules/pseudoclients/operserv.cpp b/modules/pseudoclients/operserv.cpp
index 10908ef03..b2463dc4f 100644
--- a/modules/pseudoclients/operserv.cpp
+++ b/modules/pseudoclients/operserv.cpp
@@ -35,19 +35,7 @@ class SGLineManager : public XLineManager
void SendDel(XLine *x) anope_override
{
- try
- {
- if (!IRCD->CanSZLine)
- throw SocketException("SZLine is not supported");
- else if (x->GetUser() != "*")
- throw SocketException("Can not ZLine a username");
- sockaddrs(x->GetHost());
- IRCD->SendSZLineDel(x);
- }
- catch (const SocketException &)
- {
- IRCD->SendAkillDel(x);
- }
+ IRCD->SendAkillDel(x);
}
bool Check(User *u, const XLine *x) anope_override
@@ -70,7 +58,7 @@ class SGLineManager : public XLineManager
if (!x->GetReal().empty() && !Anope::Match(u->realname, x->GetReal()))
return false;
- if (!x->GetHost().empty())
+ if (x->GetHost().find('/') != Anope::string::npos)
{
try
{
@@ -82,7 +70,7 @@ class SGLineManager : public XLineManager
catch (const SocketException &) { }
}
- if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()))
+ if (x->GetHost().empty() || Anope::Match(u->host, x->GetHost()) || Anope::Match(u->ip, x->GetHost()))
return true;
return false;
diff --git a/src/access.cpp b/src/access.cpp
index dd5881108..7a178b446 100644
--- a/src/access.cpp
+++ b/src/access.cpp
@@ -152,18 +152,18 @@ Serializable* ChanAccess::Unserialize(Serializable *obj, Serialize::Data &data)
return access;
}
-bool ChanAccess::Matches(const User *u, const NickCore *nc) const
+bool ChanAccess::Matches(const User *u, const NickCore *acc) const
{
bool is_mask = this->mask.find_first_of("!@?*") != Anope::string::npos;
if (u && is_mask && Anope::Match(u->nick, this->mask))
return true;
else if (u && Anope::Match(u->GetDisplayedMask(), this->mask))
return true;
- else if (nc)
- for (unsigned i = nc->aliases->size(); i > 0; --i)
+ else if (acc)
+ for (unsigned i = 0; i < acc->aliases->size(); ++i)
{
- const NickAlias *na = nc->aliases->at(i - 1);
- if (na && Anope::Match(na->nick, this->mask))
+ const NickAlias *na = acc->aliases->at(i);
+ if (Anope::Match(na->nick, this->mask))
return true;
}
return false;
diff --git a/src/bots.cpp b/src/bots.cpp
index 698a37f4e..f1a96eacf 100644
--- a/src/bots.cpp
+++ b/src/bots.cpp
@@ -224,8 +224,8 @@ void BotInfo::Join(Channel *c, ChannelStatus *status)
void BotInfo::Join(const Anope::string &chname, ChannelStatus *status)
{
- Channel *c = Channel::Find(chname);
- return this->Join(c ? c : new Channel(chname), status);
+ bool c;
+ return this->Join(Channel::FindOrCreate(chname, c), status);
}
void BotInfo::Part(Channel *c, const Anope::string &reason)
diff --git a/src/channels.cpp b/src/channels.cpp
index 8e4074352..f3a061e94 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -33,11 +33,6 @@ Channel::Channel(const Anope::string &nname, time_t ts)
this->name = nname;
- size_t old = ChannelList.size();
- ChannelList[this->name] = this;
- if (old == ChannelList.size())
- Log(LOG_DEBUG) << "Duplicate channel " << this->name << " in table?";
-
this->creation_time = ts;
this->server_modetime = this->chanserv_modetime = 0;
this->server_modecount = this->chanserv_modecount = this->bouncy_modes = this->topic_ts = this->topic_time = 0;
@@ -46,7 +41,8 @@ Channel::Channel(const Anope::string &nname, time_t ts)
if (this->ci)
this->ci->c = this;
- Log(NULL, this, "create");
+ if (Me->IsSynced())
+ Log(NULL, this, "create");
FOREACH_MOD(I_OnChannelCreate, OnChannelCreate(this));
}
@@ -57,7 +53,8 @@ Channel::~Channel()
ModeManager::StackerDel(this);
- Log(NULL, this, "destroy");
+ if (Me->IsSynced())
+ Log(NULL, this, "destroy");
if (this->ci)
this->ci->c = NULL;
@@ -71,27 +68,20 @@ void Channel::Reset()
for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
{
- ChanUserContainer *uc = *it;
+ ChanUserContainer *uc = it->second;
ChannelStatus f = uc->status;
- uc->status.modes.clear();
+ uc->status.Clear();
if (BotInfo::Find(uc->user->nick))
- {
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
-
- if (f.modes.count(cm->name))
- this->SetMode(NULL, cm, uc->user->GetUID(), false);
- }
- }
+ for (size_t i = 0; i < f.Modes().length(); ++i)
+ this->SetMode(NULL, ModeManager::FindChannelModeByName(f.Modes()[i]), uc->user->GetUID(), false);
}
this->CheckModes();
for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
- this->SetCorrectModes((*it)->user, true, false);
+ this->SetCorrectModes(it->second->user, true, false);
if (this->ci && Me && Me->IsSynced())
this->ci->RestoreTopic();
@@ -99,7 +89,7 @@ void Channel::Reset()
void Channel::Sync()
{
- if (!this->HasMode("PERM") && (this->users.empty() || (this->users.size() == 1 && this->ci && this->ci->bi && *this->ci->bi == this->users.front()->user)))
+ if (!this->HasMode("PERM") && (this->users.empty() || (this->users.size() == 1 && this->ci && this->ci->bi && *this->ci->bi == this->users.begin()->second->user)))
{
this->Hold();
}
@@ -175,11 +165,12 @@ void Channel::CheckModes()
ChanUserContainer* Channel::JoinUser(User *user)
{
- Log(user, this, "join");
+ if (user->server->IsSynced())
+ Log(user, this, "join");
ChanUserContainer *cuc = new ChanUserContainer(user, this);
- user->chans.push_back(cuc);
- this->users.push_back(cuc);
+ user->chans[this] = cuc;
+ this->users[user] = cuc;
if (this->ci && this->ci->HasExt("PERSIST") && this->creation_time > this->ci->time_registered)
{
@@ -194,31 +185,18 @@ ChanUserContainer* Channel::JoinUser(User *user)
void Channel::DeleteUser(User *user)
{
- Log(user, this, "leave");
+ if (user->server->IsSynced() && !user->Quitting())
+ Log(user, this, "leave");
+
FOREACH_MOD(I_OnLeaveChannel, OnLeaveChannel(user, this));
- ChanUserContainer *cul;
- ChanUserList::iterator cit, cit_end;
- for (cit = this->users.begin(), cit_end = this->users.end(); cit != cit_end && (*cit)->user != user; ++cit);
- if (cit == cit_end)
- {
+ ChanUserContainer *cu = user->FindChannel(this);
+ if (!this->users.erase(user))
Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant user " << user->nick << " from channel " << this->name;
- return;
- }
- cul = *cit;
- this->users.erase(cit);
- ChanUserList::iterator uit, uit_end;
- for (uit = user->chans.begin(), uit_end = user->chans.end(); uit != uit_end && (*uit)->chan != this; ++uit);
- if (uit == uit_end)
+ if (!user->chans.erase(this))
Log(LOG_DEBUG) << "Channel::DeleteUser() tried to delete nonexistant channel " << this->name << " from " << user->nick << "'s channel list";
- else
- {
- if (cul != *uit)
- Log(LOG_DEBUG) << "Channel::DeleteUser() mismatch between user and channel usre container objects";
- user->chans.erase(uit);
- }
- delete cul;
+ delete cu;
/* Channel is persistent, it shouldn't be deleted and the service bot should stay */
if (this->HasExt("PERSIST") || (this->ci && this->ci->HasExt("PERSIST")))
@@ -238,30 +216,30 @@ void Channel::DeleteUser(User *user)
delete this;
}
-ChanUserContainer *Channel::FindUser(const User *u) const
+ChanUserContainer *Channel::FindUser(User *u) const
{
- for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
- if ((*it)->user == u)
- return *it;
+ ChanUserList::const_iterator it = this->users.find(u);
+ if (it != this->users.end())
+ return it->second;
return NULL;
}
-bool Channel::HasUserStatus(const User *u, ChannelModeStatus *cms) const
+bool Channel::HasUserStatus(User *u, ChannelModeStatus *cms)
{
/* Usually its more efficient to search the users channels than the channels users */
ChanUserContainer *cc = u->FindChannel(this);
if (cc)
{
if (cms)
- return cc->status.modes.count(cms->name);
+ return cc->status.HasMode(cms->mchar);
else
- return cc->status.modes.empty();
+ return cc->status.Empty();
}
return false;
}
-bool Channel::HasUserStatus(const User *u, const Anope::string &mname) const
+bool Channel::HasUserStatus(User *u, const Anope::string &mname)
{
return HasUserStatus(u, anope_dynamic_static_cast<ChannelModeStatus *>(ModeManager::FindChannelModeByName(mname)));
}
@@ -345,7 +323,7 @@ void Channel::SetModeInternal(MessageSource &setter, ChannelMode *cm, const Anop
/* Set the status on the user */
ChanUserContainer *cc = u->FindChannel(this);
if (cc)
- cc->status.modes.insert(cm->name);
+ cc->status.AddMode(cm->mchar);
FOREACH_RESULT(I_OnChannelModeSet, OnChannelModeSet(this, setter, cm->name, param));
@@ -418,7 +396,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
/* Remove the status on the user */
ChanUserContainer *cc = u->FindChannel(this);
if (cc)
- cc->status.modes.erase(cm->name);
+ cc->status.DelMode(cm->mchar);
FOREACH_RESULT(I_OnChannelModeUnset, OnChannelModeUnset(this, setter, cm->name, param));
@@ -427,7 +405,7 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
/* Reset modes on bots if we're supposed to */
if (this->ci && this->ci->bi && this->ci->bi == bi)
{
- if (ModeManager::DefaultBotModes.modes.count(cm->name))
+ if (ModeManager::DefaultBotModes.HasMode(cm->mchar))
this->SetMode(bi, cm, bi->GetUID());
}
@@ -964,16 +942,16 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
if (give_modes && (!user->Account() || user->Account()->HasExt("AUTOOP")) && (!check_noop || !ci->HasExt("NOAUTOOP")))
{
if (owner && u_access.HasPriv("AUTOOWNER"))
- this->SetMode(NULL, "OWNER", user->GetUID());
+ this->SetMode(NULL, owner, user->GetUID());
else if (admin && u_access.HasPriv("AUTOPROTECT"))
- this->SetMode(NULL, "PROTECT", user->GetUID());
+ this->SetMode(NULL, admin, user->GetUID());
if (op && u_access.HasPriv("AUTOOP"))
- this->SetMode(NULL, "OP", user->GetUID());
+ this->SetMode(NULL, op, user->GetUID());
else if (halfop && u_access.HasPriv("AUTOHALFOP"))
- this->SetMode(NULL, "HALFOP", user->GetUID());
+ this->SetMode(NULL, halfop, user->GetUID());
else if (voice && u_access.HasPriv("AUTOVOICE"))
- this->SetMode(NULL, "VOICE", user->GetUID());
+ this->SetMode(NULL, voice, user->GetUID());
}
/* If this channel has secureops, or the registered channel mode exists and the channel does not have +r set (aka the channel
* was created just now or while we were off), or the registered channel mode does not exist and channel is syncing (aka just
@@ -983,16 +961,16 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
if ((ci->HasExt("SECUREOPS") || (registered && !this->HasMode("REGISTERED")) || (!registered && this->HasExt("SYNCING") && user->server->IsSynced())) && !user->server->IsULined())
{
if (owner && !u_access.HasPriv("AUTOOWNER") && !u_access.HasPriv("OWNERME"))
- this->RemoveMode(NULL, "OWNER", user->GetUID());
+ this->RemoveMode(NULL, owner, user->GetUID());
if (admin && !u_access.HasPriv("AUTOPROTECT") && !u_access.HasPriv("PROTECTME"))
- this->RemoveMode(NULL, "PROTECT", user->GetUID());
+ this->RemoveMode(NULL, admin, user->GetUID());
if (op && this->HasUserStatus(user, "OP") && !u_access.HasPriv("AUTOOP") && !u_access.HasPriv("OPDEOPME"))
- this->RemoveMode(NULL, "OP", user->GetUID());
+ this->RemoveMode(NULL, op, user->GetUID());
if (halfop && !u_access.HasPriv("AUTOHALFOP") && !u_access.HasPriv("HALFOPME"))
- this->RemoveMode(NULL, "HALFOP", user->GetUID());
+ this->RemoveMode(NULL, halfop, user->GetUID());
}
// Check mlock
@@ -1016,7 +994,7 @@ void Channel::SetCorrectModes(User *user, bool give_modes, bool check_noop)
}
}
-bool Channel::Unban(const User *u, bool full)
+bool Channel::Unban(User *u, bool full)
{
if (!this->HasMode("BAN"))
return false;
@@ -1047,3 +1025,12 @@ Channel* Channel::Find(const Anope::string &name)
return NULL;
}
+Channel *Channel::FindOrCreate(const Anope::string &name, bool &created, time_t ts)
+{
+ Channel* &chan = ChannelList[name];
+ created = chan == NULL;
+ if (!chan)
+ chan = new Channel(name, ts);
+ return chan;
+}
+
diff --git a/src/config.cpp b/src/config.cpp
index 1c2aae988..4d1267f23 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -137,6 +137,7 @@ ServerConfig::ServerConfig()
Log() << "Unknown casemap " << this->CaseMap << " - casemap not changed";
}
}
+ Anope::CaseMapRebuild();
if (this->SessionIPv4CIDR > 32 || this->SessionIPv6CIDR > 128)
throw ConfigException("Session CIDR value out of range");
@@ -894,12 +895,10 @@ static bool DoServices(ServerConfig *config, const Anope::string &, const Anope:
continue; // Can't happen
/* Remove all existing modes */
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm && cm->type == MODE_STATUS)
- c->RemoveMode(bi, cm, bi->GetUID());
- }
+ ChanUserContainer *cu = c->FindUser(bi);
+ if (cu != NULL)
+ for (size_t i = 0; i < cu->status.Modes().length(); ++i)
+ c->RemoveMode(bi, ModeManager::FindChannelModeByChar(cu->status.Modes()[i]), bi->GetUID());
/* Set the new modes */
for (unsigned j = 0; j < want_modes.length(); ++j)
{
diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp
index 2f7816746..aac381c9b 100644
--- a/src/hashcomp.cpp
+++ b/src/hashcomp.cpp
@@ -13,6 +13,30 @@
/* Case map in use by Anope */
std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<char>());
+/* Cache of the above case map, forced upper */
+static unsigned char case_map_upper[256], case_map_lower[256];
+
+/* called whenever Anope::casemap is modified to rebuild the casemap cache */
+void Anope::CaseMapRebuild()
+{
+ const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
+
+ for (unsigned i = 0; i < sizeof(case_map_upper); ++i)
+ {
+ case_map_upper[i] = ct.toupper(i);
+ case_map_lower[i] = ct.tolower(i);
+ }
+}
+
+unsigned char Anope::tolower(unsigned char c)
+{
+ return case_map_lower[c];
+}
+
+unsigned char Anope::toupper(unsigned char c)
+{
+ return case_map_upper[c];
+}
/*
*
@@ -23,29 +47,25 @@ std::locale Anope::casemap = std::locale(std::locale(), new Anope::ascii_ctype<c
bool ci::ci_char_traits::eq(char c1st, char c2nd)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- return ct.toupper(c1st) == ct.toupper(c2nd);
+ return case_map_upper[static_cast<unsigned char>(c1st)] == case_map_upper[static_cast<unsigned char>(c2nd)];
}
bool ci::ci_char_traits::ne(char c1st, char c2nd)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- return ct.toupper(c1st) != ct.toupper(c2nd);
+ return !eq(c1st, c2nd);
}
bool ci::ci_char_traits::lt(char c1st, char c2nd)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- return ct.toupper(c1st) < ct.toupper(c2nd);
+ return case_map_upper[static_cast<unsigned char>(c1st)] < case_map_upper[static_cast<unsigned char>(c2nd)];
}
int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
-
for (unsigned i = 0; i < n; ++i)
{
- register char c1 = ct.toupper(*str1), c2 = ct.toupper(*str2);
+ register unsigned char c1 = case_map_upper[static_cast<unsigned char>(*str1)],
+ c2 = case_map_upper[static_cast<unsigned char>(*str2)];
if (c1 > c2)
return 1;
@@ -62,9 +82,7 @@ int ci::ci_char_traits::compare(const char *str1, const char *str2, size_t n)
const char *ci::ci_char_traits::find(const char *s1, int n, char c)
{
- const std::ctype<char> &ct = std::use_facet<std::ctype<char> >(Anope::casemap);
- register char c_u = ct.toupper(c);
- while (n-- > 0 && ct.toupper(*s1) != c_u)
+ while (n-- > 0 && case_map_upper[static_cast<unsigned char>(*s1)] != static_cast<unsigned char>(c))
++s1;
return n >= 0 ? s1 : NULL;
}
@@ -74,35 +92,29 @@ bool ci::less::operator()(const Anope::string &s1, const Anope::string &s2) cons
return s1.ci_str().compare(s2.ci_str()) < 0;
}
-sepstream::sepstream(const Anope::string &source, char seperator) : tokens(source), sep(seperator)
+sepstream::sepstream(const Anope::string &source, char seperator) : tokens(source), sep(seperator), pos(0)
{
- last_starting_position = n = tokens.begin();
}
bool sepstream::GetToken(Anope::string &token)
{
- Anope::string::iterator lsp = last_starting_position;
+ size_t p = this->pos;
- while (n != tokens.end())
+ while (p < this->tokens.length() && this->tokens[p] == this->sep)
+ ++p;
+
+ if (this->StreamEnd())
{
- if (*n == sep || n + 1 == tokens.end())
- {
- last_starting_position = n + 1;
- token = Anope::string(lsp, n + 1 == tokens.end() ? n + 1 : n);
-
- while (token.length() && token.rfind(sep) == token.length() - 1)
- token.erase(token.end() - 1);
-
- ++n;
-
- return true;
- }
-
- ++n;
+ token.clear();
+ return false;
}
- token.clear();
- return false;
+ while (p < this->tokens.length() && this->tokens[p] != this->sep)
+ ++p;
+
+ token = this->tokens.substr(this->pos, p - this->pos);
+ this->pos = p + 1;
+ return true;
}
bool sepstream::GetToken(Anope::string &token, int num)
@@ -135,11 +147,11 @@ bool sepstream::GetTokenRemainder(Anope::string &token, int num)
const Anope::string sepstream::GetRemaining()
{
- return Anope::string(n, tokens.end());
+ return !this->StreamEnd() ? this->tokens.substr(this->pos) : "";
}
bool sepstream::StreamEnd()
{
- return n == tokens.end();
+ return this->pos >= this->tokens.length();
}
diff --git a/src/logger.cpp b/src/logger.cpp
index d46030486..f738cb2e1 100644
--- a/src/logger.cpp
+++ b/src/logger.cpp
@@ -56,9 +56,7 @@ static Anope::string GetTimeStamp()
static inline Anope::string CreateLogName(const Anope::string &file, time_t t = Anope::CurTime)
{
char timestamp[32];
-
tm *tm = localtime(&t);
-
strftime(timestamp, sizeof(timestamp), "%Y%m%d", tm);
return Anope::LogDir + "/" + file + "." + timestamp;
@@ -68,7 +66,12 @@ LogFile::LogFile(const Anope::string &name) : filename(name), stream(name.c_str(
{
}
-Anope::string LogFile::GetName() const
+LogFile::~LogFile()
+{
+ this->stream.close();
+}
+
+const Anope::string &LogFile::GetName() const
{
return this->filename;
}
@@ -77,8 +80,6 @@ Log::Log(LogType t, const Anope::string &cat, const BotInfo *b) : bi(b), u(NULL)
{
if (!bi && Config)
bi = Global;
- if (bi)
- this->sources.push_back(bi->nick);
}
Log::Log(LogType t, CommandSource &source, Command *_c, const ChannelInfo *_ci) : nick(source.GetNick()), u(source.GetUser()), nc(source.nc), c(_c), chan(NULL), ci(_ci), s(NULL), m(NULL), type(t)
@@ -96,13 +97,6 @@ Log::Log(LogType t, CommandSource &source, Command *_c, const ChannelInfo *_ci)
if (this->bi == NULL && Config)
this->bi = Global;
this->category = c->name;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- if (u)
- this->sources.push_back(u->nick);
- this->sources.push_back(c->name);
- if (ci)
- this->sources.push_back(ci->name);
}
Log::Log(const User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u), nc(NULL), c(NULL), chan(ch), ci(chan ? *chan->ci : NULL), s(NULL), m(NULL), type(LOG_CHANNEL), category(cat)
@@ -112,11 +106,6 @@ Log::Log(const User *_u, Channel *ch, const Anope::string &cat) : bi(NULL), u(_u
if (Config)
this->bi = ChanServ;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- if (u)
- this->sources.push_back(u->nick);
- this->sources.push_back(chan->name);
}
Log::Log(const User *_u, const Anope::string &cat, const BotInfo *_bi) : bi(_bi), u(_u), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_USER), category(cat)
@@ -126,9 +115,6 @@ Log::Log(const User *_u, const Anope::string &cat, const BotInfo *_bi) : bi(_bi)
if (!this->bi && Config)
this->bi = Global;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- this->sources.push_back(u->nick);
}
Log::Log(Server *serv, const Anope::string &cat, const BotInfo *_bi) : bi(_bi), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(serv), m(NULL), type(LOG_SERVER), category(cat)
@@ -140,23 +126,16 @@ Log::Log(Server *serv, const Anope::string &cat, const BotInfo *_bi) : bi(_bi),
this->bi = OperServ;
if (!this->bi && Config)
this->bi = Global;
- if (this->bi)
- this->sources.push_back(this->bi->nick);
- this->sources.push_back(s->GetName());
}
Log::Log(const BotInfo *b, const Anope::string &cat) : bi(b), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(NULL), type(LOG_NORMAL), category(cat)
{
if (!this->bi && Config)
this->bi = Global;
- if (this->bi)
- this->sources.push_back(bi->nick);
}
Log::Log(Module *mod, const Anope::string &cat) : bi(NULL), u(NULL), nc(NULL), c(NULL), chan(NULL), ci(NULL), s(NULL), m(mod), type(LOG_MODULE), category(cat)
{
- if (m)
- this->sources.push_back(m->name);
}
Log::~Log()
@@ -167,11 +146,12 @@ Log::~Log()
std::cout << GetTimeStamp() << " " << this->BuildPrefix() << this->buf.str() << std::endl;
else if (this->type == LOG_TERMINAL)
std::cout << this->BuildPrefix() << this->buf.str() << std::endl;
- for (unsigned i = 0; Config && i < Config->LogInfos.size(); ++i)
- {
- LogInfo *l = Config->LogInfos[i];
- l->ProcessMessage(this);
- }
+
+ if (Config)
+ for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
+ if (Config->LogInfos[i]->HasType(this->type, this->category))
+ Config->LogInfos[i]->ProcessMessage(this);
+
FOREACH_MOD(I_OnLog, OnLog(this));
}
@@ -264,40 +244,20 @@ Anope::string Log::BuildPrefix() const
return buffer;
}
-LogInfo::LogInfo(int la, bool rio, bool ldebug) : log_age(la), raw_io(rio), debug(ldebug)
+LogInfo::LogInfo(int la, bool rio, bool ldebug) : last_day(0), log_age(la), raw_io(rio), debug(ldebug)
{
}
LogInfo::~LogInfo()
{
- for (std::map<Anope::string, LogFile *>::iterator it = this->logfiles.begin(), it_end = this->logfiles.end(); it != it_end; ++it)
- {
- LogFile *f = it->second;
-
- if (f && f->stream.is_open())
- f->stream.close();
- delete f;
- }
+ for (unsigned i = 0; i < this->logfiles.size(); ++i)
+ delete this->logfiles[i];
this->logfiles.clear();
}
-void LogInfo::AddType(std::list<Anope::string> &list, const Anope::string &type)
-{
- for (std::list<Anope::string>::iterator it = list.begin(), it_end = list.end(); it != it_end; ++it)
- {
- if (Anope::Match(type, *it))
- {
- Log() << "Log: Type " << type << " is already covered by " << *it;
- return;
- }
- }
-
- list.push_back(type);
-}
-
bool LogInfo::HasType(LogType ltype, const Anope::string &type) const
{
- const std::list<Anope::string> *list = NULL;
+ const std::vector<Anope::string> *list = NULL;
switch (ltype)
{
case LOG_ADMIN:
@@ -338,9 +298,9 @@ bool LogInfo::HasType(LogType ltype, const Anope::string &type) const
if (list == NULL)
return false;
- for (std::list<Anope::string>::const_iterator it = list->begin(), it_end = list->end(); it != it_end; ++it)
+ for (unsigned i = 0; i < list->size(); ++i)
{
- Anope::string cat = *it;
+ Anope::string cat = list->at(i);
bool inverse = false;
if (cat[0] == '~')
{
@@ -356,36 +316,63 @@ bool LogInfo::HasType(LogType ltype, const Anope::string &type) const
return false;
}
-void LogInfo::ProcessMessage(const Log *l)
+void LogInfo::OpenLogFiles()
{
- static time_t lastwarn = Anope::CurTime;
+ for (unsigned i = 0; i < this->logfiles.size(); ++i)
+ delete this->logfiles[i];
+ this->logfiles.clear();
- if (!l)
- throw CoreException("Bad values passed to LogInfo::ProcessMessages");
- else if (!this->HasType(l->type, l->category))
- return;
-
+ for (unsigned i = 0; i < this->targets.size(); ++i)
+ {
+ const Anope::string &target = this->targets[i];
+
+ if (target.empty() || target[0] == '#' || target == "globops")
+ continue;
+
+ LogFile *lf = new LogFile(CreateLogName(target));
+ if (!lf->stream.is_open())
+ {
+ Log() << "Unable to open logfile " << lf->GetName();
+ delete lf;
+ }
+ else
+ this->logfiles.push_back(lf);
+ }
+}
+
+void LogInfo::ProcessMessage(const Log *l)
+{
if (!this->sources.empty())
{
bool log = false;
- for (std::list<Anope::string>::const_iterator it = this->sources.begin(), it_end = this->sources.end(); it != it_end; ++it)
+ for (unsigned i = 0; i < this->sources.size() && !log; ++i)
{
- if (std::find(l->sources.begin(), l->sources.end(), *it) != l->sources.end())
- {
+ const Anope::string &src = this->sources[i];
+
+ if (l->bi && src == l->bi->nick)
+ log = true;
+ else if (l->u && src == l->u->nick)
+ log = true;
+ else if (l->nc && src == l->nc->display)
+ log = true;
+ else if (l->ci && src == l->ci->name)
+ log = true;
+ else if (l->m && src == l->m->name)
+ log = true;
+ else if (l->s && src == l->s->GetName())
log = true;
- break;
- }
}
if (!log)
return;
}
- for (std::list<Anope::string>::iterator it = this->targets.begin(), it_end = this->targets.end(); it != it_end; ++it)
+ const Anope::string &buffer = l->BuildPrefix() + l->buf.str();
+
+ for (unsigned i = 0; i < this->targets.size(); ++i)
{
- const Anope::string &target = *it;
- Anope::string buffer = l->BuildPrefix() + l->buf.str();
+ const Anope::string &target = this->targets[i];
- if (target[0] == '#')
+ if (!target.empty() && target[0] == '#')
{
if (UplinkSock && l->type <= LOG_NORMAL && Me && Me->IsSynced())
{
@@ -402,63 +389,35 @@ void LogInfo::ProcessMessage(const Log *l)
IRCD->SendGlobops(l->bi, "%s", buffer.c_str());
}
}
- else
- {
- LogFile *log = NULL;
- std::map<Anope::string, LogFile *>::iterator lit = this->logfiles.find(target);
- if (lit != this->logfiles.end())
- {
- log = lit->second;
- if (log && log->GetName() != CreateLogName(target))
- {
- delete log;
- this->logfiles.erase(lit);
- log = new LogFile(CreateLogName(target));
- this->logfiles[target] = log;
-
- if (this->log_age)
- {
- Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->log_age);
- if (IsFile(oldlog))
- {
- unlink(oldlog.c_str());
- Log(LOG_DEBUG) << "Deleted old logfile " << oldlog;
- }
- }
- }
- if (!log || !log->stream.is_open())
- {
- if (log && lastwarn + 300 < Anope::CurTime)
- {
- lastwarn = Anope::CurTime;
- Log() << "Unable to open logfile " << log->GetName();
- }
- delete log;
- this->logfiles.erase(lit);
- log = NULL;
- }
- }
- else if (lit == this->logfiles.end())
+ }
+
+ tm *tm = localtime(&Anope::CurTime);
+ if (tm->tm_mday != this->last_day)
+ {
+ this->last_day = tm->tm_mday;
+ this->OpenLogFiles();
+
+ if (this->log_age)
+ for (unsigned i = 0; i < this->targets.size(); ++i)
{
- log = new LogFile(CreateLogName(target));
+ const Anope::string &target = this->targets[i];
+
+ if (target.empty() || target[0] == '#' || target == "globops")
+ continue;
- if (!log->stream.is_open())
+ Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->log_age);
+ if (IsFile(oldlog))
{
- if (lastwarn + 300 < Anope::CurTime)
- {
- lastwarn = Anope::CurTime;
- Log() << "Unable to open logfile " << log->GetName();
- }
- delete log;
- log = NULL;
+ unlink(oldlog.c_str());
+ Log(LOG_DEBUG) << "Deleted old logfile " << oldlog;
}
- else
- this->logfiles[target] = log;
}
+ }
- if (log)
- log->stream << GetTimeStamp() << " " << buffer << std::endl;
- }
+ for (unsigned i = 0; i < this->logfiles.size(); ++i)
+ {
+ LogFile *lf = this->logfiles[i];
+ lf->stream << GetTimeStamp() << " " << buffer << std::endl;
}
}
diff --git a/src/main.cpp b/src/main.cpp
index 2e15f5874..059650df0 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -106,6 +106,9 @@ static Anope::string GetFullProgDir(const Anope::string &argv0)
int main(int ac, char **av, char **envp)
{
+ /* String comparisons won't work until we build the case map cache, so do it first */
+ Anope::CaseMapRebuild();
+
BinaryDir = GetFullProgDir(av[0]);
if (BinaryDir[BinaryDir.length() - 1] == '.')
BinaryDir = BinaryDir.substr(0, BinaryDir.length() - 2);
diff --git a/src/messages.cpp b/src/messages.cpp
index 567a24b6a..178d376c3 100644
--- a/src/messages.cpp
+++ b/src/messages.cpp
@@ -64,7 +64,7 @@ void Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
{
for (User::ChanUserList::iterator it = user->chans.begin(), it_end = user->chans.end(); it != it_end; )
{
- ChanUserContainer *cc = *it++;
+ ChanUserContainer *cc = it->second++;
Anope::string channame = cc->chan->name;
FOREACH_MOD(I_OnPrePartChannel, OnPrePartChannel(user, cc->chan));
@@ -84,14 +84,12 @@ void Join::Run(MessageSource &source, const std::vector<Anope::string> &params)
void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, const Anope::string &modes, const std::list<SJoinUser> &users)
{
- Channel *c = Channel::Find(chan);
+ bool created;
+ Channel *c = Channel::FindOrCreate(chan, created, ts ? ts : Anope::CurTime);
bool keep_their_modes = true;
- if (!c)
- {
- c = new Channel(chan, ts ? ts : Anope::CurTime);
+ if (created)
c->Extend("SYNCING");
- }
/* Some IRCds do not include a TS */
else if (!ts)
;
@@ -124,7 +122,8 @@ void Join::SJoin(MessageSource &source, const Anope::string &chan, time_t ts, co
ChanUserContainer *cc = c->JoinUser(u);
/* Update their status internally on the channel */
- cc->status = status;
+ if (keep_their_modes)
+ cc->status = status;
/* Set whatever modes the user should have, and remove any that
* they aren't allowed to have (secureops etc).
@@ -193,7 +192,7 @@ void Kill::Run(MessageSource &source, const std::vector<Anope::string> &params)
bi->introduced = true;
for (User::ChanUserList::const_iterator cit = bi->chans.begin(), cit_end = bi->chans.end(); cit != cit_end; ++cit)
- IRCD->SendJoin(bi, (*cit)->chan, &(*cit)->status);
+ IRCD->SendJoin(bi, cit->second->chan, &cit->second->status);
}
else
u->KillInternal(source.GetSource(), params[1]);
diff --git a/src/misc.cpp b/src/misc.cpp
index ad8512c56..20a53e7cc 100644
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -406,7 +406,7 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
}
else
{
- if (tolower(wild) != tolower(string) && wild != '?')
+ if (Anope::tolower(wild) != Anope::tolower(string) && wild != '?')
return false;
}
@@ -441,7 +441,7 @@ bool Anope::Match(const Anope::string &str, const Anope::string &mask, bool case
}
else
{
- if (tolower(wild) == tolower(string) || wild == '?')
+ if (Anope::tolower(wild) == Anope::tolower(string) || wild == '?')
{
++m;
++s;
@@ -529,7 +529,7 @@ void Anope::Unhex(const Anope::string &src, Anope::string &dest)
Anope::string rv;
for (size_t i = 0; i + 1 < len; i += 2)
{
- char h = std::tolower(src[i], Anope::casemap), l = std::tolower(src[i + 1], Anope::casemap);
+ char h = Anope::tolower(src[i]), l = Anope::tolower(src[i + 1]);
unsigned char byte = (h >= 'a' ? h - 'a' + 10 : h - '0') << 4;
byte += (l >= 'a' ? l - 'a' + 10 : l - '0');
rv += byte;
diff --git a/src/modes.cpp b/src/modes.cpp
index 0eee41682..a1ecdbfee 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -22,6 +22,9 @@ std::map<Channel *, StackerInfo *> ModeManager::ChannelStackerObjects;
std::vector<ChannelMode *> ModeManager::ChannelModes;
std::vector<UserMode *> ModeManager::UserModes;
+static std::map<Anope::string, ChannelMode *> ChannelModesByName;
+static std::map<Anope::string, UserMode *> UserModesByName;
+
/* Number of generic modes we support */
unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0;
@@ -32,33 +35,48 @@ std::list<Anope::string> ModeManager::ModeLockOff;
/* Default modes bots have on channels */
ChannelStatus ModeManager::DefaultBotModes;
-Anope::string ChannelStatus::BuildCharPrefixList() const
+void ChannelStatus::AddMode(char c)
{
- Anope::string ret;
+ if (modes.find(c) == Anope::string::npos)
+ modes.append(c);
+}
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
+void ChannelStatus::DelMode(char c)
+{
+ modes = modes.replace_all_cs(c, "");
+}
- if (this->modes.count(cm->name))
- ret += cm->mchar;
- }
+bool ChannelStatus::HasMode(char c) const
+{
+ return modes.find(c) != Anope::string::npos;
+}
- return ret;
+bool ChannelStatus::Empty() const
+{
+ return modes.empty();
+}
+
+void ChannelStatus::Clear()
+{
+ modes.clear();
+}
+
+const Anope::string &ChannelStatus::Modes() const
+{
+ return modes;
}
Anope::string ChannelStatus::BuildModePrefixList() const
{
Anope::string ret;
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
+ for (size_t i = 0; i < modes.length(); ++i)
{
- ChannelMode *cm = ModeManager::ChannelModes[i];
-
- if (this->modes.count(cm->name))
+ ChannelMode *cm = ModeManager::FindChannelModeByName(modes[i]);
+ if (cm != NULL && cm->type == MODE_STATUS)
{
ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
- ret += cms->Symbol;
+ ret += cms->symbol;
}
}
@@ -119,7 +137,7 @@ ChannelModeParam::~ChannelModeParam()
{
}
-ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char mSymbol, short mlevel) : ChannelMode(mname, modeChar), Symbol(mSymbol), level(mlevel)
+ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char msymbol, short mlevel) : ChannelMode(mname, modeChar), symbol(msymbol), level(mlevel)
{
this->type = MODE_STATUS;
}
@@ -296,7 +314,12 @@ bool ModeManager::AddUserMode(UserMode *um)
Log() << "ModeManager: Added generic support for user mode " << um->mchar;
}
- ModeManager::UserModes.push_back(um);
+ unsigned want = um->mchar;
+ if (want >= ModeManager::UserModes.size())
+ ModeManager::UserModes.resize(want + 1);
+ ModeManager::UserModes[want] = um;
+
+ UserModesByName[um->name] = um;
FOREACH_MOD(I_OnUserModeAdd, OnUserModeAdd(um));
@@ -314,7 +337,21 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
Log() << "ModeManager: Added generic support for channel mode " << cm->mchar;
}
- ModeManager::ChannelModes.push_back(cm);
+ unsigned want = cm->mchar;
+ if (want >= ModeManager::ChannelModes.size())
+ ModeManager::ChannelModes.resize(want + 1);
+ ModeManager::ChannelModes[want] = cm;
+
+ if (cm->type == MODE_STATUS)
+ {
+ ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
+ want = cms->symbol;
+ if (want >= ModeManager::ChannelModes.size())
+ ModeManager::ChannelModes.resize(want + 1);
+ ModeManager::ChannelModes[want] = cms;
+ }
+
+ ChannelModesByName[cm->name] = cm;
/* Apply this mode to the new default mlock if its used */
UpdateDefaultMLock(Config);
@@ -326,97 +363,111 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
void ModeManager::RemoveUserMode(UserMode *um)
{
- for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
- {
- UserMode *mode = ModeManager::UserModes[i];
- if (um == mode)
- {
- ModeManager::UserModes.erase(ModeManager::UserModes.begin() + i);
- break;
- }
- }
+ if (!um)
+ return;
+
+ unsigned want = um->mchar;
+ if (want >= ModeManager::UserModes.size())
+ return;
+
+ if (ModeManager::UserModes[want] != um)
+ return;
+
+ ModeManager::UserModes[want] = NULL;
+
+ UserModesByName.erase(um->name);
StackerDel(um);
}
void ModeManager::RemoveChannelMode(ChannelMode *cm)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
+ if (!cm)
+ return;
+
+ unsigned want = cm->mchar;
+ if (want >= ModeManager::ChannelModes.size())
+ return;
+
+ if (ModeManager::ChannelModes[want] != cm)
+ return;
+
+ ModeManager::ChannelModes[want] = NULL;
+
+ if (cm->type == MODE_STATUS)
{
- ChannelMode *mode = ModeManager::ChannelModes[i];
- if (cm == mode)
- {
- ModeManager::ChannelModes.erase(ModeManager::ChannelModes.begin() + i);
- break;
- }
+ ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
+ want = cms->symbol;
+
+ if (want >= ModeManager::ChannelModes.size())
+ return;
+
+ if (ModeManager::ChannelModes[want] != cm)
+ return;
+
+ ModeManager::ChannelModes[want] = NULL;
}
+ ChannelModesByName.erase(cm->name);
+
StackerDel(cm);
}
-ChannelMode *ModeManager::FindChannelModeByChar(char Mode)
+ChannelMode *ModeManager::FindChannelModeByChar(char mode)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm->mchar == Mode)
- return cm;
- }
-
- return NULL;
+ unsigned want = mode;
+ if (want >= ModeManager::ChannelModes.size())
+ return NULL;
+
+ return ModeManager::ChannelModes[want];
}
-UserMode *ModeManager::FindUserModeByChar(char Mode)
+UserMode *ModeManager::FindUserModeByChar(char mode)
{
- for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
- {
- UserMode *um = ModeManager::UserModes[i];
- if (um->mchar == Mode)
- return um;
- }
-
- return NULL;
+ unsigned want = mode;
+ if (want >= ModeManager::UserModes.size())
+ return NULL;
+
+ return ModeManager::UserModes[want];
}
ChannelMode *ModeManager::FindChannelModeByName(const Anope::string &name)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm->name == name)
- return cm;
- }
-
+ std::map<Anope::string, ChannelMode *>::iterator it = ChannelModesByName.find(name);
+ if (it != ChannelModesByName.end())
+ return it->second;
return NULL;
}
UserMode *ModeManager::FindUserModeByName(const Anope::string &name)
{
- for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
- {
- UserMode *um = ModeManager::UserModes[i];
- if (um->name == name)
- return um;
- }
-
+ std::map<Anope::string, UserMode *>::iterator it = UserModesByName.find(name);
+ if (it != UserModesByName.end())
+ return it->second;
return NULL;
}
-char ModeManager::GetStatusChar(char Value)
+char ModeManager::GetStatusChar(char value)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm->type == MODE_STATUS)
- {
- ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
+ unsigned want = value;
+ if (want >= ModeManager::ChannelModes.size())
+ return 0;
+
+ ChannelMode *cm = ModeManager::ChannelModes[want];
+ if (cm == NULL || cm->type != MODE_STATUS)
+ return 0;
+
+ return cm->mchar;
+}
- if (Value == cms->Symbol)
- return cms->mchar;
- }
- }
+const std::vector<ChannelMode *> &ModeManager::GetChannelModes()
+{
+ return ChannelModes;
+}
- return 0;
+const std::vector<UserMode *> &ModeManager::GetUserModes()
+{
+ return UserModes;
}
void ModeManager::StackerAdd(const BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param)
@@ -592,17 +643,9 @@ void ModeManager::UpdateDefaultMLock(ServerConfig *config)
}
/* Set Bot Modes */
- DefaultBotModes.modes.clear();
+ DefaultBotModes.Clear();
for (unsigned i = 0; i < config->BotModes.length(); ++i)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(config->BotModes[i]);
-
- if (cm && cm->type == MODE_STATUS)
- DefaultBotModes.modes.insert(cm->name);
- else
- /* We don't know the mode yet so just use the mode char */
- DefaultBotModes.modes.insert(config->BotModes[i]);
- }
+ DefaultBotModes.AddMode(config->BotModes[i]);
}
Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0)
@@ -689,7 +732,7 @@ const Anope::string Entry::GetMask() const
return this->mask;
}
-bool Entry::Matches(const User *u, bool full) const
+bool Entry::Matches(User *u, bool full) const
{
/* First check if this mode has defined any matches (usually for extbans). */
if (IRCD->IsExtbanValid(this->mask))
diff --git a/src/process.cpp b/src/process.cpp
index 795c7c40a..a767b87c2 100644
--- a/src/process.cpp
+++ b/src/process.cpp
@@ -21,30 +21,21 @@ void Anope::Process(const Anope::string &buffer)
/* If debugging, log the buffer */
Log(LOG_RAWIO) << "Received: " << buffer;
- /* Strip all extra spaces */
- Anope::string buf = buffer;
- while (buf.find(" ") != Anope::string::npos)
- buf = buf.replace_all_cs(" ", " ");
-
- if (buf.empty())
+ if (buffer.empty())
return;
+ spacesepstream buf_sep(buffer);
+
Anope::string source;
- if (buf[0] == ':')
+ if (buffer[0] == ':')
{
- size_t space = buf.find_first_of(" ");
- if (space == Anope::string::npos)
- return;
- source = buf.substr(1, space - 1);
- buf = buf.substr(space + 1);
- if (source.empty() || buf.empty())
- return;
+ buf_sep.GetToken(source);
+ source.erase(0, 1);
}
- spacesepstream buf_sep(buf);
-
- Anope::string command = buf;
- buf_sep.GetToken(command);
+ Anope::string command;
+ if (!buf_sep.GetToken(command))
+ return;
Anope::string buf_token;
std::vector<Anope::string> params;
@@ -95,7 +86,7 @@ void Anope::Process(const Anope::string &buffer)
else if (m->HasFlag(IRCDMESSAGE_REQUIRE_USER) && !src.GetUser())
Log(LOG_DEBUG) << "unexpected non-user source " << source << " for " << command;
else if (m->HasFlag(IRCDMESSAGE_REQUIRE_SERVER) && !source.empty() && !src.GetServer())
- Log(LOG_DEBUG) << "unexpected non-server soruce " << source << " for " << command;
+ Log(LOG_DEBUG) << "unexpected non-server source " << source << " for " << command;
else
m->Run(src, params);
}
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 35f302ba8..b97f1158e 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -393,7 +393,7 @@ unsigned IRCDProto::GetMaxListFor(Channel *c)
MessageSource::MessageSource(const Anope::string &src) : source(src), u(NULL), s(NULL)
{
if (src.empty())
- this->s = !Me->GetLinks().empty() ? Me->GetLinks().front() : NULL;
+ this->s = Servers::GetUplink();
else if (IRCD->RequiresID || src.find('.') != Anope::string::npos)
this->s = Server::Find(src);
if (this->s == NULL)
diff --git a/src/regchannel.cpp b/src/regchannel.cpp
index a35fa5d4d..9148d99fd 100644
--- a/src/regchannel.cpp
+++ b/src/regchannel.cpp
@@ -578,7 +578,10 @@ void ChannelInfo::AddAccess(ChanAccess *taccess)
const NickAlias *na = NickAlias::Find(taccess->mask);
if (na != NULL)
+ {
na->nc->AddChannelReference(this);
+ taccess->nc = na->nc;
+ }
}
ChanAccess *ChannelInfo::GetAccess(unsigned index) const
@@ -612,8 +615,19 @@ AccessGroup ChannelInfo::AccessFor(const User *u)
group.nc = nc;
for (unsigned i = 0, end = this->GetAccessCount(); i < end; ++i)
- if (this->GetAccess(i)->Matches(u, nc))
- group.push_back(this->GetAccess(i));
+ {
+ ChanAccess *a = this->GetAccess(i);
+
+ if (a->nc)
+ {
+ if (a->nc == nc)
+ group.push_back(a);
+ }
+ else if (a->Matches(u, nc))
+ {
+ group.push_back(a);
+ }
+ }
if (group.founder || !group.empty())
{
@@ -635,8 +649,19 @@ AccessGroup ChannelInfo::AccessFor(const NickCore *nc)
group.nc = nc;
for (unsigned i = 0, end = this->GetAccessCount(); i < end; ++i)
- if (this->GetAccess(i)->Matches(NULL, nc))
+ {
+ ChanAccess *a = this->GetAccess(i);
+
+ if (a->nc)
+ {
+ if (a->nc == nc)
+ group.push_back(a);
+ }
+ else if (this->GetAccess(i)->Matches(NULL, nc))
+ {
group.push_back(this->GetAccess(i));
+ }
+ }
if (group.founder || !group.empty())
{
diff --git a/src/servers.cpp b/src/servers.cpp
index 1dd9d8a37..28ff7bf17 100644
--- a/src/servers.cpp
+++ b/src/servers.cpp
@@ -23,6 +23,9 @@
/* Anope */
Server *Me = NULL;
+Anope::map<Server *> Servers::ByName;
+Anope::map<Server *> Servers::ByID;
+
std::set<Anope::string> Servers::Capab;
Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Anope::string &desc, const Anope::string &ssid, bool jupe) : name(sname), hops(shops), description(desc), sid(ssid), uplink(up)
@@ -30,6 +33,10 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
syncing = true;
juped = jupe;
+ Servers::ByName[sname] = this;
+ if (!ssid.empty())
+ Servers::ByID[ssid] = this;
+
Log(this, "connect") << "uplinked to " << (this->uplink ? this->uplink->GetName() : "no uplink") << " connected to the network";
/* Add this server to our uplinks leaf list */
@@ -105,8 +112,8 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
if (c->users.empty())
IRCD->SendChannel(c);
else
- for (User::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit)
- IRCD->SendJoin((*cit)->user, c, &(*cit)->status);
+ for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit)
+ IRCD->SendJoin(cit->second->user, c, &cit->second->status);
}
}
}
@@ -148,6 +155,10 @@ Server::~Server()
for (unsigned i = this->links.size(); i > 0; --i)
this->links[i - 1]->Delete(this->quit_reason);
+
+ Servers::ByName.erase(this->name);
+ if (!this->sid.empty())
+ Servers::ByID.erase(this->sid);
}
void Server::Delete(const Anope::string &reason)
@@ -248,12 +259,8 @@ void Server::Sync(bool sync_links)
ChannelInfo *ci = it->second;
if (ci->HasExt("PERSIST"))
{
- bool created = false;
- if (!ci->c)
- {
- ci->c = new Channel(ci->name, ci->time_registered);
- created = true;
- }
+ bool created;
+ ci->c = Channel::FindOrCreate(ci->name, created, ci->time_registered);
if (ModeManager::FindChannelModeByName("PERM") != NULL)
{
ci->c->SetMode(NULL, "PERM");
@@ -325,30 +332,21 @@ void Server::Notice(const BotInfo *source, const Anope::string &message)
IRCD->SendGlobalNotice(source, this, message);
}
-Server *Server::Find(const Anope::string &name, Server *s)
+Server *Server::Find(const Anope::string &name, bool name_only)
{
- Log(LOG_DEBUG_2) << "Server::Find called for " << name;
-
- if (!s)
- s = Me;
- if (s->GetName().equals_ci(name) || s->GetSID().equals_cs(name))
- return s;
-
- if (!s->GetLinks().empty())
+ Anope::map<Server *>::iterator it;
+
+ if (!name_only)
{
- for (unsigned i = 0, j = s->GetLinks().size(); i < j; ++i)
- {
- Server *serv = s->GetLinks()[i];
-
- if (serv->GetName().equals_ci(name) || serv->GetSID().equals_cs(name))
- return serv;
- Log(LOG_DEBUG_2) << "Server::Find checking " << serv->GetName() << " server tree for " << name;
- Server *server = Server::Find(name, serv);
- if (server)
- return server;
- }
+ it = Servers::ByID.find(name);
+ if (it != Servers::ByID.end())
+ return it->second;
}
-
+
+ it = Servers::ByName.find(name);
+ if (it != Servers::ByName.end())
+ return it->second;
+
return NULL;
}
diff --git a/src/users.cpp b/src/users.cpp
index 708a8062c..1355911bf 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -66,7 +66,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->nc = NULL;
this->UpdateHost();
- if (sserver) // Our bots are introduced on startup with no server
+ if (sserver && sserver->IsSynced()) // Our bots are introduced on startup with no server
{
++sserver->users;
Log(this, "connect") << (!svhost.empty() ? Anope::string("(") + svhost + ") " : "") << "(" << srealname << ") " << sip << " connected to the network (" << sserver->GetName() << ")";
@@ -76,7 +76,8 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
{
MaxUserCount = UserListByNick.size();
MaxUserTime = Anope::CurTime;
- Log(this, "maxusers") << "connected - new maximum user count: " << UserListByNick.size();
+ if (sserver && sserver->IsSynced())
+ Log(this, "maxusers") << "connected - new maximum user count: " << UserListByNick.size();
}
bool exempt = false;
@@ -230,7 +231,8 @@ User::~User()
{
if (this->server != NULL)
{
- Log(this, "disconnect") << "(" << this->realname << ") disconnected from the network (" << this->server->GetName() << ")";
+ if (this->server->IsSynced())
+ Log(this, "disconnect") << "(" << this->realname << ") disconnected from the network (" << this->server->GetName() << ")";
--this->server->users;
}
@@ -243,7 +245,7 @@ User::~User()
--OperCount;
while (!this->chans.empty())
- this->chans.front()->chan->DeleteUser(this);
+ this->chans.begin()->second->chan->DeleteUser(this);
UserListByNick.erase(this->nick);
if (!this->uid.empty())
@@ -422,6 +424,9 @@ void User::Identify(NickAlias *na)
void User::Login(NickCore *core)
{
+ if (core == this->nc)
+ return;
+
this->Logout();
this->nc = core;
core->users.push_back(this);
@@ -648,7 +653,8 @@ void User::SetModesInternal(const char *umodes, ...)
vsnprintf(buf, BUFSIZE - 1, umodes, args);
va_end(args);
- Log(this, "mode") << "changes modes to " << buf;
+ if (this->server && this->server->IsSynced())
+ Log(this, "mode") << "changes modes to " << buf;
spacesepstream sep(buf);
sep.GetToken(modebuf);
@@ -718,11 +724,11 @@ Anope::string User::GetModes() const
return m + params;
}
-ChanUserContainer *User::FindChannel(const Channel *c) const
+ChanUserContainer *User::FindChannel(Channel *c) const
{
- for (User::ChanUserList::const_iterator it = this->chans.begin(), it_end = this->chans.end(); it != it_end; ++it)
- if ((*it)->chan == c)
- return *it;
+ User::ChanUserList::const_iterator it = this->chans.find(c);
+ if (it != this->chans.end())
+ return it->second;
return NULL;
}