chat_nav.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package server
  2. import (
  3. "context"
  4. "io"
  5. "log/slog"
  6. "github.com/mkaminski/goaim/oscar"
  7. "github.com/mkaminski/goaim/state"
  8. )
  9. type ChatNavHandler interface {
  10. CreateRoomHandler(ctx context.Context, sess *state.Session, inFrame oscar.SNACFrame, inBody oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate) (oscar.SNACMessage, error)
  11. RequestChatRightsHandler(ctx context.Context, inFrame oscar.SNACFrame) oscar.SNACMessage
  12. RequestRoomInfoHandler(ctx context.Context, inFrame oscar.SNACFrame, inBody oscar.SNAC_0x0D_0x04_ChatNavRequestRoomInfo) (oscar.SNACMessage, error)
  13. }
  14. func NewChatNavRouter(handler ChatNavHandler, logger *slog.Logger) ChatNavRouter {
  15. return ChatNavRouter{
  16. ChatNavHandler: handler,
  17. RouteLogger: RouteLogger{
  18. Logger: logger,
  19. },
  20. }
  21. }
  22. type ChatNavRouter struct {
  23. ChatNavHandler
  24. RouteLogger
  25. }
  26. func (rt *ChatNavRouter) RouteChatNav(ctx context.Context, sess *state.Session, inFrame oscar.SNACFrame, r io.Reader, w io.Writer, sequence *uint32) error {
  27. switch inFrame.SubGroup {
  28. case oscar.ChatNavRequestChatRights:
  29. outSNAC := rt.RequestChatRightsHandler(ctx, inFrame)
  30. rt.logRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  31. return sendSNAC(outSNAC.Frame, outSNAC.Body, sequence, w)
  32. case oscar.ChatNavRequestRoomInfo:
  33. inBody := oscar.SNAC_0x0D_0x04_ChatNavRequestRoomInfo{}
  34. if err := oscar.Unmarshal(&inBody, r); err != nil {
  35. return err
  36. }
  37. outSNAC, err := rt.RequestRoomInfoHandler(ctx, inFrame, inBody)
  38. if err != nil {
  39. return err
  40. }
  41. rt.logRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  42. return sendSNAC(outSNAC.Frame, outSNAC.Body, sequence, w)
  43. case oscar.ChatNavCreateRoom:
  44. inBody := oscar.SNAC_0x0E_0x02_ChatRoomInfoUpdate{}
  45. if err := oscar.Unmarshal(&inBody, r); err != nil {
  46. return err
  47. }
  48. outSNAC, err := rt.CreateRoomHandler(ctx, sess, inFrame, inBody)
  49. if err != nil {
  50. return err
  51. }
  52. roomName, _ := inBody.GetString(oscar.ChatTLVRoomName)
  53. rt.Logger.InfoContext(ctx, "user started a chat room", slog.String("roomName", roomName))
  54. rt.logRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  55. return sendSNAC(outSNAC.Frame, outSNAC.Body, sequence, w)
  56. default:
  57. return ErrUnsupportedSubGroup
  58. }
  59. }
  60. type ChatCookie struct {
  61. Cookie []byte `len_prefix:"uint16"`
  62. SessID string `len_prefix:"uint16"`
  63. }