icbm.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package handler
  2. import (
  3. "context"
  4. "io"
  5. "log/slog"
  6. "github.com/mk6i/retro-aim-server/server/oscar"
  7. "github.com/mk6i/retro-aim-server/server/oscar/middleware"
  8. "github.com/mk6i/retro-aim-server/state"
  9. "github.com/mk6i/retro-aim-server/wire"
  10. )
  11. type ICBMService interface {
  12. ChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x06_ICBMChannelMsgToHost) (*wire.SNACMessage, error)
  13. ClientEvent(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x14_ICBMClientEvent) error
  14. EvilRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, inBody wire.SNAC_0x04_0x08_ICBMEvilRequest) (wire.SNACMessage, error)
  15. ParameterQuery(ctx context.Context, inFrame wire.SNACFrame) wire.SNACMessage
  16. ClientErr(ctx context.Context, sess *state.Session, frame wire.SNACFrame, body wire.SNAC_0x04_0x0B_ICBMClientErr) error
  17. }
  18. func NewICBMHandler(logger *slog.Logger, icbmService ICBMService) ICBMHandler {
  19. return ICBMHandler{
  20. ICBMService: icbmService,
  21. RouteLogger: middleware.RouteLogger{
  22. Logger: logger,
  23. },
  24. }
  25. }
  26. type ICBMHandler struct {
  27. ICBMService
  28. middleware.RouteLogger
  29. }
  30. func (h ICBMHandler) AddParameters(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  31. inBody := wire.SNAC_0x04_0x02_ICBMAddParameters{}
  32. h.LogRequest(ctx, inFrame, inBody)
  33. return wire.UnmarshalBE(&inBody, r)
  34. }
  35. func (h ICBMHandler) ParameterQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw oscar.ResponseWriter) error {
  36. outSNAC := h.ICBMService.ParameterQuery(ctx, inFrame)
  37. h.LogRequestAndResponse(ctx, inFrame, outSNAC, outSNAC.Frame, outSNAC.Body)
  38. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  39. }
  40. func (h ICBMHandler) ChannelMsgToHost(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  41. inBody := wire.SNAC_0x04_0x06_ICBMChannelMsgToHost{}
  42. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  43. return err
  44. }
  45. outSNAC, err := h.ICBMService.ChannelMsgToHost(ctx, sess, inFrame, inBody)
  46. if err != nil {
  47. return err
  48. }
  49. h.Logger.InfoContext(ctx, "user sent an IM", slog.String("recipient", inBody.ScreenName))
  50. if outSNAC == nil {
  51. return nil
  52. }
  53. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  54. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  55. }
  56. func (h ICBMHandler) EvilRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  57. inBody := wire.SNAC_0x04_0x08_ICBMEvilRequest{}
  58. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  59. return err
  60. }
  61. outSNAC, err := h.ICBMService.EvilRequest(ctx, sess, inFrame, inBody)
  62. if err != nil {
  63. return err
  64. }
  65. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  66. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  67. }
  68. func (h ICBMHandler) ClientErr(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  69. inBody := wire.SNAC_0x04_0x0B_ICBMClientErr{}
  70. h.LogRequest(ctx, inFrame, inBody)
  71. err := wire.UnmarshalBE(&inBody, r)
  72. if err != nil {
  73. return err
  74. }
  75. return h.ICBMService.ClientErr(ctx, sess, inFrame, inBody)
  76. }
  77. func (h ICBMHandler) ClientEvent(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  78. inBody := wire.SNAC_0x04_0x14_ICBMClientEvent{}
  79. if err := wire.UnmarshalBE(&inBody, r); err != nil {
  80. return err
  81. }
  82. h.LogRequest(ctx, inFrame, inBody)
  83. return h.ICBMService.ClientEvent(ctx, sess, inFrame, inBody)
  84. }