summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/numerics.h1
-rw-r--r--include/xline.h17
-rw-r--r--src/coremods/core_stats.cpp10
-rw-r--r--src/modules/m_cban.cpp2
-rw-r--r--src/modules/m_rline.cpp2
-rw-r--r--src/modules/m_shun.cpp2
-rw-r--r--src/modules/m_svshold.cpp2
-rw-r--r--src/xline.cpp27
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()
{