]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_spanningtree/compat.cpp
c14115bed1e3fceb90a3afade36bd02fe4eff3cf
[user/henk/code/inspircd.git] / src / modules / m_spanningtree / compat.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #include "inspircd.h"
21 #include "main.h"
22 #include "treesocket.h"
23
24 static std::string newline("\n");
25
26 void TreeSocket::WriteLine(std::string line)
27 {
28         if (LinkState == CONNECTED)
29         {
30                 if (line[0] != ':')
31                 {
32                         ServerInstance->Logs->Log("m_spanningtree", LOG_DEFAULT, "Sending line without server prefix!");
33                         line = ":" + ServerInstance->Config->GetSID() + " " + line;
34                 }
35                 if (proto_version != ProtocolVersion)
36                 {
37                         std::string::size_type a = line.find(' ');
38                         std::string::size_type b = line.find(' ', a + 1);
39                         std::string command = line.substr(a + 1, b-a-1);
40                         // now try to find a translation entry
41                         // TODO a more efficient lookup method will be needed later
42                         if (proto_version < 1205)
43                         {
44                                 if (command == "IJOIN")
45                                 {
46                                         // Convert
47                                         // :<uid> IJOIN <chan> [<ts> [<flags>]]
48                                         // to
49                                         // :<sid> FJOIN <chan> <ts> + [<flags>],<uuid>
50                                         std::string::size_type c = line.find(' ', b + 1);
51                                         if (c == std::string::npos)
52                                         {
53                                                 // No TS or modes in the command
54                                                 // :22DAAAAAB IJOIN #chan
55                                                 const std::string channame = line.substr(b+1, c-b-1);
56                                                 Channel* chan = ServerInstance->FindChan(channame);
57                                                 if (!chan)
58                                                         return;
59
60                                                 line.push_back(' ');
61                                                 line.append(ConvToStr(chan->age));
62                                                 line.append(" + ,");
63                                         }
64                                         else
65                                         {
66                                                 std::string::size_type d = line.find(' ', c + 1);
67                                                 if (d == std::string::npos)
68                                                 {
69                                                         // TS present, no modes
70                                                         // :22DAAAAAC IJOIN #chan 12345
71                                                         line.append(" + ,");
72                                                 }
73                                                 else
74                                                 {
75                                                         // Both TS and modes are present
76                                                         // :22DAAAAAC IJOIN #chan 12345 ov
77                                                         std::string::size_type e = line.find(' ', d + 1);
78                                                         if (e != std::string::npos)
79                                                                 line.erase(e);
80
81                                                         line.insert(d, " +");
82                                                         line.push_back(',');
83                                                 }
84                                         }
85
86                                         // Move the uuid to the end and replace the I with an F
87                                         line.append(line.substr(1, 9));
88                                         line.erase(4, 6);
89                                         line[5] = 'F';
90                                 }
91                                 else if (command == "RESYNC")
92                                         return;
93                                 else if (command == "METADATA")
94                                 {
95                                         // Drop TS for channel METADATA
96                                         // :sid METADATA #target TS extname ...
97                                         //     A        B       C  D
98                                         if (b == std::string::npos)
99                                                 return;
100
101                                         std::string::size_type c = line.find(' ', b + 1);
102                                         if (c == std::string::npos)
103                                                 return;
104
105                                         if (line[b + 1] == '#')
106                                         {
107                                                 // We're sending channel metadata
108                                                 std::string::size_type d = line.find(' ', c + 1);
109                                                 if (d == std::string::npos)
110                                                         return;
111
112                                                 line.erase(c, d-c);
113                                         }
114                                 }
115                         }
116                 }
117         }
118
119         ServerInstance->Logs->Log("m_spanningtree", LOG_RAWIO, "S[%d] O %s", this->GetFd(), line.c_str());
120         this->WriteData(line);
121         this->WriteData(newline);
122 }
123
124 namespace
125 {
126         bool InsertCurrentChannelTS(std::vector<std::string>& params)
127         {
128                 Channel* chan = ServerInstance->FindChan(params[0]);
129                 if (!chan)
130                         return false;
131
132                 // Insert the current TS of the channel between the first and the second parameters
133                 params.insert(params.begin()+1, ConvToStr(chan->age));
134                 return true;
135         }
136 }
137
138 bool TreeSocket::PreProcessOldProtocolMessage(User*& who, std::string& cmd, std::vector<std::string>& params)
139 {
140         if ((cmd == "METADATA") && (params.size() >= 3))
141         {
142                 // :20D METADATA #channel extname :extdata
143                 return InsertCurrentChannelTS(params);
144         }
145
146         return true; // Passthru
147 }