]> jfr.im git - irc/rqf/shadowircd.git/commitdiff
target change: Allow free replies.
authorJilles Tjoelker <redacted>
Mon, 15 Feb 2010 00:07:07 +0000 (01:07 +0100)
committerJilles Tjoelker <redacted>
Mon, 15 Feb 2010 00:07:07 +0000 (01:07 +0100)
When a user receives a private message, notice or RPL_UMODEGMSG,
add the source to a special set of 5 target slots.
These slots are checked in the normal way when sending messages,
allowing a reply without using up a free target.

This feature will not be very useful if a user is being messaged
by many different users; to help this, messages blocked entirely
by +g or +R do not affect the targets. CTCP replies also remain
free in terms of targets.

include/client.h
modules/core/m_message.c

index 4920fb6b9be7ec3e285d84d8823e9841598a00a1..4a28a3079c959fc21372b623d3f95e3a99daab40 100644 (file)
@@ -54,6 +54,7 @@ struct Blacklist;
 #define IDLEN          10
 
 #define TGCHANGE_NUM           10      /* how many targets we keep track of */
+#define TGCHANGE_REPLY         5       /* how many reply targets */
 #define TGCHANGE_INITIAL       10      /* initial free targets (normal) */
 #define TGCHANGE_INITIAL_LOW   4       /* initial free targets (possible spambot) */
 
@@ -259,7 +260,11 @@ struct LocalUser
        struct AuthRequest *auth_request;
 
        /* target change stuff */
-       uint32_t targets[TGCHANGE_NUM]; /* targets were aware of (fnv32(use_id(target_p))) */
+       /* targets we're aware of (fnv32(use_id(target_p))):
+        * 0..TGCHANGE_NUM-1 regular slots
+        * TGCHANGE_NUM..TGCHANGE_NUM+TGCHANGE_REPLY-1 reply slots
+        */
+       uint32_t targets[TGCHANGE_NUM + TGCHANGE_REPLY];
        unsigned int targets_free;      /* free targets */
        time_t target_last;             /* last time we cleared a slot */
 
index 8b90052dcabce48670ce2f1e88b541838c367465..2b7a750ca33fbdba6194c19f66074d7f5f15063b 100644 (file)
@@ -662,6 +662,7 @@ expire_tgchange(void *unused)
        }
 }
 
+/* checks if source_p is allowed to send to target_p */
 static int
 add_target(struct Client *source_p, struct Client *target_p)
 {
@@ -685,7 +686,7 @@ add_target(struct Client *source_p, struct Client *target_p)
        targets = source_p->localClient->targets;
 
        /* check for existing target, and move it to the head */
-       for(i = 0; i < TGCHANGE_NUM; i++)
+       for(i = 0; i < TGCHANGE_NUM + TGCHANGE_REPLY; i++)
        {
                if(targets[i] == hashv)
                {
@@ -733,13 +734,49 @@ add_target(struct Client *source_p, struct Client *target_p)
                SetTGChange(source_p);
        }
 
-       for(i = TGCHANGE_NUM - 1; i > 0; i--)
+       for(i = TGCHANGE_NUM + TGCHANGE_REPLY - 1; i > 0; i--)
                targets[i] = targets[i - 1];
        targets[0] = hashv;
        source_p->localClient->targets_free--;
        return 1;
 }
 
+/* allows source_p to send to target_p */
+static void
+add_reply_target(struct Client *source_p, struct Client *target_p)
+{
+       int i, j;
+       uint32_t hashv;
+       uint32_t *targets;
+
+       /* can msg themselves or services without using any target slots */
+       if(source_p == target_p || IsService(target_p))
+               return;
+
+       hashv = fnv_hash_upper((const unsigned char *)use_id(target_p), 32);
+       targets = source_p->localClient->targets;
+
+       /* check for existing target, and move it to the first reply slot
+        * if it is in a reply slot
+        */
+       for(i = 0; i < TGCHANGE_NUM + TGCHANGE_REPLY; i++)
+       {
+               if(targets[i] == hashv)
+               {
+                       if(i > TGCHANGE_NUM)
+                       {
+                               for(j = i; j > TGCHANGE_NUM; j--)
+                                       targets[j] = targets[j - 1];
+                               targets[TGCHANGE_NUM] = hashv;
+                       }
+                       return;
+               }
+       }
+       for(i = TGCHANGE_NUM + TGCHANGE_REPLY - 1; i > TGCHANGE_NUM; i--)
+               targets[i] = targets[i - 1];
+       targets[TGCHANGE_NUM] = hashv;
+}
+
 /*
  * msg_client
  *
@@ -813,6 +850,7 @@ msg_client(int p_or_n, const char *command,
                        /* Here is the anti-flood bot/spambot code -db */
                        if(accept_message(source_p, target_p) || IsOper(source_p))
                        {
+                               add_reply_target(target_p, source_p);
                                sendto_one(target_p, ":%s!%s@%s %s %s :%s",
                                           source_p->name,
                                           source_p->username,
@@ -843,6 +881,7 @@ msg_client(int p_or_n, const char *command,
                                                                   form_str(RPL_TARGNOTIFY),
                                                                   target_p->name);
 
+                                       add_reply_target(target_p, source_p);
                                        sendto_one(target_p, form_str(RPL_UMODEGMSG),
                                                   me.name, target_p->name, source_p->name,
                                                   source_p->username, source_p->host);
@@ -852,7 +891,10 @@ msg_client(int p_or_n, const char *command,
                        }
                }
                else
+               {
+                       add_reply_target(target_p, source_p);
                        sendto_anywhere(target_p, source_p, command, ":%s", text);
+               }
        }
        else
                sendto_anywhere(target_p, source_p, command, ":%s", text);