File: modules_online.cpp

package info (click to toggle)
znc 1.10.1-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 12,164 kB
  • sloc: cpp: 58,072; javascript: 11,859; python: 1,635; perl: 1,229; tcl: 219; sh: 200; ansic: 187; makefile: 82
file content (117 lines) | stat: -rw-r--r-- 3,859 bytes parent folder | download
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
/*
 * Copyright (C) 2004-2025 ZNC, see the NOTICE file for details.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <znc/User.h>
#include <znc/IRCNetwork.h>
#include <znc/znc.h>

class CFOModule : public CModule {
  public:
    MODCONSTRUCTOR(CFOModule) {}
    ~CFOModule() override {}

    bool IsOnlineModNick(const CString& sNick) {
        const CString& sPrefix = GetUser()->GetStatusPrefix();
        if (!sNick.StartsWith(sPrefix)) return false;

        CString sModNick = sNick.substr(sPrefix.length());
        if (sModNick.Equals("status") ||
            GetNetwork()->GetModules().FindModule(sModNick) ||
            GetUser()->GetModules().FindModule(sModNick) ||
            CZNC::Get().GetModules().FindModule(sModNick))
            return true;
        return false;
    }

    EModRet OnUserRaw(CString& sLine) override {
        // Handle ISON
        if (sLine.Token(0).Equals("ison")) {
            VCString vsNicks;

            // Get the list of nicks which are being asked for
            sLine.Token(1, true).TrimLeft_n(":").Split(" ", vsNicks, false);

            CString sBNCNicks;
            for (const CString& sNick : vsNicks) {
                if (IsOnlineModNick(sNick)) {
                    sBNCNicks += " " + sNick;
                }
            }
            // Remove the leading space
            sBNCNicks.LeftChomp();

            if (!GetNetwork()->GetIRCSock()) {
                // if we are not connected to any IRC server, send
                // an empty or module-nick filled response.
                PutUser(":irc.znc.in 303 " + GetClient()->GetNick() + " :" +
                        sBNCNicks);
            } else {
                // We let the server handle this request and then act on
                // the 303 response from the IRC server.
                m_ISONRequests.push_back(sBNCNicks);
            }
        }

        // Handle WHOIS
        if (sLine.Token(0).Equals("whois")) {
            CString sNick = sLine.Token(1);

            if (IsOnlineModNick(sNick)) {
                CIRCNetwork* pNetwork = GetNetwork();
                PutUser(":znc.in 311 " + pNetwork->GetCurNick() + " " + sNick +
                        " znc znc.in * :" + sNick);
                PutUser(":znc.in 312 " + pNetwork->GetCurNick() + " " + sNick +
                        " *.znc.in :Bouncer");
                PutUser(":znc.in 318 " + pNetwork->GetCurNick() + " " + sNick +
                        " :End of /WHOIS list.");

                return HALT;
            }
        }

        return CONTINUE;
    }

    EModRet OnRaw(CString& sLine) override {
        // Handle 303 reply if m_Requests is not empty
        if (sLine.Token(1) == "303" && !m_ISONRequests.empty()) {
            VCString::iterator it = m_ISONRequests.begin();

            sLine.Trim();

            // Only append a space if this isn't an empty reply
            if (sLine.Right(1) != ":") {
                sLine += " ";
            }

            // add BNC nicks to the reply
            sLine += *it;
            m_ISONRequests.erase(it);
        }

        return CONTINUE;
    }

  private:
    VCString m_ISONRequests;
};

template <>
void TModInfo<CFOModule>(CModInfo& Info) {
    Info.SetWikiPage("modules_online");
}

NETWORKMODULEDEFS(CFOModule, t_s("Makes ZNC's *modules to be \"online\"."))