buddy.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package handler
  2. import (
  3. "context"
  4. "github.com/mkaminski/goaim/oscar"
  5. "github.com/mkaminski/goaim/state"
  6. )
  7. func NewBuddyService() *BuddyService {
  8. return &BuddyService{}
  9. }
  10. type BuddyService struct {
  11. }
  12. func (s BuddyService) RightsQueryHandler(context.Context) oscar.SNACMessage {
  13. return oscar.SNACMessage{
  14. Frame: oscar.SNACFrame{
  15. FoodGroup: oscar.Buddy,
  16. SubGroup: oscar.BuddyRightsReply,
  17. },
  18. Body: oscar.SNAC_0x03_0x03_BuddyRightsReply{
  19. TLVRestBlock: oscar.TLVRestBlock{
  20. TLVList: oscar.TLVList{
  21. oscar.NewTLV(0x01, uint16(100)),
  22. oscar.NewTLV(0x02, uint16(100)),
  23. oscar.NewTLV(0x03, uint16(100)),
  24. oscar.NewTLV(0x04, uint16(100)),
  25. },
  26. },
  27. },
  28. }
  29. }
  30. func broadcastArrival(ctx context.Context, sess *state.Session, sm SessionManager, fm FeedbagManager) error {
  31. screenNames, err := fm.InterestedUsers(sess.ScreenName())
  32. if err != nil {
  33. return err
  34. }
  35. sm.BroadcastToScreenNames(ctx, screenNames, oscar.SNACMessage{
  36. Frame: oscar.SNACFrame{
  37. FoodGroup: oscar.Buddy,
  38. SubGroup: oscar.BuddyArrived,
  39. },
  40. Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
  41. TLVUserInfo: oscar.TLVUserInfo{
  42. ScreenName: sess.ScreenName(),
  43. WarningLevel: sess.Warning(),
  44. TLVBlock: oscar.TLVBlock{
  45. TLVList: sess.UserInfo(),
  46. },
  47. },
  48. },
  49. })
  50. return nil
  51. }
  52. func broadcastDeparture(ctx context.Context, sess *state.Session, sm SessionManager, fm FeedbagManager) error {
  53. screenNames, err := fm.InterestedUsers(sess.ScreenName())
  54. if err != nil {
  55. return err
  56. }
  57. sm.BroadcastToScreenNames(ctx, screenNames, oscar.SNACMessage{
  58. Frame: oscar.SNACFrame{
  59. FoodGroup: oscar.Buddy,
  60. SubGroup: oscar.BuddyDeparted,
  61. },
  62. Body: oscar.SNAC_0x03_0x0B_BuddyDeparted{
  63. TLVUserInfo: oscar.TLVUserInfo{
  64. ScreenName: sess.ScreenName(),
  65. WarningLevel: sess.Warning(),
  66. },
  67. },
  68. })
  69. return nil
  70. }
  71. func unicastArrival(ctx context.Context, srcScreenName, destScreenName string, sm SessionManager) {
  72. sess := sm.RetrieveByScreenName(srcScreenName)
  73. switch {
  74. case sess == nil:
  75. fallthrough
  76. case sess.Invisible(): // don't tell user this buddy is online
  77. return
  78. }
  79. sm.SendToScreenName(ctx, destScreenName, oscar.SNACMessage{
  80. Frame: oscar.SNACFrame{
  81. FoodGroup: oscar.Buddy,
  82. SubGroup: oscar.BuddyArrived,
  83. },
  84. Body: oscar.SNAC_0x03_0x0A_BuddyArrived{
  85. TLVUserInfo: sess.TLVUserInfo(),
  86. },
  87. })
  88. }
  89. func unicastDeparture(ctx context.Context, srcScreenName, destScreenName string, sm SessionManager) {
  90. sess := sm.RetrieveByScreenName(srcScreenName)
  91. switch {
  92. case sess == nil:
  93. fallthrough
  94. case sess.Invisible(): // don't tell user this buddy is online
  95. return
  96. }
  97. sm.SendToScreenName(ctx, destScreenName, oscar.SNACMessage{
  98. Frame: oscar.SNACFrame{
  99. FoodGroup: oscar.Buddy,
  100. SubGroup: oscar.BuddyDeparted,
  101. },
  102. Body: oscar.SNAC_0x03_0x0B_BuddyDeparted{
  103. TLVUserInfo: oscar.TLVUserInfo{
  104. // don't include the TLV block, otherwise the AIM client fails
  105. // to process the block event
  106. ScreenName: sess.ScreenName(),
  107. WarningLevel: sess.Warning(),
  108. },
  109. },
  110. })
  111. }