chat_nav.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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, chatRegistry *state.ChatRegistry, newChatSessMgr func() SessionManager) *ChatNavService {
  18. return &ChatNavService{
  19. logger: logger,
  20. chatRegistry: chatRegistry,
  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() SessionManager
  30. }
  31. func (s ChatNavService) RequestChatRightsHandler(_ context.Context, inFrame oscar.SNACFrame) oscar.SNACMessage {
  32. return oscar.SNACMessage{
  33. Frame: oscar.SNACFrame{
  34. FoodGroup: oscar.ChatNav,
  35. SubGroup: oscar.ChatNavNavInfo,
  36. RequestID: inFrame.RequestID,
  37. },
  38. Body: oscar.SNAC_0x0D_0x09_ChatNavNavInfo{
  39. TLVRestBlock: oscar.TLVRestBlock{
  40. TLVList: oscar.TLVList{
  41. oscar.NewTLV(0x02, uint8(10)),
  42. oscar.NewTLV(0x03, oscar.SNAC_0x0D_0x09_TLVExchangeInfo{
  43. Identifier: 4,
  44. TLVBlock: oscar.TLVBlock{
  45. TLVList: oscar.TLVList{
  46. oscar.NewTLV(0x0002, uint16(0x0010)),
  47. oscar.NewTLV(0x00c9, uint16(15)),
  48. oscar.NewTLV(0x00d3, "default Exchange"),
  49. oscar.NewTLV(0x00d5, uint8(2)),
  50. oscar.NewTLV(0xd6, "us-ascii"),
  51. oscar.NewTLV(0xd7, "en"),
  52. oscar.NewTLV(0xd8, "us-ascii"),
  53. oscar.NewTLV(0xd9, "en"),
  54. },
  55. },
  56. }),
  57. },
  58. },
  59. },
  60. }
  61. }
  62. func (s ChatNavService) CreateRoomHandler(_ context.Context, sess *state.Session, inFrame oscar.SNACFrame, inBody oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate) (oscar.SNACMessage, error) {
  63. name, hasName := inBody.GetString(oscar.ChatTLVRoomName)
  64. if !hasName {
  65. return oscar.SNACMessage{}, errors.New("unable to find chat name")
  66. }
  67. room := s.newChatRoom()
  68. room.DetailLevel = inBody.DetailLevel
  69. room.Exchange = inBody.Exchange
  70. room.InstanceNumber = inBody.InstanceNumber
  71. room.Name = name
  72. chatSessMgr := s.newChatSessMgr()
  73. s.chatRegistry.Register(room, chatSessMgr)
  74. // add user to chat room
  75. chatSessMgr.NewSessionWithSN(sess.ID(), sess.ScreenName())
  76. return oscar.SNACMessage{
  77. Frame: oscar.SNACFrame{
  78. FoodGroup: oscar.ChatNav,
  79. SubGroup: oscar.ChatNavNavInfo,
  80. RequestID: inFrame.RequestID,
  81. },
  82. Body: oscar.SNAC_0x0D_0x09_ChatNavNavInfo{
  83. TLVRestBlock: oscar.TLVRestBlock{
  84. TLVList: oscar.TLVList{
  85. oscar.NewTLV(oscar.ChatNavTLVRoomInfo, oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate{
  86. Exchange: inBody.Exchange,
  87. Cookie: room.Cookie,
  88. InstanceNumber: inBody.InstanceNumber,
  89. DetailLevel: inBody.DetailLevel,
  90. TLVBlock: oscar.TLVBlock{
  91. TLVList: room.TLVList(),
  92. },
  93. }),
  94. },
  95. },
  96. },
  97. }, nil
  98. }
  99. func (s ChatNavService) RequestRoomInfoHandler(_ context.Context, inFrame oscar.SNACFrame, inBody oscar.SNAC_0x0D_0x04_ChatNavRequestRoomInfo) (oscar.SNACMessage, error) {
  100. room, _, err := s.chatRegistry.Retrieve(string(inBody.Cookie))
  101. if err != nil {
  102. return oscar.SNACMessage{}, err
  103. }
  104. return oscar.SNACMessage{
  105. Frame: oscar.SNACFrame{
  106. FoodGroup: oscar.ChatNav,
  107. SubGroup: oscar.ChatNavNavInfo,
  108. RequestID: inFrame.RequestID,
  109. },
  110. Body: oscar.SNAC_0x0D_0x09_ChatNavNavInfo{
  111. TLVRestBlock: oscar.TLVRestBlock{
  112. TLVList: oscar.TLVList{
  113. oscar.NewTLV(0x04, oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate{
  114. Exchange: 4,
  115. Cookie: room.Cookie,
  116. InstanceNumber: 100,
  117. DetailLevel: 2,
  118. TLVBlock: oscar.TLVBlock{
  119. TLVList: room.TLVList(),
  120. },
  121. }),
  122. },
  123. },
  124. },
  125. }, nil
  126. }