diff options
| -rw-r--r-- | include/bots.h | 18 | ||||
| -rw-r--r-- | include/channels.h | 26 | ||||
| -rw-r--r-- | include/extern.h | 2 | ||||
| -rw-r--r-- | include/modes.h | 8 | ||||
| -rw-r--r-- | include/services.h | 10 | ||||
| -rw-r--r-- | include/users.h | 9 | ||||
| -rw-r--r-- | modules/core/cs_set_persist.cpp | 4 | ||||
| -rw-r--r-- | modules/core/db_plain.cpp | 38 | ||||
| -rw-r--r-- | modules/core/os_chanlist.cpp | 4 | ||||
| -rw-r--r-- | modules/extra/db_mysql.cpp | 25 | ||||
| -rw-r--r-- | modules/protocol/bahamut.cpp | 65 | ||||
| -rw-r--r-- | modules/protocol/inspircd11.cpp | 63 | ||||
| -rw-r--r-- | modules/protocol/inspircd12.cpp | 55 | ||||
| -rw-r--r-- | modules/protocol/inspircd20.cpp | 57 | ||||
| -rw-r--r-- | modules/protocol/ratbox.cpp | 50 | ||||
| -rw-r--r-- | modules/protocol/unreal32.cpp | 50 | ||||
| -rw-r--r-- | src/bots.cpp | 34 | ||||
| -rw-r--r-- | src/channels.cpp | 144 | ||||
| -rw-r--r-- | src/chanserv.cpp | 4 | ||||
| -rw-r--r-- | src/init.cpp | 36 | ||||
| -rw-r--r-- | src/main.cpp | 9 | ||||
| -rw-r--r-- | src/modes.cpp | 51 | ||||
| -rw-r--r-- | src/protocol.cpp | 5 | ||||
| -rw-r--r-- | src/regchannel.cpp | 71 | ||||
| -rw-r--r-- | src/servers.cpp | 8 |
25 files changed, 435 insertions, 411 deletions
diff --git a/include/bots.h b/include/bots.h index 7d2fa74f3..f6b8d2e14 100644 --- a/include/bots.h +++ b/include/bots.h @@ -71,8 +71,22 @@ class CoreExport BotInfo : public User, public Flags<BotFlag, BI_END> */ void UnAssign(User *u, ChannelInfo *ci); - void Join(Channel *c); - void Join(const Anope::string &chname); + /** Join this bot to a channel + * @param c The channel + * @param update_ts Assume we're updating the TS for this channel + */ + void Join(Channel *c, bool update_ts = false); + + /** Join this bot to a channel + * @param chname The channel name + * @param update_ts Assume we're updating the TS for this channel + */ + void Join(const Anope::string &chname, bool update_ts = false); + + /** Part this bot from a channel + * @param c The channel + * @param reason The reason we're parting + */ void Part(Channel *c, const Anope::string &reason = ""); }; diff --git a/include/channels.h b/include/channels.h index 845f8fc36..8c5d83c5d 100644 --- a/include/channels.h +++ b/include/channels.h @@ -44,7 +44,7 @@ struct UserContainer { User *user; UserData ud; - Flags<ChannelModeName> *Status; + ChannelStatus *Status; UserContainer(User *u) : user(u) { } virtual ~UserContainer() { } @@ -104,6 +104,11 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags> int16 bouncy_modes; /* Did we fail to set modes here? */ int16 topic_sync; /* Is the topic in sync? */ + /** Call if we need to unset all modes and clear all user status (internally). + * Only useful if we get a SJOIN with a TS older than what we have here + */ + void Reset(); + /** Restore the channel topic, set mlock (key), set stickied bans, etc */ void Sync(); @@ -217,23 +222,27 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags> /** Clear all the modes from the channel * @param bi The client unsetting the modes + * @param internal Only remove the modes internally */ - void ClearModes(BotInfo *bi = NULL); + void ClearModes(BotInfo *bi = NULL, bool internal = false); /** Clear all the bans from the channel * @param bi The client unsetting the modes + * @param internal Only remove the modes internally */ - void ClearBans(BotInfo *bi = NULL); + void ClearBans(BotInfo *bi = NULL, bool internal = false); /** Clear all the excepts from the channel * @param bi The client unsetting the modes + * @param internal Only remove the modes internally */ - void ClearExcepts(BotInfo *bi = NULL); + void ClearExcepts(BotInfo *bi = NULL, bool internal = false); /** Clear all the invites from the channel * @param bi The client unsetting the modes + * @param internal Only remove the modes internally */ - void ClearInvites(BotInfo *bi = NULL); + void ClearInvites(BotInfo *bi = NULL, bool internal = false); /** Get a param from the channel * @param Name The mode @@ -268,6 +277,13 @@ class CoreExport Channel : public Extensible, public Flags<ChannelFlags> * @return true if the kick was scucessful, false if a module blocked the kick */ bool Kick(BotInfo *bi, User *u, const char *reason = NULL, ...); + + /** Get a string of the modes set on this channel + * @param complete Include mode parameters + * @param plus If set to false (with complete), mode parameters will not be given for modes requring no parameters to be unset + * @return A mode string + */ + Anope::string GetModes(bool complete, bool plus); }; #endif // CHANNELS_H diff --git a/include/extern.h b/include/extern.h index b2dd30b79..4dc6cb4ba 100644 --- a/include/extern.h +++ b/include/extern.h @@ -66,8 +66,6 @@ E void ChanSetInternalModes(Channel *c, int ac, const char **av); E User *nc_on_chan(Channel *c, const NickCore *nc); -E Anope::string chan_get_modes(Channel *chan, int complete, int plus); - E int get_access_level(ChannelInfo *ci, NickAlias *na); E int get_access_level(ChannelInfo *ci, NickCore *nc); E Anope::string get_xop_level(int level); diff --git a/include/modes.h b/include/modes.h index 6447550ad..4d0706a9a 100644 --- a/include/modes.h +++ b/include/modes.h @@ -420,7 +420,7 @@ class CoreExport ModeManager public: /* List of all modes Anope knows about */ - static std::list<Mode *> Modes; + static std::map<Anope::string, Mode *> Modes; /* User modes */ static std::map<char, UserMode *> UserModesByChar; @@ -468,6 +468,12 @@ class CoreExport ModeManager */ static UserMode *FindUserModeByName(UserModeName Name); + /** Find a mode by name + * @param name The mode name + * @return The mode + */ + static Mode *FindModeByName(const Anope::string &name); + /** Gets the channel mode char for a symbol (eg + returns v) * @param Value The symbol * @return The char diff --git a/include/services.h b/include/services.h index 15670c8ac..ca02d087e 100644 --- a/include/services.h +++ b/include/services.h @@ -730,13 +730,13 @@ struct LevelInfo /*************************************************************************/ -#include "users.h" -#include "bots.h" - /* This structure stocks ban data since it must not be removed when * user is kicked. */ +#include "users.h" +#include "bots.h" + struct BanData { BanData *next, *prev; @@ -973,7 +973,8 @@ class CoreExport IRCDProto virtual void SendQuit(const BotInfo *bi, const char *fmt, ...); virtual void SendPing(const Anope::string &servname, const Anope::string &who); virtual void SendPong(const Anope::string &servname, const Anope::string &who); - virtual void SendJoin(const BotInfo *bi, const Anope::string &, time_t) = 0; + virtual void SendJoin(const BotInfo *, const Anope::string &, time_t) = 0; + virtual void SendJoin(BotInfo *, const ChannelContainer *); virtual void SendSQLineDel(const XLine *x) = 0; virtual void SendInvite(const BotInfo *bi, const Anope::string &chan, const Anope::string &nick); virtual void SendPart(const BotInfo *bi, const Channel *chan, const char *fmt, ...); @@ -998,6 +999,7 @@ class CoreExport IRCDProto virtual void SendSVSJoin(const Anope::string &, const Anope::string &, const Anope::string &, const Anope::string &) { } virtual void SendSVSPart(const Anope::string &, const Anope::string &, const Anope::string &) { } virtual void SendSWhois(const Anope::string &, const Anope::string &, const Anope::string &) { } + virtual void SendBOB() { } virtual void SendEOB() { } virtual void SendServer(const Server *) = 0; virtual bool IsNickValid(const Anope::string &) { return true; } diff --git a/include/users.h b/include/users.h index 78d83c062..40e98b114 100644 --- a/include/users.h +++ b/include/users.h @@ -17,10 +17,17 @@ typedef unordered_map_namespace::unordered_map<Anope::string, User *, Anope::has extern CoreExport user_map UserListByNick; extern CoreExport user_uid_map UserListByUID; +class ChannelStatus : public Flags<ChannelModeName> +{ + public: + Anope::string BuildCharPrefixList() const; + Anope::string BuildModePrefixList() const; +}; + struct ChannelContainer { Channel *chan; - Flags<ChannelModeName> *Status; + ChannelStatus *Status; ChannelContainer(Channel *c) : chan(c) { } virtual ~ChannelContainer() { } diff --git a/modules/core/cs_set_persist.cpp b/modules/core/cs_set_persist.cpp index fe3c84242..955e2082f 100644 --- a/modules/core/cs_set_persist.cpp +++ b/modules/core/cs_set_persist.cpp @@ -33,6 +33,8 @@ class CommandCSSetPersist : public Command if (!ci->HasFlag(CI_PERSIST)) { ci->SetFlag(CI_PERSIST); + if (ci->c) + ci->c->SetFlag(CH_PERSIST); /* Channel doesn't exist, create it */ if (!ci->c) @@ -65,6 +67,8 @@ class CommandCSSetPersist : public Command if (ci->HasFlag(CI_PERSIST)) { ci->UnsetFlag(CI_PERSIST); + if (ci->c) + ci->c->UnsetFlag(CH_PERSIST); /* Unset perm mode */ if (cm && ci->c && ci->c->HasMode(CMODE_PERM)) diff --git a/modules/core/db_plain.cpp b/modules/core/db_plain.cpp index 7f90ad6f9..9c47306ca 100644 --- a/modules/core/db_plain.cpp +++ b/modules/core/db_plain.cpp @@ -1011,43 +1011,33 @@ class DBPlain : public Module if (ci->GetMLockCount(true)) { db << "MD MLOCK_ON"; - for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) + for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) { - if ((*it)->Class == MC_CHANNEL) - { - ChannelMode *cm = debug_cast<ChannelMode *>(*it); - - if (ci->HasMLock(cm->Name, true)) - db << " " << cm->NameAsString; - } + ChannelMode *cm = it->second; + if (ci->HasMLock(cm->Name, true)) + db << " " << cm->NameAsString; } db << endl; } if (ci->GetMLockCount(false)) { db << "MD MLOCK_OFF"; - for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) - { - if ((*it)->Class == MC_CHANNEL) - { - ChannelMode *cm = debug_cast<ChannelMode *>(*it); - if (ci->HasMLock(cm->Name, false)) - db << " " << cm->NameAsString; - } + for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) + { + ChannelMode *cm = it->second; + if (ci->HasMLock(cm->Name, false)) + db << " " << cm->NameAsString; } db << endl; } - for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) + for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) { - if ((*it)->Class == MC_CHANNEL) - { - ChannelMode *cm = debug_cast<ChannelMode *>(*it); + ChannelMode *cm = it->second; + Anope::string Param; - Anope::string Param; - if (ci->GetParam(cm->Name, Param)) - db << "MD MLP " << cm->NameAsString << " " << Param << endl; - } + if (ci->GetParam(cm->Name, Param)) + db << "MD MLP " << cm->NameAsString << " " << Param << endl; } if (!ci->memos.memos.empty()) { diff --git a/modules/core/os_chanlist.cpp b/modules/core/os_chanlist.cpp index 8fcb1c397..87b3d736d 100644 --- a/modules/core/os_chanlist.cpp +++ b/modules/core/os_chanlist.cpp @@ -46,7 +46,7 @@ class CommandOSChanList : public Command if (!cc->chan->HasMode(*it)) continue; - notice_lang(Config->s_OperServ, u, OPER_CHANLIST_RECORD, cc->chan->name.c_str(), cc->chan->users.size(), chan_get_modes(cc->chan, 1, 1).c_str(), !cc->chan->topic.empty() ? cc->chan->topic.c_str() : ""); + notice_lang(Config->s_OperServ, u, OPER_CHANLIST_RECORD, cc->chan->name.c_str(), cc->chan->users.size(), cc->chan->GetModes(true, true).c_str(), !cc->chan->topic.empty() ? cc->chan->topic.c_str() : ""); } } else @@ -64,7 +64,7 @@ class CommandOSChanList : public Command if (!c->HasMode(*it)) continue; - notice_lang(Config->s_OperServ, u, OPER_CHANLIST_RECORD, c->name.c_str(), c->users.size(), chan_get_modes(c, 1, 1).c_str(), !c->topic.empty() ? c->topic.c_str() : ""); + notice_lang(Config->s_OperServ, u, OPER_CHANLIST_RECORD, c->name.c_str(), c->users.size(), c->GetModes(true, true).c_str(), !c->topic.empty() ? c->topic.c_str() : ""); } } diff --git a/modules/extra/db_mysql.cpp b/modules/extra/db_mysql.cpp index 27a1226d1..4aeac0322 100644 --- a/modules/extra/db_mysql.cpp +++ b/modules/extra/db_mysql.cpp @@ -199,15 +199,11 @@ static Anope::string MakeMLock(ChannelInfo *ci, bool status) { Anope::string ret; - for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) + for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) { - if ((*it)->Class == MC_CHANNEL) - { - ChannelMode *cm = debug_cast<ChannelMode *>(*it); - - if (ci->HasMLock(cm->Name, status)) - ret += " " + cm->NameAsString; - } + ChannelMode *cm = it->second; + if (ci->HasMLock(cm->Name, status)) + ret += " " + cm->NameAsString; } if (!ret.empty()) @@ -230,16 +226,13 @@ static Anope::string GetMLockParams(ChannelInfo *ci) { Anope::string ret; - for (std::list<Mode *>::iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) + for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) { - if ((*it)->Class == MC_CHANNEL) - { - ChannelMode *cm = debug_cast<ChannelMode *>(*it); + ChannelMode *cm = it->second; - Anope::string param; - if (ci->GetParam(cm->Name, param)) - ret += " " + cm->NameAsString + " " + param; - } + Anope::string param; + if (ci->GetParam(cm->Name, param)) + ret += " " + cm->NameAsString + " " + param; } if (!ret.empty()) diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 572b91367..9c3e107a4 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -197,6 +197,19 @@ class BahamutIRCdProto : public IRCDProto send_cmd(user->nick, "SJOIN %ld %s", static_cast<long>(chantime), channel.c_str()); } + void SendJoin(BotInfo *user, const ChannelContainer *cc) + { + SendJoin(user, cc->chan->name, cc->chan->creation_time); + for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) + { + if (cc->Status->HasFlag(it->second->Name)) + { + cc->chan->SetMode(user, it->second, user->nick); + } + } + cc->chan->SetModes(user, false, "%s", cc->chan->GetModes(true, true).c_str()); + } + void SendAkill(const XLine *x) { // Calculate the time left before this would expire, capping it at 2 days @@ -226,6 +239,11 @@ class BahamutIRCdProto : public IRCDProto this->SendModeInternal(NULL, u, merge_args(ac, av)); } + void SendBOB() + { + send_cmd("", "BURST"); + } + void SendEOB() { send_cmd("", "BURST 0"); @@ -290,56 +308,26 @@ int anope_event_sjoin(const Anope::string &source, int ac, const char **av) { Channel *c = findchan(av[1]); time_t ts = Anope::string(av[0]).is_number_only() ? convertTo<time_t>(av[0]) : 0; - bool was_created = false; bool keep_their_modes = false; if (!c) { c = new Channel(av[1], ts); - was_created = true; + c->SetFlag(CH_SYNCING); } /* Our creation time is newer than what the server gave us */ else if (c->creation_time > ts) { c->creation_time = ts; + c->Reset(); - /* Remove status from all of our users */ - for (std::list<Mode *>::const_iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) - { - Mode *m = *it; - - if (m->Type != MODE_STATUS) - continue; - - ChannelMode *cm = debug_cast<ChannelMode *>(m); - - for (CUserList::const_iterator uit = c->users.begin(), uit_end = c->users.end(); uit != uit_end; ++uit) - { - UserContainer *uc = *uit; - - c->RemoveMode(NULL, cm, uc->user->nick); - } - } - if (c->ci) - { - /* Rejoin the bot to fix the TS */ - if (c->ci->bi) - { - c->ci->bi->Part(c, "TS reop"); - c->ci->bi->Join(c); - } - /* Reset mlock */ - check_modes(c); - } + /* Reset mlock */ + check_modes(c); } /* Their TS is newer than ours, our modes > theirs, unset their modes if need be */ - else + else if (ts > c->creation_time) keep_their_modes = false; - /* Mark the channel as syncing */ - if (was_created) - c->SetFlag(CH_SYNCING); - /* If we need to keep their modes, and this SJOIN string contains modes */ if (keep_their_modes && ac >= 4) { @@ -350,7 +338,7 @@ int anope_event_sjoin(const Anope::string &source, int ac, const char **av) /* For a reason unknown to me, bahamut will send a SJOIN from the user joining a channel * if the channel already existed */ - if (!was_created && ac == 2) + if (!c->HasFlag(CH_SYNCING) && ac == 2) { User *u = finduser(source); if (!u) @@ -396,7 +384,8 @@ int anope_event_sjoin(const Anope::string &source, int ac, const char **av) continue; } - Status.push_back(cm); + if (keep_their_modes) + Status.push_back(cm); } User *u = finduser(buf); @@ -433,7 +422,7 @@ int anope_event_sjoin(const Anope::string &source, int ac, const char **av) } /* Channel is done syncing */ - if (was_created) + if (c->HasFlag(CH_SYNCING)) { /* Unset the syncing flag */ c->UnsetFlag(CH_SYNCING); diff --git a/modules/protocol/inspircd11.cpp b/modules/protocol/inspircd11.cpp index c06b74501..cc2c99fa6 100644 --- a/modules/protocol/inspircd11.cpp +++ b/modules/protocol/inspircd11.cpp @@ -185,6 +185,19 @@ class InspIRCdProto : public IRCDProto send_cmd(user->nick, "JOIN %s %ld", channel.c_str(), static_cast<long>(chantime)); } + void SendJoin(BotInfo *user, const ChannelContainer *cc) + { + SendJoin(user, cc->chan->name, cc->chan->creation_time); + for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) + { + if (cc->Status->HasFlag(it->second->Name)) + { + cc->chan->SetMode(user, it->second, user->nick); + } + } + cc->chan->SetModes(user, false, "%s", cc->chan->GetModes(true, true).c_str()); + } + /* UNSQLINE */ void SendSQLineDel(const XLine *x) { @@ -270,6 +283,11 @@ class InspIRCdProto : public IRCDProto send_cmd(source, "SVSPART %s %s", nick.c_str(), chan.c_str()); } + void SendBOB() + { + send_cmd("", "BURST %ld", time(NULL)); + } + void SendEOB() { send_cmd("", "ENDBURST"); @@ -386,56 +404,26 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) { Channel *c = findchan(av[0]); time_t ts = Anope::string(av[1]).is_number_only() ? convertTo<time_t>(av[1]) : 0; - bool was_created = false; bool keep_their_modes = true; if (!c) { c = new Channel(av[0], ts); - was_created = true; + c->SetFlag(CH_SYNCING); } /* Our creation time is newer than what the server gave us */ else if (c->creation_time > ts) { c->creation_time = ts; + c->Reset(); - /* Remove status from all of our users */ - for (std::list<Mode *>::const_iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) - { - Mode *m = *it; - - if (m->Type != MODE_STATUS) - continue; - - ChannelMode *cm = debug_cast<ChannelMode *>(m); - - for (CUserList::const_iterator uit = c->users.begin(), uit_end = c->users.end(); uit != uit_end; ++uit) - { - UserContainer *uc = *uit; - - c->RemoveMode(NULL, cm, uc->user->nick); - } - } - if (c->ci) - { - /* Rejoin the bot to fix the TS */ - if (c->ci->bi) - { - c->ci->bi->Part(c, "TS reop"); - c->ci->bi->Join(c); - } - /* Reset mlock */ - check_modes(c); - } + /* Reset mlock */ + check_modes(c); } /* Their TS is newer than ours, our modes > theirs, unset their modes if need be */ - else + else if (ts > c->creation_time) keep_their_modes = false; - /* Mark the channel as syncing */ - if (was_created) - c->SetFlag(CH_SYNCING); - spacesepstream sep(av[ac - 1]); Anope::string buf; while (sep.GetToken(buf)) @@ -456,7 +444,8 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) } buf.erase(buf.begin()); - Status.push_back(cm); + if (keep_their_modes) + Status.push_back(cm); } User *u = finduser(buf); @@ -492,7 +481,7 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) } /* Channel is done syncing */ - if (was_created) + if (c->HasFlag(CH_SYNCING)) { /* Unset the syncing flag */ c->UnsetFlag(CH_SYNCING); diff --git a/modules/protocol/inspircd12.cpp b/modules/protocol/inspircd12.cpp index a78ead0a8..55a371700 100644 --- a/modules/protocol/inspircd12.cpp +++ b/modules/protocol/inspircd12.cpp @@ -185,6 +185,11 @@ class InspIRCdProto : public IRCDProto send_cmd(TS6SID, "FJOIN %s %ld + :,%s", channel.c_str(), static_cast<long>(chantime), user->GetUID().c_str()); } + void SendJoin(BotInfo *user, const ChannelContainer *cc) + { + send_cmd(TS6SID, "FJOIN %s %ld +%s :%s,%s", cc->chan->name.c_str(), static_cast<long>(cc->chan->creation_time), cc->chan->GetModes(true, true).c_str(), cc->Status->BuildCharPrefixList().c_str(), user->GetUID().c_str()); + } + /* UNSQLINE */ void SendSQLineDel(const XLine *x) { @@ -275,6 +280,11 @@ class InspIRCdProto : public IRCDProto send_cmd(TS6SID, "METADATA %s swhois :%s", u->GetUID().c_str(), mask.c_str()); } + void SendBOB() + { + send_cmd(TS6SID, "BURST %ld", time(NULL)); + } + void SendEOB() { send_cmd(TS6SID, "ENDBURST"); @@ -427,56 +437,26 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) { Channel *c = findchan(av[0]); time_t ts = Anope::string(av[1]).is_number_only() ? convertTo<time_t>(av[1]) : 0; - bool was_created = false; bool keep_their_modes = true; if (!c) { c = new Channel(av[0], ts); - was_created = true; + c->SetFlag(CH_SYNCING); } /* Our creation time is newer than what the server gave us */ else if (c->creation_time > ts) { c->creation_time = ts; + c->Reset(); - /* Remove status from all of our users */ - for (std::list<Mode *>::const_iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) - { - Mode *m = *it; - - if (m->Type != MODE_STATUS) - continue; - - ChannelMode *cm = debug_cast<ChannelMode *>(m); - - for (CUserList::const_iterator uit = c->users.begin(), uit_end = c->users.end(); uit != uit_end; ++uit) - { - UserContainer *uc = *uit; - - c->RemoveMode(NULL, cm, uc->user->nick); - } - } - if (c->ci) - { - /* Rejoin the bot to fix the TS */ - if (c->ci->bi) - { - c->ci->bi->Part(c, "TS reop"); - c->ci->bi->Join(c); - } - /* Reset mlock */ - check_modes(c); - } + /* Reset mlock */ + check_modes(c); } /* Their TS is newer than ours, our modes > theirs, unset their modes if need be */ - else + else if (ts > c->creation_time) keep_their_modes = false; - /* Mark the channel as syncing */ - if (was_created) - c->SetFlag(CH_SYNCING); - /* If we need to keep their modes, and this FJOIN string contains modes */ if (keep_their_modes && ac >= 4) { @@ -502,7 +482,8 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) } buf.erase(buf.begin()); - Status.push_back(cm); + if (keep_their_modes) + Status.push_back(cm); } buf.erase(buf.begin()); @@ -539,7 +520,7 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) } /* Channel is done syncing */ - if (was_created) + if (c->HasFlag(CH_SYNCING)) { /* Unset the syncing flag */ c->UnsetFlag(CH_SYNCING); diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index c55bc7020..8a8748d49 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -183,6 +183,11 @@ class InspIRCdProto : public IRCDProto send_cmd(TS6SID, "FJOIN %s %ld + :,%s", channel.c_str(), static_cast<long>(chantime), user->GetUID().c_str()); } + void SendJoin(BotInfo *user, const ChannelContainer *cc) + { + send_cmd(TS6SID, "FJOIN %s %ld +%s :%s,%s", cc->chan->name.c_str(), static_cast<long>(cc->chan->creation_time), cc->chan->GetModes(true, true).c_str(), cc->Status->BuildCharPrefixList().c_str(), user->GetUID().c_str()); + } + /* UNSQLINE */ void SendSQLineDel(const XLine *x) { @@ -276,6 +281,11 @@ class InspIRCdProto : public IRCDProto send_cmd(TS6SID, "METADATA %s swhois :%s", u->GetUID().c_str(), mask.c_str()); } + void SendBOB() + { + send_cmd(TS6SID, "BURST %ld", time(NULL)); + } + void SendEOB() { send_cmd(TS6SID, "ENDBURST"); @@ -425,56 +435,26 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) { Channel *c = findchan(av[0]); time_t ts = Anope::string(av[1]).is_number_only() ? convertTo<time_t>(av[1]) : 0; - bool was_created = false; bool keep_their_modes = true; if (!c) { c = new Channel(av[0], ts); - was_created = true; + c->SetFlag(CH_SYNCING); } /* Our creation time is newer than what the server gave us */ else if (c->creation_time > ts) { c->creation_time = ts; + c->Reset(); - /* Remove status from all of our users */ - for (std::list<Mode *>::const_iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) - { - Mode *m = *it; - - if (m->Type != MODE_STATUS) - continue; - - ChannelMode *cm = debug_cast<ChannelMode *>(m); - - for (CUserList::const_iterator uit = c->users.begin(), uit_end = c->users.end(); uit != uit_end; ++uit) - { - UserContainer *uc = *uit; - - c->RemoveMode(NULL, cm, uc->user->nick); - } - } - if (c->ci) - { - /* Rejoin the bot to fix the TS */ - if (c->ci->bi) - { - c->ci->bi->Part(c, "TS reop"); - c->ci->bi->Join(c); - } - /* Reset mlock */ - check_modes(c); - } + /* Reset mlock */ + check_modes(c); } - /* Their TS is newer than ours, our modes > theirs, unset their modes if need be */ - else + /* Their TS is newer than ours, our modes > theirs, unset their modes */ + else if (ts > c->creation_time) keep_their_modes = false; - /* Mark the channel as syncing */ - if (was_created) - c->SetFlag(CH_SYNCING); - /* If we need to keep their modes, and this FJOIN string contains modes */ if (keep_their_modes && ac >= 4) { @@ -500,7 +480,8 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) } buf.erase(buf.begin()); - Status.push_back(cm); + if (keep_their_modes) + Status.push_back(cm); } buf.erase(buf.begin()); @@ -537,7 +518,7 @@ int anope_event_fjoin(const Anope::string &source, int ac, const char **av) } /* Channel is done syncing */ - if (was_created) + if (c->HasFlag(CH_SYNCING)) { /* Unset the syncing flag */ c->UnsetFlag(CH_SYNCING); diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 8db46a3d5..a26ee9598 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -145,6 +145,11 @@ class RatboxProto : public IRCDTS6Proto send_cmd("", "SJOIN %ld %s + :%s", static_cast<long>(chantime), channel.c_str(), user->GetUID().c_str()); } + void SendJoin(const BotInfo *user, const ChannelContainer *cc) + { + send_cmd("", "SJOIN %ld %s +%s :%s%s", static_cast<long>(cc->chan->creation_time), cc->chan->name.c_str(), cc->chan->GetModes(true, true).c_str(), cc->Status->BuildModePrefixList().c_str(), user->GetUID().c_str()); + } + void SendAkill(const XLine *x) { BotInfo *bi = OperServ; @@ -281,56 +286,26 @@ int anope_event_sjoin(const Anope::string &source, int ac, const char **av) { Channel *c = findchan(av[1]); time_t ts = Anope::string(av[0]).is_number_only() ? convertTo<time_t>(av[0]) : 0; - bool was_created = false; bool keep_their_modes = true; if (!c) { c = new Channel(av[1], ts); - was_created = true; + c->SetFlag(CH_SYNCING); } /* Our creation time is newer than what the server gave us */ else if (c->creation_time > ts) { c->creation_time = ts; + c->Reset(); - /* Remove status from all of our users */ - for (std::list<Mode *>::const_iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) - { - Mode *m = *it; - - if (m->Type != MODE_STATUS) - continue; - - ChannelMode *cm = debug_cast<ChannelMode *>(m); - - for (CUserList::const_iterator uit = c->users.begin(), uit_end = c->users.end(); uit != uit_end; ++uit) - { - UserContaine |
