diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 9590d788f0..abcf33f7f2 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,6 +4,13 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK.  ALL UNTESTED BUGFIXES/FEATURES GO
 IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
 
 
+2008/01/15
+	* Manner system fixing [ultramage]
+	- better-than-aegis 'red bubble' packet updates; now it shows correctly
+	- added support for /rc, which is basically mute for 60 minutes
+	- fixed typo in r12076 making gm-mute start on the gm instead of target
+	- fixed @mute not ending the status properly when using negative values
+	- adde missing clif_manner_message(), sends info about manner updates
 2008/01/14
 	* Fixed missing mob_spawn call, which was making CR_CULTIVATION not
 	  actually spawn the plant. [Skotlex]
diff --git a/db/packet_db.txt b/db/packet_db.txt
index 31d2bb4738..7dde4caffc 100644
--- a/db/packet_db.txt
+++ b/db/packet_db.txt
@@ -499,7 +499,7 @@ packet_ver: 9
 0x0193,18,actionrequest,7:17
 
 //2004-08-16aSakexe
-0x0212,26
+0x0212,26,rc,2
 0x0213,26,check,2
 0x0214,42
 
@@ -1069,7 +1069,7 @@ packet_ver: 22
 0x02e7,-1
 
 //2008-01-02aSakexe
-0x01df,6,gmreqnochatcount,2
+0x01df,6,gmreqaccname,2
 0x02e8,-1
 0x02e9,-1
 0x02ea,-1
@@ -1079,5 +1079,12 @@ packet_ver: 22
 0x02ee,60
 0x02ef,8
 
+//2008-01-08aSakexe
+//0x01df,0
+0x02a6,204
+0x02a7,204
+//0x02a8,0
+//0x02a9,0
+
 //Add new packets here
 //packet_ver: 23
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index cc6e218745..ea8a1d1632 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -6744,10 +6744,18 @@ int atcommand_mute(const int fd, struct map_session_data* sd, const char* comman
 		return -1;
 	}
 
-	clif_GM_silence(sd, pl_sd, 0);
-	pl_sd->status.manner -= manner;
-	if(pl_sd->status.manner < 0)
+	clif_manner_message(sd, 0);
+	clif_manner_message(pl_sd, 5);
+
+	if( pl_sd->status.manner < manner ) {
+		pl_sd->status.manner -= manner;
 		sc_start(&pl_sd->bl,SC_NOCHAT,100,0,0);
+	} else {
+		pl_sd->status.manner = 0;
+		status_change_end(&pl_sd->bl,SC_NOCHAT,-1);
+	}
+
+	clif_GM_silence(sd, pl_sd, (manner > 0 ? 1 : 0));
 
 	return 0;
 }
diff --git a/src/map/clif.c b/src/map/clif.c
index 4b0b7e7ec4..3b15f3e1a4 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -2180,7 +2180,6 @@ int clif_updatestatus(struct map_session_data *sd,int type)
 		break;
 	case SP_MANNER:
 		WFIFOL(fd,4)=sd->status.manner;
-		clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
 		break;
 	case SP_STATUSPOINT:
 		WFIFOL(fd,4)=sd->status.status_point;
@@ -3405,9 +3404,6 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d
 		)
 		clif_hpmeter_single(sd->fd, dstsd->bl.id, dstsd->battle_status.hp, dstsd->battle_status.max_hp);
 
-	if(dstsd->status.manner < 0)
-		clif_changestatus(&dstsd->bl,SP_MANNER,dstsd->status.manner);
-		
 	// pvp circle for duel [LuzZza]
 	//if(dstsd->duel_group)
 	//	clif_specialeffect(&dstsd->bl, 159, 4);
@@ -6899,23 +6895,42 @@ int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int ty
 	return 0;
 }
 
-int clif_GM_silence(struct map_session_data *sd, struct map_session_data *tsd, int type)
+/// Displays various manner-related status messages
+/// R 014a <type>.L
+/// type: 0 - "A manner point has been successfully aligned."
+///       1 - ?
+///       2 - ?
+///       3 - "Chat Block has been applied by GM due to your ill-mannerous action."
+///       4 - "Automated Chat Block has been applied due to Anti-Spam System."
+///       5 - "You got a good point from %s."
+void clif_manner_message(struct map_session_data* sd, uint32 type)
 {
 	int fd;
+	nullpo_retv(sd);
 	
-	nullpo_retr(0, sd);
-	nullpo_retr(0, tsd);
+	fd = sd->fd;
+	WFIFOHEAD(fd,packet_len(0x14a));
+	WFIFOW(fd,0) = 0x14a;
+	WFIFOL(fd,2) = type;
+	WFIFOSET(fd, packet_len(0x14a));
+}
+
+/// Followup to 0x14a type 3/5, informs who did the manner adjustment action.
+/// R 014b <type>.B <GM name>.24B
+/// type: 0 - positive (unmute)
+///       1 - negative (mute)
+void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, uint8 type)
+{
+	int fd;	
+	nullpo_retv(sd);
+	nullpo_retv(tsd);
 
 	fd = tsd->fd;
-	if (fd <= 0)
-		return 0;
 	WFIFOHEAD(fd,packet_len(0x14b));
 	WFIFOW(fd,0) = 0x14b;
-	WFIFOB(fd,2) = 0;
-	memcpy(WFIFOP(fd,3), sd->status.name, NAME_LENGTH);
+	WFIFOB(fd,2) = type;
+	safestrncpy((char*)WFIFOP(fd,3), sd->status.name, NAME_LENGTH);
 	WFIFOSET(fd, packet_len(0x14b));
-
-	return 0;
 }
 
 /*==========================================
@@ -10391,42 +10406,74 @@ void clif_parse_GMHide(int fd, struct map_session_data *sd)
 }
 
 /*==========================================
- * GM adjustment of a player's manner value
- * /red
+ * GM adjustment of a player's manner value (right-click GM menu)
  * S 0149 <id>.L <type>.B <value>.W
  * type: 0 - positive points
  *       1 - negative points
+ *       2 - self mute (+10 minutes)
  *------------------------------------------*/
 void clif_parse_GMReqNoChat(int fd,struct map_session_data *sd)
 {
-	int type, value, level;
+	int id, type, value, level;
 	struct map_session_data *dstsd;
 
-	dstsd = map_id2sd(RFIFOL(fd,2));
+	id = RFIFOL(fd,2);
 	type = RFIFOB(fd,6);
 	value = RFIFOW(fd,7);
 
-	if (type == 0)
+	if( type == 0 )
 		value = 0 - value;
 
 	//If type is 2 and the ids don't match, this is a crafted hacked packet!
 	//Disabled because clients keep self-muting when you give players public @ commands... [Skotlex]
-	if (type == 2/* && sd->bl.id != dstsd->bl.id*/)
+	if (type == 2 /* && (pc_isGM(sd) > 0 || sd->bl.id != id)*/)
 		return;
-	
-	if (
-		((level = pc_isGM(sd)) > pc_isGM(dstsd) && level >= get_atcommand_level(atcommand_mute))
-		|| (type == 2 && !level))
+
+	dstsd = map_id2sd(id);
+	if( dstsd == NULL )
+		return;
+
+	if( (level = pc_isGM(sd)) > pc_isGM(dstsd) && level >= get_atcommand_level(atcommand_mute) )
 	{
-		clif_GM_silence(sd, dstsd, ((type == 2) ? 1 : type));
-		dstsd->status.manner -= value;
-		if(dstsd->status.manner < 0)
-			sc_start(&sd->bl,SC_NOCHAT,100,0,0);
-		else
-		{
+		clif_manner_message(sd, 0);
+		clif_manner_message(dstsd, 5);
+
+		if( dstsd->status.manner < value ) {
+			dstsd->status.manner -= value;
+			sc_start(&dstsd->bl,SC_NOCHAT,100,0,0);
+		} else {
 			dstsd->status.manner = 0;
-			status_change_end(&sd->bl,SC_NOCHAT,-1);
+			status_change_end(&dstsd->bl,SC_NOCHAT,-1);
 		}
+
+		if( type != 2 )
+			clif_GM_silence(sd, dstsd, type);
+	}
+}
+
+/*==========================================
+ * GM adjustment of a player's manner value by -60 (using name)
+ * /rc <name>
+ * S 0212 <name>.24B
+ *------------------------------------------*/
+void clif_parse_GMRc(int fd, struct map_session_data* sd)
+{
+	char* name = (char*)RFIFOP(fd,2);
+	struct map_session_data* dstsd;
+	name[23] = '\0';
+	dstsd = map_nick2sd(name);
+	if( dstsd == NULL )
+		return;
+
+	if( pc_isGM(sd) > pc_isGM(dstsd) && pc_isGM(sd) >= get_atcommand_level(atcommand_mute) )
+	{
+		clif_manner_message(sd, 0);
+		clif_manner_message(dstsd, 3);
+
+		dstsd->status.manner -= 60;
+		sc_start(&dstsd->bl,SC_NOCHAT,100,0,0);
+
+		clif_GM_silence(sd, dstsd, 1);
 	}
 }
 
@@ -11942,6 +11989,7 @@ static int packetdb_readdb(void)
 		{clif_parse_GMShift,"remove"},
 		{clif_parse_GMShift,"shift"},
 		{clif_parse_GMChangeMapType,"changemaptype"},
+		{clif_parse_GMRc,"rc"},
 
 		{clif_parse_NoviceDoriDori,"sndoridori"},
 		{clif_parse_NoviceExplosionSpirits,"snexplosionspirits"},
diff --git a/src/map/clif.h b/src/map/clif.h
index 5933a40e0b..3b188a468a 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -362,7 +362,8 @@ int clif_message(struct block_list *bl, const char* msg); // messages (from mobs
 
 int clif_GM_kickack(struct map_session_data *sd,int id);
 int clif_GM_kick(struct map_session_data *sd,struct map_session_data *tsd,int type);
-int clif_GM_silence(struct map_session_data *sd,struct map_session_data *tsd,int type);
+void clif_manner_message(struct map_session_data* sd, uint32 type);
+void clif_GM_silence(struct map_session_data* sd, struct map_session_data* tsd, uint8 type);
 int clif_timedout(struct map_session_data *sd);
 
 int clif_disp_overhead(struct map_session_data *sd, const char* mes);
diff --git a/src/map/status.c b/src/map/status.c
index 4108359d85..ce33bceeb9 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -5212,7 +5212,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 		case SC_NOCHAT:
 			tick = 60000;
 			val1 = battle_config.manner_system; //Mute filters.
-			if (sd) clif_updatestatus(sd,SP_MANNER);
+			if (sd)
+			{
+				clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner);
+				clif_updatestatus(sd,SP_MANNER);
+			}
 			break;
 
 		case SC_STONE:
@@ -6922,6 +6926,7 @@ int status_change_timer(int tid, unsigned int tick, int id, int data)
 	case SC_NOCHAT:
 		if(sd){
 			sd->status.manner++;
+			clif_changestatus(bl,SP_MANNER,sd->status.manner);
 			clif_updatestatus(sd,SP_MANNER);
 			if (sd->status.manner < 0)
 			{	//Every 60 seconds your manner goes up by 1 until it gets back to 0.