-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnickserv.h
More file actions
169 lines (136 loc) · 3.5 KB
/
nickserv.h
File metadata and controls
169 lines (136 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/**
* COPYRIGHT 2014 (C) Jason Volk
* COPYRIGHT 2014 (C) Svetlana Tkachenko
*
* DISTRIBUTED UNDER THE GNU GENERAL PUBLIC LICENSE (GPL) (see: LICENSE)
*/
class NickServ : public Service
{
Users &users;
Chans &chans;
Events &events;
void handle_identified(const Capture &capture);
void handle_listchans(const Capture &capture);
void handle_info(const Capture &capture);
void captured(const Capture &capture) override; // Fully collected messages from Service
NickServ &operator<<(const flush_t f) override;
public:
void identify(const std::string &acct, const std::string &pass);
void regain(const std::string &nick, const std::string &pass = "");
void ghost(const std::string &nick, const std::string &pass);
void listchans();
NickServ(Users &users, Chans &chans, Events &events);
};
inline
NickServ::NickServ(Users &users,
Chans &chans,
Events &events):
Service("NickServ"),
users(users),
chans(chans),
events(events)
{
}
inline
void NickServ::listchans()
{
Stream &out(*this);
out << "LISTCHANS" << flush;
terminator_next("channel access match");
}
inline
void NickServ::identify(const std::string &acct,
const std::string &pass)
{
Stream &out(*this);
out << "identify" << " " << acct << " " << pass << flush;
terminator_next("You are now identified");
}
inline
void NickServ::ghost(const std::string &nick,
const std::string &pass)
{
Stream &out(*this);
out << "ghost" << " " << nick << " " << pass << flush;
terminator_any();
}
inline
void NickServ::regain(const std::string &nick,
const std::string &pass)
{
Stream &out(*this);
out << "regain" << " " << nick << " " << pass << flush;
terminator_any();
}
inline
void NickServ::captured(const Capture &msg)
{
const auto &header(msg.front());
if(header.find("Information on") == 0)
handle_info(msg);
else if(header.find("Access flag(s)") == 0)
handle_listchans(msg);
else if(header.find("You are now identified") == 0)
handle_identified(msg);
else
throw Exception("Unhandled NickServ capture.");
}
inline
void NickServ::handle_info(const Capture &msg)
{
const auto tok(tokens(msg.front()));
const auto &name(tolower(tok.at(2)));
const auto &primary(tolower(tok.at(4).substr(0,tok.at(4).size()-2))); // Chop off "):]"
Acct acct(&name);
Adoc info(acct.get("info"));
info.put("account",primary);
info.put("_fetched_",time(NULL));
auto it(msg.begin());
for(++it; it != msg.end(); ++it)
{
const auto kv(split(*it," : "));
const auto &key(chomp(chomp(kv.first),"."));
const auto &val(kv.second);
info.put(key,val);
}
acct.set("info",info);
}
inline
void NickServ::handle_listchans(const Capture &msg)
{
auto &sess(get_sess());
for(const auto &line : msg)
{
const auto tok(tokens(line));
const Mode flags(tok.at(2).substr(1)); // chop leading +
const auto chan(tok.at(4));
sess.access[chan] = flags;
}
// Automatically join the channels where we have access
if(sess.has_opt("as-a-service") && (!sess.has_opt("cloaked") || sess.is(CLOAKED)))
chans.servicejoin();
}
inline
void NickServ::handle_identified(const Capture &capture)
{
auto &sess(get_sess());
sess.set(IDENTIFIED);
}
inline
NickServ &NickServ::operator<<(const flush_t)
{
const scope clear([&]
{
Stream::clear();
});
Quote ns("ns");
ns << get_str() << flush;
return *this;
}
inline
std::ostream &operator<<(std::ostream &s,
const NickServ &ns)
{
s << dynamic_cast<const Service &>(ns) << std::endl;
return s;
}