/** * Implements #prpl->login(). This logins an account in. * * @param acc The #account_t. **/ static void steam_login(account_t *acc) { SteamData *sata; SteamApiReq *req; gchar *str; sata = steam_data_new(acc); imcb_log(sata->ic, "Connecting"); if ((sata->api->token == NULL) || (sata->api->sessid == NULL)) { str = set_getstr(&acc->set, "cgid"); g_free(sata->api->cgid); sata->api->cgid = g_strdup(str); str = set_getstr(&acc->set, "esid"); g_free(sata->api->esid); sata->api->esid = g_strdup(str); imcb_log(sata->ic, "Requesting authentication key"); req = steam_api_req_new(sata->api, steam_cb_key, sata); steam_api_req_key(req, acc->user); return; } imcb_log(sata->ic, "Sending logon request"); req = steam_api_req_new(sata->api, steam_cb_logon, sata); steam_api_req_logon(req); }
static void steam_cb_friends(SteamApiReq *req, gpointer data) { bee_user_t *bu; gchar sid[STEAM_ID_STRMAX]; GList *l; SteamData *sata = data; SteamUser *user; SteamUserInfo *info; struct im_connection *ic = sata->ic; if (steam_req_error(sata, req, TRUE)) { return; } if (!(ic->flags & BEE_USER_ONLINE)) { imcb_connected(ic); } for (l = req->infs->head; l != NULL; l = l->next) { info = l->data; STEAM_ID_STR(info->id, sid); /* Attempt to grab the buddy before adding */ bu = bee_user_by_handle(sata->ic->bee, sata->ic, sid); if (bu == NULL) { imcb_add_buddy(sata->ic, sid, NULL); imcb_buddy_nick_hint(sata->ic, sid, info->nick); imcb_rename_buddy(sata->ic, sid, info->fullname); } bu = bee_user_by_handle(sata->ic->bee, sata->ic, sid); if (G_UNLIKELY(bu == NULL)) { continue; } user = bu->data; user->vtime = info->vtime; switch (info->rel) { case STEAM_USER_REL_FRIEND: steam_user_status(sata, info, bu); break; case STEAM_USER_REL_IGNORE: ic->deny = g_slist_prepend(ic->deny, g_strdup(bu->handle)); break; } if (info->unread > 0) { req = steam_api_req_new(req->api, steam_cb_msgs, sata); steam_api_req_msgs(req, info->id, info->vtime); } } req = steam_api_req_new(req->api, steam_cb_poll, sata); steam_api_req_poll(req); }
/** * Processes the error of a #SteamApiReq. * * @param sata The #SteamData. * @param req The #SteamApiReq. * @param logout TRUE to logout, otherwise FALSE. * * @return TRUE if an error exists, otherwise FALSE. **/ static gboolean steam_req_error(SteamData *sata, SteamApiReq *req, gboolean logout) { if (req->err == NULL) return FALSE; if (g_error_matches(req->err, STEAM_API_ERROR, STEAM_API_ERROR_EXPRIED)) { STEAM_UTIL_DEBUGLN("Relogging on due to expired session"); steam_http_free_reqs(req->api->http); req = steam_api_req_new(req->api, steam_cb_relogon, sata); steam_api_req_logon(req); return TRUE; } if (g_error_matches(req->err, STEAM_HTTP_ERROR, STEAM_HTTP_ERROR_CLOSED)) { STEAM_UTIL_DEBUGLN("Request (%p) forcefully closed", req->req); /* Ignore closed HTTP connections */ return TRUE; } STEAM_UTIL_DEBUGLN("Error: %s", req->err->message); imcb_error(sata->ic, "%s", req->err->message); if (logout) { STEAM_UTIL_DEBUGLN("Reconnecting due to error"); imc_logout(sata->ic, logout); } return TRUE; }
/** * Implements #prpl->rem_deny(). This unblocks a buddy. * * @param ic The #im_connection. * @param who The handle of the buddy. **/ static void steam_rem_deny(struct im_connection *ic, char *who) { SteamData *sata = ic->proto_data; SteamApiReq *req; req = steam_api_req_new(sata->api, steam_cb_user_action, sata); steam_api_req_user_ignore(req, STEAM_ID_NEW_STR(who), FALSE); }
/** * Implements #prpl->auth_allow(). This denies buddy requests. * * @param ic The #im_connection. * @param who The handle of the buddy. **/ static void steam_auth_deny(struct im_connection *ic, const char *who) { SteamData *sata = ic->proto_data; SteamApiReq *req; req = steam_api_req_new(sata->api, steam_cb_user_action, sata); steam_api_req_user_accept(req, STEAM_ID_NEW_STR(who), STEAM_API_ACCEPT_TYPE_IGNORE); }
/** * Implements #prpl->add_deny(). This blocks a buddy. * * @param ic The #im_connection. * @param who The handle of the buddy. **/ static void steam_add_deny(struct im_connection *ic, char *who) { SteamData *sata = ic->proto_data; SteamApiReq *req; imcb_buddy_status(ic, who, 0, NULL, NULL); req = steam_api_req_new(sata->api, steam_cb_user_action, sata); steam_api_req_user_ignore(req, STEAM_ID_NEW_STR(who), TRUE); }
/** * Implements #prpl->remove_buddy(). This removes a buddy. * * @param ic The #im_connection. * @param name The name of the buddy to add. * @param group The group of the buddy. (Irrelevant to this plugin) **/ static void steam_remove_buddy(struct im_connection *ic, char *name, char *group) { SteamData *sata = ic->proto_data; SteamApiReq *req; req = steam_api_req_new(sata->api, steam_cb_user_action, sata); steam_api_req_user_remove(req, STEAM_ID_NEW_STR(name)); }
/** * Implements #prpl->get_info(). This retrieves the info of a buddy. * * @param ic The #im_connection. * @param who The handle of the buddy. **/ static void steam_get_info(struct im_connection *ic, char *who) { SteamData *sata = ic->proto_data; SteamApiReq *req; SteamUserInfo *info; info = steam_user_info_new(STEAM_ID_NEW_STR(who)); req = steam_api_req_new(sata->api, steam_cb_user_info, sata); g_queue_push_head(req->infs, info); steam_api_req_user_info(req); }
/** * Implements #prpl->add_buddy(). This adds a buddy. * * @param ic The #im_connection. * @param name The name of the buddy to add. * @param group The group of the buddy. (Irrelevant to this plugin) **/ static void steam_add_buddy(struct im_connection *ic, char *name, char *group) { SteamData *sata = ic->proto_data; SteamApiReq *req; gchar *str; if (g_ascii_strncasecmp(name, "steamid:", 8) != 0) { req = steam_api_req_new(sata->api, steam_cb_user_search, sata); steam_api_req_user_search(req, name, 5); return; } str = strchr(name, ':'); if ((str != NULL) && ((++str)[0] != 0)) { req = steam_api_req_new(sata->api, steam_cb_user_action, sata); steam_api_req_user_add(req, STEAM_ID_NEW_STR(str)); } else { imcb_error(sata->ic, "No Steam ID specified"); } }
/** * Implemented #SteamApiFunc for #steam_api_req_logon() for relogging. * * @param req The #SteamApiReq. * @param data The user defined data, which is #SteamData. **/ static void steam_cb_relogon(SteamApiReq *req, gpointer data) { SteamData *sata = data; if (steam_req_error(sata, req, TRUE)) return; STEAM_UTIL_DEBUGLN("Relogon completed"); /* Update the friend list for good measures */ req = steam_api_req_new(req->api, steam_cb_friends, sata); steam_api_req_friends(req); }
/** * Implemented #SteamApiFunc for #steam_api_req_logon(). * * @param req The #SteamApiReq. * @param data The user defined data, which is #SteamData. **/ static void steam_cb_logon(SteamApiReq *req, gpointer data) { SteamData *sata = data; if (steam_req_error(sata, req, TRUE)) return; set_setstr(&sata->ic->acc->set, "umqid", req->api->umqid); imcb_log(sata->ic, "Requesting friends list"); req = steam_api_req_new(req->api, steam_cb_friends, sata); steam_api_req_friends(req); }
static void steam_cb_relogon(SteamApiReq *req, gpointer data) { SteamData *sata = data; if (steam_req_error(sata, req, TRUE)) { return; } steam_util_debug_info("Relogon completed"); req = steam_api_req_new(req->api, steam_cb_friends, sata); steam_api_req_friends(req); }
/** * Implemented #SteamApiFunc for #steam_api_req_poll(). * * @param req The #SteamApiReq. * @param data The user defined data, which is #SteamData. **/ static void steam_cb_poll(SteamApiReq *req, gpointer data) { SteamData *sata = data; GList *l; if (steam_req_error(sata, req, TRUE)) return; for (l = req->msgs->head; l != NULL; l = l->next) steam_user_msg(sata, l->data, 0); req = steam_api_req_new(req->api, steam_cb_poll, sata); steam_api_req_poll(req); }
/** * Implements #prpl->logout(). This logs an account out. * * @param ic The #im_connection. **/ static void steam_logout(struct im_connection *ic) { SteamData *sata = ic->proto_data; SteamApiReq *req; steam_http_free_reqs(sata->api->http); if (ic->flags & BEE_USER_ONLINE) { req = steam_api_req_new(sata->api, steam_cb_logoff, sata); steam_api_req_logoff(req); } else { steam_data_free(sata); } }
/** * Implements #prpl->send_typing(). This sends the typing state message. * * @param ic The #im_connection. * @param who The handle of the buddy. * @param flags The message flags. (Irrelevant to this plugin) * * @return 0. (Upstream bitlbe does nothing with this) **/ static int steam_send_typing(struct im_connection *ic, char *who, int flags) { SteamData *sata = ic->proto_data; SteamApiReq *req; SteamUserMsg *msg; msg = steam_user_msg_new(STEAM_ID_NEW_STR(who)); msg->type = STEAM_USER_MSG_TYPE_TYPING; req = steam_api_req_new(sata->api, steam_cb_msg, sata); steam_api_req_msg(req, msg); steam_user_msg_free(msg); return 0; }
/** * Implemented #SteamApiFunc for #steam_api_req_key(). * * @param req The #SteamApiReq. * @param data The user defined data, which is #SteamData. **/ static void steam_cb_key(SteamApiReq *req, gpointer data) { SteamData *sata = data; account_t *acc; gchar *ac; gchar *cc; if (steam_req_error(sata, req, TRUE)) return; acc = sata->ic->acc; ac = set_getstr(&acc->set, "authcode"); cc = set_getstr(&acc->set, "captcha"); imcb_log(sata->ic, "Requesting authentication token"); req = steam_api_req_new(req->api, steam_cb_auth, sata); steam_api_req_auth(req, acc->user, acc->pass, ac, cc); }
static void steam_cb_user_search(SteamApiReq *req, gpointer data) { const gchar *tag; gchar sid[STEAM_ID_STRMAX]; GList *l; guint i; SteamData *sata = data; SteamUserInfo *info; if (steam_req_error(sata, req, TRUE)) { return; } for (l = req->infs->head, i = 0; (l != NULL) && (i < 2); l = l->next, i++); switch (i) { case 0: imcb_error(sata->ic, "Failed to find any friend(s)"); return; case 1: info = req->infs->head->data; req = steam_api_req_new(req->api, steam_cb_user_action, sata); steam_api_req_user_add(req, info->id); return; } imcb_log(sata->ic, "Select from one of the following Steam Friends:"); tag = sata->ic->acc->tag; for (l = req->infs->head, i = 1; l != NULL; l = l->next, i++) { info = l->data; STEAM_ID_STR(info->id, sid); imcb_log(sata->ic, "%u. `%s' %s", i, info->nick, info->profile); imcb_log(sata->ic, "-- add %s steamid:%s", tag, sid); } }
/** * Implements #prpl->buddy_msg(). This sends a message to a buddy. * * @param ic The #im_connection. * @param to The handle of the buddy. * @param message The message to send. * @param flags The message flags. (Irrelevant to this plugin) * * @return 0. (Upstream bitlbe does nothing with this) **/ static int steam_buddy_msg(struct im_connection *ic, char *to, char *message, int flags) { SteamData *sata = ic->proto_data; SteamApiReq *req; SteamUserMsg *msg; msg = steam_user_msg_new(STEAM_ID_NEW_STR(to)); msg->type = STEAM_USER_MSG_TYPE_SAYTEXT; msg->text = g_strdup(message); /* As of January 23, 2013, Valve has disabled support for /me. It * was disabled as it "allowed some users to modify the color of * their chat text." * * See the ChangeLog for more information: http://goo.gl/TETV5 */ /* if (g_str_has_prefix(message, "/me")) { if (strlen(message) < 5) return 0; msg->type = STEAM_USER_MSG_TYPE_EMOTE; msg->text = g_strdup(message + 4); } else { msg->type = STEAM_USER_MSG_TYPE_SAYTEXT; msg->text = g_strdup(message); } */ req = steam_api_req_new(sata->api, steam_cb_msg, sata); steam_api_req_msg(req, msg); steam_user_msg_free(msg); return 0; }