buddy.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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, frameIn oscar.SNACFrame) oscar.SNACMessage {
  13. return oscar.SNACMessage{
  14. Frame: oscar.SNACFrame{
  15. FoodGroup: oscar.Buddy,
  16. SubGroup: oscar.BuddyRightsReply,
  17. RequestID: frameIn.RequestID,
  18. },
  19. Body: oscar.SNAC_0x03_0x03_BuddyRightsReply{
  20. TLVRestBlock: oscar.TLVRestBlock{
  21. TLVList: oscar.TLVList{
  22. oscar.NewTLV(0x01, uint16(100)),
  23. oscar.NewTLV(0x02, uint16(100)),
  24. oscar.NewTLV(0x03, uint16(100)),
  25. oscar.NewTLV(0x04, uint16(100)),
  26. },
  27. },
  28. },
  29. }
  30. }
  31. func broadcastArrival(ctx context.Context, sess *state.Session, messageRelayer MessageRelayer, feedbagManager FeedbagManager) error {
  32. screenNames, err := feedbagManager.AdjacentUsers(sess.ScreenName())
  33. if err != nil {
  34. return err
  35. }
  36. messageRelayer.RelayToScreenNames(ctx, screenNames, oscar.SNACMessage{
  37. Frame: oscar.SNACFrame{
  38. FoodGroup: oscar.Buddy,
  39. SubGroup: oscar.BuddyArrived,
  40. },
  41. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  42. TLVUserInfo: sess.TLVUserInfo(),
  43. },
  44. })
  45. return nil
  46. }
  47. func broadcastDeparture(ctx context.Context, sess *state.Session, messageRelayer MessageRelayer, feedbagManager FeedbagManager) error {
  48. screenNames, err := feedbagManager.AdjacentUsers(sess.ScreenName())
  49. if err != nil {
  50. return err
  51. }
  52. messageRelayer.RelayToScreenNames(ctx, screenNames, oscar.SNACMessage{
  53. Frame: oscar.SNACFrame{
  54. FoodGroup: oscar.Buddy,
  55. SubGroup: oscar.BuddyDeparted,
  56. },
  57. Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
  58. TLVUserInfo: oscar.TLVUserInfo{
  59. // don't include the TLV block, otherwise the AIM client fails
  60. // to process the block event
  61. ScreenName: sess.ScreenName(),
  62. WarningLevel: sess.Warning(),
  63. },
  64. },
  65. })
  66. return nil
  67. }
  68. func unicastArrival(ctx context.Context, from *state.Session, to *state.Session, messageRelayer MessageRelayer) {
  69. messageRelayer.RelayToScreenName(ctx, to.ScreenName(), oscar.SNACMessage{
  70. Frame: oscar.SNACFrame{
  71. FoodGroup: oscar.Buddy,
  72. SubGroup: oscar.BuddyArrived,
  73. },
  74. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  75. TLVUserInfo: from.TLVUserInfo(),
  76. },
  77. })
  78. }
  79. func unicastDeparture(ctx context.Context, from *state.Session, to *state.Session, messageRelayer MessageRelayer) {
  80. messageRelayer.RelayToScreenName(ctx, to.ScreenName(), oscar.SNACMessage{
  81. Frame: oscar.SNACFrame{
  82. FoodGroup: oscar.Buddy,
  83. SubGroup: oscar.BuddyDeparted,
  84. },
  85. Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
  86. TLVUserInfo: oscar.TLVUserInfo{
  87. // don't include the TLV block, otherwise the AIM client fails
  88. // to process the block event
  89. ScreenName: from.ScreenName(),
  90. WarningLevel: from.Warning(),
  91. },
  92. },
  93. })
  94. }