if (command == "IJOIN")
{
// Convert
- // :<uid> IJOIN <chan> [<ts> [<flags>]]
+ // :<uid> IJOIN <chan> <membid> [<ts> [<flags>]]
// to
// :<sid> FJOIN <chan> <ts> + [<flags>],<uuid>
std::string::size_type c = line.find(' ', b + 1);
if (c == std::string::npos)
+ return;
+
+ std::string::size_type d = line.find(' ', c + 1);
+ // Erase membership id first
+ line.erase(c, d-c);
+ if (d == std::string::npos)
{
// No TS or modes in the command
// :22DAAAAAB IJOIN #chan
}
else
{
- std::string::size_type d = line.find(' ', c + 1);
+ d = line.find(' ', c + 1);
if (d == std::string::npos)
{
// TS present, no modes
// If there is no expiration time then everything will be erased from 'd'
line.erase(d, e-d);
}
+ else if (command == "FJOIN")
+ {
+ // Strip membership ids
+ // :22D FJOIN #chan 1234 +f 4:3 :o,22DAAAAAB:15 o,22DAAAAAA:15
+ // :22D FJOIN #chan 1234 +f 4:3 o,22DAAAAAB:15
+ // :22D FJOIN #chan 1234 +Pf 4:3 :
+
+ // If the last parameter is prefixed by a colon then it's a userlist which may have 0 or more users;
+ // if it isn't, then it is a single member
+ std::string::size_type spcolon = line.find(" :");
+ if (spcolon != std::string::npos)
+ {
+ spcolon++;
+ // Loop while there is a ':' in the userlist, this is never true if the channel is empty
+ std::string::size_type pos = std::string::npos;
+ while ((pos = line.rfind(':', pos-1)) > spcolon)
+ {
+ // Find the next space after the ':'
+ std::string::size_type sp = line.find(' ', pos);
+ // Erase characters between the ':' and the next space after it, including the ':' but not the space;
+ // if there is no next space, everything will be erased between pos and the end of the line
+ line.erase(pos, sp-pos);
+ }
+ }
+ else
+ {
+ // Last parameter is a single member
+ std::string::size_type sp = line.rfind(' ');
+ std::string::size_type colon = line.find(':', sp);
+ line.erase(colon);
+ }
+ }
+ else if (command == "KICK")
+ {
+ // Strip membership id if the KICK has one
+ if (b == std::string::npos)
+ return;
+
+ std::string::size_type c = line.find(' ', b + 1);
+ if (c == std::string::npos)
+ return;
+
+ std::string::size_type d = line.find(' ', c + 1);
+ if ((d < line.size()-1) && (original_line[d+1] != ':'))
+ {
+ // There is a third parameter which doesn't begin with a colon, erase it
+ std::string::size_type e = line.find(' ', d + 1);
+ line.erase(d, e-d);
+ }
+ }
+ else if (command == "SINFO")
+ {
+ // :22D SINFO version :InspIRCd-2.2
+ // A B C
+ std::string::size_type c = line.find(' ', b + 1);
+ if (c == std::string::npos)
+ return;
+
+ // Only translating SINFO version, discard everything else
+ if (line.compare(b, 9, " version ", 9))
+ return;
+
+ line = line.substr(0, 5) + "VERSION" + line.substr(c);
+ }
}
ServerInstance->Logs->Log(MODNAME, LOG_RAWIO, "S[%d] O %s", this->GetFd(), line.c_str());
this->WriteData(line);
// Insert channel timestamp after the channel name; the 3rd parameter, if there, is the invite expiration time
return InsertCurrentChannelTS(params, 1, 2);
}
+ else if (cmd == "VERSION")
+ {
+ // :20D VERSION :InspIRCd-2.0
+ // change to
+ // :20D SINFO version :InspIRCd-2.0
+ cmd = "SINFO";
+ params.insert(params.begin(), "version");
+ }
return true; // Passthru
}