# HG changeset patch # User Sadrul Habib Chowdhury # Date 1203268540 0 # Node ID 3867cef6a0d51414bbb4ac9cdfc039fb9d4a0af1 # Parent d270b6aebabc2b66ad208605bb1bca259d233f75# Parent bf4902fce6e41a3579ff1309d1b2d29cc4489057 merge of '679333d47d0d179f9027ef1c5f82a2eef5811b95' and '782f53e182e5aae0645ddca95945dd0c104330ff' diff -r d270b6aebabc -r 3867cef6a0d5 libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Sun Feb 17 17:14:29 2008 +0000 +++ b/libpurple/protocols/myspace/myspace.c Sun Feb 17 17:15:40 2008 +0000 @@ -73,7 +73,7 @@ static gboolean msim_check_alive(gpointer data); #endif -static gboolean msim_we_are_logged_on(MsimSession *session, MsimMessage *msg); +static gboolean msim_is_username_set(MsimSession *session, MsimMessage *msg); static gboolean msim_process(MsimSession *session, MsimMessage *msg); @@ -1546,14 +1546,14 @@ } #endif -/** Called when the session key arrives. */ +/** Called when the session key arrives to check whether the user + * has a username, and set one if desired. */ static gboolean -msim_we_are_logged_on(MsimSession *session, MsimMessage *msg) +msim_is_username_set(MsimSession *session, MsimMessage *msg) { - MsimMessage *body; - g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE); g_return_val_if_fail(msg != NULL, FALSE); + g_return_val_if_fail(session->gc != NULL, FALSE); session->sesskey = msim_msg_get_integer(msg, "sesskey"); purple_debug_info("msim", "SESSKEY=<%d>\n", session->sesskey); @@ -1581,27 +1581,39 @@ /* Set display name to username (otherwise will show email address) */ purple_connection_set_display_name(session->gc, session->username); + /* If user lacks a username, help them get one. */ + if (msim_msg_get_integer(msg, "uniquenick") == session->userid) { + purple_debug_info("msim_is_username_set", "no username is set\n"); + purple_request_yes_no(session->gc, + _("MySpaceIM - No Username Set"), + _("You appear to have no MySpace username."), + _("Would you like to set one now? (Note: THIS CANNOT BE CHANGED!)"), + 0, + session->account, + NULL, + NULL, + session->gc, + G_CALLBACK(msim_set_username_cb), + G_CALLBACK(msim_do_not_set_username_cb)); + purple_debug_info("msim_is_username_set","'username not set' alert prompted\n"); + return FALSE; + } + return TRUE; +} + +/** Called after username is set, if necessary and we're open for business. */ +gboolean msim_we_are_logged_on(MsimSession *session) +{ + MsimMessage *body; + + g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE); + /* The session is now set up, ready to be connected. This emits the * signedOn signal, so clients can now do anything with msimprpl, and * we're ready for it (session key, userid, username all setup). */ purple_connection_update_progress(session->gc, _("Connected"), 3, 4); purple_connection_set_state(session->gc, PURPLE_CONNECTED); - - /* Additional post-connect operations */ - - - if (msim_msg_get_integer(msg, "uniquenick") == session->userid) { - purple_debug_info("msim_we_are_logged_on", "TODO: pick username\n"); - /* No username is set. */ - purple_notify_error(session->account, - _("No username set"), - _("Please go to http://editprofile.myspace.com/index.cfm?fuseaction=profile.username and choose a username and try to login again."), NULL); - purple_connection_error_reason (session->gc, - PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set")); - return FALSE; - } - body = msim_msg_new( "UserID", MSIM_TYPE_INTEGER, session->userid, NULL); @@ -1687,7 +1699,14 @@ if (msim_msg_get_integer(msg, "lc") == 1) { return msim_login_challenge(session, msg); } else if (msim_msg_get_integer(msg, "lc") == 2) { - return msim_we_are_logged_on(session, msg); + /* return msim_we_are_logged_on(session, msg); */ + if (msim_is_username_set(session, msg)) { + return msim_we_are_logged_on(session); + } else { + /* No username is set... We'll wait for the callbacks to do their work */ + /* When they're all done, the last one will call msim_we_are_logged_on() and pick up where we left off */ + return FALSE; + } } else if (msim_msg_get(msg, "bm")) { return msim_incoming_bm(session, msg); } else if (msim_msg_get(msg, "rid")) { diff -r d270b6aebabc -r 3867cef6a0d5 libpurple/protocols/myspace/myspace.h --- a/libpurple/protocols/myspace/myspace.h Sun Feb 17 17:14:29 2008 +0000 +++ b/libpurple/protocols/myspace/myspace.h Sun Feb 17 17:15:40 2008 +0000 @@ -45,6 +45,7 @@ #include "cipher.h" /* for SHA-1 */ #include "util.h" /* for base64 */ #include "debug.h" /* for purple_debug_info */ +#include "request.h" /* For dialogs used in setting the username */ #include "xmlnode.h" #include "core.h" @@ -88,6 +89,9 @@ * warn user that it may be too long. */ #define MSIM_MAX_PASSWORD_LENGTH 10 +/* Maximum length of usernames, when setting. */ +#define MSIM_MAX_USERNAME_LENGTH 25 + /* Build version of MySpaceIM to report to servers (1.0.xxx.0) */ #define MSIM_CLIENT_VERSION 697 @@ -108,6 +112,7 @@ /* Time between keepalives (seconds) - if no data within this time, is dead. */ #define MSIM_KEEPALIVE_INTERVAL (3 * 60) +/*#define MSIM_USE_KEEPALIVE*/ /* Time to check if alive (milliseconds) */ #define MSIM_KEEPALIVE_INTERVAL_CHECK (30 * 1000) @@ -221,6 +226,8 @@ gboolean msim_send_bm(MsimSession *session, const gchar *who, const gchar *text, int type); +gboolean msim_we_are_logged_on(MsimSession *session); + void msim_unrecognized(MsimSession *session, MsimMessage *msg, gchar *note); guint msim_new_reply_callback(MsimSession *session, MSIM_USER_LOOKUP_CB cb, gpointer data); diff -r d270b6aebabc -r 3867cef6a0d5 libpurple/protocols/myspace/persist.h --- a/libpurple/protocols/myspace/persist.h Sun Feb 17 17:14:29 2008 +0000 +++ b/libpurple/protocols/myspace/persist.h Sun Feb 17 17:15:40 2008 +0000 @@ -73,7 +73,8 @@ /** Messages to Change/send information */ MSIM_PERSIST_DSN_LID(MC_USER_PREFERENCES, 1, 10) MSIM_PERSIST_DSN_LID(MC_CONTACT_INFO, 0, 9) -MSIM_PERSIST_DSN_LID(MC_IMPORT_ALL_FRIENDS, 14, 21) +MSIM_PERSIST_DSN_LID(MC_SET_USERNAME, 9, 14) +MSIM_PERSIST_DSN_LID(MC_IMPORT_ALL_FRIENDS, 14, 21) MSIM_PERSIST_DSN_LID(MC_INVITE, 16, 25) /** Messages to Delete information */ diff -r d270b6aebabc -r 3867cef6a0d5 libpurple/protocols/myspace/user.c --- a/libpurple/protocols/myspace/user.c Sun Feb 17 17:14:29 2008 +0000 +++ b/libpurple/protocols/myspace/user.c Sun Feb 17 17:15:40 2008 +0000 @@ -24,6 +24,15 @@ static void msim_downloaded_buddy_icon(PurpleUtilFetchUrlData *url_data, gpointer user_data, const gchar *url_text, gsize len, const gchar *error_message); +/* Callbacks for setting the username bit */ +static void msim_check_username_availability_cb(PurpleConnection *gc, const char *value); +static void msim_username_is_available_cb(MsimSession *session, MsimMessage *userinfo, gpointer data); +static void msim_set_username_confirmed_cb(PurpleConnection *gc); +static void msim_username_is_set_cb(MsimSession *session, MsimMessage *userinfo, gpointer data); +static void msim_set_username(MsimSession *session, const gchar *username, + MSIM_USER_LOOKUP_CB cb, gpointer data); +static char *msim_username_to_set; + /** Format the "now playing" indicator, showing the artist and song. * @return Return a new string (must be g_free()'d), or NULL. */ @@ -487,6 +496,19 @@ return strspn(user, "0123456789") == strlen(user); } +/** Return whether a given username is syntactically valid. + * Note: does not actually check that the user exists. */ +gboolean +msim_is_valid_username(const gchar *user) +{ + return !msim_is_userid(user) && /* Not all numeric */ + strlen(user) <= MSIM_MAX_USERNAME_LENGTH + && strspn(user, "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "_" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == strlen(user); +} + /** * Check if a string is an email address (contains an @). * @@ -537,4 +559,279 @@ user->image_url); /* checksum */ } +/*** + * If they hit cancel or no at any point in the Setting Username process, we come here. * + * Currently.. We're safe letting them get by without setting it.. Unless we hear otherwise.. * + * So for now, give them a menu.. If this becomes an issue with the Official client.. boot them here */ +void msim_do_not_set_username_cb(PurpleConnection *gc) { + purple_debug_info("msim", "Dont set username"); + /* Protocol won't log in now without a username set.. Disconnect */ + purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_AUTHENTICATION_FAILED, _("No username set")); +} + +/** They've decided to set a username! Yay! */ +void msim_set_username_cb(PurpleConnection *gc) { + g_return_if_fail(gc != NULL); + purple_debug_info("msim","Set username\n"); + purple_request_input(gc, _("MySpaceIM - Please Set a Username"), + _("Please enter a username to check its availability:"), + NULL, + "", FALSE, FALSE, NULL, + _("OK"), G_CALLBACK(msim_check_username_availability_cb), + _("Cancel"), G_CALLBACK(msim_do_not_set_username_cb), + purple_connection_get_account(gc), + NULL, + NULL, + gc); +} + +/** Once they've submitted their desired new username, + * check if it is available here. */ +static void msim_check_username_availability_cb(PurpleConnection *gc, const char *username_to_check) +{ + MsimMessage *user_msg; + MsimSession *session; + + g_return_if_fail(gc != NULL); + + session = (MsimSession *)gc->proto_data; + + g_return_if_fail(MSIM_SESSION_VALID(session)); + + purple_debug_info("msim_check_username_availability_cb", "Checking username: %s\n", username_to_check); + + user_msg = msim_msg_new( + "user", MSIM_TYPE_STRING, g_strdup(username_to_check), + NULL); + + /* 25 characters: letters, numbers, underscores */ + /* TODO: VERIFY ABOVE */ + + /* \persist\1\sesskey\288500516\cmd\1\dsn\5\uid\204084363\lid\7\rid\367\body\UserName=Jaywalker\final\ */ + /* Official client uses a standard lookup... So do we! */ + msim_lookup_user(session, username_to_check, msim_username_is_available_cb, user_msg); +} + +/** This is where we do a bit more than merely prompt the user. + * Now we have some real data to tell us the state of their requested username + * \persistr\\cmd\257\dsn\5\uid\204084363\lid\7\rid\367\body\UserName=TheAlbinoRhino1\final\ */ +static void msim_username_is_available_cb(MsimSession *session, MsimMessage *userinfo, gpointer data) +{ + MsimMessage *msg; + gchar *username; + MsimMessage *body; + gint userid; + + purple_debug_info("msim_username_is_available_cb", "Look up username callback made\n"); + + msg = (MsimMessage *)data; + g_return_if_fail(MSIM_SESSION_VALID(session)); + g_return_if_fail(msg != NULL); + + username = msim_msg_get_string(msg, "user"); + body = msim_msg_get_dictionary(userinfo, "body"); + + if (!body) { + purple_debug_info("msim_username_is_available_cb", "No body for %s?!\n", username); + purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, + "An error occured while trying to set the username.\n" + "Please try again, or visit http://editprofile.myspace.com/index.cfm?" + "fuseaction=profile.username to set your username."); + return; + } + + userid = msim_msg_get_integer(body, "UserID"); + + purple_debug_info("msim_username_is_available_cb", "Returned username is %s and userid is %d\n", username, userid); + msim_msg_free(body); + msim_msg_free(msg); + + /* The response for a free username will ONLY have the UserName in it.. + * thus making UserID return 0 when we msg_get_integer it */ + if (userid == 0) { + /* This username is currently unused */ + purple_debug_info("msim_username_is_available_cb", "Username available. Prompting to Confirm.\n"); + msim_username_to_set = g_strdup(username); + g_free(username); + purple_request_yes_no(session->gc, + _("MySpaceIM - Username Available"), + _("This username is available. Would you like to set it?"), + _("ONCE SET, THIS CANNOT BE CHANGED!"), + 0, + session->account, + NULL, + NULL, + session->gc, + G_CALLBACK(msim_set_username_confirmed_cb), + G_CALLBACK(msim_do_not_set_username_cb)); + } else { + /* Looks like its in use or we have an invalid response */ + purple_debug_info("msim_username_is_available_cb", "Username unavaiable. Prompting for new entry.\n"); + purple_request_input(session->gc, _("MySpaceIM - Please Set a Username"), + _("This username is unavailable."), + _("Please try another username:"), + "", FALSE, FALSE, NULL, + _("OK"), G_CALLBACK(msim_check_username_availability_cb), + _("Cancel"), G_CALLBACK(msim_do_not_set_username_cb), + session->account, + NULL, + NULL, + session->gc); + } +} + +/* They've confirmed that username that was available, Lets make the call to set it */ +static void msim_set_username_confirmed_cb(PurpleConnection *gc) +{ + MsimMessage *user_msg; + MsimSession *session; + + g_return_if_fail(gc != NULL); + + session = (MsimSession *)gc->proto_data; + + g_return_if_fail(MSIM_SESSION_VALID(session)); + + + user_msg = msim_msg_new( + "user", MSIM_TYPE_STRING, g_strdup(msim_username_to_set), + NULL); + + purple_debug_info("msim_set_username_confirmed_cb", "Setting username to %s\n", msim_username_to_set); + + /* Sets our username... keep your fingers crossed :) */ + msim_set_username(session, msim_username_to_set, msim_username_is_set_cb, user_msg); + g_free(msim_username_to_set); +} + +/** + * Asynchronously set new username, calling callback when receive result. + * + * @param session + * @param username The username we're setting for ourselves. Not freed. + * @param cb Callback, called with user information when available. + * @param data An arbitray data pointer passed to the callback. + */ +static void +msim_set_username(MsimSession *session, const gchar *username, + MSIM_USER_LOOKUP_CB cb, gpointer data) +{ + MsimMessage *body; + guint rid; + + g_return_if_fail(MSIM_SESSION_VALID(session)); + g_return_if_fail(username != NULL); + g_return_if_fail(cb != NULL); + + purple_debug_info("msim", "msim_set_username: " + "Setting username %s\n", username); + + msim_msg_dump("msim_set_username: data=%s\n", (MsimMessage *)data); + + /* Setup callback. Response will be associated with request using 'rid'. */ + rid = msim_new_reply_callback(session, cb, data); + + /* TODO: I dont know if the ContactType is -/ALWAYS/- 1 */ + + body = msim_msg_new("UserName", MSIM_TYPE_STRING, g_strdup(username),NULL); +/* \setinfo\\sesskey\469958979\info\Age=21.AvatarUrl=.BandName=.ContactType=1.DisplayName=Msim.Gender=M.ImageURL=http:/1/1x.myspace.com/1images/1no_pic.gif.LastLogin=128335268400000000.Location=US.ShowAvatar=False.SongName=.TotalFriends=1.UserName=msimprpl2\final\ +*/ + + /* Send request */ + g_return_if_fail(msim_send(session, + "setinfo", MSIM_TYPE_BOOLEAN, TRUE, + "sesskey", MSIM_TYPE_INTEGER, session->sesskey, + "info", MSIM_TYPE_DICTIONARY, body, + NULL)); + body = msim_msg_new("UserName", MSIM_TYPE_STRING, g_strdup(username),NULL); + g_return_if_fail(msim_send(session, + "persist", MSIM_TYPE_INTEGER, 1, + "sesskey", MSIM_TYPE_INTEGER, session->sesskey, + "cmd", MSIM_TYPE_INTEGER, MSIM_CMD_GET, + "dsn", MSIM_TYPE_INTEGER, MG_MYSPACE_INFO_BY_STRING_DSN, + "uid", MSIM_TYPE_INTEGER, session->userid, + "lid", MSIM_TYPE_INTEGER, MG_MYSPACE_INFO_BY_STRING_LID, + "rid", MSIM_TYPE_INTEGER, rid, + "body", MSIM_TYPE_DICTIONARY, body, + NULL)); +} + +/** Called after username is set. */ +static void msim_username_is_set_cb(MsimSession *session, MsimMessage *userinfo, gpointer data) +{ + gchar *username, *errmsg; + MsimMessage *body; + + guint rid; + gint cmd,dsn,uid,lid,code; + /* \persistr\\cmd\258\dsn\9\uid\204084363\lid\14\rid\369\body\UserName=TheAlbinoRhino1.Code=0\final\ */ + + purple_debug_info("msim","username_is_set made\n"); + + g_return_if_fail(MSIM_SESSION_VALID(session)); + + + msim_msg_dump("username_is_set message is: %s\n", userinfo); + cmd = msim_msg_get_integer(userinfo, "cmd"); + dsn = msim_msg_get_integer(userinfo, "dsn"); + uid = msim_msg_get_integer(userinfo, "uid"); + lid = msim_msg_get_integer(userinfo, "lid"); + body = msim_msg_get_dictionary(userinfo, "body"); + errmsg = g_strdup("An error occured while trying to set the username.\n" + "Please try again, or visit http://editprofile.myspace.com/index.cfm?" + "fuseaction=profile.username to set your username."); + + if (!body) { + purple_debug_info("msim_username_is_set_cb", "No body"); + /* Error: No body! */ + purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); + } + username = msim_msg_get_string(body, "UserName"); + code = msim_msg_get_integer(body,"Code"); + + msim_msg_free(body); + + purple_debug_info("msim_username_is_set_cb", + "cmd = %d, dsn = %d, lid = %d, code = %d, username = %s\n", + cmd, dsn, lid, code, username); + + if (cmd == (MSIM_CMD_BIT_REPLY | MSIM_CMD_PUT) + && dsn == MC_SET_USERNAME_DSN + && lid == MC_SET_USERNAME_LID) { + purple_debug_info("msim_username_is_set_cb", "Proper cmd,dsn,lid for username_is_set!\n"); + purple_debug_info("msim_username_is_set_cb", "Username Set with return code %d\n",code); + if (code == 0) { + /* Good! */ + msim_we_are_logged_on(session); + } else { + purple_debug_info("msim_username_is_set", "code is %d",code); + /* TODO: what to do here? */ + } + } else if (cmd == (MSIM_CMD_BIT_REPLY | MSIM_CMD_GET) + && dsn == MG_MYSPACE_INFO_BY_STRING_DSN + && lid == MG_MYSPACE_INFO_BY_STRING_LID) { + /* Not quite done... ONE MORE STEP :) */ + rid = msim_new_reply_callback(session, msim_username_is_set_cb, data); + body = msim_msg_new("UserName", MSIM_TYPE_STRING, g_strdup(username),NULL); + if (!msim_send(session, "persist", MSIM_TYPE_INTEGER, 1, + "sesskey", MSIM_TYPE_INTEGER, session->sesskey, + "cmd", MSIM_TYPE_INTEGER, MSIM_CMD_PUT, + "dsn", MSIM_TYPE_INTEGER, MC_SET_USERNAME_DSN, + "uid", MSIM_TYPE_INTEGER, session->userid, + "lid", MSIM_TYPE_INTEGER, MC_SET_USERNAME_LID, + "rid", MSIM_TYPE_INTEGER, rid, + "body", MSIM_TYPE_DICTIONARY, body, + NULL)) { + /* Error! */ + /* Can't set... Disconnect */ + purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); + } + + } else { + /* Error! */ + purple_debug_info("msim","username_is_set Error: Invalid cmd/dsn/lid combination"); + purple_connection_error_reason(session->gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR, errmsg); + } + g_free(errmsg); +} diff -r d270b6aebabc -r 3867cef6a0d5 libpurple/protocols/myspace/user.h --- a/libpurple/protocols/myspace/user.h Sun Feb 17 17:14:29 2008 +0000 +++ b/libpurple/protocols/myspace/user.h Sun Feb 17 17:15:40 2008 +0000 @@ -51,6 +51,9 @@ gboolean msim_store_user_info(MsimSession *session, MsimMessage *msg, MsimUser *user); gboolean msim_is_userid(const gchar *user); gboolean msim_is_email(const gchar *user); +gboolean msim_is_valid_username(const gchar *user); void msim_lookup_user(MsimSession *session, const gchar *user, MSIM_USER_LOOKUP_CB cb, gpointer data); +void msim_set_username_cb(PurpleConnection *gc); +void msim_do_not_set_username_cb(PurpleConnection *gc); #endif /* !_MYSPACE_USER_H */ diff -r d270b6aebabc -r 3867cef6a0d5 pidgin/pixmaps/toolbar/16/get-attention.png Binary file pidgin/pixmaps/toolbar/16/get-attention.png has changed