m_joinmute module

These are old archives. They are kept for historic purposes only.
Post Reply
bosini
Posts: 8
Joined: Sat Jul 24, 2010 12:16 pm

m_joinmute module

Post by bosini »

once uppon a time there was a module called m_joinmute and was very helpfull because it in some way prevents textflood clones/bots/drones to bother much and gives a little time (actually X secs) to chanops/ircops etc to take actions upon them , now i dont know if that module was UnrealIRCD native but i saw many UnrealIRCD servers that uses that. if anyone have any idea where can i find it it would be greatfull . i tried google but i found nothing.

thanks in advance
WordPress rocks phpBB rocks UnrealIRCD rocks but all of them only installed on FreeBSD !!!
katsklaw
Posts: 1124
Joined: Sun Apr 18, 2004 5:06 pm
Contact:

Re: m_joinmute module

Post by katsklaw »

you should check out the channel modes in the helpop system, sounds like mode +j and +f
bosini
Posts: 8
Joined: Sat Jul 24, 2010 12:16 pm

Re: m_joinmute module

Post by bosini »

katsklaw wrote:you should check out the channel modes in the helpop system, sounds like mode +j and +f
oh i checked out but it is not exactly the m_joinmute module makes the new joins not to be able to speak the a channel who has the +J (new chan mode added not to be confused with the +j jointhrottle mode). the +J has a second parameter that is the number of secconds a user cannot speak to the channel for example if you set:

mode #channel +J 10

every user have to wait for 10 seconds before he/she can do anything on that channel privmsgs, notices, actions ctcp etc etc
WordPress rocks phpBB rocks UnrealIRCD rocks but all of them only installed on FreeBSD !!!
katsklaw
Posts: 1124
Joined: Sun Apr 18, 2004 5:06 pm
Contact:

Re: m_joinmute module

Post by katsklaw »

bosini wrote:
katsklaw wrote:you should check out the channel modes in the helpop system, sounds like mode +j and +f
oh i checked out but it is not exactly the m_joinmute module makes the new joins not to be able to speak the a channel who has the +J (new chan mode added not to be confused with the +j jointhrottle mode). the +J has a second parameter that is the number of secconds a user cannot speak to the channel for example if you set:

mode #channel +J 10

every user have to wait for 10 seconds before he/she can do anything on that channel privmsgs, notices, actions ctcp etc etc

Sounds rather nazi'ish to me. After 14 years on IRC I must say I really don't see why this would be a good thing. Perhaps you can share your concerns and see if we can't find a more user friendly solution. :D
Stealth
Head of Support
Posts: 2085
Joined: Tue Jun 15, 2004 8:50 pm
Location: Chino Hills, CA, US
Contact:

Re: m_joinmute module

Post by Stealth »

The module was designed to stop floods where bots/drones/clones would join and immediately start spamming. The best use I have seen this used for is to stop automated flyby spam (join -> spam -> part).

It also assists channel ops when multiple flood bots join giving them a chance to stop the text flood before the joinmute timeout. Sure you can use jointhrottle to stop them, however if there will always be some that still get in (it would be VERY nazi to set +j 1:2 or something such as that to be effective against flooders).

I have the first version of m_joinmute, but I don't know how well it works or if it works at all. I know there were a few versions after the first but I do not know what happened to them.
katsklaw
Posts: 1124
Joined: Sun Apr 18, 2004 5:06 pm
Contact:

Re: m_joinmute module

Post by katsklaw »

That makes sense, I was thinking more like spamfilters, which would take care of the spam part.

My very humble opinion is that channels should be free to take care of channel affairs, including flooder control on their own. Yes, it's cool to have tools such as +RMj and f. To some this module would be yet another tool, it just seems more inconvenient to innocent users than anything. Especially registered users would then have to wait N seconds to say hi back to the channel when they are greeted even though I'm sure the module could exclude +r users. that said, the more stuff that is in the ircd for it to remember is more chance of lag server/network wide. Personally I'd rather have users supply their own eggdrop bot to handle this kinda stuff to keep the resource usage down to insure the ircd/services is fast for everyone. :)
bosini
Posts: 8
Joined: Sat Jul 24, 2010 12:16 pm

Re: m_joinmute module

Post by bosini »

Sounds rather nazi'ish to me. After 14 years on IRC I must say I really don't see why this would be a good thing. Perhaps you can share your concerns and see if we can't find a more user friendly solution. :D
well first of all it prevents malicious users from damaging channels unless someone wishes to keep the channels permamently +M or +m well mostly +m because today ways of flooding can even register a nick so the +m is the mos apropriate.
The module was designed to stop floods where bots/drones/clones would join and immediately start spamming. The best use I have seen this used for is to stop automated flyby spam (join -> spam -> part).

It also assists channel ops when multiple flood bots join giving them a chance to stop the text flood before the joinmute timeout. Sure you can use jointhrottle to stop them, however if there will always be some that still get in (it would be VERY nazi to set +j 1:2 or something such as that to be effective against flooders).

I have the first version of m_joinmute, but I don't know how well it works or if it works at all. I know there were a few versions after the first but I do not know what happened to the
well actually it was designed against the join -> spam -> part kind of flood.if you can in some way send me the version you have it would be very nice of you.
That makes sense, I was thinking more like spamfilters, which would take care of the spam part.

My very humble opinion is that channels should be free to take care of channel affairs, including flooder control on their own. Yes, it's cool to have tools such as +RMj and f. To some this module would be yet another tool, it just seems more inconvenient to innocent users than anything. Especially registered users would then have to wait N seconds to say hi back to the channel when they are greeted even though I'm sure the module could exclude +r users. that said, the more stuff that is in the ircd for it to remember is more chance of lag server/network wide. Personally I'd rather have users supply their own eggdrop bot to handle this kinda stuff to keep the resource usage down to insure the ircd/services is fast for everyone. :)
well you are right , ircds must remain resource-loaded at the minimum possible. but the fact is that certain features are not reliable and fast resposive as inside the services and the ircd itself. channel managment and protection for example could be very easily be set up through egdrops etc. but once you are under a serious attack (and i speak for experience) all the external tools fail and the only thing you can relay on is your ircd and services well configured (protection side). now i know that the modyle this post was created on is not one of the mission critical ones i talked about over here but it is very helpfull. yes some users can experience some "delays" but its worth it for the stability of your server.

another thing i liked to say here is that actually there is a module that at my opinion should absolutely be "ported" on UnrealIRCD from InspIRCD the m_connect_flood module. there was a similar one for anope 1.7.x and it was very usefulf because it sets services on "DESIRED DEFCON MODE" once x users connect in y secconds.

any way thanks guys for your interest in this post !!! :P
WordPress rocks phpBB rocks UnrealIRCD rocks but all of them only installed on FreeBSD !!!
bosini
Posts: 8
Joined: Sat Jul 24, 2010 12:16 pm

Re: m_joinmute module

Post by bosini »

Post Scriptum:
(it would be VERY nazi to set +j 1:2 or something such as that to be effective against flooders).
actually i have my channels on +j 1:60 but i still have the set::auto-join and they still connect. now i have lots of akills though services but the glines remains for a specified amount of time then they are removed from the ircd gline list to be reset automatically when the os akilled bot reconnects. now the main problem is that the lag of time between the services to set the gline (and even if set::auto-join is disabled) there is time for the clones/drones/bots to spam at least a line into the flooded channel
WordPress rocks phpBB rocks UnrealIRCD rocks but all of them only installed on FreeBSD !!!
Stealth
Head of Support
Posts: 2085
Joined: Tue Jun 15, 2004 8:50 pm
Location: Chino Hills, CA, US
Contact:

Re: m_joinmute module

Post by Stealth »

Next time I boot my laptop I'll paste the code here.
bosini
Posts: 8
Joined: Sat Jul 24, 2010 12:16 pm

Re: m_joinmute module

Post by bosini »

Stealth wrote:Next time I boot my laptop I'll paste the code here.
:P well thank you very much :P
WordPress rocks phpBB rocks UnrealIRCD rocks but all of them only installed on FreeBSD !!!
bosini
Posts: 8
Joined: Sat Jul 24, 2010 12:16 pm

Re: m_joinmute module

Post by bosini »

thanks anyway !!!
WordPress rocks phpBB rocks UnrealIRCD rocks but all of them only installed on FreeBSD !!!
Stealth
Head of Support
Posts: 2085
Joined: Tue Jun 15, 2004 8:50 pm
Location: Chino Hills, CA, US
Contact:

Re: m_joinmute module

Post by Stealth »

Here is the most recent version of the module that I have:

Code: Select all

/*
 *   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
bosini
Posts: 8
Joined: Sat Jul 24, 2010 12:16 pm

Re: m_joinmute module

Post by bosini »

thank you very much Stealth you are the greatest
WordPress rocks phpBB rocks UnrealIRCD rocks but all of them only installed on FreeBSD !!!
Post Reply