diff options
| author | Adam <Adam@anope.org> | 2010-08-21 01:40:36 -0400 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2010-08-21 01:40:36 -0400 |
| commit | fb551f0d5d412246a5221e8e9e310c191033b317 (patch) | |
| tree | e737cdf9db93d53313701695c338ab9c96e83e9f | |
| parent | 931b0777fbd961a4ca961ddfa763af92dcce946c (diff) | |
Made Anope keep track of channels its clients are in if it splits from its uplink, then burst them back to its uplink once connection is reestablished.
Also made Anope use TS enforcement to change persistant channels creation time to the time they were registered.
| -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), cha |
