2
0

bridge_message.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. package afreeca
  2. import (
  3. "fmt"
  4. "git.beejay.kim/tool/service/ascii"
  5. "github.com/mailru/easyjson"
  6. "github.com/spf13/cast"
  7. "strings"
  8. )
  9. type BridgeCommand string
  10. const (
  11. BridgeCommandInitGateway BridgeCommand = "INIT_GW"
  12. BridgeCommandInitBroadcast BridgeCommand = "INIT_BROAD"
  13. BridgeCommandKeepAlive BridgeCommand = "KEEPALIVE"
  14. BridgeCommandLogin BridgeCommand = "FLASH_LOGIN"
  15. BridgeCommandCertTicket BridgeCommand = "CERTTICKETEX"
  16. BridgeCommandUserCount BridgeCommand = "GETUSERCNT"
  17. BridgeCommandUserCountExtended BridgeCommand = "GETUSERCNTEX"
  18. BridgeCommandChannelCommon BridgeCommand = "JOINCH_COMMON"
  19. BridgeCommandChannelInfo BridgeCommand = "GETCHINFOEX"
  20. BridgeCommand_GETBJADCON BridgeCommand = "GETBJADCON"
  21. BridgeCommand_GETITEM_SELL BridgeCommand = "GETITEM_SELL"
  22. BridgeCommandClosed BridgeCommand = "CLOSECH"
  23. )
  24. //easyjson:json
  25. type BridgeMessage struct {
  26. Command BridgeCommand `json:"SVC"`
  27. Result int `json:"RESULT"`
  28. Data map[string]any `json:"DATA"`
  29. }
  30. func (bm *BridgeMessage) AddArgument(k string, v any) {
  31. switch v.(type) {
  32. case int:
  33. bm.Data[k] = v.(int)
  34. case int8:
  35. bm.Data[k] = v.(int8)
  36. case int16:
  37. bm.Data[k] = v.(int16)
  38. case int32:
  39. bm.Data[k] = v.(int32)
  40. case int64:
  41. bm.Data[k] = v.(int64)
  42. case uint:
  43. bm.Data[k] = v.(uint)
  44. case uint8:
  45. bm.Data[k] = v.(uint8)
  46. case uint16:
  47. bm.Data[k] = v.(uint16)
  48. case uint32:
  49. bm.Data[k] = v.(uint32)
  50. case uint64:
  51. bm.Data[k] = v.(uint64)
  52. default:
  53. bm.Data[k] = cast.ToString(v)
  54. }
  55. }
  56. func (bm *BridgeMessage) MustMarshall() []byte {
  57. buf, err := easyjson.Marshal(bm)
  58. if err != nil {
  59. return nil
  60. }
  61. return buf
  62. }
  63. type BridgeMessageValue []string
  64. func (arg *BridgeMessageValue) AddTuple(k string, v any) {
  65. var list []string
  66. if list = *arg; list == nil {
  67. list = []string{}
  68. }
  69. *arg = append(list, fmt.Sprintf(`%s%s`, k, cast.ToString(v)))
  70. }
  71. func (arg BridgeMessageValue) String() string {
  72. return strings.Join(arg, "")
  73. }
  74. type BridgeMessageValueParams []string
  75. func (arg BridgeMessageValueParams) String() string {
  76. return strings.Join(arg, "")
  77. }
  78. func (arg *BridgeMessageValueParams) Add(k string, v any) {
  79. var list []string
  80. if list = *arg; list == nil {
  81. list = []string{}
  82. }
  83. ack := string([]byte{ascii.Acknowledgement})
  84. *arg = append(list, ack, "&", ack, k, ack, "=", ack, cast.ToString(v))
  85. }
  86. func NewBridgeInitGatewayMessage(bid string, uuid string, ch Channel, cookieGetter func(string) string) *BridgeMessage {
  87. m := NewBridgeMessage(BridgeCommandInitGateway)
  88. m.AddArgument("BJID", bid)
  89. m.AddArgument("JOINLOG", makeJoinLog(ch, cookieGetter))
  90. m.AddArgument("QUALITY", "sd")
  91. m.AddArgument("addinfo", func() BridgeMessageValue {
  92. info := BridgeMessageValue{}
  93. info.AddTuple("ad_lang", "ko")
  94. info.AddTuple("is_auto", 0)
  95. return info
  96. }())
  97. m.AddArgument("broadno", ch.Id)
  98. m.AddArgument("category", ch.Category)
  99. m.AddArgument("cc_cli_type", 19)
  100. m.AddArgument("cli_type", 44)
  101. m.AddArgument("cookie", "")
  102. m.AddArgument("fanticket", ch.FanToken)
  103. m.AddArgument("gate_ip", ch.GatewayIp)
  104. m.AddArgument("gate_port", ch.GatewayPort)
  105. m.AddArgument("guid", uuid)
  106. m.AddArgument("update_info", 0)
  107. return m
  108. }
  109. func NewBridgeInitBroadcastMessage(uuid string, ch Channel, cookieGetter func(string) string) *BridgeMessage {
  110. m := NewBridgeMessage(BridgeCommandInitBroadcast)
  111. m.AddArgument("JOINLOG", makeJoinLog(ch, cookieGetter))
  112. m.AddArgument("QUALITY", "sd")
  113. m.AddArgument("cc_cli_type", 19)
  114. m.AddArgument("cli_type", 44)
  115. m.AddArgument("center_ip", ch.CenterIp)
  116. m.AddArgument("center_port", ch.CenterPort)
  117. m.AddArgument("guid", uuid)
  118. m.AddArgument("passwd", "")
  119. m.AddArgument("append_data", "")
  120. m.AddArgument("gw_ticket", "")
  121. return m
  122. }
  123. func NewBridgeMessage(cmd BridgeCommand) *BridgeMessage {
  124. return &BridgeMessage{
  125. Command: cmd,
  126. Data: map[string]any{},
  127. }
  128. }
  129. func makeJoinLog(ch Channel, cookieGetter func(string) string) BridgeMessageValue {
  130. joinlog := BridgeMessageValue{}
  131. joinlog.AddTuple("log", func() BridgeMessageValueParams {
  132. params := BridgeMessageValueParams{}
  133. params.Add("uuid", cookieGetter("_au"))
  134. params.Add("geo_cc", ch.GeoName)
  135. params.Add("geo_rc", ch.GeoCode)
  136. params.Add("acpt_lang", ch.AcceptLanguage)
  137. params.Add("svc_lang", ch.ServiceLanguage)
  138. params.Add("os", "mac")
  139. params.Add("is_streamer", false)
  140. params.Add("is_rejoin", false)
  141. params.Add("is_streamer", false)
  142. params.Add("is_auto", false)
  143. params.Add("is_support_adaptive", false)
  144. params.Add("uuid_3rd", cookieGetter("_au3rd"))
  145. params.Add("subscribe", -1)
  146. return params
  147. }())
  148. joinlog.AddTuple("liveualog", func() BridgeMessageValueParams {
  149. params := BridgeMessageValueParams{}
  150. params.Add("is_clearmode", false)
  151. params.Add("lowlatency", 0)
  152. return params
  153. }())
  154. return joinlog
  155. }