cs_fantasy_stats.cpp

Go to the documentation of this file.
00001 /* Chanstats core functions
00002  *
00003  * (C) 2003-2013 Anope Team
00004  * Contact us at team@anope.org
00005  *
00006  * Please read COPYING and README for further details.
00007  *
00008  * Based on the original code of Epona by Lara.
00009  * Based on the original code of Services by Andy Church.
00010  */
00011 
00012 /*************************************************************************/
00013 
00014 #include "module.h"
00015 #include "../extra/sql.h"
00016 
00017 class MySQLInterface : public SQL::Interface
00018 {
00019  public:
00020         MySQLInterface(Module *o) : SQL::Interface(o) { }
00021 
00022         void OnResult(const SQL::Result &r) anope_override
00023         {
00024         }
00025 
00026         void OnError(const SQL::Result &r) anope_override
00027         {
00028                 if (!r.GetQuery().query.empty())
00029                         Log(LOG_DEBUG) << "Chanstats: Error executing query " << r.finished_query << ": " << r.GetError();
00030                 else
00031                         Log(LOG_DEBUG) << "Chanstats: Error executing query: " << r.GetError();
00032         }
00033 };
00034 
00035 
00036 class CommandCSStats : public Command
00037 {
00038  public:
00039         CommandCSStats(Module *creator) : Command (creator, "chanserv/stats", 0, 2)
00040         {
00041                 this->SetDesc(_("Displays your Channel Stats"));
00042                 this->SetSyntax(_("\037nick\037"));
00043         }
00044 
00045         void Execute(CommandSource &source, const std::vector<Anope::string> &params);
00046 };
00047 
00048 class CommandCSGStats : public Command
00049 {
00050  public:
00051         CommandCSGStats(Module *creator) : Command (creator, "chanserv/gstats", 0, 2)
00052         {
00053                 this->SetDesc(_("Displays your Global Stats"));
00054                 this->SetSyntax(_("\037nick\037"));
00055         }
00056 
00057         void Execute(CommandSource &source, const std::vector<Anope::string> &params);
00058 };
00059 
00060 
00061 class CSStats;
00062 static CSStats *me;
00063 class CSStats : public Module
00064 {
00065         CommandCSStats commandcsstats;
00066         CommandCSGStats commandcsgstats;
00067         ServiceReference<SQL::Provider> sql;
00068         MySQLInterface sqlinterface;
00069         Anope::string prefix;
00070  public:
00071         CSStats(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
00072                 commandcsstats(this), commandcsgstats(this), sql("", ""), sqlinterface(this)
00073         {
00074                 me = this;
00075                 this->SetAuthor("Anope");
00076 
00077                 Implementation i[] = { I_OnReload };
00078                 ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
00079                 this->OnReload();
00080         }
00081 
00082         void OnReload() anope_override
00083         {
00084                 ConfigReader config;
00085                 prefix = config.ReadValue("chanstats", "prefix", "anope_", 0);
00086                 Anope::string engine = config.ReadValue("chanstats", "engine", "", 0);
00087                 this->sql = ServiceReference<SQL::Provider>("SQL::Provider", engine);
00088         }
00089 
00090         SQL::Result RunQuery(const SQL::Query &query)
00091         {
00092                 if (!this->sql)
00093                         throw SQL::Exception("Unable to locate SQL reference, is m_mysql loaded and configured correctly?");
00094 
00095                 SQL::Result res = this->sql->RunQuery(query);
00096                 if (!res.GetError().empty())
00097                         throw SQL::Exception(res.GetError());
00098                 return res;
00099         }
00100 
00101         void DoStats(CommandSource &source, const bool is_global, const std::vector<Anope::string> &params)
00102         {
00103                 if (!source.c)
00104                         return;
00105 
00106                 Anope::string display;
00107                 if (params.empty())
00108                         display = source.nc->display;
00109                 else if (const NickAlias *na = NickAlias::Find(params[0]))
00110                         display = na->nc->display;
00111                 else
00112                 {
00113                         source.Reply(_("%s not found."), params[0].c_str());
00114                         return;
00115                 }
00116 
00117                 try
00118                 {
00119                         SQL::Query query;
00120                         query = "SELECT letters, words, line, smileys_happy+smileys_sad+smileys_other as smileys,"
00121                                 "actions FROM `" + prefix + "chanstats` "
00122                                 "WHERE `nick` = @nick@ AND `chan` = @channel@ AND `type` = 'total';";
00123                         if (is_global)
00124                                 query.SetValue("channel", "");
00125                         else
00126                                 query.SetValue("channel", source.c->ci->name);
00127                         query.SetValue("nick", display);
00128                         SQL::Result res = this->RunQuery(query);
00129 
00130                         if (res.Rows() > 0)
00131                         {
00132                                 if (is_global)
00133                                         source.Reply(_("Network stats for %s:"), display.c_str());
00134                                 else
00135                                         source.Reply(_("Channel stats for %s on %s:"), display.c_str(), source.c->name.c_str());
00136 
00137                                 source.Reply(_("letters: %s, words: %s, lines: %s, smileys %s, actions: %s"),
00138                                                 res.Get(0, "letters").c_str(), res.Get(0, "words").c_str(),
00139                                                 res.Get(0, "line").c_str(), res.Get(0, "smileys").c_str(),
00140                                                 res.Get(0, "actions").c_str());
00141                         }
00142                         else
00143                                 source.Reply(_("No stats for %s."), display.c_str());
00144                 }
00145                 catch (const SQL::Exception &ex)
00146                 {
00147                         Log(LOG_DEBUG) << ex.GetReason();
00148                 }
00149 
00150         }
00151 };
00152 
00153 void CommandCSStats::Execute(CommandSource &source, const std::vector<Anope::string> &params)
00154 {
00155         me->DoStats(source, false, params);
00156 }
00157 
00158 void CommandCSGStats::Execute(CommandSource &source, const std::vector<Anope::string> &params)
00159 {
00160         me->DoStats(source, true, params);
00161 }
00162 
00163 MODULE_INIT(CSStats)
00164