watch.c
上传用户:tany51
上传日期:2013-06-12
资源大小:1397k
文件大小:10k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /*
  2.  * Copyright (C) 1999,2000  Ross Combs (rocombs@cs.nmsu.edu)
  3.  *
  4.  * This program is free software; you can redistribute it and/or
  5.  * modify it under the terms of the GNU General Public License
  6.  * as published by the Free Software Foundation; either version 2
  7.  * of the License, or (at your option) any later version.
  8.  *
  9.  * This program is distributed in the hope that it will be useful,
  10.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the Free Software
  16.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  */
  18. #define WATCH_INTERNAL_ACCESS
  19. #include "common/setup_before.h"
  20. #ifdef STDC_HEADERS
  21. # include <stdlib.h>
  22. #else
  23. # ifdef HAVE_MALLOC_H
  24. #  include <malloc.h>
  25. # endif
  26. #endif
  27. #ifdef HAVE_STRING_H
  28. # include <string.h>
  29. #else
  30. # ifdef HAVE_STRINGS_H
  31. #  include <strings.h>
  32. # endif
  33. # ifdef HAVE_MEMORY_H
  34. #  include <memory.h>
  35. # endif
  36. #endif
  37. #include "compat/strcasecmp.h"
  38. #include "common/field_sizes.h"
  39. #include "common/list.h"
  40. #include "account.h"
  41. #include "connection.h"
  42. #include "common/eventlog.h"
  43. #include "message.h"
  44. #include "watch.h"
  45. #include "friends.h"
  46. #include "common/setup_after.h"
  47. static t_list * watchlist_head=NULL;
  48. /* who == NULL means anybody */
  49. extern int watchlist_add_events(t_connection * owner, t_account * who, char const * clienttag, t_watch_event events)
  50. {
  51.     t_elem const * curr;
  52.     t_watch_pair * pair;
  53.     
  54.     if (!owner)
  55.     {
  56. eventlog(eventlog_level_error,"watchlist_add_events","got NULL owner");
  57. return -1;
  58.     }
  59.     
  60.     LIST_TRAVERSE_CONST(watchlist_head,curr)
  61.     {
  62. pair = elem_get_data(curr);
  63. if (!pair) /* should not happen */
  64. {
  65.     eventlog(eventlog_level_error,"watchlist_add_events","watchlist contains NULL item");
  66.     return -1;
  67. }
  68. if (pair->owner==owner && pair->who==who && ((clienttag == NULL && strlen(pair->clienttag) == 0) || ((clienttag != NULL) && (strcasecmp(pair->clienttag, clienttag)==0))))
  69. {
  70.     pair->what |= events;
  71.     return 0;
  72. }
  73.     }
  74.     
  75.     if (!(pair = malloc(sizeof(t_watch_pair))))
  76.     {
  77. eventlog(eventlog_level_error,"watchlist_add_events","could not allocate memory for pair");
  78. return -1;
  79.     }
  80. if(clienttag)
  81. strcpy(pair->clienttag, clienttag);
  82. else
  83. strcpy(pair->clienttag, "");
  84.     pair->owner = owner;
  85.     pair->who   = who;
  86.     pair->what  = events;
  87.     
  88.     if (list_prepend_data(watchlist_head,pair)<0)
  89.     {
  90. free(pair);
  91. eventlog(eventlog_level_error,"watchlist_add_events","could not prepend temp");
  92. return -1;
  93.     }
  94.     
  95.     return 0;
  96. }
  97. /* who == NULL means anybody */
  98. extern int watchlist_del_events(t_connection * owner, t_account * who, char const * clienttag, t_watch_event events)
  99. {
  100.     t_elem *       curr;
  101.     t_watch_pair * pair;
  102.     
  103.     if (!owner)
  104.     {
  105. eventlog(eventlog_level_error,"watchlist_del_events","got NULL owner");
  106. return -1;
  107.     }
  108.     
  109.     LIST_TRAVERSE(watchlist_head,curr)
  110.     {
  111. pair = elem_get_data(curr);
  112. if (!pair) /* should not happen */
  113. {
  114.     eventlog(eventlog_level_error,"watchlist_del_events","watchlist contains NULL item");
  115.     return -1;
  116. }
  117. if (pair->owner==owner && pair->who==who && (clienttag == NULL || strcasecmp(clienttag, pair->clienttag) == 0))
  118. {
  119.     pair->what &= ~events;
  120.     if (pair->what==0)
  121.     {
  122. if (list_remove_elem(watchlist_head,curr)<0)
  123. {
  124.     eventlog(eventlog_level_error,"watchlist_del_events","could not remove item");
  125.     pair->owner = NULL;
  126. }
  127. else
  128.     free(pair);
  129.     }
  130.     
  131.     list_purge(watchlist_head);
  132.     
  133.     return 0;
  134. }
  135.     }
  136.     
  137.     return -1; /* not found */
  138. }
  139. /* this differs from del_events because it doesn't return an error if nothing was found */
  140. extern int watchlist_del_all_events(t_connection * owner)
  141. {
  142.     t_elem *       curr;
  143.     t_watch_pair * pair;
  144.     
  145.     if (!owner)
  146.     {
  147. eventlog(eventlog_level_error,"watchlist_del_all_events","got NULL owner");
  148. return -1;
  149.     }
  150.     
  151.     LIST_TRAVERSE(watchlist_head,curr)
  152.     {
  153. pair = elem_get_data(curr);
  154. if (!pair) /* should not happen */
  155. {
  156.     eventlog(eventlog_level_error,"watchlist_del_all_events","watchlist contains NULL item");
  157.     return -1;
  158. }
  159. if (pair->owner==owner)
  160. {
  161.     if (list_remove_elem(watchlist_head,curr)<0)
  162.     {
  163. eventlog(eventlog_level_error,"watchlist_del_all_events","could not remove item");
  164. pair->owner = NULL;
  165.     }
  166.     else
  167.       { free(pair); }
  168. }
  169.     }
  170.     
  171.     list_purge(watchlist_head);
  172.     
  173.     return 0;
  174. }
  175. /* this differs from del_events because it doesn't return an error if nothing was found */
  176. extern int watchlist_del_by_account(t_account * who)
  177. {
  178.     t_elem *       curr;
  179.     t_watch_pair * pair;
  180.     
  181.     if (!who)
  182.     {
  183. eventlog(eventlog_level_error,"watchlist_del_by_account","got NULL account");
  184. return -1;
  185.     }
  186.     
  187.     LIST_TRAVERSE(watchlist_head,curr)
  188.     {
  189. pair = elem_get_data(curr);
  190. if (!pair) /* should not happen */
  191. {
  192.     eventlog(eventlog_level_error,"watchlist_del_all_events","watchlist contains NULL item");
  193.     return -1;
  194. }
  195. if (pair->who==who)
  196. {
  197.     if (list_remove_elem(watchlist_head,curr)<0)
  198.     {
  199. eventlog(eventlog_level_error,"watchlist_del_all_events","could not remove item");
  200. pair->owner = NULL;
  201.     }
  202.     else
  203.       { free(pair); }
  204. }
  205.     }
  206.     
  207.     list_purge(watchlist_head);
  208.     
  209.     return 0;
  210. }
  211. static int handle_event_whisper(t_account *account, char const *gamename, char const * clienttag, t_watch_event event)
  212. {
  213.     t_elem const * curr;
  214.     t_watch_pair * pair;
  215.     char msg[512];
  216.     int cnt = 0;
  217.     char const *myusername;
  218.     t_list * flist;
  219.     t_connection * dest_c;
  220.     t_friend * fr;
  221.     char const * game_title;
  222.     if (!account)
  223.     {
  224. eventlog(eventlog_level_error,"handle_event_whisper","got NULL account");
  225. return -1;
  226.     }
  227.     if (!(myusername = account_get_name(account)))
  228.     {
  229. eventlog(eventlog_level_error,"handle_event_whisper","got NULL account name");
  230. return -1;
  231.     }
  232.     game_title = conn_get_user_game_title(clienttag);
  233.     /* mutual friends handling */
  234.     flist = account_get_friends(account);
  235.     if(flist)
  236.     {
  237.         if (event == watch_event_joingame) {
  238.          if (gamename)
  239.         sprintf(msg,"Your friend %s has entered a %s game named "%s".",myusername,game_title,gamename);
  240.          else
  241.         sprintf(msg,"Your friend %s has entered a %s game",myusername,game_title);
  242.      }
  243.         if (event == watch_event_leavegame)sprintf(msg,"Your friend %s has left a %s game.",myusername,game_title);
  244.         if (event == watch_event_login)    sprintf(msg,"Your friend %s has entered the PvPGN Realm.",myusername);
  245.         if (event == watch_event_logout)   sprintf(msg,"Your friend %s has left the PvPGN Realm",myusername);
  246.         LIST_TRAVERSE(flist,curr)
  247.         { 
  248.             if (!(fr = elem_get_data(curr)))
  249.             {
  250.                 eventlog(eventlog_level_error,__FUNCTION__,"found NULL entry in list");
  251.                 continue;
  252.             }
  253.         
  254.             dest_c = connlist_find_connection_by_account(fr->friendacc);
  255.       
  256.             if (dest_c==NULL) /* If friend is offline, go on to next */
  257.         continue;
  258.             else { 
  259.      cnt++; /* keep track of successful whispers */
  260.      if(friend_get_mutual(fr))
  261.              message_send_text(dest_c,message_type_info,dest_c,msg);
  262.     }
  263.      }
  264.     }
  265.     if (cnt) eventlog(eventlog_level_info,"handle_event_whisper","notified %d friends about %s",cnt,myusername);
  266.     /* watchlist handling */
  267.     if (event == watch_event_joingame) 
  268.     {
  269. if (gamename)
  270.          sprintf(msg,"Watched user %s has entered a %s game named "%s".",myusername,game_title,gamename);
  271. else
  272.     sprintf(msg,"Watched user %s has entered a %s game",myusername,game_title);
  273.     }
  274.     if (event == watch_event_leavegame)sprintf(msg,"Watched user %s has left a %s game.",myusername,game_title);
  275.     if (event == watch_event_login)    sprintf(msg,"Watched user %s has entered the PvPGN Realm.",myusername);
  276.     if (event == watch_event_logout)   sprintf(msg,"Watched user %s has left the PvPGN Realm",myusername);
  277.     account_unget_name(myusername);
  278.     LIST_TRAVERSE_CONST(watchlist_head,curr)
  279.     {
  280.       pair = elem_get_data(curr);
  281.       if (!pair) /* should not happen */
  282. {
  283.   eventlog(eventlog_level_error,"watchlist_notify_event","watchlist contains NULL item");
  284.   return -1;
  285. }
  286. if (pair->owner && (!pair->who || pair->who==account) && (strlen(pair->clienttag) == 0 || (clienttag && strcasecmp(pair->clienttag, clienttag)==0)) && (pair->what&event))
  287. message_send_text(pair->owner,message_type_info,pair->owner,msg);
  288.     }
  289.   
  290.     return 0;
  291. }
  292. extern int watchlist_notify_event(t_account * who, char const * gamename, char const * clienttag, t_watch_event event)
  293. {
  294.     switch (event)
  295.     {
  296.     case watch_event_login:
  297.     case watch_event_logout:
  298.     case watch_event_joingame:
  299.     case watch_event_leavegame:
  300.       handle_event_whisper(who,gamename,clienttag,event);
  301.       break;
  302.     default:
  303.       eventlog(eventlog_level_error,"watchlist_notify_event","got unknown event %u",(unsigned int)event);
  304.       return -1;
  305.     }
  306.     return 0;
  307. }
  308. extern int watchlist_create(void)
  309. {
  310.     if (!(watchlist_head = list_create()))
  311.         return -1;
  312.     return 0;
  313. }
  314. extern int watchlist_destroy(void)
  315. {
  316.     t_elem *       curr;
  317.     t_watch_pair * pair;
  318.     
  319.     if (watchlist_head)
  320.     {
  321. LIST_TRAVERSE(watchlist_head,curr)
  322. {
  323.     pair = elem_get_data(curr);
  324.     if (!pair) /* should not happen */
  325.     {
  326. eventlog(eventlog_level_error,"watchlist_destroy","watchlist contains NULL item");
  327. continue;
  328.     }
  329.     
  330.     if (list_remove_elem(watchlist_head,curr)<0)
  331.          eventlog(eventlog_level_error,"watchlist_destroy","could not remove item from list");
  332.     free(pair);
  333. }
  334. if (list_destroy(watchlist_head)<0)
  335.     return -1;
  336. watchlist_head = NULL;
  337.     }
  338.     
  339.     return 0;
  340. }