]> jfr.im git - irc/rqf/shadowircd.git/blobdiff - modules/m_tb.c
Allow /ojoin !#channel/%#channel, if admin/halfop are enabled.
[irc/rqf/shadowircd.git] / modules / m_tb.c
index ad5741bb712092344f627fcc1dd59ce4bc099acd..e02cc5725b64e997f9cac6590f36fbfe4caed68d 100644 (file)
 #include "s_serv.h"
 
 static int ms_tb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
+static int ms_etb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[]);
 
 struct Message tb_msgtab = {
        "TB", 0, 0, 0, MFLG_SLOW,
        {mg_unreg, mg_ignore, mg_ignore, {ms_tb, 4}, mg_ignore, mg_ignore}
 };
 
-mapi_clist_av1 tb_clist[] =  { &tb_msgtab, NULL };
+struct Message etb_msgtab = {
+       "ETB", 0, 0, 0, MFLG_SLOW,
+       {mg_unreg, mg_ignore, {ms_etb, 5}, {ms_etb, 5}, mg_ignore, mg_ignore}
+};
+
+mapi_clist_av1 tb_clist[] =  { &tb_msgtab, &etb_msgtab, NULL };
 DECLARE_MODULE_AV1(tb, NULL, NULL, tb_clist, NULL, NULL, "$Revision: 1349 $");
 
 /* m_tb()
@@ -118,3 +124,131 @@ ms_tb(struct Client *client_p, struct Client *source_p, int parc, const char *pa
 
        return 0;
 }
+
+/* ms_etb()
+ *
+ * parv[1] - channel ts
+ * parv[2] - channel
+ * parv[3] - topic ts
+ * parv[4] - topicwho
+ * parv[5] - topic
+ */
+static int
+ms_etb(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+       struct Channel *chptr;
+       const char *newtopic;
+       const char *newtopicwho;
+       time_t channelts, newtopicts;
+       struct Client *fakesource_p, *source_server_p;
+       int textchange, can_use_tb, member;
+
+       channelts = atol(parv[1]);
+       chptr = find_channel(parv[2]);
+
+       if(chptr == NULL)
+               return 0;
+
+       newtopicts = atol(parv[3]);
+
+       /* Hide connecting server on netburst -- jilles */
+       if (IsServer(source_p) && ConfigServerHide.flatten_links &&
+                       !HasSentEob(source_p))
+               fakesource_p = &me;
+       else
+               fakesource_p = source_p;
+
+       newtopicwho = parv[4];
+       newtopic = parv[parc - 1];
+
+       if(chptr->topic == NULL || chptr->channelts > channelts ||
+                       (chptr->channelts == channelts && chptr->topic_time < newtopicts))
+       {
+               textchange = chptr->topic == NULL || strcmp(chptr->topic, newtopic);
+               can_use_tb = textchange && !EmptyString(newtopic) &&
+                       (chptr->topic == NULL || chptr->topic_time > newtopicts);
+
+               set_channel_topic(chptr, newtopic, newtopicwho, newtopicts);
+               newtopic = chptr->topic ? chptr->topic : "";
+               if (chptr->topic_info)
+                       newtopicwho = chptr->topic_info;
+
+               /* Do not send a textually identical topic to clients,
+                * but do propagate the new topicts/topicwho to servers.
+                */
+               if(textchange)
+               {
+                       if (IsPerson(fakesource_p))
+                               sendto_channel_local(ALL_MEMBERS, chptr,
+                                               ":%s!%s@%s TOPIC %s :%s",
+                                               fakesource_p->name,
+                                               fakesource_p->username,
+                                               fakesource_p->host,
+                                               chptr->chname,
+                                               newtopic);
+                       else
+                               sendto_channel_local(ALL_MEMBERS, chptr,
+                                               ":%s TOPIC %s :%s",
+                                               fakesource_p->name,
+                                               chptr->chname, newtopic);
+               }
+               /* Propagate channelts as given, because an older channelts
+                * forces any change.
+                */
+               sendto_server(client_p, chptr, CAP_EOPMOD|CAP_TS6, NOCAPS,
+                             ":%s ETB %ld %s %ld %s :%s",
+                             use_id(source_p), (long)channelts, chptr->chname,
+                             (long)newtopicts, newtopicwho, newtopic);
+               source_server_p = IsServer(source_p) ? source_p : source_p->servptr;
+               if (can_use_tb)
+                       sendto_server(client_p, chptr, CAP_TB|CAP_TS6, CAP_EOPMOD,
+                                     ":%s TB %s %ld %s :%s",
+                                     use_id(source_server_p),
+                                     chptr->chname, (long)newtopicts,
+                                     newtopicwho, newtopic);
+               else if (IsPerson(source_p) && textchange)
+               {
+                       member = IsMember(source_p, chptr);
+                       if (!member)
+                               sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+                                             ":%s SJOIN %ld %s + :@%s",
+                                             use_id(source_server_p),
+                                             (long)chptr->channelts,
+                                             chptr->chname, use_id(source_p));
+                       if (EmptyString(newtopic) ||
+                                       newtopicts >= rb_current_time() - 60)
+                               sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+                                             ":%s TOPIC %s :%s",
+                                             use_id(source_p),
+                                             chptr->chname, newtopic);
+                       else
+                       {
+                               sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+                                             ":%s TOPIC %s :%s",
+                                             use_id(source_p),
+                                             chptr->chname, "");
+                               sendto_server(client_p, chptr, CAP_TB|CAP_TS6, CAP_EOPMOD,
+                                             ":%s TB %s %ld %s :%s",
+                                             use_id(source_server_p),
+                                             chptr->chname, (long)newtopicts,
+                                             newtopicwho, newtopic);
+                       }
+                       if (!member)
+                               sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+                                             ":%s PART %s :Topic set for %s",
+                                             use_id(source_p),
+                                             chptr->chname, newtopicwho);
+               }
+               else if (textchange)
+               {
+                       /* Should not send :server ETB if not all servers
+                        * support EOPMOD.
+                        */
+                       sendto_server(client_p, chptr, CAP_TS6, CAP_EOPMOD,
+                                     ":%s NOTICE %s :*** Notice -- Dropping topic change for %s",
+                                     me.id, chptr->chname, chptr->chname);
+               }
+       }
+
+       return 0;
+}