|
From: <sid...@us...> - 2010-08-13 20:15:52
|
Revision: 381
http://libyahoo2.svn.sourceforge.net/libyahoo2/?rev=381&view=rev
Author: siddheshp
Date: 2010-08-13 20:15:45 +0000 (Fri, 13 Aug 2010)
Log Message:
-----------
Merge libyahoo2 chatroom code
Conflicts:
libyahoo2/src/libyahoo2.c
libyahoo2/src/sample_client.c
libyahoo2/src/yahoo2.h
libyahoo2/src/yahoo2_callbacks.h
libyahoo2/src/yahoo2_types.h
libyahoo2/src/yahoo_httplib.c
Modified Paths:
--------------
trunk/libyahoo2/src/libyahoo2.c
trunk/libyahoo2/src/sample_client.c
trunk/libyahoo2/src/yahoo2.h
trunk/libyahoo2/src/yahoo2_callbacks.h
trunk/libyahoo2/src/yahoo2_types.h
trunk/libyahoo2/src/yahoo_httplib.c
Added Paths:
-----------
trunk/libyahoo2/doc/ymsg-chatroom.txt
Added: trunk/libyahoo2/doc/ymsg-chatroom.txt
===================================================================
--- trunk/libyahoo2/doc/ymsg-chatroom.txt (rev 0)
+++ trunk/libyahoo2/doc/ymsg-chatroom.txt 2010-08-13 20:15:45 UTC (rev 381)
@@ -0,0 +1,169 @@
+Yahoo Messenger Protocol -- Chat Room
+----------------------------------------
+
+The YMSG protocol used in chat room.
+Seven types of messages used here:
+1) Chat Online
+2) Chat Join : Messages send when joining the chat room.
+3) Chat Comment : Send comment to server or Receive comments from others from server
+4) Chat Join : When a user joined the chat room, will receive a message from the server
+5) Chat Logout : When a user left the chat room, will receive a message from the server
+6) Chat Exit : Left the chat room, send a message to tell the server
+7) Ignore User : Ignore/Unignore a specified user, and the server will not send the user's comments any more
+
+
+1.Chat Online
+
+Service: Chat Online (150 0×96)
+
+Client –> Server :
+
+109 : username
+1 : username
+6 : abcde
+98 : us
+445 : en-us
+135 : ym10.0.0.1258
+
+Server –> Client :
+
+1 : username
+6 : abcde
+98 : us
+109 : username
+135 : ym10.0.0.1258
+445 : en-us
+302 : 10019
+10019 : username
+303 : 10019
+
+2. Chat Join
+
+Service: Chat Join (152 0×98)
+
+Client –> Server :
+
+1 : username
+104 : #ChatRoom(China : 1)
+129 : (Chat Room ID)
+62 : 2
+
+Server –> Client :
+
+13 : 1
+104 : #ChatRoom(China : 1)
+105 : To help preven spam … …
+109 : username
+302 : 10019
+10019 : username
+303 : 10019
+109 : Yahoo
+141 : Messenger Chat Admin
+
+Now client receives the URL of the image for verification. Libyahoo2 will be in charge of extracting the URL and handle it to client to display the image.
+
+Server –> Client
+
+13 : 1
+104 : #ChatRoom(China : 1)
+105 : (Information from the chat room)
+108 : (Number of members in this package)
+126 : 328704
+128 : 1032
+129 : (Chat Room ID)
+130 : (Some Unrecognizable characters to show the first join)
+302 : 10019
+10019 : username
+303 : 10019
+#For all the users in the chat room:
+109 : user name
+110 : 0
+111 : (sex) neuter/male/female
+113 : (number)
+141 : (nick name ?) james
+142 : (country) New Zealand
+
+Special Situation : Disconnect. Maybe the chat room is full
+
+Server –> Client :
+Status : Disconnected(4294967295)
+114 : -35
+
+3. Chat Comment
+
+Service : Comment(168 0xa8)
+
+Client –> Server
+
+1 : username
+104: #ChatRoom(China:1)
+124 : (Message Type)
+117 : (Content)
+
+Server –> Client
+
+104 : #ChatRoom(China:1)
+109 : (From) Yahoo/username
+117 : (Content)
+124 : (Message Type)
+
+4. Chat Join
+
+Service : Chat Join (152 0×98)
+
+Server –> Client :
+
+104 : #ChatRoom(China : 1)
+105 : (Information from the chat room)
+108 : 1
+109 : username(who is joining)
+113 : (number)
+
+5. Chat Exit
+
+Service : Chat Exit(155 0×9b)
+
+Server –> Client
+
+104 : #ChatRoom(China:1)
+108 : 1
+109 : username(who is leaving)
+113 : (number)
+
+6. Chat Logout
+
+Service : Chat Logout (160 0xa0)
+
+Client –> Server
+
+1 : username
+1005 : (number)
+
+Server –> Client
+
+1 : username
+1005 : (number) <same with the number sent to server>
+302 : 10019
+10019 : username
+303 : 10019
+
+7. Ignore user
+
+Service : Ignore Contact (133 0x85)
+
+Client -->Server
+
+1 : my username
+13 : 1 if ignore a user / 2 if unignore a user
+302 : 319
+300 : 319
+7 : user to be ignored
+301 : 319
+303 : 319
+
+Server --> Client
+
+0 : user to be ignored
+1 : my username
+13 : 1 if ignore a user / 2 if unignore a user
+66 : 0
Modified: trunk/libyahoo2/src/libyahoo2.c
===================================================================
--- trunk/libyahoo2/src/libyahoo2.c 2010-08-05 03:36:23 UTC (rev 380)
+++ trunk/libyahoo2/src/libyahoo2.c 2010-08-13 20:15:45 UTC (rev 381)
@@ -93,6 +93,11 @@
struct yahoo_callbacks *yc = NULL;
+struct yahoo_post_data {
+ struct yahoo_input_data *yid;
+ char *data;
+};
+
void yahoo_register_callbacks(struct yahoo_callbacks *tyc)
{
yc = tyc;
@@ -103,6 +108,7 @@
static int yahoo_send_data(void *fd, void *data, int len);
static void _yahoo_http_connected(int id, void *fd, int error, void *data);
static void yahoo_connected(void *fd, int error, void *data);
+static void _yahoo_http_post_connected(int id, void *fd, int error, void *data);
int yahoo_log_message(char *fmt, ...)
{
@@ -204,6 +210,7 @@
YList *txqueues;
int write_tag;
+ int chat_room_id;
};
struct yahoo_server_settings {
@@ -465,6 +472,51 @@
}
}
+/* Free chat room list */
+static void yahoo_free_chat_room_list(YList *list)
+{
+ YList *lobby, *templ;
+ while(list != NULL) {
+ FREE(((yahoo_chatroom_info *)list->data)->type);
+ FREE(((yahoo_chatroom_info *)list->data)->topic);
+ FREE(((yahoo_chatroom_info *)list->data)->name);
+ lobby = list->prev;
+ while(lobby != NULL) {
+ templ = lobby->prev;
+ FREE(lobby->data);
+ FREE(lobby);
+ lobby = templ;
+ }
+ list = list->next;
+ }
+ y_list_free(list);
+}
+/*
+static void yahoo_free_chat_cat_list(YList *list)
+{
+ YList *ptr = list->next;
+ free_chat_cat_list(list->next);
+ FREE(list);
+}
+*/
+static void yahoo_free_chat_cat_list(YList *list)
+{
+ FREE(((yahoo_chatroom_category *)list->data)->name);
+
+ if(((yahoo_chatroom_category *)(list->data))->room_list)
+ yahoo_free_chat_room_list(((yahoo_chatroom_category *)list->data)->room_list);
+
+ if (list->prev) {
+ yahoo_free_chat_cat_list(list->prev);
+ }
+ if (list->next) {
+ yahoo_free_chat_cat_list(list->next);
+ }
+
+ FREE(list->data);
+ FREE(list);
+}
+
/* Free webcam data */
static void yahoo_free_webcam(struct yahoo_webcam *wcm)
{
@@ -1052,6 +1104,12 @@
int membercount = 0;
int chaterr = 0;
YList *l;
+ char *end, *head;
+ char content[256], vcode[8];
+ int length;
+ struct yahoo_post_data *yad;
+ struct yahoo_input_data *new_yid;
+ static int verify_image = 1;
yahoo_dump_unhandled(pkt);
for (l = pkt->hash; l; l = l->next) {
@@ -1163,6 +1221,42 @@
WARNING(("Got more than 1 member on a normal join"));
}
/* this should only ever have one, but just in case */
+
+ /* skip the message "To help prevent spam ..." to the url of the image for verification
+ the URL is in the first message server send to client
+ if what user input is wrong, new image URL will be send in form of HTTP*/
+ if (verify_image == 1) {
+ verify_image = 0;
+ end = strstr(topic, ".jpg");
+ end[4] = '\0';
+
+ /* find the URL of the image, the SECOND "http://" in the string */
+ head = strstr(topic, "http://");
+ topic = head + 7; /*skip the first "http://" */
+ head = strstr(topic, "http://");
+
+ /* handle the URL to client to show the image and get the code in the image*/
+ YAHOO_CALLBACK(ext_yahoo_chat_verify)(head, vcode);
+
+ /* construct a HTTP post message to send the verification code to the server*/
+ length = snprintf(content, sizeof(content), "question=%s"
+ "&answer=%s"
+ "&.intl=us&.lang=en-US",
+ head, vcode);
+
+ new_yid = y_new0(struct yahoo_input_data, 1);
+ new_yid->type = YAHOO_CONNECTION_CAPTCHA;
+ new_yid->yd = yid->yd;
+
+ yad = y_new0(struct yahoo_post_data, 1);
+ yad->yid = new_yid;
+ yad->data = strdup(content);
+ yahoo_http_post(yid->yd->client_id, "http://captcha.chat.yahoo.com/captcha1",
+ NULL, length, _yahoo_http_post_connected, yad);
+ break;
+ }
+
+ /* The second time receive the message of this type, it will contain all the members in the chat room*/
while (members) {
YList *n = members->next;
currentmember = members->data;
@@ -1850,7 +1944,7 @@
yahoo_packet_hash(packet, 2, "1");
yahoo_packet_hash(packet, 59, yd->cookie_b);
yahoo_packet_hash(packet, 98, "us"); /* TODO Put country code */
- yahoo_packet_hash(packet, 135, "9.0.0.2152");
+ yahoo_packet_hash(packet, 135, YMSG_VERSION);
yahoo_send_packet(yid, packet, 0);
@@ -2955,18 +3049,261 @@
}
}
-static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid,
- int over)
+static void traverse_cat_list(YList *list, int level)
{
+ int i;
+ for(i=0; i<level; i++)
+ putchar('\t');
+ printf("%d - %s\n", ((yahoo_chatroom_category *)list->data)->id, ((yahoo_chatroom_category *)list->data)->name);
+ if(list->prev)
+ traverse_cat_list(list->prev, level+1);
+ if(list->next)
+ traverse_cat_list(list->next, level);
+}
+
+static void traverse_room_list(YList *list)
+{
+ YList *lobby;
+
+ while(list != NULL) {
+ lobby = list->prev;
+ while(lobby != NULL) {
+ printf("%d - %s %d [%d] [w%d]\n",
+ ((yahoo_chatroom_info *)list->data)->id, ((yahoo_chatroom_info *)list->data)->name,
+ ((yahoo_lobby_info *)lobby->data)->count, ((yahoo_lobby_info *)lobby->data)->users,
+ ((yahoo_lobby_info *)lobby->data)->webcams);
+ lobby = lobby->prev;
+ }
+ list = list->next;
+ }
+}
+
+static YList *find_room_category(YList *list, int cat_id)
+{
+ YList *cat_pos = NULL;
+ if (((yahoo_chatroom_category *)(list->data))->id == cat_id) {
+ return list;
+ }
+
+ if(list->prev)
+ cat_pos = find_room_category(list->prev, cat_id);
+ if(list->next && !cat_pos)
+ cat_pos = find_room_category(list->next, cat_id);
+
+ return cat_pos;
+}
+
+static char *get_xml_chatroom_info(char *content, char *pattern)
+{
+ char *header, *tailer, *info;
+ header = strstr(content, pattern);
+ header += strlen(pattern);
+ tailer = strchr(header, '"');
+ *tailer = '\0';
+ info = y_new0(char, tailer - header + 1);
+ strcpy(info, header);
+ *tailer = '"';
+ return info;
+}
+
+static void parse_chat_cat_xml(int id, const char *xml)
+{
+ struct yahoo_data *yd = find_conn_by_id(id);
+ struct yahoo_input_data *yid = find_input_by_id_and_type(id, YAHOO_CONNECTION_CHATCAT);
+ char *content = strdup(xml), *header, *tailer;
+ int child_mode = 0;
+ YList *room_list;
+ YList *list_ptr;
+ YList *cat_stack[5];
+ int stack_ptr = 0;
+ YList *temp, *child, *tail, *category;
+
+ room_list = y_new0(struct _YList, 1);
+ list_ptr = room_list;
+ content = strstr(content, "<category"); /* Find the first category */
+
+ if (content == NULL) {
+ category = find_room_category(yd->chat_room_list, yid->chat_room_id);
+
+ content = strdup(xml);
+ content = strstr(content, "<chatRooms>");
+ if (content == NULL) {
+ printf("Error : Cannot find anything!\n");
+ return ;
+ }
+
+ content += strlen("<chatRooms>");
+
+ content = strchr(content, '<');
+ while(*(content + 1) != '/') {
+ /* find all the fields of a chat room */
+ temp = y_new0(struct _YList, 1);
+ temp->data = y_new0(struct yahoo_chatroom, 1);
+ tail = temp;
+
+ ((yahoo_chatroom_info *)(temp->data))->type = get_xml_chatroom_info(content, "type=\"");
+ ((yahoo_chatroom_info *)(temp->data))->id = atoi(get_xml_chatroom_info(content, "id=\""));
+ ((yahoo_chatroom_info *)(temp->data))->name = get_xml_chatroom_info(content, "name=\"");
+ ((yahoo_chatroom_info *)(temp->data))->topic = get_xml_chatroom_info(content, "topic=\"");
+
+ /* find all lobbys of a chat room */
+
+ content = strchr(content+1, '<');
+ while(*(content + 1) != '/') {
+ child = y_new0(struct _YList, 1);
+ child->data = y_new0(struct yahoo_lobby, 1);
+
+ ((yahoo_lobby_info *)(child->data))->count = atoi(get_xml_chatroom_info(content, "count=\""));
+ ((yahoo_lobby_info *)(child->data))->users = atoi(get_xml_chatroom_info(content, "users=\""));
+ ((yahoo_lobby_info *)(child->data))->voices = atoi(get_xml_chatroom_info(content, "voices=\""));
+ ((yahoo_lobby_info *)(child->data))->webcams = atoi(get_xml_chatroom_info(content, "webcams=\""));
+
+ /* prev is used as a pointer to the the lobby*/
+ tail->prev = child;
+ tail = child;
+
+ content = strchr(content+1, '<');
+ }
+
+ list_ptr->next = temp;
+ list_ptr = temp;
+
+ content = strchr(content+1, '<');
+ }
+
+ ((yahoo_chatroom_category *)(category->data))->room_list = room_list->next;
+
+ } else {
+ while(stack_ptr >= 0) {
+ /* prev is used as a pointer linked with its child categories */
+
+ /* Find the id */
+ temp = y_new0(struct _YList, 1);
+ temp->data = y_new0(struct yahoo_chatroom_category, 1);
+ header = strchr(content, '"');
+ tailer = strchr(header+1, '"');
+ *tailer = '\0';
+ ((yahoo_chatroom_category *)(temp->data))->id = atoi(strdup(header + 1));
+
+ /* Find the name*/
+ header = strchr(tailer+1, '"');
+ tailer = strchr(header+1, '"');
+ *tailer = '\0';
+ ((yahoo_chatroom_category *)(temp->data))->name = strdup(header + 1);
+ ((yahoo_chatroom_category *)(temp->data))->room_list = NULL;
+
+ content = strchr(tailer+1, '>');
+ if(child_mode == 1) {
+ list_ptr->prev = temp;
+ list_ptr = temp;
+ cat_stack[stack_ptr] = temp;
+ child_mode = 0;
+ } else {
+ list_ptr->next = temp;
+ list_ptr = temp;
+ cat_stack[stack_ptr] = temp;
+ }
+
+ if (*(content-1) != '/') {
+ stack_ptr ++;
+ child_mode = 1;
+ }
+
+ /* find the next category */
+ content = strchr(content, '<');
+ while (*(content+1) == '/' && stack_ptr >= 0) {
+ stack_ptr --;
+ list_ptr = cat_stack[stack_ptr];
+ content = strchr(content + 1, '<');
+ }
+ }
+
+ yd->chat_room_list = room_list->next;
+ }
+ FREE(room_list); /* free the head node */
+}
+
+static void yahoo_process_chatcat_connection(struct yahoo_input_data *yid, int over)
+{
if (over)
return;
- if (strstr((char *)yid->rxqueue + (yid->rxlen - 20), "</content>")) {
+ if (strstr((char *)yid->rxqueue, "</content>")) {
+ parse_chat_cat_xml(yid->yd->client_id, (char *)yid->rxqueue);
+
+ /* ext_yahoo_chat_cat_xml() needs to be deprecated in future releases */
YAHOO_CALLBACK(ext_yahoo_chat_cat_xml) (yid->yd->client_id,
(char *)yid->rxqueue);
}
}
+static void yahoo_process_captcha_connection(struct yahoo_input_data *yid, int over)
+{
+ char content[256], vcode[8];
+ char *url, *location;
+ int length;
+ struct yahoo_post_data *yad;
+ struct yahoo_input_data *new_yid;
+ struct yahoo_packet *pkt;
+ struct yahoo_data *yd = yid->yd;
+ int id = yd->client_id;
+ char *judge;
+ http_data data;
+
+ if (over)
+ return;
+
+ yahoo_set_http_data((char *)yid->rxqueue, yid->rxlen, &data);
+ location = yahoo_http_get_header_value(data, "Location");
+
+ /*location = strstr((char *)yid->rxqueue, "Location:");*/
+ if (location == NULL) {
+ return ; /* Do not found the content, must have error*/
+ }
+
+ judge = strstr(location, "tryagain=1");
+ if (judge == NULL) {
+ judge = strstr(location, "close");
+ if (judge != NULL) {
+ /* Successfully logged in*/
+ printf("Successfully Logged in\n");
+ } else {
+ printf("Error in captcha process\n");
+ }
+ yahoo_input_close(yid);
+ return ;
+ } else {
+ location = judge;
+ /* Find the end of the URL*/
+ url = strstr(location, ".jpg");
+ url[4] = '\0';
+
+ /* Find the head of the URL*/
+ url = strstr(location, "http://");
+
+ /* handle the URL to client to show the image and get the code in the image*/
+ YAHOO_CALLBACK(ext_yahoo_chat_verify)(url, vcode);
+
+ /* construct a HTTP post message to send the verification code to the server*/
+ length = snprintf(content, sizeof(content), "question=%s"
+ "&answer=%s"
+ "&.intl=us&.lang=en-US",
+ url, vcode);
+
+ new_yid = y_new0(struct yahoo_input_data, 1);
+ new_yid->type = YAHOO_CONNECTION_CAPTCHA;
+ new_yid->yd = yid->yd;
+
+ yad = y_new0(struct yahoo_post_data, 1);
+ yad->yid = new_yid;
+ yad->data = strdup(content);
+ yahoo_input_close(yid);
+ yahoo_http_post(new_yid->yd->client_id, "http://captcha.chat.yahoo.com/captcha1",
+ NULL, length, _yahoo_http_post_connected, yad);
+ }
+ yahoo_free_http_data(&data);
+}
+
static void yahoo_process_yab_connection(struct yahoo_input_data *yid, int over)
{
struct yahoo_data *yd = yid->yd;
@@ -3508,12 +3845,15 @@
static void (*yahoo_process_connection[]) (struct yahoo_input_data *,
int over) = {
-yahoo_process_pager_connection, yahoo_process_ft_connection,
+ yahoo_process_pager_connection,
+ yahoo_process_ft_connection,
yahoo_process_yab_connection,
yahoo_process_webcam_master_connection,
yahoo_process_webcam_connection,
yahoo_process_chatcat_connection,
- yahoo_process_search_connection, yahoo_process_auth_connection};
+ yahoo_process_search_connection,
+ yahoo_process_auth_connection,
+ yahoo_process_captcha_connection};
int yahoo_read_ready(int id, void *fd, void *data)
{
@@ -3581,6 +3921,8 @@
yd->current_status = -1;
yd->client_id = ++last_id;
+
+ yd->chat_room_list = NULL;
add_to_list(yd);
@@ -3891,11 +4233,6 @@
_yahoo_http_connected, yid);
}
-struct yahoo_post_data {
- struct yahoo_input_data *yid;
- char *data;
-};
-
static void _yahoo_http_post_connected(int id, void *fd, int error, void *data)
{
struct yahoo_post_data *yad = data;
@@ -4400,6 +4737,7 @@
struct yahoo_input_data *yid;
char url[1024];
char buff[1024];
+ YList *category;
if (!yd)
return;
@@ -4407,11 +4745,22 @@
yid = y_new0(struct yahoo_input_data, 1);
yid->yd = yd;
yid->type = YAHOO_CONNECTION_CHATCAT;
+ yid->chat_room_id = chatroomid;
if (chatroomid == 0) {
+ if (yd->chat_room_list) {
+ yahoo_free_chat_cat_list(yd->chat_room_list);
+ yd->chat_room_list = NULL;
+ }
snprintf(url, 1024,
"http://insider.msg.yahoo.com/ycontent/?chatcat=0");
} else {
+ if (!(yd->chat_room_list)) {
+ return;
+ }
+ category = find_room_category(yd->chat_room_list, chatroomid);
+ if(((yahoo_chatroom_category *)(category->data))->room_list)
+ yahoo_free_chat_room_list(((yahoo_chatroom_category *)(category->data))->room_list);
snprintf(url, 1024,
"http://insider.msg.yahoo.com/ycontent/?chatroom_%d=0",
chatroomid);
@@ -4421,12 +4770,12 @@
inputs = y_list_prepend(inputs, yid);
- yahoo_http_get(yid->yd->client_id, url, buff, 0, 0,
+ yahoo_http_get(yid->yd->client_id, url, buff, 1, 0,
_yahoo_http_connected, yid);
}
void yahoo_chat_logon(int id, const char *from, const char *room,
- const char *roomid)
+ const char *roomid, const char *country, const char *language)
{
struct yahoo_input_data *yid =
find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
@@ -4438,17 +4787,27 @@
yd = yid->yd;
+ /* First, send a CHAT ONLINE message*/
pkt = yahoo_packet_new(YAHOO_SERVICE_CHATONLINE, YPACKET_STATUS_DEFAULT,
yd->session_id);
yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
yahoo_packet_hash(pkt, 109, yd->user);
yahoo_packet_hash(pkt, 6, "abcde");
+ if(country && language) {
+ yahoo_packet_hash(pkt, 98, country);
+ yahoo_packet_hash(pkt, 445, language);
+ } else {
+ yahoo_packet_hash(pkt, 98, "us");
+ yahoo_packet_hash(pkt, 445, "en-us");
+ }
+ yahoo_packet_hash(pkt, 135, YMSG_VERSION);
yahoo_send_packet(yid, pkt, 0);
yahoo_packet_free(pkt);
-
+
+ /* Second, Send a CHAT JOIN message*/
pkt = yahoo_packet_new(YAHOO_SERVICE_CHATJOIN, YPACKET_STATUS_DEFAULT,
yd->session_id);
@@ -4494,12 +4853,44 @@
yahoo_packet_free(pkt);
}
+void yahoo_chat_ignore(int id, const char *from, const char *user, int ignore)
+/*ignore = 1 means we are trying to ignore the user
+ ignore = 0 means we have already ignored the user and don't want to ignore him any more*/
+{
+ struct yahoo_input_data *yid =
+ find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
+ struct yahoo_data *yd;
+ struct yahoo_packet *pkt;
+
+ yd = yid->yd;
+
+ pkt = yahoo_packet_new(YAHOO_SERVICE_IGNORECONTACT, YPACKET_STATUS_DEFAULT,
+ yd->session_id);
+
+ yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
+ if(ignore)
+ yahoo_packet_hash(pkt, 13, "1");
+ else
+ yahoo_packet_hash(pkt, 13, "2");
+ yahoo_packet_hash(pkt, 302, "319");
+ yahoo_packet_hash(pkt, 300, "319");
+ yahoo_packet_hash(pkt, 7, user);
+ yahoo_packet_hash(pkt, 301, "319");
+ yahoo_packet_hash(pkt, 303, "319");
+
+ yahoo_send_packet(yid, pkt, 0);
+
+ yahoo_packet_free(pkt);
+}
+
void yahoo_chat_logoff(int id, const char *from)
{
struct yahoo_input_data *yid =
find_input_by_id_and_type(id, YAHOO_CONNECTION_PAGER);
struct yahoo_data *yd;
struct yahoo_packet *pkt;
+ char c1005[8] = "12345678";
+ /* Any value of the field 1005 will cause not much difference, just use a hard-coding value */
if (!yid)
return;
@@ -4510,6 +4901,7 @@
yd->session_id);
yahoo_packet_hash(pkt, 1, (from ? from : yd->user));
+ yahoo_packet_hash(pkt, 1005, c1005);
yahoo_send_packet(yid, pkt, 0);
@@ -5483,6 +5875,25 @@
return yd->buddies;
}
+const YList *yahoo_get_chat_room_list(int id, int roomid, void *ext_data)
+{
+ struct yahoo_data *yd = find_conn_by_id(id);
+ YList *category;
+
+ if (!yd)
+ return NULL;
+ if(roomid == 0)
+ return yd->chat_room_list;
+ else {
+ if(yd->chat_room_list) {
+ category = find_room_category(yd->chat_room_list, roomid);
+ return ((yahoo_chatroom_category *)(category->data))->room_list;
+ } else {
+ return NULL;
+ }
+ }
+}
+
const YList *yahoo_get_ignorelist(int id)
{
struct yahoo_data *yd = find_conn_by_id(id);
Modified: trunk/libyahoo2/src/sample_client.c
===================================================================
--- trunk/libyahoo2/src/sample_client.c 2010-08-05 03:36:23 UTC (rev 380)
+++ trunk/libyahoo2/src/sample_client.c 2010-08-13 20:15:45 UTC (rev 381)
@@ -463,9 +463,173 @@
printf(" Location: %s", ycm->location);
}
+static void ext_yahoo_chat_verify(const char *url, char *vcode)
+{
+ printf("%s\n", url);
+ printf("Please input the verification code:");
+ scanf("%s", vcode);
+}
+
+static void traverse_cat_list(YList *list, int level)
+{
+ int i;
+ for(i=0; i<level; i++)
+ putchar('\t');
+ printf("%d - %s\n", ((yahoo_chatroom_category *)list->data)->id, ((yahoo_chatroom_category *)list->data)->name);
+ if(list->prev)
+ traverse_cat_list(list->prev, level+1);
+ if(list->next)
+ traverse_cat_list(list->next, level);
+}
+
+static void traverse_room_list(YList *list)
+{
+ YList *lobby;
+
+ while(list != NULL) {
+ lobby = list->prev;
+ while(lobby != NULL) {
+ printf("%d - %s %d [%d] [w%d]\n",
+ ((yahoo_chatroom_info *)list->data)->id, ((yahoo_chatroom_info *)list->data)->name,
+ ((yahoo_lobby_info *)lobby->data)->count, ((yahoo_lobby_info *)lobby->data)->users,
+ ((yahoo_lobby_info *)lobby->data)->webcams);
+ lobby = lobby->prev;
+ }
+ list = list->next;
+ }
+}
+
+static char *get_xml_chatroom_info(char *content, char *pattern)
+{
+ char *header, *tailer, *info;
+ header = strstr(content, pattern);
+ header += strlen(pattern);
+ tailer = strchr(header, '"');
+ *tailer = '\0';
+ info = malloc(tailer - header + 1);
+ strcpy(info, header);
+ *tailer = '"';
+ return info;
+}
+
static void ext_yahoo_chat_cat_xml(int id, const char *xml)
{
- print_message(("%s", xml));
+ char *content = strdup(xml), *header, *tailer;
+ int child_mode = 0;
+ YList *room_list;
+ YList *list_ptr;
+ YList *cat_stack[5];
+ int stack_ptr = 0;
+ YList *temp, *child, *tail;
+
+ content = strstr(content, "<category"); /* Find the first category*/
+
+ if (content == NULL) {
+ room_list = calloc(1, sizeof(YList));
+ list_ptr = room_list;
+
+ content = strdup(xml);
+ content = strstr(content, "<chatRooms>");
+ if (content == NULL) {
+ printf("Error : Cannot find anything!\n");
+ return ;
+ }
+
+ content += strlen("<chatRooms>");
+
+ content = strchr(content, '<');
+ while(*(content + 1) != '/') {
+
+ /* find all the fields of a chat room */
+ temp = calloc(1, sizeof(YList));
+ temp->data = calloc(1, sizeof(yahoo_chatroom_info));
+ tail = temp;
+
+ ((yahoo_chatroom_info *)(temp->data))->type = get_xml_chatroom_info(content, "type=\"");
+ ((yahoo_chatroom_info *)(temp->data))->id = atoi(get_xml_chatroom_info(content, "id=\""));
+ ((yahoo_chatroom_info *)(temp->data))->name = get_xml_chatroom_info(content, "name=\"");
+ ((yahoo_chatroom_info *)(temp->data))->topic = get_xml_chatroom_info(content, "topic=\"");
+
+ /* find all lobbys of a chat room */
+
+ content = strchr(content+1, '<');
+ while(*(content + 1) != '/') {
+ child = calloc(1, sizeof(YList));
+ child->data = calloc(1, sizeof(yahoo_lobby_info));
+
+ ((yahoo_lobby_info *)child->data)->count = atoi(get_xml_chatroom_info(content, "count=\""));
+ ((yahoo_lobby_info *)child->data)->users = atoi(get_xml_chatroom_info(content, "users=\""));
+ ((yahoo_lobby_info *)child->data)->voices = atoi(get_xml_chatroom_info(content, "voices=\""));
+ ((yahoo_lobby_info *)child->data)->webcams = atoi(get_xml_chatroom_info(content, "webcams=\""));
+
+ /* prev is used as a pointer to the the lobby*/
+ tail->prev = child;
+ tail = child;
+
+ content = strchr(content+1, '<');
+ }
+
+ list_ptr->next = temp;
+ list_ptr = temp;
+
+ content = strchr(content+1, '<');
+ }
+
+ /* Traverse the structure and print them out */
+ traverse_room_list(room_list->next);
+
+ } else {
+ /* Create a head node */
+ room_list = calloc(1, sizeof(YList));
+ list_ptr = room_list;
+
+ while(stack_ptr >= 0) {
+ /* prev is used as a pointer linked with its child categories */
+
+ /* Find the id */
+ temp = calloc(1, sizeof(YList));
+ temp->data = calloc(1, sizeof(yahoo_chatroom_category));
+ header = strchr(content, '"');
+ tailer = strchr(header+1, '"');
+ *tailer = '\0';
+ ((yahoo_chatroom_category *)temp->data)->id = atoi(strdup(header + 1));
+
+ /* Find the name*/
+ header = strchr(tailer+1, '"');
+ tailer = strchr(header+1, '"');
+ *tailer = '\0';
+ ((yahoo_chatroom_category *)temp->data)->name = strdup(header + 1);
+ ((yahoo_chatroom_category *)temp->data)->room_list = NULL;
+
+ content = strchr(tailer+1, '>');
+ if(child_mode == 1) {
+ list_ptr->prev = temp;
+ list_ptr = temp;
+ cat_stack[stack_ptr] = temp;
+ child_mode = 0;
+ } else {
+ list_ptr->next = temp;
+ list_ptr = temp;
+ cat_stack[stack_ptr] = temp;
+ }
+
+ if (*(content-1) != '/') {
+ stack_ptr ++;
+ child_mode = 1;
+ }
+
+ /* find the next category */
+ content = strchr(content, '<');
+ while (*(content+1) == '/' && stack_ptr >= 0) {
+ stack_ptr --;
+ list_ptr = cat_stack[stack_ptr];
+ content = strchr(content + 1, '<');
+ }
+ }
+
+ /* Traverse the structure and print them out */
+ traverse_cat_list(room_list->next, 0);
+ }
}
static void ext_yahoo_chat_join(int id, const char *me, const char *room, const char * topic, YList *members, void *fd)
@@ -1444,8 +1608,23 @@
int roomid;
roomid = atoi(copy);
yahoo_get_chatrooms(ylad->id, roomid);
+ } else if(!strncasecmp(cmd, "CHR", strlen("CHR"))) {
+ int roomid;
+ void *ext_data;
+ roomid = atoi(copy);
+ YList *list = yahoo_get_chat_room_list(ylad->id, roomid, ext_data);
+ if(list) {
+ if(roomid == 0)
+ traverse_cat_list(list, 0);
+ else
+ traverse_room_list(list);
+ }
+
} else if(!strncasecmp(cmd, "CHJ", strlen("CHJ"))) {
+ /* Command Format "CHJ roomid roomname" */
char *roomid, *roomname;
+ char country[] = "us";
+ char language[] = "en-us";
/* Linux, FreeBSD, Solaris:1 */
/* 1600326591 */
roomid = copy;
@@ -1456,24 +1635,38 @@
}
roomname = copy;
if(roomid && roomname) {
- yahoo_chat_logon(ylad->id, NULL, roomname, roomid);
+ yahoo_chat_logon(ylad->id, NULL, roomname, roomid, country, language);
}
} else if(!strncasecmp(cmd, "CHM", strlen("CHM"))) {
+ /* Command Format "CHM roomname msg" */
char *msg, *roomname;
roomname = copy;
- tmp = strstr(copy, " ");
+ tmp = strchr(copy, ' ');
if(tmp) {
*tmp = '\0';
- copy = tmp+2;
+ copy = tmp+1;
}
msg = copy;
if(roomname && msg) {
yahoo_chat_message(ylad->id, NULL, roomname, msg, 1, 0);
}
+ } else if(!strncasecmp(cmd, "CHI", strlen("CHI"))) {
+ /* Ignore a member in the chat room, Command Format "CHI user_to_be_ignored" */
+ char *user;
+ user = copy;
+ yahoo_chat_ignore(ylad->id, NULL, user, 1);
+
+ } else if(!strncasecmp(cmd, "CHU", strlen("CHU"))) {
+ /* Unignore a member in the chat room, Command Format "CHI user_to_be_ignored" */
+ char *user;
+ user = copy;
+ yahoo_chat_ignore(ylad->id, NULL, user, 0);
+
} else if(!strncasecmp(cmd, "CHX", strlen("CHX"))) {
yahoo_chat_logoff(ylad->id, NULL);
+
} else if(!strncasecmp(cmd, "STA", strlen("STA"))) {
if(isdigit(copy[0])) {
state = (enum yahoo_status)atoi(copy);
@@ -1853,6 +2046,7 @@
yc.ext_yahoo_conf_userjoin = ext_yahoo_conf_userjoin;
yc.ext_yahoo_conf_userleave = ext_yahoo_conf_userleave;
yc.ext_yahoo_conf_message = ext_yahoo_conf_message;
+ yc.ext_yahoo_chat_verify = ext_yahoo_chat_verify;
yc.ext_yahoo_chat_cat_xml = ext_yahoo_chat_cat_xml;
yc.ext_yahoo_chat_join = ext_yahoo_chat_join;
yc.ext_yahoo_chat_userjoin = ext_yahoo_chat_userjoin;
Modified: trunk/libyahoo2/src/yahoo2.h
===================================================================
--- trunk/libyahoo2/src/yahoo2.h 2010-08-05 03:36:23 UTC (rev 380)
+++ trunk/libyahoo2/src/yahoo2.h 2010-08-13 20:15:45 UTC (rev 381)
@@ -139,10 +139,12 @@
void yahoo_get_chatrooms(int id, int chatroomid);
/* join room with specified roomname and roomid */
void yahoo_chat_logon(int id, const char *from, const char *room,
- const char *roomid);
+ const char *roomid, const char *country, const char *language);
/* Send message "msg" to room with specified roomname, msgtype is 1-normal message or 2-/me mesage */
void yahoo_chat_message(int id, const char *from, const char *room,
const char *msg, const int msgtype, const int utf8);
+/* Ignore a contact in the chat room, ignore = 1 represents ignore and ignore = 0 represents unignore */
+ void yahoo_chat_ignore(int id, const char *from, const char *user, int ignore);
/* Log off chat */
void yahoo_chat_logoff(int id, const char *from);
Modified: trunk/libyahoo2/src/yahoo2_callbacks.h
===================================================================
--- trunk/libyahoo2/src/yahoo2_callbacks.h 2010-08-05 03:36:23 UTC (rev 380)
+++ trunk/libyahoo2/src/yahoo2_callbacks.h 2010-08-13 20:15:45 UTC (rev 381)
@@ -238,6 +238,16 @@
const char *me, const char *who, const char *room);
/*
+ * Name: ext_yahoo_chat_cat_verify
+ * Called when user log into chat room, client will receive a image
+ * while user needs to type in the characters in the image to verify
+ * Params:
+ * url - the URL of the image for verification
+ * vcode - the characters which is typed in by the user
+ */
+ void YAHOO_CALLBACK_TYPE(ext_yahoo_chat_verify) (const char *url, char *vcode);
+
+/*
* Name: ext_yahoo_chat_cat_xml
* Called when ?
* Params:
Modified: trunk/libyahoo2/src/yahoo2_types.h
===================================================================
--- trunk/libyahoo2/src/yahoo2_types.h 2010-08-05 03:36:23 UTC (rev 380)
+++ trunk/libyahoo2/src/yahoo2_types.h 2010-08-13 20:15:45 UTC (rev 381)
@@ -28,6 +28,8 @@
extern "C" {
#endif
+#define YMSG_VERSION "9.0.0.2152"
+
enum yahoo_service { /* these are easier to see in hex */
YAHOO_SERVICE_LOGON = 1,
YAHOO_SERVICE_LOGOFF,
@@ -229,7 +231,8 @@
YAHOO_CONNECTION_WEBCAM,
YAHOO_CONNECTION_CHATCAT,
YAHOO_CONNECTION_SEARCH,
- YAHOO_CONNECTION_AUTH
+ YAHOO_CONNECTION_AUTH,
+ YAHOO_CONNECTION_CAPTCHA
};
enum yahoo_webcam_direction_type {
@@ -302,6 +305,8 @@
void *server_settings;
struct yahoo_process_status_entry *half_user;
+
+ YList *chat_room_list;
};
struct yab {
@@ -324,6 +329,26 @@
struct yab *yab_entry;
};
+ typedef struct yahoo_chatroom_category{
+ int id;
+ char *name;
+ YList *room_list;
+ } yahoo_chatroom_category;
+
+ typedef struct yahoo_chatroom{
+ char *type;
+ int id;
+ char *name;
+ char *topic;
+ } yahoo_chatroom_info;
+
+ typedef struct yahoo_lobby{
+ int count;
+ int users;
+ int voices;
+ int webcams;
+ } yahoo_lobby_info;
+
enum yahoo_search_type {
YAHOO_SEARCH_KEYWORD = 0,
YAHOO_SEARCH_YID,
@@ -390,6 +415,19 @@
int f213; /* 213 state */
};
+ typedef struct pair{
+ char *name;
+ char *value;
+ }namevalue_pair;
+
+ typedef struct{
+ char *http_version;
+ char *status_code;
+ YList *headers;
+ char *content;
+ }http_data;
+
+
#ifdef __cplusplus
}
#endif
Modified: trunk/libyahoo2/src/yahoo_httplib.c
===================================================================
--- trunk/libyahoo2/src/yahoo_httplib.c 2010-08-05 03:36:23 UTC (rev 380)
+++ trunk/libyahoo2/src/yahoo_httplib.c 2010-08-13 20:15:45 UTC (rev 381)
@@ -61,6 +61,83 @@
extern enum yahoo_log_level log_level;
+char *yahoo_http_get_header_value(http_data data, char *field)
+{
+ YList *ptr = data.headers;
+ while(ptr != NULL) {
+ if(!strcmp(field, ((struct pair *)(ptr->data))->name))
+ return ((struct pair *)(ptr->data))->value;
+ ptr = ptr->next;
+ }
+ return NULL;
+}
+
+void yahoo_get_http_data(http_data data)
+{
+ YList *ptr = data.headers;
+ printf("%s, %s\n", data.http_version, data.status_code);
+ while(ptr != NULL) {
+ printf("%s : %s\n", ((struct pair *)(ptr->data))->name, ((struct pair *)(ptr->data))->value);
+ ptr = ptr->next;
+ }
+ printf("%s\n", data.content);
+}
+
+void yahoo_set_http_data(char *input, int length, http_data *struct_packet)
+{
+ char *head, *tail;
+ char *raw_packet = strdup(input);
+ namevalue_pair *temp_header;
+ YList *temp_ylist;
+
+ struct_packet->headers = NULL;
+
+ /* Get HTTP version and the status code */
+ struct_packet->http_version = y_new(char, 4);
+ struct_packet->status_code = y_new(char, 4);
+ sscanf(raw_packet, "%*[^/]/%s %s", struct_packet->http_version, struct_packet->status_code);
+
+ head = strstr(raw_packet, "\r\n");
+ head = head + 2;
+ while(*head != '\r' || *(head+1) != '\n') {
+ temp_header = y_new(struct pair, 1);
+ temp_ylist = y_new(struct _YList, 1);
+
+ tail = strchr(head, ':');
+ *tail = '\0';
+ temp_header->name = strdup(head);
+
+ head = tail+2;
+ tail = strstr(head, "\r\n");
+ *tail = '\0';
+ temp_header->value = strdup(head);
+
+ struct_packet->headers = y_list_append(struct_packet->headers, temp_header);
+
+ head = tail+2;
+ }
+ head += 2;
+ tail = raw_packet + length;
+ *tail = '\0';
+ struct_packet->content = strdup(head);
+}
+
+void yahoo_free_http_data(http_data *http_pkt)
+{
+ YList *rm;
+ FREE(http_pkt->http_version);
+ FREE(http_pkt->status_code);
+
+ while(http_pkt->headers) {
+ rm = http_pkt->headers;
+ FREE(((namevalue_pair *)(http_pkt->headers->data))->name);
+ FREE(((namevalue_pair *)(http_pkt->headers->data))->value);
+ FREE(http_pkt->headers->data);
+ http_pkt->headers = y_list_remove_link(http_pkt->headers, http_pkt->headers);
+ y_list_free_1(rm);
+ }
+}
+
int yahoo_tcp_readline(char *ptr, int maxlen, void *fd)
{
int n, rc;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|