chat_nav.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package handler
  2. import (
  3. "context"
  4. "errors"
  5. "log/slog"
  6. "time"
  7. "github.com/google/uuid"
  8. "github.com/mkaminski/goaim/oscar"
  9. "github.com/mkaminski/goaim/state"
  10. )
  11. func NewChatRoom() state.ChatRoom {
  12. return state.ChatRoom{
  13. Cookie: uuid.New().String(),
  14. CreateTime: time.Now(),
  15. }
  16. }
  17. func NewChatNavService(logger *slog.Logger, cr *state.ChatRegistry, newChatRoom func() state.ChatRoom, newChatSessMgr func() ChatSessionManager) *ChatNavService {
  18. return &ChatNavService{
  19. logger: logger,
  20. chatRegistry: cr,
  21. newChatRoom: NewChatRoom,
  22. newChatSessMgr: newChatSessMgr,
  23. }
  24. }
  25. type ChatNavService struct {
  26. logger *slog.Logger
  27. chatRegistry *state.ChatRegistry
  28. newChatRoom func() state.ChatRoom
  29. newChatSessMgr func() ChatSessionManager
  30. }
  31. func (s ChatNavService) RequestChatRightsHandler(context.Context) oscar.SNACMessage {
  32. return oscar.SNACMessage{
  33. Frame: oscar.SNACFrame{
  34. FoodGroup: oscar.ChatNav,
  35. SubGroup: oscar.ChatNavNavInfo,
  36. },
  37. Body: oscar.SNAC_0x0D_0x09_ChatNavNavInfo{
  38. TLVRestBlock: oscar.TLVRestBlock{
  39. TLVList: oscar.TLVList{
  40. oscar.NewTLV(0x02, uint8(10)),
  41. oscar.NewTLV(0x03, oscar.SNAC_0x0D_0x09_TLVExchangeInfo{
  42. Identifier: 4,
  43. TLVBlock: oscar.TLVBlock{
  44. TLVList: oscar.TLVList{
  45. oscar.NewTLV(0x0002, uint16(0x0010)),
  46. oscar.NewTLV(0x00c9, uint16(15)),
  47. oscar.NewTLV(0x00d3, "default Exchange"),
  48. oscar.NewTLV(0x00d5, uint8(2)),
  49. oscar.NewTLV(0xd6, "us-ascii"),
  50. oscar.NewTLV(0xd7, "en"),
  51. oscar.NewTLV(0xd8, "us-ascii"),
  52. oscar.NewTLV(0xd9, "en"),
  53. },
  54. },
  55. }),
  56. },
  57. },
  58. },
  59. }
  60. }
  61. func (s ChatNavService) CreateRoomHandler(ctx context.Context, sess *state.Session, snacPayloadIn oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate) (oscar.SNACMessage, error) {
  62. name, hasName := snacPayloadIn.GetString(oscar.ChatTLVRoomName)
  63. if !hasName {
  64. return oscar.SNACMessage{}, errors.New("unable to find chat name")
  65. }
  66. room := s.newChatRoom()
  67. room.DetailLevel = snacPayloadIn.DetailLevel
  68. room.Exchange = snacPayloadIn.Exchange
  69. room.InstanceNumber = snacPayloadIn.InstanceNumber
  70. room.Name = name
  71. chatSessMgr := s.newChatSessMgr()
  72. s.chatRegistry.Register(room, chatSessMgr)
  73. // add user to chat room
  74. chatSessMgr.NewSessionWithSN(sess.ID(), sess.ScreenName())
  75. return oscar.SNACMessage{
  76. Frame: oscar.SNACFrame{
  77. FoodGroup: oscar.ChatNav,
  78. SubGroup: oscar.ChatNavNavInfo,
  79. },
  80. Body: oscar.SNAC_0x0D_0x09_ChatNavNavInfo{
  81. TLVRestBlock: oscar.TLVRestBlock{
  82. TLVList: oscar.TLVList{
  83. oscar.NewTLV(oscar.ChatNavTLVRoomInfo, oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate{
  84. Exchange: snacPayloadIn.Exchange,
  85. Cookie: room.Cookie,
  86. InstanceNumber: snacPayloadIn.InstanceNumber,
  87. DetailLevel: snacPayloadIn.DetailLevel,
  88. TLVBlock: oscar.TLVBlock{
  89. TLVList: room.TLVList(),
  90. },
  91. }),
  92. },
  93. },
  94. },
  95. }, nil
  96. }
  97. func (s ChatNavService) RequestRoomInfoHandler(_ context.Context, snacPayloadIn oscar.SNAC_0x0D_0x04_ChatNavRequestRoomInfo) (oscar.SNACMessage, error) {
  98. room, _, err := s.chatRegistry.Retrieve(string(snacPayloadIn.Cookie))
  99. if err != nil {
  100. return oscar.SNACMessage{}, err
  101. }
  102. return oscar.SNACMessage{
  103. Frame: oscar.SNACFrame{
  104. FoodGroup: oscar.ChatNav,
  105. SubGroup: oscar.ChatNavNavInfo,
  106. },
  107. Body: oscar.SNAC_0x0D_0x09_ChatNavNavInfo{
  108. TLVRestBlock: oscar.TLVRestBlock{
  109. TLVList: oscar.TLVList{
  110. oscar.NewTLV(0x04, oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate{
  111. Exchange: 4,
  112. Cookie: room.Cookie,
  113. InstanceNumber: 100,
  114. DetailLevel: 2,
  115. TLVBlock: oscar.TLVBlock{
  116. TLVList: room.TLVList(),
  117. },
  118. }),
  119. },
  120. },
  121. },
  122. }, nil
  123. }