]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_spanningtree/compat.cpp
Merge insp20
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / compat.cpp
index 9561442b5c4ac70bf1b625269ca2b7ab074976d2..1d573b8b426454b8380542b18cbdf17324b898b7 100644 (file)
 
 static std::string newline("\n");
 
-void TreeSocket::WriteLine(std::string line)
+void TreeSocket::WriteLine(const std::string& original_line)
 {
        if (LinkState == CONNECTED)
        {
-               if (line[0] != ':')
+               if (original_line.c_str()[0] != ':')
                {
-                       ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Sending line without server prefix!");
-                       line = ":" + ServerInstance->Config->GetSID() + " " + line;
+                       ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Sending line without server prefix!");
+                       WriteLine(":" + ServerInstance->Config->GetSID() + " " + original_line);
+                       return;
                }
                if (proto_version != ProtocolVersion)
                {
+                       std::string line = original_line;
                        std::string::size_type a = line.find(' ');
                        std::string::size_type b = line.find(' ', a + 1);
                        std::string command = line.substr(a + 1, b-a-1);
@@ -93,7 +95,7 @@ void TreeSocket::WriteLine(std::string line)
                                        return;
                                else if (command == "METADATA")
                                {
-                                       // Drop TS for channel METADATA
+                                       // Drop TS for channel METADATA, translate METADATA operquit into an OPERQUIT command
                                        // :sid METADATA #target TS extname ...
                                        //     A        B       C  D
                                        if (b == std::string::npos)
@@ -103,21 +105,28 @@ void TreeSocket::WriteLine(std::string line)
                                        if (c == std::string::npos)
                                                return;
 
+                                       std::string::size_type d = line.find(' ', c + 1);
+                                       if (d == std::string::npos)
+                                               return;
+
                                        if (line[b + 1] == '#')
                                        {
                                                // We're sending channel metadata
-                                               std::string::size_type d = line.find(' ', c + 1);
-                                               if (d == std::string::npos)
-                                                       return;
-
                                                line.erase(c, d-c);
                                        }
+                                       else if (line.substr(c, d-c) == " operquit")
+                                       {
+                                               // ":22D METADATA 22DAAAAAX operquit :message" -> ":22DAAAAAX OPERQUIT :message"
+                                               line = ":" + line.substr(b+1, c-b) + "OPERQUIT" + line.substr(d);
+                                       }
                                }
                                else if (command == "FTOPIC")
                                {
                                        // Drop channel TS for FTOPIC
-                                       // :sid FTOPIC #target TS TopicTS ...
-                                       //     A      B       C  D
+                                       // :sid FTOPIC #target TS TopicTS setter :newtopic
+                                       //     A      B       C  D       E      F
+                                       // :uid FTOPIC #target TS TopicTS :newtopic
+                                       //     A      B       C  D       E
                                        if (b == std::string::npos)
                                                return;
 
@@ -129,7 +138,14 @@ void TreeSocket::WriteLine(std::string line)
                                        if (d == std::string::npos)
                                                return;
 
-                                       line.erase(c, d-c);
+                                       std::string::size_type e = line.find(' ', d + 1);
+                                       if (line[e+1] == ':')
+                                       {
+                                               line.erase(c, e-c);
+                                               line.erase(a+1, 1);
+                                       }
+                                       else
+                                               line.erase(c, d-c);
                                }
                                else if ((command == "PING") || (command == "PONG"))
                                {
@@ -154,11 +170,15 @@ void TreeSocket::WriteLine(std::string line)
                                        }
                                }
                        }
+                       ServerInstance->Logs->Log(MODNAME, LOG_RAWIO, "S[%d] O %s", this->GetFd(), line.c_str());
+                       this->WriteData(line);
+                       this->WriteData(newline);
+                       return;
                }
        }
 
-       ServerInstance->Logs->Log("m_spanningtree", LOG_RAWIO, "S[%d] O %s", this->GetFd(), line.c_str());
-       this->WriteData(line);
+       ServerInstance->Logs->Log(MODNAME, LOG_RAWIO, "S[%d] O %s", this->GetFd(), original_line.c_str());
+       this->WriteData(original_line);
        this->WriteData(newline);
 }
 
@@ -178,7 +198,7 @@ namespace
 
 bool TreeSocket::PreProcessOldProtocolMessage(User*& who, std::string& cmd, std::vector<std::string>& params)
 {
-       if ((cmd == "METADATA") && (params.size() >= 3))
+       if ((cmd == "METADATA") && (params.size() >= 3) && (params[0][0] == '#'))
        {
                // :20D METADATA #channel extname :extdata
                return InsertCurrentChannelTS(params);
@@ -212,7 +232,7 @@ bool TreeSocket::PreProcessOldProtocolMessage(User*& who, std::string& cmd, std:
                        if (!server)
                        {
                                // We've no idea what this is, log and stop processing
-                               ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Received a " + cmd + " with an unknown target: \"" + params[0] + "\", command dropped");
+                               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Received a " + cmd + " with an unknown target: \"" + params[0] + "\", command dropped");
                                return false;
                        }
 
@@ -242,6 +262,41 @@ bool TreeSocket::PreProcessOldProtocolMessage(User*& who, std::string& cmd, std:
 
                params.swap(p);
        }
+       else if (cmd == "SVSMODE")
+       {
+               cmd = "MODE";
+       }
+       else if (cmd == "OPERQUIT")
+       {
+               // Translate OPERQUIT into METADATA
+               if (params.empty())
+                       return false;
+
+               cmd = "METADATA";
+               params.insert(params.begin(), who->uuid);
+               params.insert(params.begin()+1, "operquit");
+               who = MyRoot->ServerUser;
+       }
+       else if ((cmd == "TOPIC") && (params.size() >= 2))
+       {
+               // :20DAAAAAC TOPIC #chan :new topic
+               cmd = "FTOPIC";
+               if (!InsertCurrentChannelTS(params))
+                       return false;
+
+               params.insert(params.begin()+2, ConvToStr(ServerInstance->Time()));
+       }
+       else if (cmd == "MODENOTICE")
+       {
+               // MODENOTICE is always supported by 2.0 but it's optional in 2.2.
+               params.insert(params.begin(), "*");
+               params.insert(params.begin()+1, cmd);
+               cmd = "ENCAP";
+       }
+       else if (cmd == "RULES")
+       {
+               return false;
+       }
 
        return true; // Passthru
 }