oservice.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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 OServiceService interface {
  12. ClientVersions(ctx context.Context, frame wire.SNACFrame, bodyIn wire.SNAC_0x01_0x17_OServiceClientVersions) wire.SNACMessage
  13. IdleNotification(ctx context.Context, sess *state.Session, bodyIn wire.SNAC_0x01_0x11_OServiceIdleNotification) error
  14. RateParamsQuery(ctx context.Context, frame wire.SNACFrame) wire.SNACMessage
  15. RateParamsSubAdd(context.Context, wire.SNAC_0x01_0x08_OServiceRateParamsSubAdd)
  16. SetPrivacyFlags(ctx context.Context, bodyIn wire.SNAC_0x01_0x14_OServiceSetPrivacyFlags)
  17. SetUserInfoFields(ctx context.Context, sess *state.Session, frame wire.SNACFrame, bodyIn wire.SNAC_0x01_0x1E_OServiceSetUserInfoFields) (wire.SNACMessage, error)
  18. UserInfoQuery(ctx context.Context, sess *state.Session, frame wire.SNACFrame) wire.SNACMessage
  19. }
  20. type OServiceBOSService interface {
  21. OServiceService
  22. HostOnline() wire.SNACMessage
  23. ServiceRequest(ctx context.Context, sess *state.Session, frame wire.SNACFrame, bodyIn wire.SNAC_0x01_0x04_OServiceServiceRequest) (wire.SNACMessage, error)
  24. ClientOnline(ctx context.Context, bodyIn wire.SNAC_0x01_0x02_OServiceClientOnline, sess *state.Session) error
  25. }
  26. type OServiceChatService interface {
  27. OServiceService
  28. HostOnline() wire.SNACMessage
  29. ClientOnline(ctx context.Context, sess *state.Session) error
  30. }
  31. type OServiceChatNavService interface {
  32. OServiceService
  33. HostOnline() wire.SNACMessage
  34. }
  35. type OServiceAlertService interface {
  36. OServiceService
  37. HostOnline() wire.SNACMessage
  38. }
  39. type OServiceHandler struct {
  40. OServiceService
  41. middleware.RouteLogger
  42. }
  43. func (h OServiceHandler) RateParamsQuery(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw oscar.ResponseWriter) error {
  44. outSNAC := h.OServiceService.RateParamsQuery(ctx, inFrame)
  45. h.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  46. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  47. }
  48. func (h OServiceHandler) RateParamsSubAdd(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  49. inBody := wire.SNAC_0x01_0x08_OServiceRateParamsSubAdd{}
  50. if err := wire.Unmarshal(&inBody, r); err != nil {
  51. return err
  52. }
  53. h.OServiceService.RateParamsSubAdd(ctx, inBody)
  54. h.LogRequest(ctx, inFrame, inBody)
  55. return wire.Unmarshal(&inBody, r)
  56. }
  57. func (h OServiceHandler) UserInfoQuery(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw oscar.ResponseWriter) error {
  58. outSNAC := h.OServiceService.UserInfoQuery(ctx, sess, inFrame)
  59. h.LogRequestAndResponse(ctx, inFrame, nil, outSNAC.Frame, outSNAC.Body)
  60. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  61. }
  62. func (h OServiceHandler) IdleNotification(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  63. inBody := wire.SNAC_0x01_0x11_OServiceIdleNotification{}
  64. if err := wire.Unmarshal(&inBody, r); err != nil {
  65. return err
  66. }
  67. h.LogRequest(ctx, inFrame, inBody)
  68. return h.OServiceService.IdleNotification(ctx, sess, inBody)
  69. }
  70. func (h OServiceHandler) ClientVersions(ctx context.Context, _ *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  71. inBody := wire.SNAC_0x01_0x17_OServiceClientVersions{}
  72. if err := wire.Unmarshal(&inBody, r); err != nil {
  73. return err
  74. }
  75. outSNAC := h.OServiceService.ClientVersions(ctx, inFrame, inBody)
  76. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  77. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  78. }
  79. func (h OServiceHandler) SetUserInfoFields(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  80. inBody := wire.SNAC_0x01_0x1E_OServiceSetUserInfoFields{}
  81. if err := wire.Unmarshal(&inBody, r); err != nil {
  82. return err
  83. }
  84. outSNAC, err := h.OServiceService.SetUserInfoFields(ctx, sess, inFrame, inBody)
  85. if err != nil {
  86. return err
  87. }
  88. h.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  89. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  90. }
  91. func (h OServiceHandler) Noop(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, _ io.Reader, rw oscar.ResponseWriter) error {
  92. // no-op keep-alive
  93. h.LogRequest(ctx, inFrame, nil)
  94. return nil
  95. }
  96. func (h OServiceHandler) SetPrivacyFlags(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  97. inBody := wire.SNAC_0x01_0x14_OServiceSetPrivacyFlags{}
  98. if err := wire.Unmarshal(&inBody, r); err != nil {
  99. return err
  100. }
  101. h.OServiceService.SetPrivacyFlags(ctx, inBody)
  102. h.LogRequest(ctx, inFrame, inBody)
  103. return nil
  104. }
  105. func NewOServiceHandlerForBOS(logger *slog.Logger, oServiceService OServiceService, oServiceBOSService OServiceBOSService) OServiceBOSHandler {
  106. return OServiceBOSHandler{
  107. OServiceHandler: OServiceHandler{
  108. OServiceService: oServiceService,
  109. RouteLogger: middleware.RouteLogger{
  110. Logger: logger,
  111. },
  112. },
  113. OServiceBOSService: oServiceBOSService,
  114. }
  115. }
  116. type OServiceBOSHandler struct {
  117. OServiceHandler
  118. OServiceBOSService
  119. }
  120. func (s OServiceBOSHandler) ServiceRequest(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, rw oscar.ResponseWriter) error {
  121. inBody := wire.SNAC_0x01_0x04_OServiceServiceRequest{}
  122. if err := wire.Unmarshal(&inBody, r); err != nil {
  123. return err
  124. }
  125. outSNAC, err := s.OServiceBOSService.ServiceRequest(ctx, sess, inFrame, inBody)
  126. if err != nil {
  127. return err
  128. }
  129. s.LogRequestAndResponse(ctx, inFrame, inBody, outSNAC.Frame, outSNAC.Body)
  130. return rw.SendSNAC(outSNAC.Frame, outSNAC.Body)
  131. }
  132. func (s OServiceBOSHandler) ClientOnline(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  133. inBody := wire.SNAC_0x01_0x02_OServiceClientOnline{}
  134. if err := wire.Unmarshal(&inBody, r); err != nil {
  135. return err
  136. }
  137. s.Logger.InfoContext(ctx, "user signed on")
  138. s.LogRequest(ctx, inFrame, inBody)
  139. return s.OServiceBOSService.ClientOnline(ctx, inBody, sess)
  140. }
  141. func NewOServiceHandlerForChat(logger *slog.Logger, oServiceService OServiceService, oServiceChatService OServiceChatService) OServiceChatHandler {
  142. return OServiceChatHandler{
  143. OServiceHandler: OServiceHandler{
  144. OServiceService: oServiceService,
  145. RouteLogger: middleware.RouteLogger{
  146. Logger: logger,
  147. },
  148. },
  149. OServiceChatService: oServiceChatService,
  150. }
  151. }
  152. type OServiceChatHandler struct {
  153. OServiceHandler
  154. OServiceChatService
  155. }
  156. func (s OServiceChatHandler) ClientOnline(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  157. inBody := wire.SNAC_0x01_0x02_OServiceClientOnline{}
  158. if err := wire.Unmarshal(&inBody, r); err != nil {
  159. return err
  160. }
  161. s.Logger.InfoContext(ctx, "user signed on")
  162. s.LogRequest(ctx, inFrame, inBody)
  163. return s.OServiceChatService.ClientOnline(ctx, sess)
  164. }
  165. func NewOServiceHandlerForChatNav(logger *slog.Logger, oServiceService OServiceService, oServiceChatNavService OServiceChatNavService) OServiceChatNavHandler {
  166. return OServiceChatNavHandler{
  167. OServiceHandler: OServiceHandler{
  168. OServiceService: oServiceService,
  169. RouteLogger: middleware.RouteLogger{
  170. Logger: logger,
  171. },
  172. },
  173. OServiceChatNavService: oServiceChatNavService,
  174. }
  175. }
  176. type OServiceChatNavHandler struct {
  177. OServiceHandler
  178. OServiceChatNavService
  179. }
  180. func (s OServiceChatNavHandler) ClientOnline(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  181. inBody := wire.SNAC_0x01_0x02_OServiceClientOnline{}
  182. if err := wire.Unmarshal(&inBody, r); err != nil {
  183. return err
  184. }
  185. s.Logger.InfoContext(ctx, "user signed on")
  186. s.LogRequest(ctx, inFrame, inBody)
  187. return nil
  188. }
  189. func NewOServiceHandlerForAlert(logger *slog.Logger, oServiceService OServiceService, oServiceAlertService OServiceAlertService) OServiceAlertHandler {
  190. return OServiceAlertHandler{
  191. OServiceHandler: OServiceHandler{
  192. OServiceService: oServiceService,
  193. RouteLogger: middleware.RouteLogger{
  194. Logger: logger,
  195. },
  196. },
  197. OServiceAlertService: oServiceAlertService,
  198. }
  199. }
  200. type OServiceAlertHandler struct {
  201. OServiceHandler
  202. OServiceAlertService
  203. }
  204. func (s OServiceAlertHandler) ClientOnline(ctx context.Context, sess *state.Session, inFrame wire.SNACFrame, r io.Reader, _ oscar.ResponseWriter) error {
  205. inBody := wire.SNAC_0x01_0x02_OServiceClientOnline{}
  206. if err := wire.Unmarshal(&inBody, r); err != nil {
  207. return err
  208. }
  209. s.Logger.InfoContext(ctx, "user signed on")
  210. s.LogRequest(ctx, inFrame, inBody)
  211. return nil
  212. }