2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2012, 2015 Attila Molnar <attilamolnar@hush.com>
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.
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
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/>.
24 class InviteExpireTimer : public Timer
26 Invite::Invite* const inv;
28 bool Tick(time_t currtime) CXX11_OVERRIDE;
31 InviteExpireTimer(Invite::Invite* invite, time_t timeout);
34 static Invite::APIImpl* apiimpl;
36 void RemoveInvite(Invite::Invite* inv, bool remove_user, bool remove_chan)
38 apiimpl->Destruct(inv, remove_user, remove_chan);
41 Invite::APIBase::APIBase(Module* parent)
42 : DataProvider(parent, "core_channel_invite")
46 Invite::APIImpl::APIImpl(Module* parent)
48 , userext(parent, "invite_user")
49 , chanext(parent, "invite_chan")
54 void Invite::APIImpl::Destruct(Invite* inv, bool remove_user, bool remove_chan)
56 Store<LocalUser>* ustore = userext.get(inv->user);
59 ustore->invites.erase(inv);
60 if ((remove_user) && (ustore->invites.empty()))
61 userext.unset(inv->user);
64 Store<Channel>* cstore = chanext.get(inv->chan);
67 cstore->invites.erase(inv);
68 if ((remove_chan) && (cstore->invites.empty()))
69 chanext.unset(inv->chan);
75 bool Invite::APIImpl::Remove(LocalUser* user, Channel* chan)
77 Invite* inv = Find(user, chan);
86 void Invite::APIImpl::Create(LocalUser* user, Channel* chan, time_t timeout)
88 if ((timeout != 0) && (ServerInstance->Time() >= timeout))
89 // Expired, don't bother
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);
94 Invite* inv = Find(user, chan);
97 // We only ever extend invites, so nothing to do if the existing one is not timed
101 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::APIImpl::Create(): changing expiration in %p", (void*) inv);
104 // Convert timed invite to non-expiring
105 delete inv->expiretimer;
106 inv->expiretimer = NULL;
108 else if (inv->expiretimer->GetTrigger() >= ServerInstance->Time() + timeout)
110 // New expiration time is further than the current, extend the expiration
111 inv->expiretimer->SetInterval(timeout - ServerInstance->Time());
116 inv = new Invite(user, chan);
119 inv->expiretimer = new InviteExpireTimer(inv, timeout - ServerInstance->Time());
120 ServerInstance->Timers.AddTimer(inv->expiretimer);
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);
129 Invite::Invite* Invite::APIImpl::Find(LocalUser* user, Channel* chan)
131 const List* list = APIImpl::GetList(user);
135 for (List::iterator i = list->begin(); i != list->end(); ++i)
138 if (inv->chan == chan)
145 const Invite::List* Invite::APIImpl::GetList(LocalUser* user)
147 Store<LocalUser>* list = userext.get(user);
149 return &list->invites;
153 Invite::Invite::Invite(LocalUser* u, Channel* c)
160 Invite::Invite::~Invite()
163 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::~ %p", (void*) this);
166 InviteExpireTimer::InviteExpireTimer(Invite::Invite* invite, time_t timeout)
172 bool InviteExpireTimer::Tick(time_t currtime)
174 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "InviteExpireTimer::Tick(): expired %p", (void*) inv);
175 apiimpl->Destruct(inv);