1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2014 Daniel Vassdal <shutter@canternet.org>
5  *   Copyright (C) 2013-2015 Attila Molnar <attilamolnar@hush.com>
6  *   Copyright (C) 2013, 2017, 2019 Sadie Powell <sadie@witchery.services>
7  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
8  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
9  *   Copyright (C) 2009 Uli Schlachter <psychon@inspircd.org>
10  *   Copyright (C) 2009 Robin Burchell <robin+git@viroteck.net>
11  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
12  *   Copyright (C) 2007 Craig Edwards <brain@inspircd.org>
13  *
14  * This file is part of InspIRCd.  InspIRCd is free software: you can
15  * redistribute it and/or modify it under the terms of the GNU General Public
16  * License as published by the Free Software Foundation, version 2.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
21  * details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  */
26 
27 
28 #include "inspircd.h"
29 
JoinChannels(LocalUser * u,const std::string & chanlist)30 static void JoinChannels(LocalUser* u, const std::string& chanlist)
31 {
32 	irc::commasepstream chans(chanlist);
33 	std::string chan;
34 
35 	while (chans.GetToken(chan))
36 	{
37 		if (ServerInstance->IsChannel(chan))
38 			Channel::JoinUser(u, chan);
39 	}
40 }
41 
42 class JoinTimer : public Timer
43 {
44  private:
45 	LocalUser* const user;
46 	const std::string channels;
47 	SimpleExtItem<JoinTimer>& ext;
48 
49  public:
JoinTimer(LocalUser * u,SimpleExtItem<JoinTimer> & ex,const std::string & chans,unsigned int delay)50 	JoinTimer(LocalUser* u, SimpleExtItem<JoinTimer>& ex, const std::string& chans, unsigned int delay)
51 		: Timer(delay, false)
52 		, user(u), channels(chans), ext(ex)
53 	{
54 		ServerInstance->Timers.AddTimer(this);
55 	}
56 
Tick(time_t time)57 	bool Tick(time_t time) CXX11_OVERRIDE
58 	{
59 		if (user->chans.empty())
60 			JoinChannels(user, channels);
61 
62 		ext.unset(user);
63 		return false;
64 	}
65 };
66 
67 class ModuleConnJoin : public Module
68 {
69 	SimpleExtItem<JoinTimer> ext;
70 	std::string defchans;
71 	unsigned int defdelay;
72 
73  public:
ModuleConnJoin()74 	ModuleConnJoin()
75 		: ext("join_timer", ExtensionItem::EXT_USER, this)
76 	{
77 	}
78 
ReadConfig(ConfigStatus & status)79 	void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
80 	{
81 		ConfigTag* tag = ServerInstance->Config->ConfValue("autojoin");
82 		defchans = tag->getString("channel");
83 		defdelay = tag->getDuration("delay", 0, 0, 60*15);
84 	}
85 
Prioritize()86 	void Prioritize() CXX11_OVERRIDE
87 	{
88 		ServerInstance->Modules->SetPriority(this, I_OnPostConnect, PRIORITY_LAST);
89 	}
90 
GetVersion()91 	Version GetVersion() CXX11_OVERRIDE
92 	{
93 		return Version("Allows the server administrator to force users to join one or more channels on connect.", VF_VENDOR);
94 	}
95 
OnPostConnect(User * user)96 	void OnPostConnect(User* user) CXX11_OVERRIDE
97 	{
98 		LocalUser* localuser = IS_LOCAL(user);
99 		if (!localuser)
100 			return;
101 
102 		std::string chanlist = localuser->GetClass()->config->getString("autojoin");
103 		unsigned int chandelay = localuser->GetClass()->config->getDuration("autojoindelay", 0, 0, 60*15);
104 
105 		if (chanlist.empty())
106 		{
107 			if (defchans.empty())
108 				return;
109 			chanlist = defchans;
110 			chandelay = defdelay;
111 		}
112 
113 		if (!chandelay)
114 			JoinChannels(localuser, chanlist);
115 		else
116 			ext.set(localuser, new JoinTimer(localuser, ext, chanlist, chandelay));
117 	}
118 };
119 
120 MODULE_INIT(ModuleConnJoin)
121