]> git.stg.codes - stg.git/blob - projects/rscriptd/listener.h
Complete replacement notifiers with subscriptions.
[stg.git] / projects / rscriptd / listener.h
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  *    Author : Maxim Mamontov <faust@stargazer.dp.ua>
20  */
21
22 #include "stg/blowfish.h"
23 #include "stg/rs_packets.h"
24 #include "stg/logger.h"
25
26 #include <string>
27 #include <vector>
28 #include <list>
29 #include <functional>
30 #include <mutex>
31 #pragma GCC diagnostic push
32 #pragma GCC diagnostic ignored "-Wshadow"
33 #include <jthread.hpp>
34 #pragma GCC diagnostic pop
35 #include <cstdint>
36
37 struct UserData
38 {
39     std::string params;
40     std::string login;
41     uint32_t    ip;
42     uint32_t    id;
43 };
44
45 struct PendingData
46 {
47     UserData data;
48     enum {CONNECT, ALIVE, DISCONNECT} type;
49 };
50
51 struct AliveData
52 {
53     explicit AliveData(const UserData& ud)
54         : data(ud),
55           lastAlive(time(NULL))
56     {};
57     bool operator<(const std::string& rhs) const { return data.login < rhs; };
58     UserData data;
59     time_t lastAlive;
60 };
61
62 class LISTENER
63 {
64 public:
65                         LISTENER();
66                         ~LISTENER(){};
67
68     void                SetPort(uint16_t p) { port = p; };
69     void                SetPassword(const std::string & p);
70     void                SetUserTimeout(int t) { userTimeout = t; };
71     void                SetScriptOnConnect(const std::string & script) { scriptOnConnect = script; };
72     void                SetScriptOnDisconnect(const std::string & script) { scriptOnDisconnect = script; };
73
74     bool                Start();
75     bool                Stop();
76     bool                IsRunning() const { return !receiverStopped && !processorStopped; };
77
78     const std::string & GetStrError() const { return errorStr; };
79     const std::string & GetVersion() const { return version; };
80
81 private:
82     // Threading stuff
83     void                Run(std::stop_token token);
84     void                RunProcessor(std::stop_token token);
85     // Networking stuff
86     bool                PrepareNet();
87     bool                FinalizeNet();
88     bool                RecvPacket(const std::stop_token& token);
89     // Parsing stuff
90     bool                CheckHeader(const STG::RS::PACKET_HEADER & header) const;
91     bool                GetParams(char * buffer, UserData & data);
92     // Processing stuff
93     void                ProcessPending();
94     void                ProcessTimeouts();
95     bool                Disconnect(const AliveData& data) const;
96     bool                Connect(const PendingData& data) const;
97
98     BLOWFISH_CTX        ctxS;
99     STG::Logger&        WriteServLog;
100
101     mutable std::string errorStr;
102     std::string         scriptOnConnect;
103     std::string         scriptOnDisconnect;
104     std::string         password;
105     uint16_t            port;
106
107     bool                receiverStopped;
108     bool                processorStopped;
109     std::vector<AliveData> users;
110     std::vector<PendingData> pending;
111     int                 userTimeout;
112
113     std::jthread        m_receiverThread;
114     std::jthread        m_processorThread;
115     std::mutex          m_mutex;
116
117     int                 listenSocket;
118
119     std::string         version;
120 };