本文整理汇总了C++中parameterlist::size方法的典型用法代码示例。如果您正苦于以下问题:C++ parameterlist::size方法的具体用法?C++ parameterlist::size怎么用?C++ parameterlist::size使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类parameterlist
的用法示例。
在下文中一共展示了parameterlist::size方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: LocalPing
bool TreeSocket::LocalPing(const std::string &prefix, parameterlist ¶ms)
{
if (params.size() < 1)
return true;
if (params.size() == 1)
{
std::string stufftobounce = params[0];
this->WriteLine(":"+ServerInstance->Config->GetSID()+" PONG "+stufftobounce);
return true;
}
else
{
std::string forwardto = params[1];
if (forwardto == ServerInstance->Config->ServerName || forwardto == ServerInstance->Config->GetSID())
{
// this is a ping for us, send back PONG to the requesting server
params[1] = params[0];
params[0] = forwardto;
Utils->DoOneToOne(ServerInstance->Config->GetSID(),"PONG",params,params[1]);
}
else
{
// not for us, pass it on :)
Utils->DoOneToOne(prefix,"PING",params,forwardto);
}
return true;
}
}
示例2: DelLine
bool TreeSocket::DelLine(const std::string &prefix, parameterlist ¶ms)
{
if (params.size() < 2)
return true;
std::string setter = "<unknown>";
User* user = ServerInstance->FindNick(prefix);
if (user)
setter = user->nick;
else
{
TreeServer* t = Utils->FindServer(prefix);
if (t)
setter = t->GetName();
}
/* NOTE: No check needed on 'user', this function safely handles NULL */
if (ServerInstance->XLines->DelLine(params[1].c_str(), params[0], user))
{
ServerInstance->SNO->WriteToSnoMask('X',"%s removed %s%s on %s", setter.c_str(),
params[0].c_str(), params[0].length() == 1 ? "-line" : "", params[1].c_str());
Utils->DoOneToAllButSender(prefix,"DELLINE", params, prefix);
}
return true;
}
示例3: Inbound_Server
/*
* Someone else is attempting to connect to us if this is called. Validate their credentials etc.
* -- w
*/
bool TreeSocket::Inbound_Server(parameterlist ¶ms)
{
if (params.size() < 5)
{
SendError("Protocol error - Missing SID");
return false;
}
irc::string servername = params[0].c_str();
std::string sname = params[0];
std::string password = params[1];
std::string sid = params[3];
std::string description = params[4];
this->SendCapabilities(2);
if (!ServerInstance->IsSID(sid))
{
this->SendError("Invalid format server ID: "+sid+"!");
return false;
}
for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++)
{
Link* x = *i;
if (x->Name != servername && x->Name != "*") // open link allowance
continue;
if (!ComparePass(*x, password))
{
ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
continue;
}
if (!CheckDuplicate(sname, sid))
return false;
ServerInstance->SNO->WriteToSnoMask('l',"Verified incoming server connection " + linkID + " ("+description+")");
this->SendCapabilities(2);
// Save these for later, so when they accept our credentials (indicated by BURST) we remember them
this->capab->hidden = x->Hidden;
this->capab->sid = sid;
this->capab->description = description;
this->capab->name = sname;
// Send our details: Our server name and description and hopcount of 0,
// along with the sendpass from this block.
this->WriteLine("SERVER "+ServerInstance->Config->ServerName+" "+this->MakePass(x->SendPass, this->GetTheirChallenge())+" 0 "+ServerInstance->Config->GetSID()+" :"+ServerInstance->Config->ServerDesc);
// move to the next state, we are now waiting for THEM.
this->LinkState = WAIT_AUTH_2;
return true;
}
this->SendError("Invalid credentials");
ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials");
return false;
}
示例4: Encap
/** ENCAP */
void TreeSocket::Encap(User* who, parameterlist ¶ms)
{
if (params.size() > 1)
{
if (ServerInstance->Config->GetSID() == params[0] || InspIRCd::Match(ServerInstance->Config->ServerName, params[0]))
{
parameterlist plist(params.begin() + 2, params.end());
ServerInstance->Parser->CallHandler(params[1], plist, who);
// discard return value, ENCAP shall succeed even if the command does not exist
}
params[params.size() - 1] = ":" + params[params.size() - 1];
if (params[0].find_first_of("*?") != std::string::npos)
{
Utils->DoOneToAllButSender(who->uuid, "ENCAP", params, who->server);
}
else
Utils->DoOneToOne(who->uuid, "ENCAP", params, params[0]);
}
}
示例5: Away
bool TreeSocket::Away(const std::string &prefix, parameterlist ¶ms)
{
User* u = ServerInstance->FindNick(prefix);
if ((!u) || (IS_SERVER(u)))
return true;
if (params.size())
{
FOREACH_MOD(I_OnSetAway, OnSetAway(u, params[params.size() - 1]));
if (params.size() > 1)
u->awaytime = atoi(params[0].c_str());
else
u->awaytime = ServerInstance->Time();
u->awaymsg = params[params.size() - 1];
params[params.size() - 1] = ":" + params[params.size() - 1];
}
else
{
FOREACH_MOD(I_OnSetAway, OnSetAway(u, ""));
u->awaymsg.clear();
}
Utils->DoOneToAllButSender(prefix,"AWAY",params,u->server);
return true;
}
示例6: RemoteServer
/*
* Some server somewhere in the network introducing another server.
* -- w
*/
bool TreeSocket::RemoteServer(const std::string &prefix, parameterlist ¶ms)
{
if (params.size() < 5)
{
SendError("Protocol error - Not enough parameters for SERVER command");
return false;
}
std::string servername = params[0];
// password is not used for a remote server
// hopcount is not used (ever)
std::string sid = params[3];
std::string description = params[4];
TreeServer* ParentOfThis = Utils->FindServer(prefix);
if (!ParentOfThis)
{
this->SendError("Protocol error - Introduced remote server from unknown server "+prefix);
return false;
}
if (!ServerInstance->IsSID(sid))
{
this->SendError("Invalid format server ID: "+sid+"!");
return false;
}
TreeServer* CheckDupe = Utils->FindServer(servername);
if (CheckDupe)
{
this->SendError("Server "+servername+" already exists!");
ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+CheckDupe->GetName()+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, already exists. Closing link with " + ParentOfThis->GetName());
return false;
}
CheckDupe = Utils->FindServer(sid);
if (CheckDupe)
{
this->SendError("Server ID "+sid+" already exists! You may want to specify the server ID for the server manually with <server:id> so they do not conflict.");
ServerInstance->SNO->WriteToSnoMask('L', "Server \2"+servername+"\2 being introduced from \2" + ParentOfThis->GetName() + "\2 denied, server ID already exists on the network. Closing link with " + ParentOfThis->GetName());
return false;
}
Link* lnk = Utils->FindLink(servername);
TreeServer *Node = new TreeServer(Utils, servername, description, sid, ParentOfThis,NULL, lnk ? lnk->Hidden : false);
ParentOfThis->AddChild(Node);
params[4] = ":" + params[4];
Utils->DoOneToAllButSender(prefix,"SERVER",params,prefix);
ServerInstance->SNO->WriteToSnoMask('L', "Server \002"+ParentOfThis->GetName()+"\002 introduced server \002"+servername+"\002 ("+description+")");
return true;
}
示例7: Push
bool TreeSocket::Push(const std::string &prefix, parameterlist ¶ms)
{
if (params.size() < 2)
return true;
User* u = ServerInstance->FindNick(params[0]);
if (!u)
return true;
if (IS_LOCAL(u))
{
u->Write(params[1]);
}
else
{
// continue the raw onwards
params[1] = ":" + params[1];
Utils->DoOneToOne(prefix,"PUSH",params,u->server);
}
return true;
}
示例8: ForceNick
/**
* SAVE command - force nick change to UID on timestamp match
*/
bool TreeSocket::ForceNick(const std::string &prefix, parameterlist ¶ms)
{
if (params.size() < 2)
return true;
User* u = ServerInstance->FindNick(params[0]);
time_t ts = atol(params[1].c_str());
if ((u) && (!IS_SERVER(u)) && (u->age == ts))
{
Utils->DoOneToAllButSender(prefix,"SAVE",params,prefix);
if (!u->ForceNickChange(u->uuid.c_str()))
{
ServerInstance->Users->QuitUser(u, "Nickname collision");
}
}
return true;
}
示例9: Error
/* Handle ERROR command */
void TreeSocket::Error(parameterlist ¶ms)
{
std::string msg = params.size() ? params[0] : "";
SetError("received ERROR " + msg);
}
示例10: ProcessConnectedLine
void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, parameterlist& params)
{
User* who = ServerInstance->FindUUID(prefix);
std::string direction;
if (!who)
{
TreeServer* ServerSource = Utils->FindServer(prefix);
if (prefix.empty())
ServerSource = MyRoot;
if (ServerSource)
{
who = ServerSource->ServerUser;
}
else
{
/* It is important that we don't close the link here, unknown prefix can occur
* due to various race conditions such as the KILL message for a user somehow
* crossing the users QUIT further upstream from the server. Thanks jilles!
*/
if ((prefix.length() == UIDGenerator::UUID_LENGTH) && (isdigit(prefix[0])) &&
((command == "FMODE") || (command == "MODE") || (command == "KICK") || (command == "TOPIC") || (command == "KILL") || (command == "ADDLINE") || (command == "DELLINE")))
{
/* Special case, we cannot drop these commands as they've been committed already on a
* part of the network by the time we receive them, so in this scenario pretend the
* command came from a server to avoid desync.
*/
who = ServerInstance->FindUUID(prefix.substr(0, 3));
if (!who)
who = this->MyRoot->ServerUser;
}
else
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Command '%s' from unknown prefix '%s'! Dropping entire command.",
command.c_str(), prefix.c_str());
return;
}
}
}
// Make sure prefix is still good
direction = who->server;
prefix = who->uuid;
/*
* Check for fake direction here, and drop any instances that are found.
* What is fake direction? Imagine the following server setup:
* 0AA <-> 0AB <-> 0AC
* Fake direction would be 0AC sending a message to 0AB claiming to be from
* 0AA, or something similar. Basically, a message taking a path that *cannot*
* be correct.
*
* When would this be seen?
* Well, hopefully never. It could be caused by race conditions, bugs, or
* "miscreant" servers, though, so let's check anyway. -- w
*
* We also check here for totally invalid prefixes (prefixes that are neither
* a valid SID or a valid UUID, so that invalid UUID or SID never makes it
* to the higher level functions. -- B
*/
TreeServer* route_back_again = Utils->BestRouteTo(direction);
if ((!route_back_again) || (route_back_again->GetSocket() != this))
{
if (route_back_again)
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Protocol violation: Fake direction '%s' from connection '%s'",
prefix.c_str(),linkID.c_str());
return;
}
// Translate commands coming from servers using an older protocol
if (proto_version < ProtocolVersion)
{
if (!PreProcessOldProtocolMessage(who, command, params))
return;
}
ServerCommand* scmd = Utils->Creator->CmdManager.GetHandler(command);
CommandBase* cmdbase = scmd;
Command* cmd;
if (!scmd)
{
// Not a special server-to-server command
cmd = ServerInstance->Parser->GetHandler(command);
if (!cmd)
{
irc::stringjoiner pmlist(params);
ServerInstance->Logs->Log(MODNAME, LOG_SPARSE, "Unrecognised S2S command :%s %s %s",
who->uuid.c_str(), command.c_str(), pmlist.GetJoined().c_str());
SendError("Unrecognised command '" + command + "' -- possibly loaded mismatched modules");
return;
}
cmdbase = cmd;
}
if (params.size() < cmdbase->min_params)
{
irc::stringjoiner pmlist(params);
//.........这里部分代码省略.........
示例11: Outbound_Reply_Server
/*
* This is used after the other side of a connection has accepted our credentials.
* They are then introducing themselves to us, BEFORE either of us burst. -- w
*/
bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms)
{
if (params.size() < 5)
{
SendError("Protocol error - Not enough parameters for SERVER command");
return false;
}
irc::string servername = params[0].c_str();
std::string sname = params[0];
std::string password = params[1];
std::string sid = params[3];
std::string description = params[4];
int hops = atoi(params[2].c_str());
this->SendCapabilities(2);
if (hops)
{
this->SendError("Server too far away for authentication");
ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, server is too far away for authentication");
return false;
}
if (!ServerInstance->IsSID(sid))
{
this->SendError("Invalid format server ID: "+sid+"!");
return false;
}
for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++)
{
Link* x = *i;
if (x->Name != servername && x->Name != "*") // open link allowance
continue;
if (!ComparePass(*x, password))
{
ServerInstance->SNO->WriteToSnoMask('l',"Invalid password on link: %s", x->Name.c_str());
continue;
}
TreeServer* CheckDupe = Utils->FindServer(sname);
if (CheckDupe)
{
std::string pname = CheckDupe->GetParent() ? CheckDupe->GetParent()->GetName() : "<ourself>";
SendError("Server "+sname+" already exists on server "+pname+"!");
ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, already exists on server "+pname);
return false;
}
CheckDupe = Utils->FindServer(sid);
if (CheckDupe)
{
this->SendError("Server ID "+sid+" already exists on the network! You may want to specify the server ID for the server manually with <server:id> so they do not conflict.");
ServerInstance->SNO->WriteToSnoMask('l',"Server \2"+assign(servername)+"\2 being introduced denied, server ID already exists on the network. Closing link.");
return false;
}
/*
* They're in WAIT_AUTH_2 (having accepted our credentials).
* Set our state to CONNECTED (since everything's peachy so far) and send our
* netburst to them, which will trigger their CONNECTED state, and BURST in reply.
*
* While we're at it, create a treeserver object so we know about them.
* -- w
*/
this->LinkState = CONNECTED;
Utils->timeoutlist.erase(this);
linkID = sname;
MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden);
Utils->TreeRoot->AddChild(MyRoot);
this->DoBurst(MyRoot);
params[4] = ":" + params[4];
/* IMPORTANT: Take password/hmac hash OUT of here before we broadcast the introduction! */
params[1] = "*";
Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname);
return true;
}
this->SendError("Invalid credentials (check the other server's linking snomask for more information)");
ServerInstance->SNO->WriteToSnoMask('l',"Server connection from \2"+sname+"\2 denied, invalid link credentials");
return false;
}
示例12: ProcessConnectedLine
void TreeSocket::ProcessConnectedLine(std::string& prefix, std::string& command, parameterlist& params)
{
User* who = FindSource(prefix, command);
if (!who)
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Command '%s' from unknown prefix '%s'! Dropping entire command.", command.c_str(), prefix.c_str());
return;
}
/*
* Check for fake direction here, and drop any instances that are found.
* What is fake direction? Imagine the following server setup:
* 0AA <-> 0AB <-> 0AC
* Fake direction would be 0AC sending a message to 0AB claiming to be from
* 0AA, or something similar. Basically, a message taking a path that *cannot*
* be correct.
*
* When would this be seen?
* Well, hopefully never. It could be caused by race conditions, bugs, or
* "miscreant" servers, though, so let's check anyway. -- w
*
* We also check here for totally invalid prefixes (prefixes that are neither
* a valid SID or a valid UUID, so that invalid UUID or SID never makes it
* to the higher level functions. -- B
*/
TreeServer* const server = TreeServer::Get(who);
if (server->GetSocket() != this)
{
ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Protocol violation: Fake direction '%s' from connection '%s'", prefix.c_str(), linkID.c_str());
return;
}
// Translate commands coming from servers using an older protocol
if (proto_version < ProtocolVersion)
{
if (!PreProcessOldProtocolMessage(who, command, params))
return;
}
ServerCommand* scmd = Utils->Creator->CmdManager.GetHandler(command);
CommandBase* cmdbase = scmd;
Command* cmd = NULL;
if (!scmd)
{
// Not a special server-to-server command
cmd = ServerInstance->Parser.GetHandler(command);
if (!cmd)
{
if (command == "ERROR")
{
this->Error(params);
return;
}
throw ProtocolException("Unknown command");
}
cmdbase = cmd;
}
if (params.size() < cmdbase->min_params)
throw ProtocolException("Insufficient parameters");
if ((!params.empty()) && (params.back().empty()) && (!cmdbase->allow_empty_last_param))
{
// the last param is empty and the command handler doesn't allow that, check if there will be enough params if we drop the last
if (params.size()-1 < cmdbase->min_params)
return;
params.pop_back();
}
CmdResult res;
if (scmd)
res = scmd->Handle(who, params);
else
{
res = cmd->Handle(params, who);
if (res == CMD_INVALID)
throw ProtocolException("Error in command handler");
}
if (res == CMD_SUCCESS)
Utils->RouteCommand(server->GetRoute(), cmdbase, params, who);
}
示例13: ProcessConnectedLine
//.........这里部分代码省略.........
}
this->LocalPong(prefix,params);
}
else if (command == "VERSION")
{
this->ServerVersion(prefix,params);
}
else if (command == "ADDLINE")
{
this->AddLine(prefix,params);
}
else if (command == "DELLINE")
{
this->DelLine(prefix,params);
}
else if (command == "SAVE")
{
this->ForceNick(prefix,params);
}
else if (command == "OPERQUIT")
{
this->OperQuit(prefix,params);
}
else if (command == "IDLE")
{
this->Whois(prefix,params);
}
else if (command == "PUSH")
{
this->Push(prefix,params);
}
else if (command == "SQUIT")
{
if (params.size() == 2)
{
this->Squit(Utils->FindServer(params[0]),params[1]);
}
}
else if (command == "SNONOTICE")
{
if (params.size() >= 2)
{
ServerInstance->SNO->WriteToSnoMask(params[0][0], "From " + who->nick + ": "+ params[1]);
params[1] = ":" + params[1];
Utils->DoOneToAllButSender(prefix, command, params, prefix);
}
}
else if (command == "BURST")
{
// Set prefix server as bursting
TreeServer* ServerSource = Utils->FindServer(prefix);
if (!ServerSource)
{
ServerInstance->SNO->WriteGlobalSno('l', "WTF: Got BURST from a non-server(?): %s", prefix.c_str());
return;
}
ServerSource->bursting = true;
Utils->DoOneToAllButSender(prefix, command, params, prefix);
}
else if (command == "ENDBURST")
{
TreeServer* ServerSource = Utils->FindServer(prefix);
if (!ServerSource)
{
ServerInstance->SNO->WriteGlobalSno('l', "WTF: Got ENDBURST from a non-server(?): %s", prefix.c_str());
示例14: RouteCommand
void SpanningTreeUtilities::RouteCommand(TreeServer* origin, const std::string &command, const parameterlist& parameters, User *user)
{
if (!ServerInstance->Parser->IsValidCommand(command, parameters.size(), user))
return;
/* We know it's non-null because IsValidCommand returned true */
Command* thiscmd = ServerInstance->Parser->GetHandler(command);
RouteDescriptor routing = thiscmd->GetRouting(user, parameters);
std::string sent_cmd = command;
parameterlist params;
if (routing.type == ROUTE_TYPE_LOCALONLY)
{
/* Broadcast when it's a core command with the default route descriptor and the source is a
* remote user or a remote server
*/
Version ver = thiscmd->creator->GetVersion();
if ((!(ver.Flags & VF_CORE)) || (IS_LOCAL(user)) || (IS_SERVER(user) == ServerInstance->FakeClient))
return;
routing = ROUTE_BROADCAST;
}
else if (routing.type == ROUTE_TYPE_OPT_BCAST)
{
params.push_back("*");
params.push_back(command);
sent_cmd = "ENCAP";
}
else if (routing.type == ROUTE_TYPE_OPT_UCAST)
{
TreeServer* sdest = FindServer(routing.serverdest);
if (!sdest)
{
ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Trying to route ENCAP to nonexistant server %s",
routing.serverdest.c_str());
return;
}
params.push_back(sdest->GetID());
params.push_back(command);
sent_cmd = "ENCAP";
}
else
{
Module* srcmodule = thiscmd->creator;
Version ver = srcmodule->GetVersion();
if (!(ver.Flags & (VF_COMMON | VF_CORE)) && srcmodule != Creator)
{
ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Routed command %s from non-VF_COMMON module %s",
command.c_str(), srcmodule->ModuleSourceFile.c_str());
return;
}
}
std::string output_text;
ServerInstance->Parser->TranslateUIDs(thiscmd->translation, parameters, output_text, true, thiscmd);
params.push_back(output_text);
if (routing.type == ROUTE_TYPE_MESSAGE)
{
char pfx = 0;
std::string dest = routing.serverdest;
if (ServerInstance->Modes->FindPrefix(dest[0]))
{
pfx = dest[0];
dest = dest.substr(1);
}
if (dest[0] == '#')
{
Channel* c = ServerInstance->FindChan(dest);
if (!c)
return;
TreeServerList list;
// TODO OnBuildExemptList hook was here
GetListOfServersForChannel(c,list,pfx, CUList());
std::string data = ":" + user->uuid + " " + sent_cmd;
for (unsigned int x = 0; x < params.size(); x++)
data += " " + params[x];
for (TreeServerList::iterator i = list.begin(); i != list.end(); i++)
{
TreeSocket* Sock = (*i)->GetSocket();
if (origin && origin->GetSocket() == Sock)
continue;
if (Sock)
Sock->WriteLine(data);
}
}
else if (dest[0] == '$')
{
if (origin)
DoOneToAllButSender(user->uuid, sent_cmd, params, origin->GetName());
else
DoOneToMany(user->uuid, sent_cmd, params);
}
else
{
//.........这里部分代码省略.........
示例15: Handle
CmdResult CommandUID::Handle(const parameterlist ¶ms, User* serversrc)
{
SpanningTreeUtilities* Utils = ((ModuleSpanningTree*)(Module*)creator)->Utils;
/** Do we have enough parameters:
* 0 1 2 3 4 5 6 7 8 9 (n-1)
* UID uuid age nick host dhost ident ip.string signon +modes (modepara) :gecos
*/
time_t age_t = ConvToInt(params[1]);
time_t signon = ConvToInt(params[7]);
std::string empty;
const std::string& modestr = params[8];
TreeServer* remoteserver = Utils->FindServer(serversrc->server);
if (!remoteserver)
return CMD_INVALID;
/* Is this a valid UID, and not misrouted? */
if (params[0].length() != 9 || params[0].substr(0,3) != serversrc->uuid)
return CMD_INVALID;
/* Check parameters for validity before introducing the client, discovered by dmb */
if (!age_t)
return CMD_INVALID;
if (!signon)
return CMD_INVALID;
if (modestr[0] != '+')
return CMD_INVALID;
TreeSocket* sock = remoteserver->GetRoute()->GetSocket();
/* check for collision */
user_hash::iterator iter = ServerInstance->Users->clientlist->find(params[2]);
if (iter != ServerInstance->Users->clientlist->end())
{
/*
* Nick collision.
*/
int collide = sock->DoCollision(iter->second, age_t, params[5], params[6], params[0]);
ServerInstance->Logs->Log("m_spanningtree",LOG_DEBUG,"*** Collision on %s, collide=%d", params[2].c_str(), collide);
if (collide != 1)
{
/* remote client lost, make sure we change their nick for the hash too
*
* This alters the line that will be sent to other servers, which
* commands normally shouldn't do; hence the required const_cast.
*/
const_cast<parameterlist&>(params)[2] = params[0];
}
}
/* IMPORTANT NOTE: For remote users, we pass the UUID in the constructor. This automatically
* sets it up in the UUID hash for us.
*/
User* _new = NULL;
try
{
_new = new RemoteUser(params[0], remoteserver->GetName());
}
catch (...)
{
ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Duplicate UUID %s in client introduction", params[0].c_str());
return CMD_INVALID;
}
(*(ServerInstance->Users->clientlist))[params[2]] = _new;
_new->nick = params[2];
_new->host = params[3];
_new->dhost = params[4];
_new->ident = params[5];
_new->fullname = params[params.size() - 1];
_new->registered = REG_ALL;
_new->signon = signon;
_new->age = age_t;
unsigned int paramptr = 9;
// Accept more '+' chars, for now
std::string::size_type pos = modestr.find_first_not_of('+');
for (std::string::const_iterator v = modestr.begin()+pos; v != modestr.end(); ++v)
{
/* For each mode thats set, find the mode handler and set it on the new user */
ModeHandler* mh = ServerInstance->Modes->FindMode(*v, MODETYPE_USER);
if (!mh)
{
ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Unrecognised mode '%c' for a user in UID, dropping link", *v);
return CMD_INVALID;
}
if (mh->GetNumParams(true))
{
if (paramptr >= params.size() - 1)
return CMD_INVALID;
std::string mp = params[paramptr++];
/* IMPORTANT NOTE:
* All modes are assumed to succeed here as they are being set by a remote server.
* Modes CANNOT FAIL here. If they DO fail, then the failure is ignored. This is important
* to note as all but one modules currently cannot ever fail in this situation, except for
* m_servprotect which specifically works this way to prevent the mode being set ANYWHERE
* but here, at client introduction. You may safely assume this behaviour is standard and
* will not change in future versions if you want to make use of this protective behaviour
* yourself.
//.........这里部分代码省略.........