📄 m_sjoin.c
字号:
sendto_realops("[BUG] Duplicate user entry in SJOIN! Please report at http://bugs.unrealircd.org !!! Chan='%s', User='%s', modeflags=%ld", chptr->chname ? chptr->chname : "<NULL>", acptr->name ? acptr->name : "<NULL>", modeflags); ircd_log(LOG_ERROR, "[BUG] Duplicate user entry in SJOIN! Please report to UnrealIrcd team!! Chan='%s', User='%s', modeflags=%ld", chptr->chname ? chptr->chname : "<NULL>", acptr->name ? acptr->name : "<NULL>", modeflags); ircd_log(LOG_ERROR, "--- Dump of parameters ---"); for (i=0; i < parc; i++) ircd_log(LOG_ERROR, "parv[%d] = '%s'", i, BadPtr(parv[i]) ? "<NULL-or-empty>" : parv[i]); ircd_log(LOG_ERROR, "--- End of dump ---");#endif } else { add_user_to_channel(chptr, acptr, modeflags); RunHook4(HOOKTYPE_REMOTE_JOIN, cptr, acptr, chptr, NULL); if (chptr->mode.mode & MODE_AUDITORIUM) { if (modeflags & (CHFL_CHANOP|CHFL_CHANPROT|CHFL_CHANOWNER)) sendto_channel_butserv(chptr, acptr, ":%s JOIN :%s", nick, chptr->chname); else sendto_chanops_butone(NULL, chptr, ":%s!%s@%s JOIN :%s", acptr->name, acptr->user->username, GetHost(acptr), chptr->chname); } else sendto_channel_butserv(chptr, acptr, ":%s JOIN :%s", nick, chptr->chname);#ifdef NEWCHFLOODPROT if (chptr->mode.floodprot && sptr->serv->flags.synced && !IsULine(sptr)) do_chanflood(chptr->mode.floodprot, FLD_JOIN);#endif } sendto_serv_butone_sjoin(cptr, ":%s JOIN %s", nick, chptr->chname); CheckStatus('q', CHFL_CHANOWNER); CheckStatus('a', CHFL_CHANPROT); CheckStatus('o', CHFL_CHANOP); CheckStatus('h', CHFL_HALFOP); CheckStatus('v', CHFL_VOICE); } else { if (removetheirs) continue; if (modeflags & CHFL_BAN) { f = add_listmode(&chptr->banlist, sptr, chptr, nick); if (f != -1) { Addit('b', nick); AddBan(nick); } } if (modeflags & CHFL_EXCEPT) { f = add_listmode(&chptr->exlist, sptr, chptr, nick); if (f != -1) { Addit('e', nick); AddEx(nick); } } if (modeflags & CHFL_INVEX) { f = add_listmode(&chptr->invexlist, sptr, chptr, nick); if (f != -1) { Addit('I', nick); AddInvex(nick); } } }docontinue: continue; } if (modebuf[1]) { modebuf[b] = '\0'; sendto_serv_butone_sjoin(cptr, ":%s MODE %s %s %s %lu", sptr->name, chptr->chname, modebuf, parabuf, chptr->creationtime); sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s %s", sptr->name, chptr->chname, modebuf, parabuf); } if (!merge && !removetheirs && !nomode) { strlcpy(modebuf, parv[3], sizeof modebuf); parabuf[0] = '\0'; if (!nopara) for (b = 4; b <= (parc - 2); b++) { strlcat(parabuf, parv[b], sizeof parabuf); strlcat(parabuf, " ", sizeof parabuf); } strlcpy(paraback, parabuf, sizeof paraback); ap = mp2parv(modebuf, parabuf); set_mode(chptr, cptr, ap->parc, ap->parv, &pcount, pvar, 0); sendto_serv_butone_sjoin(cptr, ":%s MODE %s %s %s %lu", sptr->name, chptr->chname, modebuf, paraback, chptr->creationtime); sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s %s", sptr->name, chptr->chname, modebuf, paraback); if (chptr->mode.mode & MODE_ONLYSECURE) kick_insecure_users(chptr); } if (merge && !nomode) { aCtab *acp; bcopy(&chptr->mode, &oldmode, sizeof(Mode));#ifdef EXTCMODE /* Fun.. we have to duplicate all extended modes too... */ oldmode.extmodeparam = NULL; oldmode.extmodeparam = extcmode_duplicate_paramlist(chptr->mode.extmodeparam);#endif#ifdef NEWCHFLOODPROT if (chptr->mode.floodprot) { oldmode.floodprot = MyMalloc(sizeof(ChanFloodProt)); memcpy(oldmode.floodprot, chptr->mode.floodprot, sizeof(ChanFloodProt)); }#endif /* merge the modes */ strlcpy(modebuf, parv[3], sizeof modebuf); parabuf[0] = '\0'; if (!nopara) for (b = 4; b <= (parc - 2); b++) { strlcat(parabuf, parv[b], sizeof parabuf); strlcat(parabuf, " ", sizeof parabuf); } ap = mp2parv(modebuf, parabuf); set_mode(chptr, cptr, ap->parc, ap->parv, &pcount, pvar, 0); /* Good, now we got modes, now for the differencing and outputting of modes We first see if any para modes are set */ strlcpy(modebuf, "-", sizeof modebuf); parabuf[0] = '\0'; b = 1; /* however, is this really going to happen at all? may be unneeded */ if (oldmode.limit && !chptr->mode.limit) { Addit('l', (char *)my_itoa(oldmode.limit)); } if (oldmode.key[0] && !chptr->mode.key[0]) { Addit('k', oldmode.key); } if (oldmode.link[0] && !chptr->mode.link[0]) { Addit('L', oldmode.link); }#ifdef NEWCHFLOODPROT if (oldmode.floodprot && !chptr->mode.floodprot) { char *x = channel_modef_string(oldmode.floodprot); Addit('f', x); }#else if ((oldmode.msgs || oldmode.per || oldmode.kmode) && ((chptr->mode.msgs == 0) && (chptr->mode.per == 0) && (chptr->mode.kmode == 0))) { ircsprintf(modeback, "%s%i:%i", (oldmode.kmode == 1 ? "*" : ""), oldmode.msgs, oldmode.per); Addit('f', modeback); }#endif#ifdef EXTCMODE /* First, check if we have something they don't have.. * note that: oldmode.* = us, chptr->mode.* = them. */ for (i=0; i <= Channelmode_highest; i++) { if ((Channelmode_Table[i].flag) && (oldmode.extmode & Channelmode_Table[i].mode) && !(chptr->mode.extmode & Channelmode_Table[i].mode)) { if (Channelmode_Table[i].paracount) { char *parax = Channelmode_Table[i].get_param(extcmode_get_struct(oldmode.extmodeparam, Channelmode_Table[i].flag)); Addit(Channelmode_Table[i].flag, parax); } else { Addsingle(Channelmode_Table[i].flag); } } }#endif /* Check if we had +s and it became +p, then revert it... */ if ((oldmode.mode & MODE_SECRET) && (chptr->mode.mode & MODE_PRIVATE)) { /* stay +s ! */ chptr->mode.mode &= ~MODE_PRIVATE; chptr->mode.mode |= MODE_SECRET; Addsingle('p'); /* - */ queue_s = 1; } /* Check if we had +c and it became +S, then revert it... */ if ((oldmode.mode & MODE_NOCOLOR) && (chptr->mode.mode & MODE_STRIP)) { chptr->mode.mode &= ~MODE_STRIP; chptr->mode.mode |= MODE_NOCOLOR; Addsingle('S'); /* - */ queue_c = 1; } if (!(oldmode.mode & MODE_ONLYSECURE) && (chptr->mode.mode & MODE_ONLYSECURE)) kick_insecure_users(chptr); /* Add single char modes... */ for (acp = cFlagTab; acp->mode; acp++) { if ((oldmode.mode & acp->mode) && !(chptr->mode.mode & acp->mode) && !acp->parameters) { Addsingle(acp->flag); } } if (b > 1) { Addsingle('+'); } else { strlcpy(modebuf, "+", sizeof modebuf); b = 1; } if (queue_s) Addsingle('s'); if (queue_c) Addsingle('c'); for (acp = cFlagTab; acp->mode; acp++) { if (!(oldmode.mode & acp->mode) && (chptr->mode.mode & acp->mode) && !acp->parameters) { Addsingle(acp->flag); } } /* first we check if it has been set, we did unset longer up */ if (!oldmode.limit && chptr->mode.limit) { Addit('l', (char *)my_itoa(chptr->mode.limit)); } if (!oldmode.key[0] && chptr->mode.key[0]) { Addit('k', chptr->mode.key); } if (!oldmode.link[0] && chptr->mode.link[0]) { Addit('L', chptr->mode.link); }#ifdef NEWCHFLOODPROT if (chptr->mode.floodprot && !oldmode.floodprot) { char *x = channel_modef_string(chptr->mode.floodprot); Addit('f', x); }#else if (!(oldmode.msgs || oldmode.per || oldmode.kmode) && (chptr->mode.msgs || chptr->mode.per || chptr->mode.kmode)) { ircsprintf(modeback, "%s%i:%i", (chptr->mode.kmode == 1 ? "*" : ""), chptr->mode.msgs, chptr->mode.per); Addit('f', modeback); }#endif#ifdef EXTCMODE /* Now, check if they have something we don't have.. * note that: oldmode.* = us, chptr->mode.* = them. */ for (i=0; i <= Channelmode_highest; i++) { if ((Channelmode_Table[i].flag) && !(oldmode.extmode & Channelmode_Table[i].mode) && (chptr->mode.extmode & Channelmode_Table[i].mode)) { if (Channelmode_Table[i].paracount) { char *parax = Channelmode_Table[i].get_param(extcmode_get_struct(chptr->mode.extmodeparam,Channelmode_Table[i].flag)); Addit(Channelmode_Table[i].flag, parax); } else { Addsingle(Channelmode_Table[i].flag); } } }#endif /* now, if we had diffent para modes - this loop really could be done better, but */ /* do we have an difference? */ if (oldmode.limit && chptr->mode.limit && (oldmode.limit != chptr->mode.limit)) { chptr->mode.limit = MAX(oldmode.limit, chptr->mode.limit); if (oldmode.limit != chptr->mode.limit) { Addit('l', (char *)my_itoa(chptr->mode.limit)); } } /* sketch, longest key wins */ if (oldmode.key[0] && chptr->mode.key[0] && strcmp(oldmode.key, chptr->mode.key)) { if (strcmp(oldmode.key, chptr->mode.key) > 0) { strlcpy(chptr->mode.key, oldmode.key, sizeof chptr->mode.key); } else { Addit('k', chptr->mode.key); } } /* same as above (except case insensitive #test == #TEST -- codemastr) */ if (oldmode.link[0] && chptr->mode.link[0] && stricmp(oldmode.link, chptr->mode.link)) { if (strcmp(oldmode.link, chptr->mode.link) > 0) { strlcpy(chptr->mode.link, oldmode.link, sizeof(chptr->mode.link)); } else { Addit('L', chptr->mode.link); } } /* * run a max on each? */#ifdef NEWCHFLOODPROT if (chptr->mode.floodprot && oldmode.floodprot) { char *x; int i; if (compare_floodprot_modes(chptr->mode.floodprot, oldmode.floodprot)) { chptr->mode.floodprot->per = MAX(chptr->mode.floodprot->per, oldmode.floodprot->per); for (i=0; i < NUMFLD; i++) { chptr->mode.floodprot->l[i] = MAX(chptr->mode.floodprot->l[i], oldmode.floodprot->l[i]); chptr->mode.floodprot->a[i] = MAX(chptr->mode.floodprot->a[i], oldmode.floodprot->a[i]); chptr->mode.floodprot->r[i] = MAX(chptr->mode.floodprot->r[i], oldmode.floodprot->r[i]); } x = channel_modef_string(chptr->mode.floodprot); Addit('f', x); } }#else if ((oldmode.kmode != chptr->mode.kmode) || (oldmode.msgs != chptr->mode.msgs) || (oldmode.per != chptr->mode.per)) { chptr->mode.kmode = MAX(chptr->mode.kmode, oldmode.kmode); chptr->mode.msgs = MAX(chptr->mode.msgs, oldmode.msgs); chptr->mode.per = MAX(chptr->mode.per, oldmode.per); if ((oldmode.kmode != chptr->mode.kmode) || (oldmode.msgs != chptr->mode.msgs) || (oldmode.per != chptr->mode.per)) { ircsprintf(modeback, "%s%i:%i", (chptr->mode.kmode == 1 ? "*" : ""), chptr->mode.msgs, chptr->mode.per); Addit('f', modeback); } }#endif#ifdef EXTCMODE /* Now, check for any param differences in extended channel modes.. * note that: oldmode.* = us, chptr->mode.* = them. * if we win: copy oldmode to chptr mode, if they win: send the mode */ for (i=0; i <= Channelmode_highest; i++) { if (Channelmode_Table[i].flag && Channelmode_Table[i].paracount && (oldmode.extmode & Channelmode_Table[i].mode) && (chptr->mode.extmode & Channelmode_Table[i].mode)) { int r; char *parax; CmodeParam *ourm = extcmode_get_struct(oldmode.extmodeparam,Channelmode_Table[i].flag); CmodeParam *theirm = extcmode_get_struct(chptr->mode.extmodeparam, Channelmode_Table[i].flag); r = Channelmode_Table[i].sjoin_check(chptr, ourm, theirm); switch (r) { case EXSJ_WEWON: { CmodeParam *r; parax = Channelmode_Table[i].get_param(ourm); Debug((DEBUG_DEBUG, "sjoin: we won: '%s'", parax)); r = Channelmode_Table[i].put_param(theirm, parax); if (r != theirm) /* confusing eh ;) */ AddListItem(r, chptr->mode.extmodeparam); break; } case EXSJ_THEYWON: parax = Channelmode_Table[i].get_param(theirm); Debug((DEBUG_DEBUG, "sjoin: they won: '%s'", parax)); Addit(Channelmode_Table[i].flag, parax); break; case EXSJ_SAME: Debug((DEBUG_DEBUG, "sjoin: equal")); break; default: ircd_log(LOG_ERROR, "channel.c:m_sjoin:param diff checker: got unk. retval 0x%x??", r); break; } } }#endif Addsingle('\0'); if (modebuf[1]) { sendto_serv_butone_sjoin(cptr, ":%s MODE %s %s %s %lu", sptr->name, chptr->chname, modebuf, parabuf, chptr->creationtime); sendto_channel_butserv(chptr, sptr, ":%s MODE %s %s %s", sptr->name, chptr->chname, modebuf, parabuf); }#ifdef EXTCMODE /* free the oldmode.* crap :( */ extcmode_free_paramlist(oldmode.extmodeparam); oldmode.extmodeparam = NULL; /* just to be sure ;) */#endif#ifdef NEWCHFLOODPROT /* and the oldmode.floodprot struct too... :/ */ if (oldmode.floodprot) { free(oldmode.floodprot); oldmode.floodprot = NULL; }#endif } /* we should be synched by now, */ if (oldts != -1) if (oldts != chptr->creationtime) sendto_channel_butserv(chptr, &me, ":%s NOTICE %s :*** Notice -- TS for %s changed from %ld to %ld", me.name, chptr->chname, chptr->chname, oldts, chptr->creationtime); strlcpy(parabuf, "", sizeof parabuf); for (i = 2; i <= (parc - 2); i++) { if (!parv[i]) { sendto_ops("Got null parv in SJ3 code"); continue; } strlcat(parabuf, parv[i], sizeof parabuf); if (((i + 1) <= (parc - 2))) strlcat(parabuf, " ", sizeof parabuf); } if (!chptr->users) { sub1_from_channel(chptr); return -1; } /* This sends out to SJ3 servers .. */ Debug((DEBUG_DEBUG, "Sending '%li %s :%s' to sj3-!sjb64", ts, parabuf, parv[parc - 1])); sendto_serv_butone_token_opt(cptr, OPT_SJOIN | OPT_SJ3 | OPT_NOT_SJB64, sptr->name, MSG_SJOIN, TOK_SJOIN, "%li %s :%s", ts, parabuf, parv[parc - 1]); Debug((DEBUG_DEBUG, "Sending '%B %s :%s' to sj3-sjb64", (long)ts, parabuf, parv[parc - 1])); sendto_serv_butone_token_opt(cptr, OPT_SJOIN | OPT_SJ3 | OPT_SJB64, sptr->name, MSG_SJOIN, TOK_SJOIN, "%B %s :%s", (long)ts, parabuf, parv[parc - 1]); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -