在 Sametime 协议中加一个联系人

Sametime 协议现在有一个开源的协议实现叫做 [Meanwhile],原来它自己维护了一个 Gaim 的插件,叫做 gaim-meanwhile,后来进入官方,又改回了原来的 sametime,底下的实现仍然是调用了 Meanwhile,要把这个关系搞清楚。

然后再说我碰到的问题,很早以前就发现了,不过一直没空改,今天仔细看了看给解决了。在 Gaim 中给 Sametime 帐号加一个联系人的时候,跟其他一样,要选择名字,要加入的组等信息,把这个对话框加 A。对于 Sametime 来说,后台通常是一个 LDAP 服务器,用于存储用户信息,所以这里填的名字只是整个 ID 的一部分,通常叫 UID,是唯一的,其他部分绝大多数情况下都是一样的,但不可省略。然后会调用 Meanwhile 的函数进行查找,它可能会找出好多个类似的名字,让后选择一个添加,这时候弹出的另外一个对话框 B 和 A 是一样的,不过里面的数据不同,用户名已经是整个 ID,别名也帮你自动填好了,但是对于用户来讲,在 A 中选择了一个组,要把加的这个联系人添加进去,而在 B 中的这个组和 A 中的并不相同,所以用户还得再选择一遍,非常地不方便。然后再进行相同的一次添加过程,不过这时候用户名已经是绝对唯一并且完整的了,可以直接添加。那么就要把用户组这个信息保留下来,就不需要再选择一次。

调用过程如下:

  1. 01 gtkblist.c:1048:create_group_menu() 找到 "Add a Buddy" 的回调函数
  2. 02 tbblist.c:826:gaim_gtk_blist_add_buddy_cb() 根据现在的选择状态,调整参数(帐号和用户组等)
  3. 03 blist.c:2388:gaim_blist_request_add_buddy() 调用真正的界面显示函数
  4.      在 gtkmain.c:234:gaim_gtk_ui_init() 中调用 gtkblist.c:5101:gaim_gtk_blist_get_ui_ops() 进行设置
  5.      而 gtkblist.c:5085:blist_ui_ops 就静态定义了 GTK+ 的一些回调函数。
  6. 04 gtkblist.c:4542:gaim_gtk_blist_request_add_buddy() 显示对话框,就是我们前面说到的 A
  7. 05 gtkblist.c:4489:add_buddy_cb()
  8. 06 account.c:1960:gaim_account_add_buddy() 调用帐号所属的协议中定义的添加联系人函数
  9. 07 sametime.c:4398:mw_prpl_add_buddy() Sametime 需要添加联系人
  10. 08 sametime.c:4314:add_buddy_resolved() 找出了匹配的联系人,可能不唯一
  11. 09 sametime.c:4262:multi_resolved_query() 显示给用户进行选择
  12. 10 sametime.c:4242:notify_add() 用户选择了一个,进行添加,又调用了第(4)步的函数,补充了一些数据
  13.      重复 4-8 步,这一次用户 ID 完整且唯一,可以直接进行添加。
  14. 11 sametime.c:793:buddy_add() 真正地添加一个联系人

问题就在于第 4 步和第 10 步的两次对话框中的用户组信息不一致,需要在其中的 Sametime 的回调函数中把相关的信息添加进去。这个解决起来就很容易了。一个注意的地方是在第 7 步中申请了一个结构保存了 buddy 和 group 信息,那么就需要释放掉,现在是有两个分支,一个是在第 8 步中找到了唯一的联系人并且 ID 是完整的,也就是说是第二次运行过来,应该释放一次;另外就是第 9 步用户列表显示完,在关闭的时候需要释放。

BTW,修 bug 用了 10 分钟,写这篇文章用了大半个小时,呵呵。

说句题外话,Gaim 里面大部分的协议都是自己实现的,如果能把这些协议的实现都拿出来,就像 Meanwhile 那样,就可以供另外的程序调用,这样各个 IM 客户端的实现也会减少很多的工作量,也可以集中力量针对协议本身进行开发。也就是说,协议库本身只提供功能,界面以及其他的处理由上层来做。不过这样带来的问题也很多的,比如 socket 啦,回调啦,会比较麻烦一些,设计接口的时候要考虑独立性,很多东西不能写死了,这样才能更方便地让上层来调用。

终于提交进去了

SVN r17685 by Christopher 'siege' O'Brien (taliesein),真是不容易啊。

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <blockquote>
  • You can use BBCode tags in the text.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>. The supported tag styles are: <foo>, [foo].
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.

More information about formatting options

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
  ____     ___               _      ____        _           ___ 
/ ___| / _ \ __ _ / \ | _ \ __| | _ __ |_ _|
\___ \ | (_) | / _` | / _ \ | |_) | / _` | | '_ \ | |
___) | \__, | | (_| | / ___ \ | _ < | (_| | | | | | | |
|____/ /_/ \__, | /_/ \_\ |_| \_\ \__,_| |_| |_| |___|
|_|
Enter the code depicted in ASCII art style.