2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2019-2020 Sadie Powell <sadie@witchery.services>
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/>.
21 #include "modules/geolocation.h"
22 #include "modules/stats.h"
27 RPL_STATSCOUNTRY = 801
32 , public Stats::EventListener
35 Geolocation::API geoapi;
39 : Stats::EventListener(this)
44 Version GetVersion() CXX11_OVERRIDE
46 return Version("Allows the server administrator to assign users to connect classes by the country they are connecting from.", VF_VENDOR);
49 ModResult OnSetConnectClass(LocalUser* user, ConnectClass* myclass) CXX11_OVERRIDE
51 const std::string country = myclass->config->getString("country");
53 return MOD_RES_PASSTHRU;
55 // If we can't find the location of this user then we can't assign
56 // them to a location-specific connect class.
57 Geolocation::Location* location = geoapi ? geoapi->GetLocation(user) : NULL;
58 const std::string code = location ? location->GetCode() : "XX";
60 irc::spacesepstream codes(country);
61 for (std::string token; codes.GetToken(token); )
63 // If the user matches this country code then they can use this
65 if (stdalgo::string::equalsci(token, code))
66 return MOD_RES_PASSTHRU;
69 // A list of country codes were specified but the user didn't match
71 ServerInstance->Logs->Log("CONNECTCLASS", LOG_DEBUG, "The %s connect class is not suitable as the origin country (%s) is not any of %s",
72 myclass->GetName().c_str(), code.c_str(), country.c_str());
76 ModResult OnStats(Stats::Context& stats) CXX11_OVERRIDE
78 if (stats.GetSymbol() != 'G')
79 return MOD_RES_PASSTHRU;
81 // Counter for the number of users in each country.
82 typedef std::map<Geolocation::Location*, size_t> CountryCounts;
85 // Counter for the number of users in an unknown country.
88 const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
89 for (UserManager::LocalList::const_iterator iter = list.begin(); iter != list.end(); ++iter)
91 Geolocation::Location* location = geoapi ? geoapi->GetLocation(*iter) : NULL;
98 for (CountryCounts::const_iterator iter = counts.begin(); iter != counts.end(); ++iter)
100 Geolocation::Location* location = iter->first;
101 stats.AddRow(RPL_STATSCOUNTRY, iter->second, location->GetCode(), location->GetName());
105 stats.AddRow(RPL_STATSCOUNTRY, unknown, "*", "Unknown Country");
111 MODULE_INIT(ModuleGeoClass)