diff options
-rw-r--r-- | include/numerics.h | 1 | ||||
-rw-r--r-- | include/xline.h | 17 | ||||
-rw-r--r-- | src/coremods/core_stats.cpp | 10 | ||||
-rw-r--r-- | src/modules/m_cban.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_rline.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_shun.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_svshold.cpp | 2 | ||||
-rw-r--r-- | src/xline.cpp | 27 |
8 files changed, 44 insertions, 19 deletions
diff --git a/include/numerics.h b/include/numerics.h index baae8de5c..5a05a61eb 100644 --- a/include/numerics.h +++ b/include/numerics.h @@ -50,6 +50,7 @@ enum RPL_ENDMAP = 17, // ircu RPL_MAPUSERS = 18, // insp-specific + RPL_STATS = 210, // From aircd. RPL_UMODEIS = 221, RPL_LUSERCLIENT = 251, diff --git a/include/xline.h b/include/xline.h index 0aaa21a16..fe564358f 100644 --- a/include/xline.h +++ b/include/xline.h @@ -529,14 +529,15 @@ class CoreExport XLineManager */ void ApplyLines(); - /** Handle /STATS for a given type. - * NOTE: Any items in the list for this particular line type which have expired - * will be expired and removed before the list is displayed. - * @param type The type of stats to show - * @param numeric The numeric to give to each result line - * @param stats Stats context - */ - void InvokeStats(const std::string& type, unsigned int numeric, Stats::Context& stats); + /** DEPRECATED: use the `bool InvokeStats(const std::string&, Stats::Context&)` overload instead. */ + DEPRECATED_METHOD(void InvokeStats(const std::string& type, unsigned int numeric, Stats::Context& stats)); + + /** Generates a /STATS response for the given X-line type. + * @param type The type of X-line to look up. + * @param context The stats context to respond with. + * @return True if a response was sent; otherwise, false. + */ + bool InvokeStats(const std::string& type, Stats::Context& context); /** Expire X-lines which were added by the server configuration and have been removed. */ void ExpireRemovedConfigLines(const std::string& type, const insp::flat_set<std::string>& configlines); diff --git a/src/coremods/core_stats.cpp b/src/coremods/core_stats.cpp index b95005c5b..4b30fa5b4 100644 --- a/src/coremods/core_stats.cpp +++ b/src/coremods/core_stats.cpp @@ -195,19 +195,19 @@ void CommandStats::DoStats(Stats::Context& stats) break; case 'k': - ServerInstance->XLines->InvokeStats("K",216,stats); + ServerInstance->XLines->InvokeStats("K", stats); break; case 'g': - ServerInstance->XLines->InvokeStats("G",223,stats); + ServerInstance->XLines->InvokeStats("G", stats); break; case 'q': - ServerInstance->XLines->InvokeStats("Q",217,stats); + ServerInstance->XLines->InvokeStats("Q", stats); break; case 'Z': - ServerInstance->XLines->InvokeStats("Z",223,stats); + ServerInstance->XLines->InvokeStats("Z", stats); break; case 'e': - ServerInstance->XLines->InvokeStats("E",223,stats); + ServerInstance->XLines->InvokeStats("E", stats); break; case 'E': { diff --git a/src/modules/m_cban.cpp b/src/modules/m_cban.cpp index 22382bdb3..ff99ae5bd 100644 --- a/src/modules/m_cban.cpp +++ b/src/modules/m_cban.cpp @@ -188,7 +188,7 @@ class ModuleCBan : public Module, public Stats::EventListener if (stats.GetSymbol() != 'C') return MOD_RES_PASSTHRU; - ServerInstance->XLines->InvokeStats("CBAN", 210, stats); + ServerInstance->XLines->InvokeStats("CBAN", stats); return MOD_RES_DENY; } diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp index cb6c507f1..1876604c4 100644 --- a/src/modules/m_rline.cpp +++ b/src/modules/m_rline.cpp @@ -307,7 +307,7 @@ class ModuleRLine : public Module, public Stats::EventListener if (stats.GetSymbol() != 'R') return MOD_RES_PASSTHRU; - ServerInstance->XLines->InvokeStats("R", 223, stats); + ServerInstance->XLines->InvokeStats("R", stats); return MOD_RES_DENY; } diff --git a/src/modules/m_shun.cpp b/src/modules/m_shun.cpp index 3ffe553b0..99ff05c30 100644 --- a/src/modules/m_shun.cpp +++ b/src/modules/m_shun.cpp @@ -187,7 +187,7 @@ class ModuleShun : public Module, public Stats::EventListener if (stats.GetSymbol() != 'H') return MOD_RES_PASSTHRU; - ServerInstance->XLines->InvokeStats("SHUN", 223, stats); + ServerInstance->XLines->InvokeStats("SHUN", stats); return MOD_RES_DENY; } diff --git a/src/modules/m_svshold.cpp b/src/modules/m_svshold.cpp index 9cdc307b9..0c5578492 100644 --- a/src/modules/m_svshold.cpp +++ b/src/modules/m_svshold.cpp @@ -203,7 +203,7 @@ class ModuleSVSHold : public Module, public Stats::EventListener if (stats.GetSymbol() != 'S') return MOD_RES_PASSTHRU; - ServerInstance->XLines->InvokeStats("SVSHOLD", 210, stats); + ServerInstance->XLines->InvokeStats("SVSHOLD", stats); return MOD_RES_DENY; } diff --git a/src/xline.cpp b/src/xline.cpp index 13ea2f97c..04ac67f68 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -498,13 +498,36 @@ void XLineManager::InvokeStats(const std::string& type, unsigned int numeric, St ExpireLine(n, i); } else - stats.AddRow(numeric, i->second->Displayable()+" "+ - ConvToStr(i->second->set_time)+" "+ConvToStr(i->second->duration)+" "+i->second->source+" :"+i->second->reason); + stats.AddRow(numeric, i->second->Displayable(), i->second->set_time, i->second->duration, i->second->source, i->second->reason); i = safei; } } } +bool XLineManager::InvokeStats(const std::string& type, Stats::Context& context) +{ + ContainerIter citer = lookup_lines.find(type); + if (citer == lookup_lines.end()) + return false; + + for (LookupIter liter = citer->second.begin(); liter != citer->second.end(); ) + { + // We might be about to expire the XLine so we have to increment the + // iterator early to avoid doing that causing iterator invalidation. + LookupIter current = liter++; + + XLine* xline = current->second; + if (xline->duration && xline->expiry <= ServerInstance->Time()) + { + // This XLine has expired so remove and skip it. + ExpireLine(citer, current); + continue; + } + + context.AddRow(RPL_STATS, context.GetSymbol(), xline->Displayable(), xline->set_time, xline->duration, xline->source, xline->reason); + } + return true; +} XLineManager::XLineManager() { |