diff --git a/Core/Chans.pm b/Core/Chans.pm
index cd31c9bd9117fdd0dc5d209d42115cf12949f2e3..3dd05b95e05538cc7f42f189c09546faf7b56c31 100644
--- a/Core/Chans.pm
+++ b/Core/Chans.pm
@@ -33,7 +33,7 @@ our %chans = ();
 sub chans_main
 {
 	my ($conn, $event, $reply_to, $ref_params) = @_;
-	
+
 	if(defined($ref_params->[0]))
 	{
 		my $chan = lc $ref_params->[0];
@@ -57,7 +57,7 @@ sub chans_main
 						}
 						next unless(@people);
 					}
-					
+
 					$msg .= $mode."(".join(', ', @people).")"
 						if(defined($chans{$chan}{"modes"}{$mode}->[0]));
 				}
@@ -70,7 +70,7 @@ sub chans_main
 					$msg .= $mode."(".$chans{$chan}{"modes"}{$mode}.")";
 				}
 			}
-			
+
 			if(defined($chans{$chan}{"users"}))
 			{
 				my $users = " \x034[\x033users\x034]\x03 ";
@@ -80,15 +80,15 @@ sub chans_main
 					$users .= ", " if($users ne $init_users);
 					$users .= $user;
 				}
-				
+
 				if($users eq $init_users)
 				{
 					$users .= "Well, none recorded";
 				}
-				
+
 				$msg .= $users;
 			}
-			
+
 			$conn->privmsg($reply_to, $msg);
 		}
 		else
@@ -97,8 +97,8 @@ sub chans_main
 		}
 		return 1;
 	}
-	
-	
+
+
 	if(%chans)
 	{
 		$conn->privmsg($reply_to, "Chans joined: ".join(", ", sort keys %chans));
@@ -107,8 +107,8 @@ sub chans_main
 	{
 		$conn->privmsg($reply_to, "No chans joined at the moment.");
 	}
-	
-	
+
+
 	return 1;
 } # Fin chans_main
 
@@ -121,12 +121,12 @@ sub chans_main
 sub chan_add
 {
 	my ($conn, $chan, $mode) = @_;
-	
+
 	return 0 unless(defined($conn) && defined($chan));
-	
+
 	$chan = lc $chan;
 	$::logger->debug("Adding channel $chan");
-	
+
 	if(!defined $mode)
 	{
 		# On enregistre l'event qu'on attend
@@ -141,7 +141,7 @@ sub chan_add
 		$::logger->debug("Modes: $mode");
 		&parse_modes($chan, $mode);
 	}
-	
+
 	$chans{$chan}{"users"} = [$Config::nick];
 
 	return 1;
@@ -155,9 +155,9 @@ sub chan_add
 sub channelmodeis_handle
 {
 	my ($conn, $event) = @_;
-	
+
 	return unless($conn, $event);
-	
+
 	EventHandler::remove_event("channelmodeis", "after", \&channelmodeis_handle);
 	&parse_modes(lc $event->{'args'}[1], $event->{'args'}[2]);
 } # Fin channelmodeis_handle
@@ -170,13 +170,13 @@ sub channelmodeis_handle
 sub chan_del
 {
 	my $chan = lc shift;
-	
+
 	if(defined($chans{$chan}))
 	{
 		delete $chans{$chan};
 		return 1;
 	}
-	
+
 	return 0;
 } # Fin chan_del
 
@@ -188,7 +188,7 @@ sub chan_del
 sub mode
 {
 	my $chan = lc shift;
-	
+
 	return defined($chans{$chan}) ? $chans{$chan}{"modes"} : undef;
 } # Fin mode
 
@@ -200,7 +200,7 @@ sub mode
 sub users
 {
 	my $chan = lc shift;
-	
+
 	return defined($chans{$chan}) ? $chans{$chan}{"users"} : undef;
 } # Fin users
 
@@ -212,7 +212,7 @@ sub users
 sub change_mode
 {
 	my ($chan, $mode) = @_;
-	
+
 	if(defined($chan) && defined($mode) && defined($chans{lc $chan}))
 	{
 		&parse_modes(lc $chan, $mode);
@@ -229,34 +229,34 @@ sub change_mode
 sub parse_modes
 {
 	my ($chan, $modes) = @_;
-	
+
 	return unless($chan, $modes);
-	
+
 	$chan = lc $chan;
 	$modes =~ s/\s*$//;
-	
+
 	# On sépare les modes des paramètres
 	my @modes_changed = split /\s+/, $modes;
 	$modes = shift @modes_changed;
-	
+
 	my $lg = length $modes;
-	
+
 	# Par défaut, s'il n'y a pas de "+" ou de "-", c'est "+"
 	my $add_remove = 1;
-	
+
 	# On parse chaque mode
 	for(my $i = 0; $i < $lg; ++$i)
-	{   
+	{
 		my $ch = substr($modes, $i, 1);
-		
+
 		if($ch eq "+" or $ch eq "-")
 		{
 			$add_remove = 1 if($ch eq "+");
 			$add_remove = 0 if($ch eq "-");
 			next;
 		}
-		
-		
+
+
 		if($add_remove == 1)
 		{
 			if($ch eq "k" || $ch eq "l")
@@ -266,7 +266,7 @@ sub parse_modes
 			elsif($ch eq "b")
 			{
 				if(defined $chans{$chan}{"modes"}{$ch})
-				{   
+				{
 					push @{$chans{$chan}{"modes"}{$ch}}, shift @modes_changed;
 				}
 				else
@@ -274,7 +274,7 @@ sub parse_modes
 					$chans{$chan}{"modes"}{$ch} = [shift @modes_changed];
 				}
 			}
-			elsif($ch eq "v" || $ch eq "o")
+			elsif($ch eq "v" || $ch eq "h" || $ch eq "o" || $ch eq "a" || $ch eq "q")
 			{
 				my $to_add = shift @modes_changed;
 				if(defined $chans{$chan}{"modes"}{$ch})
@@ -294,7 +294,7 @@ sub parse_modes
 		}
 		else
 		{
-			if($ch eq "v" || $ch eq "o")
+			if($ch eq "v" || $ch eq "h" || $ch eq "o" || $ch eq "a" || $ch eq "q")
 			{
 				if(defined $chans{$chan}{"modes"}{$ch})
 				{
@@ -324,9 +324,9 @@ sub parse_modes
 sub change_topic
 {
 	my ($chan, $topic) = @_;
-	
+
 	return unless($chan, $topic);
-	
+
 	$topic =~ s/\s*$//;
 	$chans{lc $chan}{"topic"} = $topic;
 } # Fin change_topic
@@ -339,15 +339,24 @@ sub change_topic
 sub is_op
 {
 	my ($chan, $user) = @_;
-	
+
 	return 0 unless defined($chan);
-	
+
 	$chan = lc $chan;
-	return 0 unless(defined $chans{$chan}{"modes"}{"o"});
-	
 	$user = $Config::nick unless(defined $user);
-	
-	return Common::is_in_list($chans{$chan}{"modes"}{"o"}, $user);
+
+	my @o, @a, @q;
+
+	@o = Common::is_in_list($chans{$chan}{"modes"}{"o"}, $user)
+		if(defined $chans{$chan}{"modes"}{"o"});
+	@a = Common::is_in_list($chans{$chan}{"modes"}{"a"}, $user)
+		if(defined $chans{$chan}{"modes"}{"a"});;
+	@q = Common::is_in_list($chans{$chan}{"modes"}{"q"}, $user)
+		if(defined $chans{$chan}{"modes"}{"q"});;
+
+	return 1 if(@o or @a or @q);
+
+	return 0;
 } # Fin is_op
 
 
@@ -358,14 +367,14 @@ sub is_op
 sub is_voice
 {
 	my ($chan, $user) = @_;
-	
+
 	return 0 unless defined($chan);
-	
+
 	$chan = lc $chan;
 	return 0 unless(defined $chans{$chan}{"modes"}{"v"});
-	
+
 	$user = $Config::nick if(!defined $user);
-	
+
 	return Common::is_in_list($chans{$chan}{"modes"}{"v"}, $user);
 } # Fin is_voice
 
@@ -377,9 +386,9 @@ sub is_voice
 sub is_inviteonly
 {
 	my $chan = lc shift;
-	
+
 	return 1 if(defined($chans{$chan}) && defined($chans{$chan}{"modes"}{"i"}));
-	
+
 	return 0;
 } # Fin is_inviteonly
 
@@ -391,10 +400,10 @@ sub is_inviteonly
 sub add_users
 {
 	my $chan = shift;
-	
+
 	return unless(defined($chan));
 	$chan = lc $chan;
-	
+
 	foreach (@_)
 	{
 		add_one_user($chan, $_);
@@ -410,10 +419,10 @@ sub add_users
 sub add_one_user
 {
 	my ($chan, $user) = @_;
-	
+
 	$chan = lc $chan;
 	return unless(defined($chans{$chan}) && defined($user));
-	
+
 	push @{$chans{$chan}{"users"}}, $user
 		if(!Common::is_in_list($chans{$chan}{"users"}, $user));
 	return 1;
@@ -428,13 +437,13 @@ sub remove_quit_user
 {
 	my $user = shift;
 	return unless($user);
-	
+
 	foreach my $chan (keys %chans)
 	{
 		# Qu'il soit sur le chan ou pas, osef
 		Common::removeall_from_list($chans{$chan}{"users"}, $user);
-		
-		my $modes = "-vo ".$user." ".$user;
+
+		my $modes = "-vhoaq ".(($user.' ') x 5);
 		change_mode($chan, $modes);
 	}
 	return 1;
@@ -448,15 +457,15 @@ sub remove_quit_user
 sub remove_user
 {
 	my ($chan, $user) = @_;
-	
+
 	return 0 unless defined($chan);
-	
+
 	$chan = lc $chan;
 	return 0 unless(defined($chans{$chan}) && defined($user));
-	
+
 	my $modes = "-vo ".$user." ".$user;
 	change_mode($chan, $modes);
-	
+
 	Common::removeall_from_list($chans{$chan}{"users"}, $user);
 	return 1;
 } # remove_user
@@ -464,21 +473,21 @@ sub remove_user
 
 # ###
 #  is_on_chan
-# Renvoie CHANS_NOT_JOINED si le chan n'est pas dans la liste, 
+# Renvoie CHANS_NOT_JOINED si le chan n'est pas dans la liste,
 # CHANS_USER_NOT_PRESENT si le pseudo n'est pas sur le chan et CHANS_OK si le
 # pseudo est sur le chan
 # ###
 sub is_on_chan
 {
 	my ($chan, $nick) = @_;
-	
+
 	return unless($chan, $nick);
 	$chan = lc $chan;
-	
+
 	return CHANS_NOT_JOINED unless(defined($chans{$chan}));
-	
+
 	return CHANS_OK if(Common::is_in_list($chans{$chan}{"users"}, $nick));
-	
+
 	return CHANS_USER_NOT_PRESENT;
 } # Fin is_on_chan
 
@@ -492,25 +501,25 @@ sub is_on_chan
 sub change_nick
 {
 	my (undef, $event) = @_;
-	
+
 	my $old_nick = $event->{'nick'};
 	my $new_nick = $event->{'args'}[0];
-	
+
 	return unless($old_nick, $new_nick);
-	
+
 	foreach my $chan (keys %chans)
 	{
 		if(is_on_chan($chan, $old_nick) == CHANS_OK)
 		{
 			Common::removeall_from_list($chans{$chan}{"users"}, $old_nick);
 			push @{$chans{$chan}{"users"}}, $new_nick;
-			
+
 			if(is_op($chan, $old_nick))
 			{
 				my $modes = "-o+o ".$old_nick." ".$new_nick;
 				parse_modes($chan, $modes);
 			}
-			
+
 			if(is_voice($chan, $old_nick))
 			{
 				my $modes = "-v+v ".$old_nick." ".$new_nick;
@@ -529,10 +538,10 @@ sub change_nick
 sub chans_help
 {
 	my ($self, $event, $reply_to, $ref_params) = @_;
-	
+
 	$self->privmsg($reply_to, "`".$Config::command_sign."chans [<chan name>]` => "
 							."display joined channels or infos of a chan");
-	
+
 	return 1;
 } # Fin chans_help
 
@@ -544,15 +553,15 @@ sub chans_help
 sub chans_save
 {
 	my ($conn, $folder, $reloading) = @_;
-	
+
 	# Si on est en train d'éteindre le bot
 	return 1 if(!defined($reloading) || !$reloading);
-	
+
 	# Si on est en train de recharger le module
 	my $file_chans = "/chans".$Config::suffixe.".sav";
-	
+
 	open CHANS, ">", $folder.$file_chans or return 0;
-	
+
 	foreach my $chan (keys %chans)
 	{
 		print CHANS $chan."\n";
@@ -582,15 +591,15 @@ sub chans_save
 		print CHANS $chans{$chan}{"topic"}."\n";
 		print CHANS join(' ', @{$chans{$chan}{"users"}})."\n";
 	}
-	
+
 	close CHANS;
-	
+
 	if($reloading)
 	{
 		# On se désenregistre, sinon on risque d'avoir deux fois le handler d'appelé
 		EventHandler::remove_event("nick", "before", \&change_nick);
 	}
-	
+
 	return 1;
 } # Fin chans_save
 
@@ -602,19 +611,19 @@ sub chans_save
 sub chans_load
 {
 	my ($conn, $folder, $reloading) = @_;
-	
+
 	# On ajoute un event handler sur le changement de pseudo (= l'évènement 'nick')
 	EventHandler::add_event("nick", "before", \&change_nick);
-	
-	
+
+
 	# Si on est en train de démarrer le bot, on s'arrête là
 	return 1 if(!defined($reloading) || !$reloading);
-	
+
 	# Si on est en train de recharger le module
 	my $file_chans = "/chans".$Config::suffixe.".sav";
-	
+
 	open CHANS, "<", $folder.$file_chans or return 1;
-	
+
 	while(my $chan = <CHANS>)
 	{
 		chomp $chan;
@@ -625,14 +634,14 @@ sub chans_load
 		my $users = <CHANS>;
 		chomp $users;
 		my @users = split / /, $users;
-		
+
 		chan_add($conn, $chan, $modes);
 		change_topic($chan, $topic);
 		add_users($chan, @users);
 	}
-	
+
 	close CHANS;
-	
+
 	return 1;
 } # Fin chans_load