Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * m_joinmute.c adds a new channel mode: +J <seconds> which stops
- * users which are not on channel for <seconds> from speaking.
- * (C) 2009 Dvlpr
- *
- * It is my first public module =P
- *
- * See file AUTHORS in IRC package for additional names of
- * the programmers.
- *
- * 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.
- */
- #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 _WIN32
- #include "version.h"
- #endif
- #define DelHook(x) if (x) HookDel(x); x = NULL
- Hook *HookJoin = NULL;
- Hook *HookPart = NULL;
- Hook *HookMessage = NULL;
- Hook *HookQuit = NULL;
- Hook *HookKick = NULL;
- static ModuleInfo *thismodinfo = NULL;
- int cb_part(aClient *cptr, aClient *sptr, aChannel *chptr, char *parv[]);
- int cb_join(aClient *cptr, aClient *sptr, aChannel *chptr, char *parv[]);
- int cb_quit(aClient *sptr, char *comment);
- int cb_kick(aClient *cptr, aClient *sptr, aClient *who, aChannel *chptr, char *comment);
- DLLFUNC char *cb_msg(aClient *, aClient *, aChannel *, char *, int);
- #ifdef HOOKTYPE_REHASH_COMPLETE
- static int cb_rehash_complete();
- Hook *HookRehashDone;
- #endif
- void add_user_to_memory(aClient *sptr, aChannel *chptr);
- typedef struct _channels_users_
- {
- struct _channel_users *prev, *next;
- aClient *source;
- aChannel *chptr;
- int joined_since;
- } UsersM;
- UsersM *muted_users; /* List of data */
- UsersM *FindUserInMemory(aClient *sptr, aChannel *chptr);
- void del_user_from_memory(UsersM *u);
- Cmode_t EXTCMODE_JOINMUTE = 0L;
- typedef struct {
- EXTCM_PAR_HEADER
- int seconds;
- } JoinMute;
- int modeJ_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what);
- CmodeParam * modeJ_put_param(CmodeParam *lst, char *para);
- char *modeJ_get_param(CmodeParam *lst);
- char *modeJ_conv_param(char *param);
- void modeJ_free_param(CmodeParam *lst);
- CmodeParam *modeJ_dup_struct(CmodeParam *src);
- int modeJ_sjoin_check(aChannel *chptr, CmodeParam *ourx, CmodeParam *theirx);
- ModuleHeader MOD_HEADER(m_joinmute)
- = {
- "m_joinmute",
- "$Id: m_joinmute.c,v 0.1 2009/04/16 14:14 $",
- "Adds +J chmode: Join Mute for X seconds",
- "3.2-b8-1",
- NULL
- };
- DLLFUNC int MOD_TEST(m_joinmute)(ModuleInfo *modinfo)
- {
- return MOD_SUCCESS;
- }
- DLLFUNC int MOD_INIT(m_joinmute)(ModuleInfo *modinfo)
- {
- CmodeInfo req;
- thismodinfo = modinfo;
- ModuleSetOptions(modinfo->handle, MOD_OPT_PERM);
- memset(&req, 0, sizeof(req));
- req.paracount = 1;
- req.flag = 'J';
- req.is_ok = modeJ_is_ok;
- req.put_param = modeJ_put_param;
- req.get_param = modeJ_get_param;
- req.conv_param = modeJ_conv_param;
- req.free_param = modeJ_free_param;
- req.dup_struct = modeJ_dup_struct;
- req.sjoin_check = modeJ_sjoin_check;
- CmodeAdd(thismodinfo->handle, req, &EXTCMODE_JOINMUTE);
- return MOD_SUCCESS;
- }
- DLLFUNC int MOD_LOAD(m_joinmute)(int module_load)
- {
- HookJoin = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_JOIN, cb_join);
- HookPart = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_PART, cb_part);
- HookMessage = HookAddPCharEx(thismodinfo->handle, HOOKTYPE_CHANMSG, cb_msg);
- HookQuit = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_QUIT, cb_quit);
- HookKick = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_KICK, cb_kick);
- #ifdef HOOKTYPE_REHASH_COMPLETE
- HookRehashDone = HookAddEx(thismodinfo->handle, HOOKTYPE_REHASH_COMPLETE, cb_rehash_complete);
- #endif
- return MOD_SUCCESS;
- }
- DLLFUNC int MOD_UNLOAD(m_joinmute)(int module_unload)
- {
- DelHook(HookJoin);
- DelHook(HookPart);
- DelHook(HookMessage);
- DelHook(HookQuit);
- #ifdef HOOKTYPE_REHASH_COMPLETE
- DelHook(HookRehashDone);
- #endif
- return MOD_SUCCESS;
- }
- int modeJ_is_ok(aClient *sptr, aChannel *chptr, char *para, int checkt, int what)
- {
- int seconds;
- if(what == MODE_ADD)
- seconds = atoi(para);
- if ((checkt == EXCHK_ACCESS) || (checkt == EXCHK_ACCESS_ERR))
- {
- if (IsPerson(sptr) && is_chan_op(sptr, chptr))
- return EX_ALLOW;
- if (checkt == EXCHK_ACCESS_ERR) /* can only be due to being halfop */
- sendto_one(sptr, err_str(ERR_NOTFORHALFOPS), me.name, sptr->name, 'J');
- return EX_DENY;
- }
- else if (checkt == EXCHK_PARAM)
- {
- if(seconds < 0 || seconds > 65536)
- {
- sendnotice(sptr, "*** [ERROR] Seconds value is out of range!");
- return EX_DENY;
- }
- return EX_ALLOW;
- }
- return 0;
- }
- CmodeParam * modeJ_put_param(CmodeParam *r_in, char *param)
- {
- JoinMute *r = (JoinMute *)r_in;
- int seconds = atoi(param);
- if (!r)
- {
- /* Need to create one */
- r = (JoinMute *)malloc(sizeof(JoinMute));
- memset(r, 0, sizeof(JoinMute));
- r->flag = 'J';
- }
- if(seconds < 0 || seconds > 65536)
- seconds = 0;
- r->seconds = seconds;
- return (CmodeParam *)r;
- }
- char *modeJ_get_param(CmodeParam *r_in)
- {
- JoinMute *r = (JoinMute *)r_in;
- static char retbuf[16];
- if (!r)
- return NULL;
- snprintf(retbuf, sizeof(retbuf), "%d", r->seconds);
- return retbuf;
- }
- char *modeJ_conv_param(char *param_in)
- {
- static char retbuf[32];
- int num = atoi(param_in);
- if(num < 0)
- num = 0;
- else if(num > 65536)
- num = 255;
- else if(!num)
- num = 0;
- snprintf(retbuf, sizeof(retbuf), "%d", num);
- return retbuf;
- }
- void modeJ_free_param(CmodeParam *r)
- {
- JoinMute *n = (JoinMute *)r;
- free(n);
- return;
- }
- CmodeParam *modeJ_dup_struct(CmodeParam *r_in)
- {
- JoinMute *n = (JoinMute *)malloc(sizeof(JoinMute));
- memcpy(n, r_in, sizeof(JoinMute));
- return (CmodeParam *)n;
- }
- int modeJ_sjoin_check(aChannel *chptr, CmodeParam *ourx, CmodeParam *theirx)
- {
- JoinMute *our = (JoinMute *)ourx;
- JoinMute *their = (JoinMute *)theirx;
- if (our->seconds == their->seconds)
- return EXSJ_SAME;
- if (our->seconds > their->seconds) /* Server with more seconds winning */
- return EXSJ_WEWON;
- else
- return EXSJ_THEYWON;
- }
- /** add_user_to_memory
- * Adds user to currently muted users list
- * Allocates the memory for data
- */
- void add_user_to_memory(aClient *sptr, aChannel *chptr)
- {
- UsersM *u = (UsersM *) MyMallocEx(sizeof(UsersM));
- if(!u)
- return;
- u->chptr = chptr;
- u->source = sptr;
- u->joined_since = TStime();
- AddListItem(u, muted_users);
- return;
- }
- /** del_user_from_memory
- * Removes user from currently muted users list
- * Frees the memory allocated for data
- */
- void del_user_from_memory(UsersM *u)
- {
- if(!u)
- return;
- DelListItem(u, muted_users);
- MyFree(u);
- return;
- }
- /** FindUserInMemory
- * Scans through currently muted users
- * to find matching one, if the user is found
- * its pointer will be returned instantly
- */
- UsersM *FindUserInMemory(aClient *sptr, aChannel *chptr)
- {
- UsersM *uz;
- for(uz = muted_users; uz; uz = (UsersM *)uz->next)
- {
- if(!find_client(uz->source->name, NULL))
- {
- del_user_from_memory(uz);
- continue;
- }
- if(!IsMember(uz->source, uz->chptr))
- {
- del_user_from_memory(uz);
- continue;
- }
- if(!(uz->chptr->mode.extmode & EXTCMODE_JOINMUTE))
- {
- del_user_from_memory(uz);
- continue;
- }
- if((uz->source == sptr) && (uz->chptr == chptr))
- return uz;
- }
- return NULL;
- }
- /* Used on quit - just remove all entries with sptr as a user */
- void clear_matching_entries(aClient *sptr)
- {
- UsersM *userz;
- for(userz = muted_users; userz; userz = (UsersM *)userz->next)
- {
- if(userz->source == sptr)
- del_user_from_memory(userz);
- }
- }
- DLLFUNC char *cb_msg(aClient *cptr, aClient *sptr, aChannel *chptr, char *text, int notice)
- {
- JoinMute *para = (JoinMute *)extcmode_get_struct(chptr->mode.extmodeparam, 'J');
- UsersM *u;
- if(!MyClient(sptr))
- return text;
- u = FindUserInMemory(sptr, chptr); /* Let's find entry in muted users list :) */
- /* hops/vops/ops are allowed to send it... */
- if(is_chan_op(sptr, chptr) || is_half_op(sptr, chptr) || has_voice(sptr, chptr) || IsAnOper(sptr))
- return text;
- if(!(chptr->mode.extmode & EXTCMODE_JOINMUTE))
- return text;
- if(!u)
- return text; /* Not found - let it be sent! -- Dvlpr */
- if((TStime() - u->joined_since) > para->seconds) /* How we know if user allowed? we just check if current time - time when user
- * joined the channel is more then seconds and if yes, we allow sending text + deleting
- * user's data from muted users list */
- {
- del_user_from_memory(u);
- return text;
- }
- /* 404! :] -- Dvlpr */
- sendto_one(sptr, ":%s 404 %s %s :Cannot send to channel: you must wait %d seconds after joining"
- " to speak", me.name, sptr->name, chptr->chname, para->seconds);
- return NULL;
- }
- int cb_join(aClient *cptr, aClient *sptr, aChannel *chptr, char *parv[])
- {
- add_user_to_memory(sptr, chptr);
- return HOOK_CONTINUE;
- }
- int cb_part(aClient *cptr, aClient *sptr, aChannel *chptr, char *parv[])
- {
- UsersM *u = FindUserInMemory(sptr, chptr);
- if(!u)
- return HOOK_CONTINUE;
- del_user_from_memory(u);
- return HOOK_CONTINUE;
- }
- int cb_quit(aClient *sptr, char *comment)
- {
- clear_matching_entries(sptr);
- return HOOK_CONTINUE;
- }
- int cb_kick(aClient *cptr, aClient *sptr, aClient *who, aChannel *chptr, char *comment)
- {
- UsersM *u = FindUserInMemory(who, chptr);
- if(!u)
- return HOOK_CONTINUE;
- del_user_from_memory(u);
- return HOOK_CONTINUE;
- }
- #ifdef HOOKTYPE_REHASH_COMPLETE
- static int cb_rehash_complete()
- {
- HookJoin = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_JOIN, cb_join);
- HookPart = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_PART, cb_part);
- HookMessage = HookAddPCharEx(thismodinfo->handle, HOOKTYPE_CHANMSG, cb_msg);
- HookQuit = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_QUIT, cb_quit);
- HookKick = HookAddEx(thismodinfo->handle, HOOKTYPE_LOCAL_KICK, cb_kick);
- return HOOK_CONTINUE;
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement