]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/coremods/core_channel/invite.cpp
Rewrite invite system
[user/henk/code/inspircd.git] / src / coremods / core_channel / invite.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2012, 2015 Attila Molnar <attilamolnar@hush.com>
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
22 #include "invite.h"
23
24 class InviteExpireTimer : public Timer
25 {
26         Invite::Invite* const inv;
27
28         bool Tick(time_t currtime) CXX11_OVERRIDE;
29
30  public:
31         InviteExpireTimer(Invite::Invite* invite, time_t timeout);
32 };
33
34 static Invite::APIImpl* apiimpl;
35
36 void RemoveInvite(Invite::Invite* inv, bool remove_user, bool remove_chan)
37 {
38         apiimpl->Destruct(inv, remove_user, remove_chan);
39 }
40
41 Invite::APIBase::APIBase(Module* parent)
42         : DataProvider(parent, "core_channel_invite")
43 {
44 }
45
46 Invite::APIImpl::APIImpl(Module* parent)
47         : APIBase(parent)
48         , userext(parent, "invite_user")
49         , chanext(parent, "invite_chan")
50 {
51         apiimpl = this;
52 }
53
54 void Invite::APIImpl::Destruct(Invite* inv, bool remove_user, bool remove_chan)
55 {
56         Store<LocalUser>* ustore = userext.get(inv->user);
57         if (ustore)
58         {
59                 ustore->invites.erase(inv);
60                 if ((remove_user) && (ustore->invites.empty()))
61                         userext.unset(inv->user);
62         }
63
64         Store<Channel>* cstore = chanext.get(inv->chan);
65         if (cstore)
66         {
67                 cstore->invites.erase(inv);
68                 if ((remove_chan) && (cstore->invites.empty()))
69                         chanext.unset(inv->chan);
70         }
71
72         delete inv;
73 }
74
75 bool Invite::APIImpl::Remove(LocalUser* user, Channel* chan)
76 {
77         Invite* inv = Find(user, chan);
78         if (inv)
79         {
80                 Destruct(inv);
81                 return true;
82         }
83         return false;
84 }
85
86 void Invite::APIImpl::Create(LocalUser* user, Channel* chan, time_t timeout)
87 {
88         if ((timeout != 0) && (ServerInstance->Time() >= timeout))
89                 // Expired, don't bother
90                 return;
91
92         ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::APIImpl::Create(): user=%s chan=%s timeout=%lu", user->uuid.c_str(), chan->name.c_str(), (unsigned long)timeout);
93
94         Invite* inv = Find(user, chan);
95         if (inv)
96         {
97                 // We only ever extend invites, so nothing to do if the existing one is not timed
98                 if (!inv->IsTimed())
99                         return;
100
101                 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::APIImpl::Create(): changing expiration in %p", (void*) inv);
102                 if (timeout == 0)
103                 {
104                         // Convert timed invite to non-expiring
105                         delete inv->expiretimer;
106                         inv->expiretimer = NULL;
107                 }
108                 else if (inv->expiretimer->GetTrigger() >= ServerInstance->Time() + timeout)
109                 {
110                         // New expiration time is further than the current, extend the expiration
111                         inv->expiretimer->SetInterval(timeout - ServerInstance->Time());
112                 }
113         }
114         else
115         {
116                 inv = new Invite(user, chan);
117                 if (timeout)
118                 {
119                         inv->expiretimer = new InviteExpireTimer(inv, timeout - ServerInstance->Time());
120                         ServerInstance->Timers.AddTimer(inv->expiretimer);
121                 }
122
123                 userext.get(user, true)->invites.push_front(inv);
124                 chanext.get(chan, true)->invites.push_front(inv);
125                 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::APIImpl::Create(): created new Invite %p", (void*) inv);
126         }
127 }
128
129 Invite::Invite* Invite::APIImpl::Find(LocalUser* user, Channel* chan)
130 {
131         const List* list = APIImpl::GetList(user);
132         if (!list)
133                 return NULL;
134
135         for (List::iterator i = list->begin(); i != list->end(); ++i)
136         {
137                 Invite* inv = *i;
138                 if (inv->chan == chan)
139                         return inv;
140         }
141
142         return NULL;
143 }
144
145 const Invite::List* Invite::APIImpl::GetList(LocalUser* user)
146 {
147         Store<LocalUser>* list = userext.get(user);
148         if (list)
149                 return &list->invites;
150         return NULL;
151 }
152
153 Invite::Invite::Invite(LocalUser* u, Channel* c)
154         : user(u)
155         , chan(c)
156         , expiretimer(NULL)
157 {
158 }
159
160 Invite::Invite::~Invite()
161 {
162         delete expiretimer;
163         ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::~ %p", (void*) this);
164 }
165
166 InviteExpireTimer::InviteExpireTimer(Invite::Invite* invite, time_t timeout)
167         : Timer(timeout)
168         , inv(invite)
169 {
170 }
171
172 bool InviteExpireTimer::Tick(time_t currtime)
173 {
174         ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "InviteExpireTimer::Tick(): expired %p", (void*) inv);
175         apiimpl->Destruct(inv);
176         return false;
177 }