mirror of
https://github.com/inspircd/inspircd.git
synced 2025-03-09 18:49:03 -04:00
Merge pull request #149 from attilamolnar/insp12+spanningtreefixes
[1.2] Fix a number of issues in m_spanningtree
This commit is contained in:
commit
99d6f092e4
@ -34,21 +34,13 @@ bool TreeSocket::Admin(const std::string &prefix, std::deque<std::string> ¶m
|
||||
if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0]))
|
||||
{
|
||||
/* It's for our server */
|
||||
string_list results;
|
||||
User* source = this->ServerInstance->FindNick(prefix);
|
||||
if (source)
|
||||
{
|
||||
std::deque<std::string> par;
|
||||
par.push_back(prefix);
|
||||
par.push_back("");
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName;
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName;
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick;
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail;
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 256 "+source->nick+" :Administrative info for "+ServerInstance->Config->ServerName);
|
||||
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 257 "+source->nick+" :Name - "+ServerInstance->Config->AdminName);
|
||||
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :Nickname - "+ServerInstance->Config->AdminNick);
|
||||
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 258 "+source->nick+" :E-Mail - "+ServerInstance->Config->AdminEmail);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -35,11 +35,11 @@ std::string TreeSocket::MyCapabilities()
|
||||
std::vector<std::string> modlist = this->ServerInstance->Modules->GetAllModuleNames(VF_COMMON);
|
||||
std::string capabilities;
|
||||
sort(modlist.begin(),modlist.end());
|
||||
for (unsigned int i = 0; i < modlist.size(); i++)
|
||||
for (std::vector<std::string>::const_iterator i = modlist.begin(); i != modlist.end(); ++i)
|
||||
{
|
||||
if (i)
|
||||
if (i != modlist.begin())
|
||||
capabilities = capabilities + ",";
|
||||
capabilities = capabilities + modlist[i];
|
||||
capabilities = capabilities + *i;
|
||||
}
|
||||
return capabilities;
|
||||
}
|
||||
|
@ -26,14 +26,11 @@
|
||||
|
||||
/* $ModDep: m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/treesocket.h */
|
||||
|
||||
|
||||
|
||||
/** remote MOTD. leet, huh? */
|
||||
bool TreeSocket::Encap(const std::string &prefix, std::deque<std::string> ¶ms)
|
||||
{
|
||||
if (params.size() > 1)
|
||||
{
|
||||
if (InspIRCd::Match(ServerInstance->Config->GetSID(), params[0]))
|
||||
if (ServerInstance->Config->GetSID() == params[0] || InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
|
||||
{
|
||||
Event event((char*) ¶ms, (Module*)this->Utils->Creator, "encap_received");
|
||||
event.Send(ServerInstance);
|
||||
@ -41,12 +38,21 @@ bool TreeSocket::Encap(const std::string &prefix, std::deque<std::string> ¶m
|
||||
|
||||
params[params.size() - 1] = ":" + params[params.size() - 1];
|
||||
|
||||
if (params[0].find('*') != std::string::npos)
|
||||
if (params[0].find_first_of("*?") != std::string::npos)
|
||||
{
|
||||
Utils->DoOneToAllButSender(prefix, "ENCAP", params, prefix);
|
||||
}
|
||||
else
|
||||
Utils->DoOneToOne(prefix, "ENCAP", params, params[0]);
|
||||
{
|
||||
/* Only forward when the route to the target is not the same as the sender.
|
||||
* This occurs with 1.2.9 and older servers, as they broadcast ENCAP even when
|
||||
* it is targetted to a single server only.
|
||||
* If we were the only target of this ENCAP, it won't be propagated.
|
||||
*/
|
||||
TreeServer* routeserver = Utils->BestRouteTo(params[0]);
|
||||
if ((routeserver) && (routeserver->GetSocket() != this))
|
||||
Utils->DoOneToOne(prefix, "ENCAP", params, params[0]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@
|
||||
/* $ModDep: m_spanningtree/cachetimer.h m_spanningtree/resolvers.h m_spanningtree/main.h m_spanningtree/utils.h m_spanningtree/treeserver.h m_spanningtree/link.h m_spanningtree/treesocket.h m_spanningtree/rconnect.h m_spanningtree/rsquit.h m_spanningtree/protocolinterface.h */
|
||||
|
||||
ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me)
|
||||
: Module(Me), max_local(0), max_global(0)
|
||||
: Module(Me), max_local(0), max_global(0), loopCall(false)
|
||||
{
|
||||
ServerInstance->Modules->UseInterface("BufferedSocketHook");
|
||||
Utils = new SpanningTreeUtilities(ServerInstance, this);
|
||||
@ -67,7 +67,6 @@ ModuleSpanningTree::ModuleSpanningTree(InspIRCd* Me)
|
||||
|
||||
delete ServerInstance->PI;
|
||||
ServerInstance->PI = new SpanningTreeProtocolInterface(this, Utils, ServerInstance);
|
||||
loopCall = false;
|
||||
|
||||
for (std::vector<User*>::const_iterator i = ServerInstance->Users->local_users.begin(); i != ServerInstance->Users->local_users.end(); i++)
|
||||
{
|
||||
@ -486,110 +485,47 @@ void ModuleSpanningTree::OnWallops(User* user, const std::string &text)
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
|
||||
void ModuleSpanningTree::LocalMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list, const std::string& message_type)
|
||||
{
|
||||
/* Server origin */
|
||||
if (user == NULL)
|
||||
return;
|
||||
|
||||
if (target_type == TYPE_USER)
|
||||
{
|
||||
User* d = (User*)dest;
|
||||
if ((d->GetFd() < 0) && (IS_LOCAL(user)))
|
||||
if (IS_REMOTE(d))
|
||||
{
|
||||
std::deque<std::string> params;
|
||||
params.clear();
|
||||
params.push_back(d->uuid);
|
||||
params.push_back(":"+text);
|
||||
Utils->DoOneToOne(user->uuid,"NOTICE",params,d->server);
|
||||
Utils->DoOneToOne(user->uuid, message_type, params, d->server);
|
||||
}
|
||||
}
|
||||
else if (target_type == TYPE_CHANNEL)
|
||||
{
|
||||
if (IS_LOCAL(user))
|
||||
Channel *c = (Channel*)dest;
|
||||
if (c)
|
||||
{
|
||||
Channel *c = (Channel*)dest;
|
||||
if (c)
|
||||
{
|
||||
std::string cname = c->name;
|
||||
if (status)
|
||||
cname = status + cname;
|
||||
TreeServerList list;
|
||||
Utils->GetListOfServersForChannel(c,list,status,exempt_list);
|
||||
for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
|
||||
{
|
||||
TreeSocket* Sock = i->second->GetSocket();
|
||||
if (Sock)
|
||||
Sock->WriteLine(":"+std::string(user->uuid)+" NOTICE "+cname+" :"+text);
|
||||
}
|
||||
}
|
||||
Utils->SendChannelMessage(user->uuid, c, text, status, exempt_list, message_type);
|
||||
}
|
||||
}
|
||||
else if (target_type == TYPE_SERVER)
|
||||
{
|
||||
if (IS_LOCAL(user))
|
||||
{
|
||||
char* target = (char*)dest;
|
||||
std::deque<std::string> par;
|
||||
par.push_back(target);
|
||||
par.push_back(":"+text);
|
||||
Utils->DoOneToMany(user->uuid,"NOTICE",par);
|
||||
}
|
||||
char* target = (char*)dest;
|
||||
std::deque<std::string> par;
|
||||
par.push_back(target);
|
||||
par.push_back(":"+text);
|
||||
Utils->DoOneToMany(user->uuid, message_type, par);
|
||||
}
|
||||
}
|
||||
|
||||
void ModuleSpanningTree::OnUserNotice(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
|
||||
{
|
||||
if ((user) && (IS_LOCAL(user)))
|
||||
LocalMessage(user, dest, target_type, text, status, exempt_list, "NOTICE");
|
||||
}
|
||||
|
||||
void ModuleSpanningTree::OnUserMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list)
|
||||
{
|
||||
/* Server origin */
|
||||
if (user == NULL)
|
||||
return;
|
||||
|
||||
if (target_type == TYPE_USER)
|
||||
{
|
||||
// route private messages which are targetted at clients only to the server
|
||||
// which needs to receive them
|
||||
User* d = (User*)dest;
|
||||
if ((d->GetFd() < 0) && (IS_LOCAL(user)))
|
||||
{
|
||||
std::deque<std::string> params;
|
||||
params.clear();
|
||||
params.push_back(d->uuid);
|
||||
params.push_back(":"+text);
|
||||
Utils->DoOneToOne(user->uuid,"PRIVMSG",params,d->server);
|
||||
}
|
||||
}
|
||||
else if (target_type == TYPE_CHANNEL)
|
||||
{
|
||||
if (IS_LOCAL(user))
|
||||
{
|
||||
Channel *c = (Channel*)dest;
|
||||
if (c)
|
||||
{
|
||||
std::string cname = c->name;
|
||||
if (status)
|
||||
cname = status + cname;
|
||||
TreeServerList list;
|
||||
Utils->GetListOfServersForChannel(c,list,status,exempt_list);
|
||||
for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
|
||||
{
|
||||
TreeSocket* Sock = i->second->GetSocket();
|
||||
if (Sock)
|
||||
Sock->WriteLine(":"+std::string(user->uuid)+" PRIVMSG "+cname+" :"+text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (target_type == TYPE_SERVER)
|
||||
{
|
||||
if (IS_LOCAL(user))
|
||||
{
|
||||
char* target = (char*)dest;
|
||||
std::deque<std::string> par;
|
||||
par.push_back(target);
|
||||
par.push_back(":"+text);
|
||||
Utils->DoOneToMany(user->uuid,"PRIVMSG",par);
|
||||
}
|
||||
}
|
||||
if ((user) && (IS_LOCAL(user)))
|
||||
LocalMessage(user, dest, target_type, text, status, exempt_list, "PRIVMSG");
|
||||
}
|
||||
|
||||
void ModuleSpanningTree::OnBackgroundTimer(time_t curtime)
|
||||
@ -611,7 +547,7 @@ void ModuleSpanningTree::OnUserJoin(User* user, Channel* channel, bool sync, boo
|
||||
params.push_back(channel->name);
|
||||
params.push_back(ConvToStr(channel->age));
|
||||
params.push_back(std::string("+") + channel->ChanModes(true));
|
||||
params.push_back(ServerInstance->Modes->ModeString(user, channel, false)+","+std::string(user->uuid));
|
||||
params.push_back(ServerInstance->Modes->ModeString(user, channel, false) + "," + user->uuid);
|
||||
Utils->DoOneToMany(ServerInstance->Config->GetSID(),"FJOIN",params);
|
||||
}
|
||||
}
|
||||
@ -638,7 +574,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos)
|
||||
Utils->DoOneToMany(user->uuid,"FNAME",params);
|
||||
}
|
||||
|
||||
void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
|
||||
void ModuleSpanningTree::OnUserPart(User* user, Channel* channel, std::string &partmessage, bool &silent)
|
||||
{
|
||||
if (IS_LOCAL(user))
|
||||
{
|
||||
@ -660,8 +596,8 @@ void ModuleSpanningTree::OnUserQuit(User* user, const std::string &reason, const
|
||||
{
|
||||
params.push_back(":"+oper_message);
|
||||
Utils->DoOneToMany(user->uuid,"OPERQUIT",params);
|
||||
params.clear();
|
||||
}
|
||||
params.clear();
|
||||
params.push_back(":"+reason);
|
||||
Utils->DoOneToMany(user->uuid,"QUIT",params);
|
||||
}
|
||||
@ -789,22 +725,17 @@ void ModuleSpanningTree::OnAddLine(User* user, XLine *x)
|
||||
if (!x->IsBurstable() || loopCall)
|
||||
return;
|
||||
|
||||
char data[MAXBUF];
|
||||
snprintf(data,MAXBUF,"%s %s %s %lu %lu :%s", x->type.c_str(), x->Displayable(),
|
||||
ServerInstance->Config->ServerName, (unsigned long)x->set_time, (unsigned long)x->duration, x->reason);
|
||||
std::deque<std::string> params;
|
||||
params.push_back(data);
|
||||
params.push_back(x->type);
|
||||
params.push_back(x->Displayable());
|
||||
params.push_back(ServerInstance->Config->ServerName);
|
||||
params.push_back(ConvToStr(x->set_time));
|
||||
params.push_back(ConvToStr(x->duration));
|
||||
params.push_back(":" + std::string(x->reason));
|
||||
|
||||
if (!user)
|
||||
{
|
||||
/* Server-set lines */
|
||||
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ADDLINE", params);
|
||||
}
|
||||
else if (IS_LOCAL(user))
|
||||
{
|
||||
/* User-set lines */
|
||||
Utils->DoOneToMany(user->uuid, "ADDLINE", params);
|
||||
}
|
||||
/* Server-set lines doesn't have a setter user */
|
||||
const std::string& source = user ? user->uuid : ServerInstance->Config->GetSID();
|
||||
Utils->DoOneToMany(source, "ADDLINE", params);
|
||||
}
|
||||
|
||||
void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
|
||||
@ -812,21 +743,13 @@ void ModuleSpanningTree::OnDelLine(User* user, XLine *x)
|
||||
if (!x->IsBurstable() || loopCall)
|
||||
return;
|
||||
|
||||
char data[MAXBUF];
|
||||
snprintf(data,MAXBUF,"%s %s", x->type.c_str(), x->Displayable());
|
||||
std::deque<std::string> params;
|
||||
params.push_back(data);
|
||||
params.push_back(x->type);
|
||||
params.push_back(x->Displayable());
|
||||
|
||||
if (!user)
|
||||
{
|
||||
/* Server-unset lines */
|
||||
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "DELLINE", params);
|
||||
}
|
||||
else if (IS_LOCAL(user))
|
||||
{
|
||||
/* User-unset lines */
|
||||
Utils->DoOneToMany(user->uuid, "DELLINE", params);
|
||||
}
|
||||
/* Server-set lines doesn't have a setter user */
|
||||
const std::string& source = user ? user->uuid : ServerInstance->Config->GetSID();
|
||||
Utils->DoOneToMany(source, "DELLINE", params);
|
||||
}
|
||||
|
||||
void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const std::deque<std::string> &text, const std::deque<TranslateType> &translate)
|
||||
@ -834,7 +757,6 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
|
||||
if ((IS_LOCAL(user)) && (user->registered == REG_ALL))
|
||||
{
|
||||
std::deque<std::string> params;
|
||||
std::string command;
|
||||
std::string output_text;
|
||||
|
||||
ServerInstance->Parser->TranslateUIDs(translate, text, output_text);
|
||||
@ -844,7 +766,7 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
|
||||
User* u = (User*)dest;
|
||||
params.push_back(u->uuid);
|
||||
params.push_back(output_text);
|
||||
command = "MODE";
|
||||
Utils->DoOneToMany(user->uuid, "MODE", params);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -852,10 +774,8 @@ void ModuleSpanningTree::OnMode(User* user, void* dest, int target_type, const s
|
||||
params.push_back(c->name);
|
||||
params.push_back(ConvToStr(c->age));
|
||||
params.push_back(output_text);
|
||||
command = "FMODE";
|
||||
Utils->DoOneToMany(user->uuid, "FMODE", params);
|
||||
}
|
||||
|
||||
Utils->DoOneToMany(user->uuid, command, params);
|
||||
}
|
||||
}
|
||||
|
||||
@ -863,18 +783,10 @@ int ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg)
|
||||
{
|
||||
if (IS_LOCAL(user))
|
||||
{
|
||||
if (awaymsg.empty())
|
||||
{
|
||||
std::deque<std::string> params;
|
||||
params.clear();
|
||||
Utils->DoOneToMany(user->uuid,"AWAY",params);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::deque<std::string> params;
|
||||
std::deque<std::string> params;
|
||||
if (!awaymsg.empty())
|
||||
params.push_back(":" + awaymsg);
|
||||
Utils->DoOneToMany(user->uuid,"AWAY",params);
|
||||
}
|
||||
Utils->DoOneToMany(user->uuid,"AWAY",params);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -58,6 +58,7 @@ class ModuleSpanningTree : public Module
|
||||
SpanningTreeUtilities* Utils;
|
||||
|
||||
void RedoConfig(Module* mod, const std::string &name);
|
||||
void LocalMessage(User* user, void* dest, int target_type, const std::string &text, char status, const CUList &exempt_list, const std::string& message_type);
|
||||
|
||||
public:
|
||||
CacheRefreshTimer *RefreshTimer;
|
||||
|
@ -48,7 +48,7 @@ bool TreeSocket::MetaData(const std::string &prefix, std::deque<std::string> &pa
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnDecodeMetaData,OnDecodeMetaData(TYPE_CHANNEL,c,params[1],params[2]));
|
||||
}
|
||||
}
|
||||
else if (*(params[0].c_str()) != '#')
|
||||
else
|
||||
{
|
||||
User* u = this->ServerInstance->FindNick(params[0]);
|
||||
if (u)
|
||||
|
@ -41,41 +41,35 @@ bool TreeSocket::Modules(const std::string &prefix, std::deque<std::string> &par
|
||||
}
|
||||
|
||||
char strbuf[MAXBUF];
|
||||
std::deque<std::string> par;
|
||||
par.push_back(prefix);
|
||||
par.push_back("");
|
||||
|
||||
User* source = this->ServerInstance->FindNick(prefix);
|
||||
if (!source)
|
||||
return true;
|
||||
|
||||
std::vector<std::string> module_names = ServerInstance->Modules->GetAllModuleNames(0);
|
||||
|
||||
for (unsigned int i = 0; i < module_names.size(); i++)
|
||||
for (std::vector<std::string>::const_iterator i = module_names.begin(); i != module_names.end(); ++i)
|
||||
{
|
||||
Module* m = ServerInstance->Modules->Find(module_names[i]);
|
||||
Module* m = ServerInstance->Modules->Find(*i);
|
||||
Version V = m->GetVersion();
|
||||
|
||||
if (IS_OPER(source))
|
||||
{
|
||||
std::string flags("Svsc");
|
||||
std::string flags("Svsc");
|
||||
int pos = 0;
|
||||
for (int mult = 1; mult <= VF_SERVICEPROVIDER; mult *= 2, ++pos)
|
||||
if (!(V.Flags & mult))
|
||||
flags[pos] = '-';
|
||||
|
||||
snprintf(strbuf, MAXBUF, "::%s 702 %s :0x%08lx %s %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(),(unsigned long)m, module_names[i].c_str(), flags.c_str(), V.version.c_str());
|
||||
snprintf(strbuf, MAXBUF, "::%s 702 %s :0x%08lx %s %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(),(unsigned long)m, i->c_str(), flags.c_str(), V.version.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(strbuf, MAXBUF, "::%s 702 %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(), module_names[i].c_str());
|
||||
snprintf(strbuf, MAXBUF, "::%s 702 %s :%s", ServerInstance->Config->ServerName, source->nick.c_str(), i->c_str());
|
||||
}
|
||||
par[1] = strbuf;
|
||||
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, std::string(strbuf));
|
||||
}
|
||||
snprintf(strbuf, MAXBUF, "::%s 703 %s :End of MODULES list", ServerInstance->Config->ServerName, source->nick.c_str());
|
||||
par[1] = strbuf;
|
||||
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, std::string(strbuf));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,33 +36,24 @@ bool TreeSocket::Motd(const std::string &prefix, std::deque<std::string> ¶ms
|
||||
if (InspIRCd::Match(this->ServerInstance->Config->ServerName, params[0]))
|
||||
{
|
||||
/* It's for our server */
|
||||
string_list results;
|
||||
User* source = this->ServerInstance->FindNick(prefix);
|
||||
|
||||
if (source)
|
||||
{
|
||||
std::deque<std::string> par;
|
||||
par.push_back(prefix);
|
||||
par.push_back("");
|
||||
|
||||
if (!ServerInstance->Config->MOTD.size())
|
||||
{
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing.";
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 422 "+source->nick+" :Message of the day file is missing.");
|
||||
return true;
|
||||
}
|
||||
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day";
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 375 "+source->nick+" :"+ServerInstance->Config->ServerName+" message of the day");
|
||||
|
||||
for (unsigned int i = 0; i < ServerInstance->Config->MOTD.size(); i++)
|
||||
std::string lineprefix = std::string("::") + ServerInstance->Config->ServerName + " 372 " + source->nick + " :- ";
|
||||
for (file_cache::const_iterator i = ServerInstance->Config->MOTD.begin(); i != ServerInstance->Config->MOTD.end(); ++i)
|
||||
{
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 372 "+source->nick+" :- "+ServerInstance->Config->MOTD[i];
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, lineprefix + *i);
|
||||
}
|
||||
|
||||
par[1] = std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day.";
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, std::string("::")+ServerInstance->Config->ServerName+" 376 "+source->nick+" :End of message of the day.");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -75,4 +66,3 @@ bool TreeSocket::Motd(const std::string &prefix, std::deque<std::string> ¶ms
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -36,15 +36,12 @@
|
||||
*/
|
||||
void TreeSocket::DoBurst(TreeServer* s)
|
||||
{
|
||||
std::string name = s->GetName();
|
||||
std::string burst = ":" + this->ServerInstance->Config->GetSID() + " BURST " +ConvToStr(ServerInstance->Time());
|
||||
std::string endburst = ":" + this->ServerInstance->Config->GetSID() + " ENDBURST";
|
||||
this->ServerInstance->SNO->WriteToSnoMask('l',"Bursting to \2%s\2 (Authentication: %s%s).",
|
||||
name.c_str(),
|
||||
s->GetName().c_str(),
|
||||
this->auth_fingerprint ? "SSL Fingerprint and " : "",
|
||||
this->auth_challenge ? "challenge-response" : "plaintext password");
|
||||
this->CleanNegotiationInfo();
|
||||
this->WriteLine(burst);
|
||||
this->WriteLine(":" + ServerInstance->Config->GetSID() + " BURST " + ConvToStr(ServerInstance->Time()));
|
||||
/* send our version string */
|
||||
this->WriteLine(std::string(":")+this->ServerInstance->Config->GetSID()+" VERSION :"+this->ServerInstance->GetVersionString());
|
||||
/* Send server tree */
|
||||
@ -55,8 +52,8 @@ void TreeSocket::DoBurst(TreeServer* s)
|
||||
this->SendChannelModes(s);
|
||||
this->SendXLines(s);
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnSyncOtherMetaData,OnSyncOtherMetaData((Module*)Utils->Creator,(void*)this));
|
||||
this->WriteLine(endburst);
|
||||
this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+name+"\2.");
|
||||
this->WriteLine(":" + ServerInstance->Config->GetSID() + " ENDBURST");
|
||||
this->ServerInstance->SNO->WriteToSnoMask('l',"Finished bursting to \2"+s->GetName()+"\2.");
|
||||
}
|
||||
|
||||
/** Recursively send the server tree with distances as hops.
|
||||
@ -229,9 +226,9 @@ void TreeSocket::SendChannelModes(TreeServer* Current)
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannel,OnSyncChannel(c->second,(Module*)Utils->Creator,(void*)this));
|
||||
list.clear();
|
||||
c->second->GetExtList(list);
|
||||
for (unsigned int j = 0; j < list.size(); j++)
|
||||
for (std::deque<std::string>::const_iterator i = list.begin(); i != list.end(); ++i)
|
||||
{
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannelMetaData,OnSyncChannelMetaData(c->second,(Module*)Utils->Creator,(void*)this,list[j]));
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnSyncChannelMetaData,OnSyncChannelMetaData(c->second,(Module*)Utils->Creator,(void*)this,*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -277,9 +274,9 @@ void TreeSocket::SendUsers(TreeServer* Current)
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnSyncUser,OnSyncUser(u->second,(Module*)Utils->Creator,(void*)this));
|
||||
list.clear();
|
||||
u->second->GetExtList(list);
|
||||
for (unsigned int j = 0; j < list.size(); j++)
|
||||
for (std::deque<std::string>::const_iterator i = list.begin(); i != list.end(); ++i)
|
||||
{
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnSyncUserMetaData,OnSyncUserMetaData(u->second,(Module*)Utils->Creator,(void*)this,list[j]));
|
||||
FOREACH_MOD_I(this->ServerInstance,I_OnSyncUserMetaData,OnSyncUserMetaData(u->second,(Module*)Utils->Creator,(void*)this,*i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,18 +78,17 @@ int ModuleSpanningTree::OnStats(char statschar, User* user, string_list &results
|
||||
if (statschar == 'p')
|
||||
{
|
||||
/* show all server ports, after showing client ports. -- w00t */
|
||||
|
||||
for (unsigned int i = 0; i < Utils->Bindings.size(); i++)
|
||||
for (std::vector<ServerSocketListener*>::const_iterator i = Utils->Bindings.begin(); i != Utils->Bindings.end(); ++i)
|
||||
{
|
||||
std::string ip = Utils->Bindings[i]->GetIP();
|
||||
std::string ip = (*i)->GetIP();
|
||||
if (ip.empty())
|
||||
ip = "*";
|
||||
|
||||
std::string transport("plaintext");
|
||||
if (Utils->Bindings[i]->GetIOHook())
|
||||
transport = BufferedSocketNameRequest(this, Utils->Bindings[i]->GetIOHook()).Send();
|
||||
if ((*i)->GetIOHook())
|
||||
transport = BufferedSocketNameRequest(this, (*i)->GetIOHook()).Send();
|
||||
|
||||
results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr(Utils->Bindings[i]->GetPort())+
|
||||
results.push_back(ConvToStr(ServerInstance->Config->ServerName) + " 249 "+user->nick+" :" + ip + ":" + ConvToStr((*i)->GetPort())+
|
||||
" (server, " + transport + ")");
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,6 @@ void ModuleSpanningTree::OnPostCommand(const std::string &command, const std::ve
|
||||
// to have any special provision in place for remote
|
||||
// commands and linking protocols.
|
||||
std::deque<std::string> params;
|
||||
params.clear();
|
||||
unsigned int n_translate = thiscmd->translation.size();
|
||||
TranslateType translate_to;
|
||||
|
||||
|
@ -48,7 +48,14 @@ void SpanningTreeProtocolInterface::GetServerList(ProtoServerList &sl)
|
||||
|
||||
void SpanningTreeProtocolInterface::SendEncapsulatedData(parameterlist &encap)
|
||||
{
|
||||
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ENCAP", encap);
|
||||
if (encap.size() < 2)
|
||||
return;
|
||||
|
||||
const std::string& target = encap[0];
|
||||
if (target.find_first_of("*?") == std::string::npos)
|
||||
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "ENCAP", encap, target);
|
||||
else
|
||||
Utils->DoOneToMany(ServerInstance->Config->GetSID(), "ENCAP", encap);
|
||||
}
|
||||
|
||||
void SpanningTreeProtocolInterface::SendMetaData(void* target, TargetTypeFlags type, const std::string &key, const std::string &data)
|
||||
@ -63,12 +70,10 @@ void SpanningTreeProtocolInterface::SendMetaData(void* target, TargetTypeFlags t
|
||||
case TYPE_CHANNEL:
|
||||
params.push_back(((Channel*)target)->name);
|
||||
break;
|
||||
case TYPE_OTHER:
|
||||
case TYPE_SERVER:
|
||||
params.push_back("*");
|
||||
break;
|
||||
default:
|
||||
throw CoreException("I don't know how to handle TYPE_OTHER.");
|
||||
break;
|
||||
}
|
||||
params.push_back(key);
|
||||
params.push_back(":" + data);
|
||||
@ -144,57 +149,32 @@ void SpanningTreeProtocolInterface::PushToClient(User* target, const std::string
|
||||
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", p, target->server);
|
||||
}
|
||||
|
||||
void SpanningTreeProtocolInterface::SendChannel(Channel* target, char status, const std::string &text)
|
||||
{
|
||||
std::string cname = target->name;
|
||||
if (status)
|
||||
cname = status + cname;
|
||||
TreeServerList list;
|
||||
CUList exempt_list;
|
||||
Utils->GetListOfServersForChannel(target,list,status,exempt_list);
|
||||
for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
|
||||
{
|
||||
TreeSocket* Sock = i->second->GetSocket();
|
||||
if (Sock)
|
||||
Sock->WriteLine(text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SpanningTreeProtocolInterface::SendChannelPrivmsg(Channel* target, char status, const std::string &text)
|
||||
{
|
||||
SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" PRIVMSG "+target->name+" :"+text);
|
||||
CUList exempt_list;
|
||||
Utils->SendChannelMessage(ServerInstance->Config->GetSID(), target, text, status, exempt_list, "PRIVMSG");
|
||||
}
|
||||
|
||||
void SpanningTreeProtocolInterface::SendChannelNotice(Channel* target, char status, const std::string &text)
|
||||
{
|
||||
SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" NOTICE "+target->name+" :"+text);
|
||||
CUList exempt_list;
|
||||
Utils->SendChannelMessage(ServerInstance->Config->GetSID(), target, text, status, exempt_list, "NOTICE");
|
||||
}
|
||||
|
||||
void SpanningTreeProtocolInterface::SendUserPrivmsg(User* target, const std::string &text)
|
||||
{
|
||||
TreeServer* serv = Utils->FindServer(target->server);
|
||||
if (serv)
|
||||
{
|
||||
TreeSocket* sock = serv->GetSocket();
|
||||
if (sock)
|
||||
{
|
||||
sock->WriteLine(":" + ServerInstance->Config->GetSID() + " PRIVMSG " + target->nick + " :"+text);
|
||||
}
|
||||
}
|
||||
parameterlist p;
|
||||
p.push_back(target->uuid);
|
||||
p.push_back(":" + text);
|
||||
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PRIVMSG", p, target->server);
|
||||
}
|
||||
|
||||
void SpanningTreeProtocolInterface::SendUserNotice(User* target, const std::string &text)
|
||||
{
|
||||
TreeServer* serv = Utils->FindServer(target->server);
|
||||
if (serv)
|
||||
{
|
||||
TreeSocket* sock = serv->GetSocket();
|
||||
if (sock)
|
||||
{
|
||||
sock->WriteLine(":" + ServerInstance->Config->GetSID() + " NOTICE " + target->nick + " :"+text);
|
||||
}
|
||||
}
|
||||
parameterlist p;
|
||||
p.push_back(target->uuid);
|
||||
p.push_back(":" + text);
|
||||
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "NOTICE", p, target->server);
|
||||
}
|
||||
|
||||
void SpanningTreeProtocolInterface::Introduce(User* user)
|
||||
|
@ -27,7 +27,6 @@ class SpanningTreeProtocolInterface : public ProtocolInterface
|
||||
{
|
||||
SpanningTreeUtilities* Utils;
|
||||
ModuleSpanningTree* Module;
|
||||
void SendChannel(Channel* target, char status, const std::string &text);
|
||||
public:
|
||||
SpanningTreeProtocolInterface(ModuleSpanningTree* mod, SpanningTreeUtilities* util, InspIRCd* Instance) : ProtocolInterface(Instance), Utils(util), Module(mod) { }
|
||||
virtual ~SpanningTreeProtocolInterface() { }
|
||||
|
@ -53,7 +53,11 @@ CmdResult CommandRSQuit::Handle (const std::vector<std::string>& parameters, Use
|
||||
|
||||
if (server_target == Utils->TreeRoot)
|
||||
{
|
||||
NoticeUser(user, "*** RSQUIT: Foolish mortal, you cannot make a server SQUIT itself! ("+parameters[0]+" matches local server name)");
|
||||
std::string msg = ":"+std::string(ServerInstance->Config->ServerName)+" NOTICE "+user->nick+" :*** RSQUIT: Foolish mortal, you cannot make a server SQUIT itself! ("+parameters[0]+" matches local server name)";
|
||||
if (IS_LOCAL(user))
|
||||
user->Write(msg);
|
||||
else
|
||||
ServerInstance->PI->PushToClient(user, ":" + msg);
|
||||
return CMD_FAILURE;
|
||||
}
|
||||
|
||||
@ -76,20 +80,3 @@ CmdResult CommandRSQuit::Handle (const std::vector<std::string>& parameters, Use
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
// XXX use protocol interface instead of rolling our own :)
|
||||
void CommandRSQuit::NoticeUser(User* user, const std::string &msg)
|
||||
{
|
||||
if (IS_LOCAL(user))
|
||||
{
|
||||
user->WriteServ("NOTICE %s :%s",user->nick.c_str(),msg.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::deque<std::string> params;
|
||||
params.push_back(user->nick);
|
||||
params.push_back("NOTICE "+ConvToStr(user->nick)+" :"+msg);
|
||||
Utils->DoOneToOne(ServerInstance->Config->GetSID(), "PUSH", params, user->server);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef __RSQUIT_H__
|
||||
#define __RSQUIT_H__
|
||||
|
||||
/** Handle /RCONNECT
|
||||
/** Handle /RSQUIT
|
||||
*/
|
||||
class CommandRSQuit : public Command
|
||||
{
|
||||
@ -29,7 +29,6 @@ class CommandRSQuit : public Command
|
||||
public:
|
||||
CommandRSQuit (InspIRCd* Instance, Module* Callback, SpanningTreeUtilities* Util);
|
||||
CmdResult Handle (const std::vector<std::string>& parameters, User *user);
|
||||
void NoticeUser(User* user, const std::string &msg);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -47,14 +47,10 @@ bool TreeSocket::Stats(const std::string &prefix, std::deque<std::string> ¶m
|
||||
User* source = this->ServerInstance->FindNick(prefix);
|
||||
if (source)
|
||||
{
|
||||
std::deque<std::string> par;
|
||||
par.push_back(prefix);
|
||||
par.push_back("");
|
||||
DoStats(this->ServerInstance, *(params[0].c_str()), source, results);
|
||||
for (size_t i = 0; i < results.size(); i++)
|
||||
for (string_list::const_iterator i = results.begin(); i != results.end(); ++i)
|
||||
{
|
||||
par[1] = "::" + results[i];
|
||||
Utils->DoOneToOne(this->ServerInstance->Config->GetSID(), "PUSH",par, source->server);
|
||||
ServerInstance->PI->PushToClient(source, "::" + *i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,18 @@ bool TreeSocket::ServiceJoin(const std::string &prefix, std::deque<std::string>
|
||||
/* only join if it's local, otherwise just pass it on! */
|
||||
if (IS_LOCAL(u))
|
||||
Channel::JoinUser(this->ServerInstance, u, params[1].c_str(), false, "", false, ServerInstance->Time());
|
||||
Utils->DoOneToAllButSender(prefix,"SVSJOIN",params,prefix);
|
||||
else
|
||||
{
|
||||
/* Only forward when the route to the target is not the same as the sender.
|
||||
* This occurs with 1.2.9 and older servers, as they broadcast SVSJOIN/SVSPART,
|
||||
* so we can end up here with a user who is reachable via the sender.
|
||||
* If that's the case, just drop the command.
|
||||
*/
|
||||
TreeServer* routeserver = Utils->BestRouteTo(u->server);
|
||||
if ((routeserver) && (routeserver->GetSocket() != this))
|
||||
Utils->DoOneToOne(prefix,"SVSJOIN",params,u->server);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -37,21 +37,30 @@ bool TreeSocket::ServicePart(const std::string &prefix, std::deque<std::string>
|
||||
if (params.size() < 2)
|
||||
return true;
|
||||
|
||||
std::string reason = "Services forced part";
|
||||
|
||||
if (params.size() == 3)
|
||||
reason = params[2];
|
||||
|
||||
User* u = this->ServerInstance->FindNick(params[0]);
|
||||
Channel* c = this->ServerInstance->FindChan(params[1]);
|
||||
|
||||
if (u)
|
||||
if (u && c)
|
||||
{
|
||||
/* only part if it's local, otherwise just pass it on! */
|
||||
if (IS_LOCAL(u))
|
||||
{
|
||||
std::string reason;
|
||||
reason = (params.size() == 3) ? params[2] : "Services forced part";
|
||||
if (!c->PartUser(u, reason))
|
||||
delete c;
|
||||
Utils->DoOneToAllButSender(prefix,"SVSPART",params,prefix);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Only forward when the route to the target is not the same as the sender.
|
||||
* This occurs with 1.2.9 and older servers, as they broadcast SVSJOIN/SVSPART,
|
||||
* so we can end up here with a user who is reachable via the sender.
|
||||
* If that's the case, just drop the command.
|
||||
*/
|
||||
TreeServer* routeserver = Utils->BestRouteTo(u->server);
|
||||
if ((routeserver) && (routeserver->GetSocket() != this))
|
||||
Utils->DoOneToOne(prefix,"SVSPART",params,u->server);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -38,7 +38,7 @@ bool TreeSocket::ParseUID(const std::string &source, std::deque<std::string> &pa
|
||||
*/
|
||||
if (params.size() < 10)
|
||||
{
|
||||
this->SendError("Invalid client introduction (wanted 10 or more parameters, got " + (params.empty() ? "0" : ConvToStr(params.size())) + "!)");
|
||||
this->SendError("Invalid client introduction (wanted 10 or more parameters, got " + ConvToStr(params.size()) + "!)");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -169,9 +169,9 @@ SpanningTreeUtilities::SpanningTreeUtilities(InspIRCd* Instance, ModuleSpanningT
|
||||
|
||||
SpanningTreeUtilities::~SpanningTreeUtilities()
|
||||
{
|
||||
for (unsigned int i = 0; i < Bindings.size(); i++)
|
||||
for (std::vector<ServerSocketListener*>::iterator i = Bindings.begin(); i != Bindings.end(); ++i)
|
||||
{
|
||||
delete Bindings[i];
|
||||
delete *i;
|
||||
}
|
||||
|
||||
while (TreeRoot->ChildCount())
|
||||
@ -300,10 +300,9 @@ bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const
|
||||
{
|
||||
TreeServer* omitroute = this->BestRouteTo(omit);
|
||||
std::string FullLine = ":" + prefix + " " + command;
|
||||
unsigned int words = params.size();
|
||||
for (unsigned int x = 0; x < words; x++)
|
||||
for (std::deque<std::string>::const_iterator i = params.begin(); i != params.end(); ++i)
|
||||
{
|
||||
FullLine = FullLine + " " + params[x];
|
||||
FullLine = FullLine + " " + *i;
|
||||
}
|
||||
unsigned int items = this->TreeRoot->ChildCount();
|
||||
for (unsigned int x = 0; x < items; x++)
|
||||
@ -326,10 +325,9 @@ bool SpanningTreeUtilities::DoOneToAllButSender(const std::string &prefix, const
|
||||
bool SpanningTreeUtilities::DoOneToMany(const std::string &prefix, const std::string &command, std::deque<std::string> ¶ms)
|
||||
{
|
||||
std::string FullLine = ":" + prefix + " " + command;
|
||||
unsigned int words = params.size();
|
||||
for (unsigned int x = 0; x < words; x++)
|
||||
for (std::deque<std::string>::const_iterator i = params.begin(); i != params.end(); ++i)
|
||||
{
|
||||
FullLine = FullLine + " " + params[x];
|
||||
FullLine = FullLine + " " + *i;
|
||||
}
|
||||
unsigned int items = this->TreeRoot->ChildCount();
|
||||
for (unsigned int x = 0; x < items; x++)
|
||||
@ -365,10 +363,9 @@ bool SpanningTreeUtilities::DoOneToOne(const std::string &prefix, const std::str
|
||||
if (Route)
|
||||
{
|
||||
std::string FullLine = ":" + prefix + " " + command;
|
||||
unsigned int words = params.size();
|
||||
for (unsigned int x = 0; x < words; x++)
|
||||
for (std::deque<std::string>::const_iterator i = params.begin(); i != params.end(); ++i)
|
||||
{
|
||||
FullLine = FullLine + " " + params[x];
|
||||
FullLine = FullLine + " " + *i;
|
||||
}
|
||||
if (Route && Route->GetSocket())
|
||||
{
|
||||
@ -472,9 +469,9 @@ void SpanningTreeUtilities::ReadConfiguration(bool rebind)
|
||||
|
||||
if (rebind)
|
||||
{
|
||||
for (unsigned int i = 0; i < Bindings.size(); i++)
|
||||
for (std::vector<ServerSocketListener*>::iterator i = Bindings.begin(); i != Bindings.end(); ++i)
|
||||
{
|
||||
delete Bindings[i];
|
||||
delete *i;
|
||||
}
|
||||
ServerInstance->BufferedSocketCull();
|
||||
Bindings.clear();
|
||||
@ -687,3 +684,20 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SpanningTreeUtilities::SendChannelMessage(const std::string& prefix, Channel* target, const std::string &text, char status, const CUList& exempt_list, const std::string& message_type)
|
||||
{
|
||||
std::string raw = ":" + prefix + " " + message_type + " ";
|
||||
if (status)
|
||||
raw.append(1, status);
|
||||
raw += target->name + " :" + text;
|
||||
|
||||
TreeServerList list;
|
||||
this->GetListOfServersForChannel(target, list, status, exempt_list);
|
||||
for (TreeServerList::iterator i = list.begin(); i != list.end(); ++i)
|
||||
{
|
||||
TreeSocket* Sock = i->second->GetSocket();
|
||||
if (Sock)
|
||||
Sock->WriteLine(raw);
|
||||
}
|
||||
}
|
||||
|
@ -222,6 +222,10 @@ class SpanningTreeUtilities : public classbase
|
||||
/** Refresh the IP cache used for allowing inbound connections
|
||||
*/
|
||||
void RefreshIPCache();
|
||||
|
||||
/** Sends a PRIVMSG or a NOTICE to a channel obeying an exempt list and an optional prefix
|
||||
*/
|
||||
void SendChannelMessage(const std::string& prefix, Channel* target, const std::string &text, char status, const CUList& exempt_list, const std::string& message_type);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user