]> jfr.im git - irc/quakenet/newserv.git/commitdiff
CHANSERV: only update channels as active if they have at least one known op, and...
authorChris Porter <redacted>
Fri, 10 Feb 2012 14:59:33 +0000 (14:59 +0000)
committerChris Porter <redacted>
Fri, 10 Feb 2012 14:59:33 +0000 (14:59 +0000)
cleanup now checks to see if a channel is still active, and if so updates lastactive.
TODO: perform this scan at least once/day

chanserv/chanserv.h
chanserv/chanservnetevents.c
chanserv/chanservuser.c
chanserv/usercmds/cleanupdb.c

index ced31983f0ba80069e7dc195a7046de0e83392b2..47537940542af889937a845bcb0a3569ebc49996 100644 (file)
 
 #define CLEANUP_AUTHHISTORY      60
 
+#define CLEANUP_MIN_CHAN_SIZE     2
+
 /* Sizes of the main hashes */
 #define   REGUSERHASHSIZE     60000
 #define   MAILDOMAINHASHSIZE  60000
@@ -902,6 +904,7 @@ void cs_handletopicchange(int hooknum, void *arg);
 void cs_handleopchange(int hooknum, void *arg);
 void cs_handlenewban(int hooknum, void *arg);
 void cs_handlechanlostuser(int hooknum, void *arg);
+int cs_ischannelactive(channel *cp, regchan *rcp);
 
 /* chanservmessages.c */
 void initmessages();
index 7989f90664f690bc7e9aea5b973bc90163936931..bed36d71a13de4a1079ae7bd31d732ef7db42c80 100644 (file)
@@ -147,7 +147,7 @@ void cs_handlejoin(int hooknum, void *arg) {
   if (rup && (rup->status & QUSTAT_DEAD))
     rup=NULL;
   
-  if (rup && (rcup=findreguseronchannel(rcp,rup)) && CUHasOpPriv(rcup) && cp->users->totalusers >= 3)
+  if (rup && (rcup=findreguseronchannel(rcp,rup)) && CUHasOpPriv(rcup) && cs_ischannelactive(cp, NULL))
     rcp->lastactive=time(NULL);
 
   /* Update last use time */
@@ -444,3 +444,48 @@ void cs_handletopicchange(int hooknum, void *arg) {
     csdb_updatetopic(rcp);
   }
 }
+
+/*
+ * active is defined as at least 2 real users (no snailbot) currently present
+ * and at least one op/master/owner.
+ * this is O(n) worst case, but very very likely to just be 2 checks.
+ */
+int cs_ischannelactive(channel *cp, regchan *rcp) {
+  int real_users = 0;
+  int seen_op = 0;
+  nick *np;
+  int i;
+
+  for (i=0;i<cp->users->hashsize;i++) {
+    if(cp->users->content[i]==nouser)
+      continue;
+
+    if((np=getnickbynumeric(cp->users->content[i]))==NULL)
+      continue;
+
+    if(NickOnServiceServer(np)) /* bad snailbot */
+      continue;
+
+    real_users++;
+
+    if(rcp && !seen_op) { /* only look for ops if we haven't seen one yet */
+      reguser *rup = getreguserfromnick(np); /* O(1) */
+      if(rup) {
+        regchanuser *rcup = findreguseronchannel(rcp, rup); /* O(1) */
+        if(rcup && CUHasOpPriv(rcup))
+          seen_op = 1;
+      }
+    }
+
+    /* so once we've seen X real users AND:
+     * - we're not looking for ops as a check had already been done by the caller
+     * - OR we're looking for ops AND we found them
+     * then the channel is active, and we're done
+     */
+    if((real_users >= CLEANUP_MIN_CHAN_SIZE) && (!rcp || (rcp && seen_op)))
+      return 1;
+  }
+
+  return 0;
+}
+
index 5d3a655fbcaff6793f9b2c632b1daf013e203ece..bd755bbe7d7d4fad625a3466571fe16b7cabc323 100644 (file)
@@ -792,7 +792,7 @@ void cs_doallautomodes(nick *np) {
           continue;
         }
 
-        if (CUKnown(rcup) && rcup->chan->index->channel->users->totalusers >= 3) {
+        if (CUHasOpPriv(rcup) && cs_ischannelactive(rcup->chan->index->channel, NULL)) {
           /* This meets the channel use criteria, update. */
           rcup->chan->lastactive=time(NULL);
           
index 273ea342145f63b23abf4035f56c1f5723f29d72..0dfb3e1052cc4b7e45cd2ba71618beaf18e66651 100644 (file)
@@ -104,6 +104,21 @@ void csu_docleanupdb_real(DBConn *dbconn, void *arg) {
       if (!(rcp=cip->exts[chanservext]))
         continue;
 
+      /* there's a bug here... if no joins or modes are done within the threshold
+       * and someone leaves just before the cleanup then the channel will be nuked.
+       */
+
+      /* this is one possible soln but relies on cleanupdb being run more frequently than
+       * the threshold:
+       */ 
+      if(cip->channel && cs_ischannelactive(cip->channel, rcp)) {
+        rcp->lastactive = t;
+        if (rcp->lastcountersync < (t - COUNTERSYNCINTERVAL)) {
+          csdb_updatechannelcounters(rcp);
+          rcp->lastcountersync=t;
+        }
+      }
+
       if(rcp->lastactive < maxchan_age) {
         /* don't remove channels with the original founder as an oper */
         founder=findreguserbyID(rcp->founder);