X-Git-Url: https://jfr.im/git/irc/quakenet/newserv.git/blobdiff_plain/3509b442ae56c07f78db2070da696d8a8ba12de2..78fdeaf6a300fd4b0a7a06987f712a3ecdd104d3:/chanserv/chanservuser.c diff --git a/chanserv/chanservuser.c b/chanserv/chanservuser.c index 00d780b5..04280500 100644 --- a/chanserv/chanservuser.c +++ b/chanserv/chanservuser.c @@ -40,7 +40,7 @@ void chanservreguser(void *arg) { csuser=getcopyconfigitem("chanserv","user","TheQBot",USERLEN); cshost=getcopyconfigitem("chanserv","host","some.host",HOSTLEN); csrealname=getcopyconfigitem("chanserv","realname","ChannelService",REALLEN); - csaccount=getcopyconfigitem("chanserv","account",csnick&&csnick->content&&csnick->content[0]?csnick->content:"Q",ACCOUNTLEN); + csaccount=getcopyconfigitem("chanserv","account",csnick&&csnick->content[0]?csnick->content:"Q",ACCOUNTLEN); Error("chanserv",ERR_INFO,"Connecting %s...",csnick->content); @@ -174,6 +174,20 @@ void chanservuserhandler(nick *target, int message, void **params) { break; } + if ((cmd->level & QCMD_ACHIEVEMENTS) && !UIsDev(rup) && + ((time(NULL) < ACHIEVEMENTS_START) || + ((time(NULL) > ACHIEVEMENTS_END) && !UIsAchievements(rup)))) { + chanservstdmessage(sender, QM_UNKNOWNCMD, cargv[0]); + break; + } + + if ((cmd->level & QCMD_TITLES) && !UIsDev(rup) && + ((time(NULL) < ACHIEVEMENTS_START) || + (time(NULL) > ACHIEVEMENTS_END))) { + chanservstdmessage(sender, QM_UNKNOWNCMD, cargv[0]); + break; + } + cmd->calls++; if (cmd->maxparams < (cargc-1)) { @@ -182,6 +196,8 @@ void chanservuserhandler(nick *target, int message, void **params) { } cmd->handler((void *)sender, cargc-1, &(cargv[1])); + + triggerhook(HOOK_CHANSERV_CMD, sender); } break; @@ -522,7 +538,7 @@ void chanservkillstdmessage(nick *target, int messageid, ... ) { va_start(va, messageid); q9vsnprintf(buf, 511, message, messageargs, va); va_end(va); - killuser(chanservnick, target, buf); + killuser(chanservnick, target, "%s", buf); } int checkpassword(reguser *rup, const char *pass) { @@ -768,7 +784,15 @@ void cs_doallautomodes(nick *np) { if ((lp=getnumerichandlefromchanhash(rcup->chan->index->channel->users, np->numeric))) { /* User is on channel.. */ - if (CUKnown(rcup) && rcup->chan->index->channel->users->totalusers >= 3) { + /* Update last use time. Do early in case of ban. */ + rcup->usetime=getnettime(); + + if (CUIsBanned(rcup)) { + cs_banuser(NULL, rcup->chan->index, np, NULL); + continue; + } + + if (CUHasOpPriv(rcup) && cs_ischannelactive(rcup->chan->index->channel, NULL)) { /* This meets the channel use criteria, update. */ rcup->chan->lastactive=time(NULL); @@ -779,9 +803,6 @@ void cs_doallautomodes(nick *np) { } } - /* Update last use time */ - rcup->usetime=getnettime(); - localsetmodeinit(&changes, rcup->chan->index->channel, chanservnick); if (*lp & CUMODE_OP) { if (!IsService(np) && (CUIsDeny(rcup) || (CIsBitch(rcup->chan) && !CUHasOpPriv(rcup)))) @@ -806,11 +827,16 @@ void cs_doallautomodes(nick *np) { } else { /* Channel exists but user is not joined: invite if they are +j-b */ if (CUIsAutoInvite(rcup) && CUKnown(rcup) && !CUIsBanned(rcup)) { - localinvite(chanservnick, rcup->chan->index->channel, np); + localinvite(chanservnick, rcup->chan->index, np); } } - } - } + } /* if (rcup->chan->index->channel) */ else { + /* Channel doesn't currently exist - send invite anyway for +j */ + if (CUIsAutoInvite(rcup) && CUKnown(rcup) && !CUIsBanned(rcup)) { + localinvite(chanservnick, rcup->chan->index, np); + } + } + } /* for */ } void cs_checknickbans(nick *np) { @@ -828,7 +854,7 @@ void cs_checknickbans(nick *np) { for (j=0;jindex->exts[chanservext]) && !CIsSuspended(rcp) && - CIsEnforce(rcp) && nickbanned_visible(np, ca[j])) + CIsEnforce(rcp) && nickbanned(np, ca[j], 1)) localkickuser(chanservnick, ca[j], np, "Banned."); } @@ -869,8 +895,8 @@ void cs_checkbans(channel *cp) { for (rbp=rcp->bans;rbp;rbp=rbp->next) { if (((!rbp->expiry) || (rbp->expiry <= now)) && - nickmatchban_visible(np, rbp->cbp)) { - if (!nickbanned_visible(np, cp)) { + nickmatchban(np, rbp->cbp, 1)) { + if (!nickbanned(np, cp, 1)) { localdosetmode_ban(&changes, bantostring(rbp->cbp), MCB_ADD); } localkickuser(chanservnick,cp,np,rbp->reason?rbp->reason->content:"Banned."); @@ -883,7 +909,7 @@ void cs_checkbans(channel *cp) { if (CIsEnforce(rcp)) { for (cbp=cp->bans;cbp;cbp=cbp->next) { - if ((cbp->timeset>=rcp->lastbancheck) && nickmatchban_visible(np, cbp)) + if ((cbp->timeset>=rcp->lastbancheck) && nickmatchban(np, cbp, 1)) localkickuser(chanservnick,cp,np,"Banned."); } rcp->lastbancheck=time(NULL); @@ -1105,7 +1131,16 @@ int cs_removechannelifempty(nick *sender, regchan *rcp) { return 0; } } - + + /* + * don't cleanup the last channel to prevent channel id reuse. + * the channel will be orphaned but will be cleaned up by cleanup eventually + */ + if(rcp->ID == lastchannelID) { + cs_log(sender,"DELCHAN FAILED %s (last id)",rcp->index->name->content); + return 0; + } + cs_log(sender,"DELCHAN %s (Empty)",rcp->index->name->content); cs_removechannel(rcp, "Last user removed - channel deleted."); @@ -1166,9 +1201,9 @@ int cs_bancheck(nick *np, channel *cp) { freesstring(rbp->reason); freechanban(rbp->cbp); freeregban(rbp); - } else if (nickmatchban_visible(np,(*rbh)->cbp)) { + } else if (nickmatchban(np,(*rbh)->cbp,1)) { /* This user matches this ban.. */ - if (!nickbanned_visible(np,cp)) { + if (!nickbanned(np,cp,1)) { /* Only bother putting the ban on the channel if they're not banned already */ /* (might be covered by this ban or a different one.. doesn't really matter */ localsetmodeinit(&changes, cp, chanservnick); @@ -1202,7 +1237,7 @@ void cs_setregban(chanindex *cip, regban *rbp) { if (cip->channel->users->content[i]!=nouser && (np=getnickbynumeric(cip->channel->users->content[i])) && !IsService(np) && !IsOper(np) && !IsXOper(np) && - nickmatchban_visible(np, rbp->cbp)) + nickmatchban(np, rbp->cbp, 1)) localkickuser(chanservnick, cip->channel, np, rbp->reason ? rbp->reason->content : "Banned."); } @@ -1216,7 +1251,7 @@ void cs_banuser(modechanges *changes, chanindex *cip, nick *np, const char *reas if (!cip->channel) return; - if (nickbanned_visible(np, cip->channel)) { + if (nickbanned(np, cip->channel, 1)) { localkickuser(chanservnick, cip->channel, np, reason?reason:"Banned."); return; } @@ -1342,7 +1377,7 @@ reguser *findreguser(nick *sender, const char *str) { * * Return 0 if it works, 1 if it don't. */ -int cs_unbanfn(nick *sender, chanindex *cip, UnbanFN fn, void *arg, int removepermbans, int abortonfailure) { +int cs_unbanfn(nick *sender, chanindex *cip, int (*fn)(void *arg, struct chanban *ban), void *arg, int removepermbans, int abortonfailure) { regban **rbh, *rbp; chanban **cbh, *cbp; regchan *rcp; @@ -1418,3 +1453,98 @@ int checkreason(nick *np, char *reason) { return 1; } + +regchan *cs_addchan(chanindex *cip, nick *sender, reguser *addedby, reguser *founder, flag_t flags, flag_t forcemodes, flag_t denymodes, short type) { + regchan *rcp; + regchanuser *rcup; + void *args[3]; + int i; + + if (cip->exts[chanservext]) + return NULL; + + /* Initialise the channel */ + rcp=getregchan(); + + /* ID, index */ + rcp->ID=++lastchannelID; + rcp->index=cip; + cip->exts[chanservext]=rcp; + + rcp->chantype=type; + rcp->flags=flags; + rcp->status=0; + rcp->bans=NULL; + rcp->lastcountersync=0; + + rcp->limit=0; + rcp->forcemodes=forcemodes; + rcp->denymodes=denymodes; + + if (CIsAutoLimit(rcp)) { + rcp->forcemodes |= CHANMODE_LIMIT; + } + + rcp->autolimit=5; + rcp->banstyle=0; + + rcp->created=rcp->lastactive=rcp->statsreset=rcp->ostatsreset=time(NULL); + rcp->banduration=0; + rcp->autoupdate=0; + rcp->lastbancheck=0; + + /* Added by */ + rcp->addedby=addedby->ID; + + /* Founder */ + rcp->founder=founder->ID; + + /* Suspend by */ + rcp->suspendby=0; + rcp->suspendtime=0; + + rcp->totaljoins=rcp->tripjoins=rcp->otripjoins=rcp->maxusers=rcp->tripusers=rcp->otripusers=0; + rcp->welcome=rcp->topic=rcp->key=rcp->suspendreason=rcp->comment=NULL; + + /* Users */ + memset(rcp->regusers,0,REGCHANUSERHASHSIZE*sizeof(reguser *)); + + rcp->checksched=NULL; + rcp->ltimestamp=0; + for (i=0;ichanopnicks[i][0]='\0'; + rcp->chanopaccts[i]=0; + } + rcp->chanoppos=0; + + /* Add new channel to db.. */ + csdb_createchannel(rcp); + + /* Add the founder as +ano */ + rcup=getregchanuser(); + rcup->chan=rcp; + rcup->user=founder; + rcup->flags=(QCUFLAG_OWNER | QCUFLAG_OP | QCUFLAG_AUTOOP); + rcup->usetime=0; + rcup->info=NULL; + rcup->changetime=time(NULL); + + addregusertochannel(rcup); + csdb_createchanuser(rcup); + csdb_chanlevhistory_insert(rcp, sender, rcup->user, 0, rcup->flags); + + args[0]=sender; + args[1]=rcup; + args[2]=(void *)0; + + triggerhook(HOOK_CHANSERV_CHANLEVMOD, args); + + /* If the channel exists, get the ball rolling */ + if (cip->channel) { + chanservjoinchan(cip->channel); + rcp->status |= QCSTAT_MODECHECK | QCSTAT_OPCHECK | QCSTAT_BANCHECK; + cs_timerfunc(cip); + } + + return rcp; +}