Index: protocols/nogaim.c
===================================================================
--- protocols/nogaim.c	(revision 4273158e2bd219602e502d593040cccb234d4805)
+++ protocols/nogaim.c	(revision 839189b091ee82937666bcaa328a7d3ecd1c573b)
@@ -657,8 +657,19 @@
 	u->away = u->status_msg = NULL;
 	
-	if( ( flags & OPT_LOGGED_IN ) && !u->online )
-	{
+	if( set_getbool( &ic->irc->set, "show_offline" ) && !u->online )
+	{
+		/* always set users as online */
 		irc_spawn( ic->irc, u );
 		u->online = 1;
+		if( !( flags & OPT_LOGGED_IN ) )
+		{
+			/* set away message if user isn't really online */
+			u->away = g_strdup( "User is offline" );
+		}
+	}
+	else if( ( flags & OPT_LOGGED_IN ) && !u->online )
+	{
+		irc_spawn( ic->irc, u );
+		u->online = 1;
 	}
 	else if( !( flags & OPT_LOGGED_IN ) && u->online )
@@ -666,12 +677,28 @@
 		struct groupchat *c;
 		
-		irc_kill( ic->irc, u );
-		u->online = 0;
-		
-		/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
-		for( c = ic->groupchats; c; c = c->next )
-			remove_chat_buddy_silent( c, handle );
-	}
-	
+		if( set_getbool( &ic->irc->set, "show_offline" ) )
+		{
+			/* keep offline users in channel and set away message to "offline" */
+			u->away = g_strdup( "User is offline" );
+
+			/* Keep showing him/her in the control channel but not in groupchats. */
+			for( c = ic->groupchats; c; c = c->next )
+			{
+				if( remove_chat_buddy_silent( c, handle ) && c->joined )
+					irc_part( c->ic->irc, u, c->channel );
+			}
+		}
+		else
+		{
+			/* kill offline users */
+			irc_kill( ic->irc, u );
+			u->online = 0;
+
+			/* Remove him/her from the groupchats to prevent PART messages after he/she QUIT already */
+			for( c = ic->groupchats; c; c = c->next )
+				remove_chat_buddy_silent( c, handle );
+		}
+	}
+
 	if( flags & OPT_AWAY )
 	{
@@ -698,9 +725,6 @@
 	}
 	
-	/* LISPy... */
-	if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
-	    ( u->online ) &&						/* Don't touch offline people */
-	    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */
-	      ( ( u->online == oo ) && ( oa == !u->away ) ) ) )		/* (De)voice people changing state */
+	/* early if-clause for show_offline even if there is some redundant code here because this isn't LISP but C ;) */
+	if( set_getbool( &ic->irc->set, "show_offline" ) && set_getbool( &ic->irc->set, "away_devoice" ) )
 	{
 		char *from;
@@ -715,7 +739,41 @@
 			                                    ic->irc->myhost );
 		}
-		irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel,
-		                                          u->away?'-':'+', u->nick );
-		g_free( from );
+
+		/* if we use show_offline, we op online users, voice away users, and devoice/deop offline users */
+		if( flags & OPT_LOGGED_IN )
+		{
+			/* user is "online" (either really online or away) */
+			irc_write( ic->irc, ":%s MODE %s %cv%co %s %s", from, ic->irc->channel,
+			                                          u->away?'+':'-', u->away?'-':'+', u->nick, u->nick );
+		}
+		else
+		{
+			/* user is offline */
+			irc_write( ic->irc, ":%s MODE %s -vo %s %s", from, ic->irc->channel, u->nick, u->nick );
+		}
+	}
+	else
+	{ 
+		/* LISPy... */
+		if( ( set_getbool( &ic->irc->set, "away_devoice" ) ) &&		/* Don't do a thing when user doesn't want it */
+		    ( u->online ) &&						/* Don't touch offline people */
+		    ( ( ( u->online != oo ) && !u->away ) ||			/* Voice joining people */
+		      ( ( u->online == oo ) && ( oa == !u->away ) ) ) )		/* (De)voice people changing state */
+		{
+			char *from;
+
+			if( set_getbool( &ic->irc->set, "simulate_netsplit" ) )
+			{
+				from = g_strdup( ic->irc->myhost );
+			}
+			else
+			{
+				from = g_strdup_printf( "%s!%s@%s", ic->irc->mynick, ic->irc->mynick,
+				                                    ic->irc->myhost );
+			}
+			irc_write( ic->irc, ":%s MODE %s %cv %s", from, ic->irc->channel,
+			                                          u->away?'-':'+', u->nick );
+			g_free( from );
+		}
 	}
 }
