Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Farpoint Internet Relay Chat Daemon, src/modules/m_roleplay.c
- * (C) 2005 William E. Donges III and the FarpointIRCd Team
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /* RPG commands originally coded by falerin.
- * Conversion to module usable by standard UnrealIRCd daemons by aquanight.
- */
- #include "config.h"
- #include "struct.h"
- #include "common.h"
- #include "sys.h"
- #include "numeric.h"
- #include "msg.h"
- #include "channel.h"
- #include <time.h>
- #include <sys/stat.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #ifdef _WIN32
- #include <io.h>
- #endif
- #include <fcntl.h>
- #include "h.h"
- #ifdef STRIPBADWORDS
- #include "badwords.h"
- #endif
- #include "proto.h"
- #ifdef _WIN32
- #include "version.h"
- #endif
- DLLFUNC int m_roleplay(aClient *cptr, aClient *sptr, int parc, char *parv[], int notice);
- DLLFUNC int m_ambiance(aClient *cptr, aClient *sptr, int parc, char *parv[]);
- DLLFUNC int m_npc(aClient *cptr, aClient *sptr, int parc, char *parv[]);
- DLLFUNC int m_npca(aClient *cptr, aClient *sptr, int parc, char *parv[]);
- DLLFUNC int m_fsay(aClient *cptr, aClient *sptr, int parc, char *parv[]);
- DLLFUNC int m_faction(aClient *cptr, aClient *sptr, int parc, char *parv[]);
- /* Place includes here */
- #define MSG_AMBIANCE "AMBIANCE"
- #define TOK_AMBIANCE "FA"
- #define MSG_NPC "NPC"
- #define TOK_NPC "FB"
- #define MSG_NPCA "NPCA"
- #define TOK_NPCA "FC"
- #define MSG_FSAY "FSAY"
- #define TOK_FSAY "FD"
- #define MSG_FACTION "FACTION"
- #define TOK_FACTION "FE"
- /* #define CanFSay(who) (IsULine((who)) || op_can_override((who)) || IsSAdmin((who))) */
- #define CanFSay(who) (IsAnOper((who)))
- ModuleHeader MOD_HEADER(m_roleplay)
- = {
- "roleplay",/* Name of module */
- "$Id: m_roleplay.c,v 2.1 2006/05/17 17:43:50 falerin/aquanight Exp $", /* Version */
- "roleplaying commands", /* Short description of module */
- "3.2-b8-1",
- NULL
- };
- /* This is called on module init, before Server Ready */
- DLLFUNC int MOD_INIT(m_roleplay)(ModuleInfo *modinfo)
- {
- /*
- * We call our add_Command crap here
- */
- add_CommandX(MSG_AMBIANCE, TOK_AMBIANCE, m_ambiance, 3, M_USER|M_SERVER|M_RESETIDLE);
- add_Command(MSG_NPC, TOK_NPC, m_npc, 3);
- add_Command(MSG_NPCA, TOK_NPCA, m_npca, 3);
- add_Command(MSG_FSAY, TOK_FSAY, m_fsay, 3);
- add_Command(MSG_FACTION, TOK_FACTION, m_faction, 3);
- return MOD_SUCCESS;
- }
- /* Is first run when server is 100% ready */
- DLLFUNC int MOD_LOAD(m_roleplay)(int module_load)
- {
- return MOD_SUCCESS;
- }
- /* Called when module is unloaded */
- DLLFUNC int MOD_UNLOAD(m_roleplay)(int module_unload)
- {
- if (del_Command(MSG_AMBIANCE, TOK_AMBIANCE, m_ambiance) < 0) {
- sendto_realops("Failed to delete command ambiance when unloading %s", MOD_HEADER(m_roleplay).name);
- }
- if (del_Command(MSG_NPC, TOK_NPC, m_npc) < 0) {
- sendto_realops("Failed to delete command npc when unloading %s", MOD_HEADER(m_roleplay).name);
- }
- if (del_Command(MSG_NPCA, TOK_NPCA, m_npca) < 0) {
- sendto_realops("Failed to delete command npca when unloading %s", MOD_HEADER(m_roleplay).name);
- }
- if (del_Command(MSG_FSAY, TOK_FSAY, m_fsay) < 0) {
- sendto_realops("Failed to delete command fsay when unloading %s", MOD_HEADER(m_roleplay).name);
- }
- if (del_Command(MSG_FACTION, TOK_FACTION, m_faction) < 0) {
- sendto_realops("Failed to delete command faction when unloading %s", MOD_HEADER(m_roleplay).name);
- }
- return MOD_SUCCESS;
- }
- static char tcmd[2048];
- static char ccmd[2048];
- static char xcmd[2048];
- static char wcmd[2048];
- static int sentalong[MAXCONNECTIONS];
- static int sentalong_marker;
- #define ADD_CRLF(buf, len) { if (len > 510) len = 510; buf[len++] = '\r'; buf[len++] = '\n'; buf[len] = '\0'; } while(0)
- /* This command handles the roleplaying functions being sent to the channel
- * by appropriately converting to the right PRIVMSG format for each command
- */
- void rpg_sendto_channelprefix_tok(aClient *one, aClient *from, aChannel *chptr, int prefix, char *cmd, char *tok, char *nick, char *npcname, char *text, char do_send_check)
- {
- Member *lp;
- aClient *acptr;
- int i;
- unsigned int tlen, clen,wlen = 0;
- char *p;
- /* For servers with token capability */
- if (!strcmp(cmd, "AMBIANCE"))
- p = ircsprintf(tcmd, ":%s %s %s :%s", from->name, tok, nick, text);
- else
- p = ircsprintf(tcmd, ":%s %s %s %s :%s", from->name, tok, nick, npcname, text);
- tlen = (int)(p - tcmd);
- ADD_CRLF(tcmd, tlen);
- /* For dumb servers without tokens */
- if (!strcmp(cmd, "AMBIANCE"))
- p = ircsprintf(ccmd, ":%s %s %s :%s", from->name, cmd, nick, text);
- else
- p = ircsprintf(ccmd, ":%s %s %s %s :%s", from->name, cmd, nick, npcname, text);
- clen = (int)(p - ccmd);
- ADD_CRLF(ccmd, clen);
- if (!strcmp(cmd, "NPC")) {
- char *chan = strchr(nick, '#'); /* impossible to become NULL? */
- if (IsPerson(from))
- p = ircsprintf(wcmd, ":\037%s\037!%s@RPG.irc %s %s :%s", npcname, from->name, MSG_PRIVATE, chan, text);
- else
- p = ircsprintf(wcmd, ":\037%s\037!Internal@RPG.irc %s %s :%s", npcname, MSG_PRIVATE, chan, text);
- wlen = (int)(p - wcmd);
- ADD_CRLF(wcmd, wlen);
- } else if (!strcmp(cmd, "NPCA")) {
- char *chan = strchr(nick, '#'); /* impossible to become NULL? */
- if (IsPerson(from))
- p = ircsprintf(wcmd, ":\037%s\037!%s@RPG.irc %s %s :\1ACTION %s\1", npcname, from->name, MSG_PRIVATE, chan, text);
- else
- p = ircsprintf(wcmd, ":\037%s\037!Internal@RPG.irc %s %s :\1ACTION %s\1", npcname, MSG_PRIVATE, chan, text);
- wlen = (int)(p - wcmd);
- ADD_CRLF(wcmd, wlen);
- } else if (!strcmp(cmd, "FSAY")) {
- char *chan = strchr(nick, '#'); /* impossible to become NULL? */
- if (IsPerson(from))
- p = ircsprintf(wcmd, ":%s!%s@RPG.irc %s %s :%s", npcname, from->name, MSG_PRIVATE, chan, text);
- else
- p = ircsprintf(wcmd, ":%s!Internal@RPG.irc %s %s :%s", npcname, MSG_PRIVATE, chan, text);
- wlen = (int)(p - wcmd);
- ADD_CRLF(wcmd, wlen);
- } else if (!strcmp(cmd, "FACTION")) {
- char *chan = strchr(nick, '#'); /* impossible to become NULL? */
- if (IsPerson(from))
- p = ircsprintf(wcmd, ":%s!%s@RPG.irc %s %s :\1ACTION %s\1", npcname, from->name, MSG_PRIVATE, chan, text);
- else
- p = ircsprintf(wcmd, ":%s!Internal@RPG.irc %s %s :\1ACTION %s\1", npcname, MSG_PRIVATE, chan, text);
- wlen = (int)(p - wcmd);
- ADD_CRLF(wcmd, wlen);
- } else {
- char *chan = strchr(nick, '#'); /* impossible to become NULL? */
- if (IsPerson(from))
- p = ircsprintf(wcmd, ":>Ambiance<!%s@RPG.irc %s %s :%s", from->name, MSG_PRIVATE, chan, text);
- else
- p = ircsprintf(wcmd, ":>Ambiance<!Internal@RPG.irc %s %s :%s", MSG_PRIVATE, chan, text);
- wlen = (int)(p - wcmd);
- ADD_CRLF(wcmd, wlen);
- }
- ++sentalong_marker;
- for (lp = chptr->members; lp; lp = lp->next)
- {
- acptr = lp->cptr;
- if (prefix == PREFIX_ALL)
- goto good;
- if ((prefix & PREFIX_HALFOP) && (lp->flags & CHFL_HALFOP))
- goto good;
- if ((prefix & PREFIX_VOICE) && (lp->flags & CHFL_VOICE))
- goto good;
- if ((prefix & PREFIX_OP) && (lp->flags & CHFL_CHANOP))
- goto good;
- #ifdef PREFIX_AQ
- if ((prefix & PREFIX_ADMIN) && (lp->flags & CHFL_CHANPROT))
- goto good;
- if ((prefix & PREFIX_OWNER) && (lp->flags & CHFL_CHANOWNER))
- goto good;
- #endif
- continue;
- good:
- i = acptr->from->slot;
- if (IsDeaf(acptr) && !sendanyways)
- continue;
- if (MyConnect(acptr) && IsRegisteredUser(acptr)) {
- sendbufto_one(acptr, wcmd, wlen);
- sentalong[i] = sentalong_marker;
- }
- else {
- /* Now check whether a message has been sent to this
- * remote link already */
- if (sentalong[i] != sentalong_marker) {
- if (IsToken(acptr->from))
- sendbufto_one(acptr, tcmd, tlen);
- else
- sendbufto_one(acptr, ccmd, clen);
- sentalong[i] = sentalong_marker;
- }
- }
- }
- return;
- }
- /*
- ** m_roleplay (used in m_ambiance() and m_npc, m_npca, m_fsay, m_faction)
- ** the general function to deliver roleplaying commands
- **
- ** parv[0] = sender prefix
- ** parv[1] = receiver list
- ** parv[2] = message text
- **
- ** massive cleanup
- ** rev argv 6/91
- **
- */
- static int recursive_webtv = 0;
- DLLFUNC int m_roleplay(aClient *cptr, aClient *sptr, int parc, char *parv[], int notice)
- {
- aClient *acptr;
- char *s;
- aChannel *chptr;
- char *nick, *npcname, *server, *p, *cmd, *cmdtok, *ctcp, *p2, *pc, *text;
- int cansend = 0;
- int prefix = 0;
- char pfixchan[CHANNELLEN + 32];
- int n;
- if (IsHandshake(sptr))
- return 0;
- if (notice == 1) {
- cmd = MSG_NPC;
- cmdtok = TOK_NPC;
- } else if (notice == 2) {
- cmd = MSG_NPCA;
- cmdtok = TOK_NPCA;
- } else if (notice == 3) {
- cmd = MSG_FSAY;
- cmdtok = TOK_FSAY;
- } else if (notice == 4) {
- cmd = MSG_FACTION;
- cmdtok = TOK_FACTION;
- } else {
- cmd = MSG_AMBIANCE;
- cmdtok = TOK_AMBIANCE;
- }
- if (parc < 2 || *parv[1] == '\0') {
- sendto_one(sptr, err_str(ERR_NORECIPIENT), me.name, parv[0], cmd);
- return -1;
- }
- if (parc < 3 || *parv[2] == '\0') {
- sendto_one(sptr, err_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
- return -1;
- }
- if ((*cmd == 'N' || *cmd == 'F') && (parc < 4 || *parv[3] == '\0')) {
- sendto_one(sptr, err_str(ERR_NOTEXTTOSEND), me.name, parv[0]);
- return -1;
- }
- if (MyConnect(sptr))
- parv[1] = (char *)canonize(parv[1]);
- for (p = NULL, nick = strtoken(&p, parv[1], ","); nick; nick = strtoken(&p, NULL, ",")) {
- /*
- ** nickname addressed?
- */
- /* OK, WHY would someone use an RPG command to target the psuedo IRC(d) clients?!
- * Let 'em use PRIVMSG like the rest of us...
- */
- if (*nick != '#') {
- sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], nick);
- return -1;
- }
- p2 = (char *)strchr(nick, '#');
- prefix = 0;
- if (p2 && (chptr = find_channel(p2, NullChn))) {
- if (p2 != nick) {
- int len = 0;
- for (pc = nick; pc != p2; pc++) {
- #ifdef PREFIX_AQ
- #define PREFIX_REST (PREFIX_ADMIN|PREFIX_OWNER)
- #else
- #define PREFIX_REST (0)
- #endif
- switch (*pc) {
- case '+':
- if (!(prefix & PREFIX_VOICE))
- prefix |= PREFIX_VOICE | PREFIX_HALFOP | PREFIX_OP | PREFIX_REST;
- break;
- case '%':
- if (!(prefix & PREFIX_HALFOP))
- prefix |= PREFIX_HALFOP | PREFIX_OP | PREFIX_REST;
- break;
- case '@':
- #ifndef PREFIX_AQ
- case '&':
- case '~':
- #endif
- if (!(prefix & PREFIX_OP))
- prefix |= PREFIX_OP | PREFIX_REST;
- break;
- #ifdef PREFIX_AQ
- case '&':
- if (!(prefix & PREFIX_ADMIN))
- prefix |= PREFIX_ADMIN | PREFIX_OWNER;
- break;
- case '~':
- if (!(prefix & PREFIX_OWNER))
- prefix |= PREFIX_OWNER;
- break;
- #endif
- default:
- break;/* ignore it :P */
- }
- }
- if (prefix) {
- /* Since we're about to later assert that the user is a chanop (or is
- * sufficiently privileged enough that he can be one anyway)...
- * skip unreal's normal prefix privilege checks.
- */
- /* Now find out the lowest prefix and use that.. (so @&~#chan becomes @#chan) */
- if (prefix & PREFIX_VOICE)
- pfixchan[0] = '+';
- else if (prefix & PREFIX_HALFOP)
- pfixchan[0] = '%';
- else if (prefix & PREFIX_OP)
- pfixchan[0] = '@';
- #ifdef PREFIX_AQ
- else if (prefix & PREFIX_ADMIN)
- pfixchan[0] = '&';
- else if (prefix & PREFIX_OWNER)
- pfixchan[0] = '~';
- #endif
- else
- abort();
- }
- pfixchan[len] = '\0';
- strlcat(pfixchan, p2, sizeof(pfixchan));
- nick = pfixchan;
- }
- if (!MyClient(sptr) || CanFSay(sptr) || is_chan_op(sptr, chptr) || is_half_op(sptr, chptr)) {
- Hook *tmphook;
- #ifdef NEWCHFLOODPROT
- if (chptr->mode.floodprot && chptr->mode.floodprot->l[FLD_TEXT])
- #else
- if (chptr->mode.per)
- #endif
- if (check_for_chan_flood(cptr, sptr, chptr) == 1)
- continue;
- if (!CHANCMDPFX) {
- if (cmd == MSG_NPC || cmd == MSG_NPCA || cmd == MSG_FACTION || cmd == MSG_FSAY)
- sendanyways = (parv[3][0] == '`' ? 1 : 0);
- else
- sendanyways = (parv[2][0] == '`' ? 1 : 0);
- } else {
- if (cmd == MSG_NPC || cmd == MSG_NPCA || cmd == MSG_FACTION || cmd == MSG_FSAY)
- sendanyways = (strchr(CHANCMDPFX,parv[3][0]) ? 1 : 0);
- else
- sendanyways = (strchr(CHANCMDPFX,parv[2][0]) ? 1 : 0);
- }
- if (cmd == MSG_NPC || cmd == MSG_NPCA || cmd == MSG_FACTION || cmd == MSG_FSAY)
- text = parv[3];
- else
- text = parv[2];
- if (cmd == MSG_NPC || cmd == MSG_NPCA || cmd == MSG_FACTION || cmd == MSG_FSAY) {
- npcname = parv[2];
- if (strchr(npcname, '!') || strchr(npcname, 31) || strchr(npcname, 15) || strchr(npcname, 3) || strchr(npcname, '@')) {
- /* Clients get thrown off royally by these. Don't allow them. */
- sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name, parv[0], npcname, "Illegal character");
- return -1;
- }
- } else
- npcname = parv[0];
- if (MyClient(sptr)) {
- #if defined(UNREAL_VERSION_GENERATION) && (UNREAL_VERSION_GENERATION > 3 || (UNREAL_VERSION_GENERATION == 3 && defined(UNREAL_VERSION_MAJOR) && (UNREAL_VERSION_MAJOR > 2 || (UNREAL_VERSION_MAJOR == 2 && defined(UNREAL_VERSION_MINOR) && UNREAL_VERSION_MINOR >= 4))))
- n = dospamfilter(sptr, text, notice ? SPAMF_CHANNOTICE : SPAMF_CHANMSG, chptr->chname, 0, NULL);
- #else
- n = dospamfilter(sptr, text, notice ? SPAMF_CHANNOTICE : SPAMF_CHANMSG, chptr->chname);
- #endif
- if (n < 0)
- return n;
- }
- for (tmphook = Hooks[HOOKTYPE_CHANMSG]; tmphook; tmphook = tmphook->next) {
- text = (*(tmphook->func.pcharfunc))(cptr, sptr, chptr, text, notice);
- if (!text)
- break;
- }
- if (!text || !npcname)
- continue;
- rpg_sendto_channelprefix_tok(cptr, sptr, chptr, prefix, cmd, cmdtok, nick, npcname, text, 1);
- #ifdef NEWCHFLOODPROT
- if (chptr->mode.floodprot && !is_skochanop(sptr, chptr) && !IsULine(sptr) && do_chanflood(chptr->mode.floodprot, FLD_MSG) && MyClient(sptr)) {
- do_chanflood_action(chptr, FLD_MSG, "msg/notice");
- }
- if (chptr->mode.floodprot && !is_skochanop(sptr, chptr) && (text[0] == '\001') && strncmp(text+1, "ACTION ", 7) && do_chanflood(chptr->mode.floodprot, FLD_CTCP) && MyClient(sptr)) {
- do_chanflood_action(chptr, FLD_CTCP, "CTCP");
- }
- #endif
- sendanyways = 0;
- continue;
- } else if (MyClient(sptr)) {
- sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED), me.name, parv[0], chptr->chname);
- }
- continue;
- } else {
- sendto_one(sptr, err_str(ERR_NOSUCHCHANNEL), me.name, parv[0], nick);
- continue;
- }
- }
- return 0;
- }
- /*
- ** m_ambiance
- ** parv[0] = sender prefix
- ** parv[1] = receiver list
- ** parv[2] = message text
- */
- DLLFUNC int m_ambiance(aClient *cptr, aClient *sptr, int parc, char *parv[])
- {
- return m_roleplay(cptr, sptr, parc, parv, 0);
- }
- /*
- ** m_npc
- ** parv[0] = sender prefix
- ** parv[1] = receiver list
- ** parv[2] = notice text
- */
- DLLFUNC int m_npc(aClient *cptr, aClient *sptr, int parc, char *parv[])
- {
- return m_roleplay(cptr, sptr, parc, parv, 1);
- }
- /*
- ** m_npca
- ** parv[0] = sender prefix
- ** parv[1] = receiver list
- ** parv[2] = notice text
- */
- DLLFUNC int m_npca(aClient *cptr, aClient *sptr, int parc, char *parv[])
- {
- return m_roleplay(cptr, sptr, parc, parv, 2);
- }
- /*
- ** m_fsay
- ** parv[0] = sender prefix
- ** parv[1] = receiver list
- ** parv[2] = notice text4
- */
- DLLFUNC int m_fsay(aClient *cptr, aClient *sptr, int parc, char *parv[])
- {
- return m_roleplay(cptr, sptr, parc, parv, (!MyClient(sptr) || CanFSay(sptr)) ? 3 : 1);
- }
- /*
- ** m_faction
- ** parv[0] = sender prefix
- ** parv[1] = receiver list44
- ** parv[2] = notice text
- */
- DLLFUNC int m_faction(aClient *cptr, aClient *sptr, int parc, char *parv[])
- {
- return m_roleplay(cptr, sptr, parc, parv, (!MyClient(sptr) || CanFSay(sptr)) ? 4 : 2);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement