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 void UnserializeInvite(LocalUser* user, const std::string& str)
43 apiimpl->Unserialize(user, str);
46 Invite::APIBase::APIBase(Module* parent)
47 : DataProvider(parent, "core_channel_invite")
51 Invite::APIImpl::APIImpl(Module* parent)
53 , userext(parent, "invite_user")
54 , chanext(parent, "invite_chan")
59 void Invite::APIImpl::Destruct(Invite* inv, bool remove_user, bool remove_chan)
61 Store<LocalUser>* ustore = userext.get(inv->user);
64 ustore->invites.erase(inv);
65 if ((remove_user) && (ustore->invites.empty()))
66 userext.unset(inv->user);
69 Store<Channel>* cstore = chanext.get(inv->chan);
72 cstore->invites.erase(inv);
73 if ((remove_chan) && (cstore->invites.empty()))
74 chanext.unset(inv->chan);
80 bool Invite::APIImpl::Remove(LocalUser* user, Channel* chan)
82 Invite* inv = Find(user, chan);
91 void Invite::APIImpl::Create(LocalUser* user, Channel* chan, time_t timeout)
93 if ((timeout != 0) && (ServerInstance->Time() >= timeout))
94 // Expired, don't bother
97 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);
99 Invite* inv = Find(user, chan);
102 // We only ever extend invites, so nothing to do if the existing one is not timed
106 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::APIImpl::Create(): changing expiration in %p", (void*) inv);
109 // Convert timed invite to non-expiring
110 delete inv->expiretimer;
111 inv->expiretimer = NULL;
113 else if (inv->expiretimer->GetTrigger() >= ServerInstance->Time() + timeout)
115 // New expiration time is further than the current, extend the expiration
116 inv->expiretimer->SetInterval(timeout - ServerInstance->Time());
121 inv = new Invite(user, chan);
124 inv->expiretimer = new InviteExpireTimer(inv, timeout - ServerInstance->Time());
125 ServerInstance->Timers.AddTimer(inv->expiretimer);
128 userext.get(user, true)->invites.push_front(inv);
129 chanext.get(chan, true)->invites.push_front(inv);
130 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::APIImpl::Create(): created new Invite %p", (void*) inv);
134 Invite::Invite* Invite::APIImpl::Find(LocalUser* user, Channel* chan)
136 const List* list = APIImpl::GetList(user);
140 for (List::iterator i = list->begin(); i != list->end(); ++i)
143 if (inv->chan == chan)
150 const Invite::List* Invite::APIImpl::GetList(LocalUser* user)
152 Store<LocalUser>* list = userext.get(user);
154 return &list->invites;
158 void Invite::APIImpl::Unserialize(LocalUser* user, const std::string& value)
160 irc::spacesepstream ss(value);
161 for (std::string channame, exptime; (ss.GetToken(channame) && ss.GetToken(exptime)); )
163 Channel* chan = ServerInstance->FindChan(channame);
165 Create(user, chan, ConvToNum<time_t>(exptime));
169 Invite::Invite::Invite(LocalUser* u, Channel* c)
176 Invite::Invite::~Invite()
179 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Invite::~ %p", (void*) this);
182 void Invite::Invite::Serialize(bool human, bool show_chans, std::string& out)
185 out.append(this->chan->name);
187 out.append(human ? user->nick : user->uuid);
191 out.append(ConvToStr(expiretimer->GetTrigger()));
197 InviteExpireTimer::InviteExpireTimer(Invite::Invite* invite, time_t timeout)
203 bool InviteExpireTimer::Tick(time_t currtime)
205 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "InviteExpireTimer::Tick(): expired %p", (void*) inv);
206 apiimpl->Destruct(inv);