buddy.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package handler
  2. import (
  3. "context"
  4. "github.com/mk6i/retro-aim-server/oscar"
  5. "github.com/mk6i/retro-aim-server/state"
  6. )
  7. // NewBuddyService creates a new instance of BuddyService.
  8. func NewBuddyService() *BuddyService {
  9. return &BuddyService{}
  10. }
  11. // BuddyService provides functionality for the buddy food group, which sends
  12. // clients notifications about the state of users on their buddy list. The food
  13. // group is used by old versions of AIM not currently supported by Retro Aim
  14. // Server. BuddyService just exists to satisfy AIM 5.x's buddy rights requests.
  15. // It may be expanded in the future to support older versions of AIM.
  16. type BuddyService struct {
  17. }
  18. // RightsQueryHandler returns buddy list service parameters.
  19. func (s BuddyService) RightsQueryHandler(_ context.Context, frameIn oscar.SNACFrame) oscar.SNACMessage {
  20. return oscar.SNACMessage{
  21. Frame: oscar.SNACFrame{
  22. FoodGroup: oscar.Buddy,
  23. SubGroup: oscar.BuddyRightsReply,
  24. RequestID: frameIn.RequestID,
  25. },
  26. Body: oscar.SNAC_0x03_0x03_BuddyRightsReply{
  27. TLVRestBlock: oscar.TLVRestBlock{
  28. TLVList: oscar.TLVList{
  29. oscar.NewTLV(oscar.BuddyTLVTagsParmMaxBuddies, uint16(100)),
  30. oscar.NewTLV(oscar.BuddyTLVTagsParmMaxWatchers, uint16(100)),
  31. oscar.NewTLV(oscar.BuddyTLVTagsParmMaxIcqBroad, uint16(100)),
  32. oscar.NewTLV(oscar.BuddyTLVTagsParmMaxTempBuddies, uint16(100)),
  33. },
  34. },
  35. },
  36. }
  37. }
  38. func broadcastArrival(ctx context.Context, sess *state.Session, messageRelayer MessageRelayer, feedbagManager FeedbagManager) error {
  39. screenNames, err := feedbagManager.AdjacentUsers(sess.ScreenName())
  40. if err != nil {
  41. return err
  42. }
  43. messageRelayer.RelayToScreenNames(ctx, screenNames, oscar.SNACMessage{
  44. Frame: oscar.SNACFrame{
  45. FoodGroup: oscar.Buddy,
  46. SubGroup: oscar.BuddyArrived,
  47. },
  48. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  49. TLVUserInfo: sess.TLVUserInfo(),
  50. },
  51. })
  52. return nil
  53. }
  54. func broadcastDeparture(ctx context.Context, sess *state.Session, messageRelayer MessageRelayer, feedbagManager FeedbagManager) error {
  55. screenNames, err := feedbagManager.AdjacentUsers(sess.ScreenName())
  56. if err != nil {
  57. return err
  58. }
  59. messageRelayer.RelayToScreenNames(ctx, screenNames, oscar.SNACMessage{
  60. Frame: oscar.SNACFrame{
  61. FoodGroup: oscar.Buddy,
  62. SubGroup: oscar.BuddyDeparted,
  63. },
  64. Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
  65. TLVUserInfo: oscar.TLVUserInfo{
  66. // don't include the TLV block, otherwise the AIM client fails
  67. // to process the block event
  68. ScreenName: sess.ScreenName(),
  69. WarningLevel: sess.Warning(),
  70. },
  71. },
  72. })
  73. return nil
  74. }
  75. func unicastArrival(ctx context.Context, from *state.Session, to *state.Session, messageRelayer MessageRelayer) {
  76. messageRelayer.RelayToScreenName(ctx, to.ScreenName(), oscar.SNACMessage{
  77. Frame: oscar.SNACFrame{
  78. FoodGroup: oscar.Buddy,
  79. SubGroup: oscar.BuddyArrived,
  80. },
  81. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  82. TLVUserInfo: from.TLVUserInfo(),
  83. },
  84. })
  85. }
  86. func unicastDeparture(ctx context.Context, from *state.Session, to *state.Session, messageRelayer MessageRelayer) {
  87. messageRelayer.RelayToScreenName(ctx, to.ScreenName(), oscar.SNACMessage{
  88. Frame: oscar.SNACFrame{
  89. FoodGroup: oscar.Buddy,
  90. SubGroup: oscar.BuddyDeparted,
  91. },
  92. Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
  93. TLVUserInfo: oscar.TLVUserInfo{
  94. // don't include the TLV block, otherwise the AIM client fails
  95. // to process the block event
  96. ScreenName: from.ScreenName(),
  97. WarningLevel: from.Warning(),
  98. },
  99. },
  100. })
  101. }