changeset 10989:b4919e8c634c

[gaim-migrate @ 12827] I bring you Yahoo! stealth settings. Thanks to Bleeter for testing and not allowing me to keep the sucky UI. committer: Tailor Script <tailor@pidgin.im>
author Daniel Atallah <daniel.atallah@gmail.com>
date Thu, 09 Jun 2005 04:15:22 +0000
parents 27f0322f06f7
children 8d74ae785a46
files ChangeLog src/protocols/yahoo/yahoo.c src/protocols/yahoo/yahoo.h src/protocols/yahoo/yahoo_friend.c src/protocols/yahoo/yahoo_friend.h src/protocols/yahoo/yahoo_packet.h
diffstat 6 files changed, 270 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Jun 09 04:12:19 2005 +0000
+++ b/ChangeLog	Thu Jun 09 04:15:22 2005 +0000
@@ -36,6 +36,7 @@
 	* Themeable mouse-over hyperlink coloring
 	* Attempt to detect the file type of a buddy icon when saving
 	  (Richard Laager)
+	* Yahoo! Stealth Settings have been implemented.
 
 	Bug fixes:
 	* People using input methods can now use Enter again.
--- a/src/protocols/yahoo/yahoo.c	Thu Jun 09 04:12:19 2005 +0000
+++ b/src/protocols/yahoo/yahoo.c	Thu Jun 09 04:15:22 2005 +0000
@@ -514,6 +514,7 @@
 	char **buddies;
 	char **tmp, **bud, *norm_bud;
 	char *grp = NULL;
+	char *perm_stealth_buddies = NULL;
 
 	if (pkt->id)
 		yd->session_id = pkt->id;
@@ -538,6 +539,9 @@
 		case 59: /* cookies, yum */
 			yahoo_process_cookie(yd, pair->value);
 			break;
+		case YAHOO_SERVICE_STEALTH_PERM:
+			perm_stealth_buddies = pair->value;
+			break;
 		}
 	}
 
@@ -611,6 +615,16 @@
 		      gc->account->username);
 	}
 
+	if (perm_stealth_buddies) {
+		buddies = g_strsplit(perm_stealth_buddies, ",", -1);
+		for (bud = buddies; bud && *bud; bud++) {
+			f = yahoo_friend_find(gc, *bud);
+			if (f)
+				f->stealth = YAHOO_STEALTH_PERM_OFFLINE;
+		}
+		g_strfreev(buddies);
+
+	}
 }
 
 static void yahoo_process_notify(GaimConnection *gc, struct yahoo_packet *pkt)
@@ -1998,6 +2012,10 @@
 	case YAHOO_SERVICE_COMMENT:
 		yahoo_process_chat_message(gc, pkt);
 		break;
+	case YAHOO_SERVICE_STEALTH_PERM:
+	case YAHOO_SERVICE_STEALTH_SESSION:
+		yahoo_process_stealth(gc, pkt);
+		break;
 	case YAHOO_SERVICE_P2PFILEXFER:
 	case YAHOO_SERVICE_FILETRANSFER:
 		yahoo_process_filetransfer(gc, pkt);
@@ -2569,6 +2587,17 @@
 	yahoo_c_invite(gc, id, "Join my conference...", buddy->name);
 }
 
+static void yahoo_stealth_settings(GaimBlistNode *node, gpointer data) {
+	GaimBuddy *buddy;
+	GaimConnection *gc;
+	int stealth_val = GPOINTER_TO_INT(data);
+
+	buddy = (GaimBuddy *) node;
+	gc = gaim_account_get_connection(buddy->account);
+
+	yahoo_friend_update_stealth(gc, buddy->name, stealth_val);
+}
+
 static void yahoo_game(GaimBlistNode *node, gpointer data) {
 
 	GaimBuddy *buddy;
@@ -2633,12 +2662,13 @@
 char *yahoo_tooltip_text(GaimBuddy *b)
 {
 	YahooFriend *f;
-	char *escaped, *status, *ret;
+	char *escaped, *status, *stealth = NULL;
+	GString *s = g_string_new("");
 
 	f = yahoo_friend_find(b->account->gc, b->name);
 	if (!f)
 		status = g_strdup_printf("\n%s", _("Not on server list"));
-	else
+	else {
 		switch (f->status) {
 		case YAHOO_STATUS_IDLE:
 			if (f->idle == -1) {
@@ -2656,12 +2686,30 @@
 			break;
 		}
 
+		switch (f->stealth) {
+			case YAHOO_STEALTH_ONLINE:
+				stealth = _("Appear Online");
+				break;
+			case YAHOO_STEALTH_PERM_OFFLINE:
+				stealth = _("Appear Permanently Offline");
+				break;
+			case YAHOO_STEALTH_DEFAULT:
+			default:
+				stealth = _("None");
+				break;
+		}
+	}
+
 	escaped = g_markup_escape_text(status, strlen(status));
-	ret = g_strdup_printf(_("\n<b>%s:</b> %s"), _("Status"), escaped);
+	g_string_append_printf(s, _("\n<b>%s:</b> %s"), _("Status"), escaped);
 	g_free(status);
 	g_free(escaped);
 
-	return ret;
+	if (stealth != NULL)
+		g_string_append_printf(s, _("\n<b>%s:</b> %s"),
+				_("Stealth"), stealth);
+
+	return g_string_free(s, FALSE);
 }
 
 static void yahoo_addbuddyfrommenu_cb(GaimBlistNode *node, gpointer data)
@@ -2691,6 +2739,44 @@
 	yahoo_chat_goto(gc, buddy->name);
 }
 
+static GList *build_stealth_submenu(YahooFriend *f, GaimConnection *gc) {
+	GList *m = NULL;
+	GaimBlistNodeAction *act;
+	struct yahoo_data *yd = (struct yahoo_data *) gc->proto_data;
+
+	if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
+		if (f->stealth != YAHOO_STEALTH_ONLINE) {
+			act = gaim_blist_node_action_new(_("Appear Online"),
+					yahoo_stealth_settings,
+					GINT_TO_POINTER(YAHOO_STEALTH_ONLINE),
+					NULL);
+			m = g_list_append(m, act);
+		} else if (f->stealth != YAHOO_STEALTH_DEFAULT) {
+			act = gaim_blist_node_action_new(_("Appear Offline"),
+					yahoo_stealth_settings,
+					GINT_TO_POINTER(YAHOO_STEALTH_DEFAULT),
+					NULL);
+			m = g_list_append(m, act);
+		}
+	}
+
+	if (f->stealth == YAHOO_STEALTH_PERM_OFFLINE) {
+		act = gaim_blist_node_action_new(
+				_("Don't Appear Permanently Offline"),
+				yahoo_stealth_settings,
+				GINT_TO_POINTER(YAHOO_STEALTH_DEFAULT), NULL);
+		m = g_list_append(m, act);
+	} else {
+		act = gaim_blist_node_action_new(
+				_("Appear Permanently Offline"),
+				yahoo_stealth_settings,
+				GINT_TO_POINTER(YAHOO_STEALTH_PERM_OFFLINE),
+				NULL);
+		m = g_list_append(m, act);
+	}
+
+	return m;
+}
 
 static GList *yahoo_buddy_menu(GaimBuddy *buddy)
 {
@@ -2711,36 +2797,42 @@
 
 		return m;
 
-	} else if (f->status == YAHOO_STATUS_OFFLINE) {
-		return NULL;
 	}
 
-	if (!yd->wm) {
-		act = gaim_blist_node_action_new(_("Join in Chat"),
+	if (f && f->status != YAHOO_STATUS_OFFLINE) {
+		if (!yd->wm) {
+			act = gaim_blist_node_action_new(_("Join in Chat"),
 				yahoo_chat_goto_menu, NULL, NULL);
-		m = g_list_append(m, act);
-	}
-
-	act = gaim_blist_node_action_new(_("Initiate Conference"),
+			m = g_list_append(m, act);
+		}
+
+		act = gaim_blist_node_action_new(_("Initiate Conference"),
 			yahoo_initiate_conference, NULL, NULL);
-	m = g_list_append(m, act);
-
-	if (yahoo_friend_get_game(f)) {
-		const char *game = yahoo_friend_get_game(f);
-		char *room;
-		char *t;
-
-		if (!(room = strstr(game, "&follow="))) /* skip ahead to the url */
-			return m;
-		while (*room && *room != '\t')          /* skip to the tab */
-			room++;
-		t = room++;                             /* room as now at the name */
-		while (*t != '\n')
-			t++;                            /* replace the \n with a space */
-		*t = ' ';
-		g_snprintf(buf2, sizeof buf2, "%s", room);
-
-		act = gaim_blist_node_action_new(buf2, yahoo_game, NULL, NULL);
+		m = g_list_append(m, act);
+
+		if (yahoo_friend_get_game(f)) {
+			const char *game = yahoo_friend_get_game(f);
+			char *room;
+			char *t;
+
+			if ((room = strstr(game, "&follow="))) {/* skip ahead to the url */
+				while (*room && *room != '\t')          /* skip to the tab */
+					room++;
+				t = room++;                             /* room as now at the name */
+				while (*t != '\n')
+					t++;                            /* replace the \n with a space */
+				*t = ' ';
+				g_snprintf(buf2, sizeof buf2, "%s", room);
+
+				act = gaim_blist_node_action_new(buf2, yahoo_game, NULL, NULL);
+				m = g_list_append(m, act);
+			}
+		}
+	}
+
+	if (f) {
+		act = gaim_blist_node_action_new(_("Stealth Settings"),
+				NULL, NULL, build_stealth_submenu(f, gc));
 		m = g_list_append(m, act);
 	}
 
@@ -2853,6 +2945,13 @@
 	return 0;
 }
 
+static void yahoo_session_stealth_remove(gpointer key, gpointer value, gpointer data)
+{
+	YahooFriend *f = value;
+	if (f && f->stealth == YAHOO_STEALTH_ONLINE)
+		f->stealth = YAHOO_STEALTH_DEFAULT;
+}
+
 static void yahoo_set_status(GaimAccount *account, GaimStatus *status)
 {
 	GaimConnection *gc = gaim_account_get_connection(account);
@@ -2955,6 +3054,10 @@
 		pkt = yahoo_packet_new(YAHOO_SERVICE_Y6_VISIBLE_TOGGLE, YAHOO_STATUS_AVAILABLE, 0);
 		yahoo_packet_hash_str(pkt, 13, "1");
 		yahoo_packet_send_and_free(pkt, yd);
+
+		/* Any per-session stealth settings are removed */
+		g_hash_table_foreach(yd->friends, yahoo_session_stealth_remove, NULL);
+
 	}
 }
 
--- a/src/protocols/yahoo/yahoo.h	Thu Jun 09 04:12:19 2005 +0000
+++ b/src/protocols/yahoo/yahoo.h	Thu Jun 09 04:15:22 2005 +0000
@@ -116,7 +116,7 @@
 	char *cookie_t;
 	int session_id;
 	gboolean jp;
-	gboolean wm;
+	gboolean wm; /* connected w/ web messenger method */
 	/* picture aka buddy icon stuff */
 	char *picture_url;
 	int picture_checksum;
--- a/src/protocols/yahoo/yahoo_friend.c	Thu Jun 09 04:12:19 2005 +0000
+++ b/src/protocols/yahoo/yahoo_friend.c	Thu Jun 09 04:15:22 2005 +0000
@@ -21,8 +21,10 @@
  *
  */
 
+#include "internal.h"
 #include "prpl.h"
 #include "util.h"
+#include "debug.h"
 
 #include "yahoo_friend.h"
 
@@ -32,6 +34,7 @@
 
 	ret = g_new0(YahooFriend, 1);
 	ret->status = YAHOO_STATUS_OFFLINE;
+	ret->stealth = YAHOO_STEALTH_DEFAULT;
 
 	return ret;
 }
@@ -133,3 +136,121 @@
 		g_free(f->ip);
 	g_free(f);
 }
+
+void yahoo_process_stealth(GaimConnection *gc, struct yahoo_packet *pkt)
+{
+	GSList *l = pkt->hash;
+	YahooFriend *f;
+	char *who = NULL;
+	int value = 0;
+
+	while (l) {
+		struct yahoo_pair *pair = l->data;
+
+		switch (pair->key) {
+			case 7:
+				who = pair->value;
+				break;
+			case 31:
+				value = strtol(pair->value, NULL, 10);
+				break;
+		}
+
+		l = l->next;
+	}
+
+	if (value != 1 && value != 2) {
+		gaim_debug_error("yahoo", "Received unknown value for stealth key: %d\n", value);
+		return;
+	}
+
+	g_return_if_fail(who != NULL);
+
+	f = yahoo_friend_find(gc, who);
+	if (!f)
+		return;
+
+	if (pkt->service == YAHOO_SERVICE_STEALTH_PERM) {
+		gaim_debug_info("yahoo", "Setting permanent stealth for %s to %d.\n", who, (value == 1));
+		/* If setting from perm offline to online when in invisible status,
+		 * this has already been taken care of (when the temp status changed) */
+		if (value == 2 && f->stealth == YAHOO_STEALTH_ONLINE) {
+		} else {
+			if (value == 1) /* Setting Perm offline */
+				f->stealth = YAHOO_STEALTH_PERM_OFFLINE;
+			else
+				f->stealth = YAHOO_STEALTH_DEFAULT;
+		}
+	} else {
+		gaim_debug_info("yahoo", "Setting session stealth for %s to %d.\n", who, (value == 1));
+		if (value == 1)
+			f->stealth = YAHOO_STEALTH_ONLINE;
+		else
+			f->stealth = YAHOO_STEALTH_DEFAULT;
+	}
+}
+
+void yahoo_friend_update_stealth(GaimConnection *gc, const char *name,
+		YahooStealthVisibility stealth)
+{
+	struct yahoo_data *yd = gc->proto_data;
+	struct yahoo_packet *pkt = NULL;
+	YahooFriend *f;
+
+	if (!yd->logged_in)
+		return;
+
+	f = yahoo_friend_find(gc, name);
+	if (!f)
+		return;
+
+	/* No need to change the value if it is already correct */
+	if (f->stealth == stealth) {
+		gaim_debug_info("yahoo", "Not setting stealth because there are no changes.\n");
+		return;
+	}
+
+	if (stealth == YAHOO_STEALTH_PERM_OFFLINE) {
+		pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM,
+				YAHOO_STATUS_AVAILABLE, yd->session_id);
+
+		yahoo_packet_hash(pkt, "ssss",
+				1, gaim_connection_get_display_name(gc),
+				31, "1", 13, "2", 7, name);
+	} else if (stealth == YAHOO_STEALTH_DEFAULT) {
+		if (f->stealth == YAHOO_STEALTH_PERM_OFFLINE) {
+			pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM,
+					YAHOO_STATUS_AVAILABLE, yd->session_id);
+
+			yahoo_packet_hash(pkt, "ssss",
+					1, gaim_connection_get_display_name(gc),
+					31, "2", 13, "2", 7, name);
+		} else if (yd->current_status == YAHOO_STATUS_INVISIBLE) {
+			pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_SESSION,
+					YAHOO_STATUS_AVAILABLE, yd->session_id);
+			yahoo_packet_hash(pkt, "ssss",
+				1, gaim_connection_get_display_name(gc),
+				31, "2", 13, "1", 7, name);
+		}
+	} else if (stealth == YAHOO_STEALTH_ONLINE) {
+		if (f->stealth == YAHOO_STEALTH_PERM_OFFLINE) {
+			pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_PERM,
+					YAHOO_STATUS_AVAILABLE, yd->session_id);
+			yahoo_packet_hash(pkt, "ssss",
+					1, gaim_connection_get_display_name(gc),
+					31, "2", 13, "2", 7, name);
+			yahoo_packet_send_and_free(pkt, yd);
+		}
+
+
+		pkt = yahoo_packet_new(YAHOO_SERVICE_STEALTH_SESSION,
+				YAHOO_STATUS_AVAILABLE, yd->session_id);
+		yahoo_packet_hash(pkt, "ssss",
+				1, gaim_connection_get_display_name(gc),
+				31, "1", 13, "1", 7, name);
+	}
+
+	if (pkt)
+		yahoo_packet_send_and_free(pkt, yd);
+}
+
--- a/src/protocols/yahoo/yahoo_friend.h	Thu Jun 09 04:12:19 2005 +0000
+++ b/src/protocols/yahoo/yahoo_friend.h	Thu Jun 09 04:15:22 2005 +0000
@@ -26,6 +26,13 @@
 #define _YAHOO_FRIEND_H_
 
 #include "yahoo.h"
+#include "yahoo_packet.h"
+
+typedef enum {
+	YAHOO_STEALTH_DEFAULT = 0,
+	YAHOO_STEALTH_ONLINE,
+	YAHOO_STEALTH_PERM_OFFLINE
+} YahooStealthVisibility;
 
 /* these are called friends instead of buddies mainly so I can use variables
  * named f and not confuse them with variables named b
@@ -39,9 +46,9 @@
 	gboolean sms;
 	char *ip;
 	gboolean bicon_sent_request;
+	YahooStealthVisibility stealth;
 } YahooFriend;
 
-
 YahooFriend *yahoo_friend_find(GaimConnection *gc, const char *name);
 YahooFriend *yahoo_friend_find_or_new(GaimConnection *gc, const char *name);
 
@@ -59,4 +66,8 @@
 
 void yahoo_friend_free(gpointer p);
 
+void yahoo_process_stealth(GaimConnection *gc, struct yahoo_packet *pkt);
+void yahoo_friend_update_stealth(GaimConnection *gc, const char *name,
+		YahooStealthVisibility stealth);
+
 #endif /* _YAHOO_FRIEND_H_ */
--- a/src/protocols/yahoo/yahoo_packet.h	Thu Jun 09 04:12:19 2005 +0000
+++ b/src/protocols/yahoo/yahoo_packet.h	Thu Jun 09 04:15:22 2005 +0000
@@ -85,6 +85,8 @@
 	YAHOO_SERVICE_CHATLOGOUT = 0xa0,
 	YAHOO_SERVICE_CHATPING,
 	YAHOO_SERVICE_COMMENT = 0xa8,
+	YAHOO_SERVICE_STEALTH_PERM = 0xb9,
+	YAHOO_SERVICE_STEALTH_SESSION = 0xba,
 	YAHOO_SERVICE_AVATAR = 0xbc,
 	YAHOO_SERVICE_PICTURE_CHECKSUM = 0xbd,
 	YAHOO_SERVICE_PICTURE = 0xbe,