GameDouyinComponentSystem.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Newtonsoft.Json.Linq;
  6. namespace ET.Server
  7. {
  8. [FriendOf(typeof (GameDouyinComponent))]
  9. public static class GameDouyinComponentSystem
  10. {
  11. public class GameDouyinComponentAwakeSystem: AwakeSystem<GameDouyinComponent>
  12. {
  13. protected override void Awake(GameDouyinComponent self)
  14. {
  15. Log.Info($"创建抖音组件...");
  16. self.InitAccessToken();
  17. }
  18. }
  19. public class GameDouyinComponentDestroySystem: DestroySystem<GameDouyinComponent>
  20. {
  21. protected override void Destroy(GameDouyinComponent self)
  22. {
  23. }
  24. }
  25. public class GameDouyinComponentUpdateSystem: UpdateSystem<GameDouyinComponent>
  26. {
  27. protected override void Update(GameDouyinComponent self)
  28. {
  29. if (TimeHelper.ClientNow() <= self.AccessTokenTime)
  30. {
  31. return;
  32. }
  33. self.InitAccessToken();
  34. }
  35. }
  36. /// <summary>
  37. /// 初始化抖音接口调用凭证
  38. /// </summary>
  39. /// <param name="self"></param>
  40. public static void InitAccessToken(this GameDouyinComponent self)
  41. {
  42. // 请求头
  43. Dictionary<string, string> head = new Dictionary<string, string>();
  44. // 参数
  45. JObject param = new JObject();
  46. param.Add("appid", DouyinConst.Appid);
  47. param.Add("secret", DouyinConst.Secret);
  48. param.Add("grant_type", "client_credential");
  49. string str = HttpHelper.PostRequestByDouyin(DouyinConst.GetAccessTokenUrl, head, param);
  50. if (string.IsNullOrEmpty(str))
  51. {
  52. Log.Error($"InitAccessToken - GetAccessTokenUrl请求失败...返回为null");
  53. return;
  54. }
  55. JObject jObject = JObject.Parse(str);
  56. int errNo = Convert.ToInt32(jObject.SelectToken("err_no"));
  57. if (errNo != 0)
  58. { string errTips = Convert.ToString(jObject.SelectToken("err_tips"));
  59. Log.Error($"InitAccessToken - GetAccessTokenUrl请求成功...返回错误:{errNo}, 错误信息:{errTips}");
  60. return;
  61. }
  62. self.AccessToken = Convert.ToString(jObject.SelectToken("data").SelectToken("access_token"));
  63. long time = Convert.ToInt64(jObject.SelectToken("data").SelectToken("expires_in"));
  64. self.AccessTokenTime = TimeHelper.ClientNow() + time * 1000;
  65. Log.Info($"AccessToken刷新完成, AccessToken:{self.AccessToken}, AccessTokenTime:{self.AccessTokenTime}");
  66. }
  67. /// <summary>
  68. /// 获取抖音直播信息
  69. /// </summary>
  70. /// <param name="self"></param>
  71. /// <param name="token"></param>
  72. /// <returns></returns>
  73. public static JObject GetRoomInfo(this GameDouyinComponent self, string token)
  74. {
  75. if (string.IsNullOrEmpty(self.AccessToken.Trim()))
  76. {
  77. Log.Error($"InitRoomId...AccessToken为null");
  78. return null;
  79. }
  80. // 请求头
  81. Dictionary<string, string> head = new Dictionary<string, string>();
  82. head.Add("X-Token", self.AccessToken.Trim());
  83. // 参数
  84. JObject param = new JObject();
  85. param.Add("token", token);
  86. string str = HttpHelper.PostRequestByDouyin(DouyinConst.GetLiveInfoUrl, head, param);
  87. if (string.IsNullOrEmpty(str))
  88. {
  89. Log.Error($"InitRoomId - GetLiveInfoUrl请求失败...返回为null");
  90. return null;
  91. }
  92. JObject jObject = JObject.Parse(str);
  93. int errNo = Convert.ToInt32(jObject.SelectToken("errcode"));
  94. if (errNo != 0)
  95. {
  96. // 容错处理
  97. if (errNo == 40004)
  98. {
  99. Log.Debug($"InitRoomId - 40004 容错处理:AccessToken不合法,下一秒重新刷新");
  100. self.AccessTokenTime = 0;
  101. }
  102. else
  103. {
  104. Log.Error($"InitRoomId - GetLiveInfoUrl请求成功...返回错误:{errNo}");
  105. }
  106. return null;
  107. }
  108. return jObject;
  109. }
  110. /// <summary>
  111. /// 礼物置顶
  112. /// </summary>
  113. /// <param name="self"></param>
  114. /// <param name="roomId"></param>
  115. public static void TopGifts(this GameDouyinComponent self, long roomId)
  116. {
  117. if (string.IsNullOrEmpty(self.AccessToken.Trim()))
  118. {
  119. Log.Error($"TopGifts...AccessToken为null");
  120. return;
  121. }
  122. // 礼物参数
  123. JArray item = new JArray();
  124. foreach (string itemKey in DouyinItem.GiftHash.Keys)
  125. {
  126. item.Add(itemKey);
  127. }
  128. // 请求头
  129. Dictionary<string, string> head = new Dictionary<string, string>();
  130. head.Add("x-token", self.AccessToken.Trim());
  131. // 参数
  132. JObject param = new JObject();
  133. param.Add("room_id", roomId.ToString());
  134. param.Add("app_id", DouyinConst.Appid);
  135. param.Add("sec_gift_id_list", item);
  136. string str = HttpHelper.PostRequestByDouyin(DouyinConst.TopGiftUrl, head, param);
  137. if (string.IsNullOrEmpty(str))
  138. {
  139. Log.Error($"TopGifts - TopGiftUrl请求失败...返回为null");
  140. return;
  141. }
  142. JObject jObject = JObject.Parse(str);
  143. int errNo = Convert.ToInt32(jObject.SelectToken("errcode"));
  144. if (errNo != 0)
  145. {
  146. if (errNo == 40004)
  147. {
  148. Log.Debug($"TopGifts - 40004 容错处理:AccessToken不合法,下一秒重新刷新");
  149. self.AccessTokenTime = 0;
  150. }
  151. else
  152. {
  153. Log.Error($"TopGifts - TopGiftUrl请求成功...返回错误:{errNo}, str={str}");
  154. }
  155. }
  156. }
  157. /// <summary>
  158. /// 签名验证
  159. /// </summary>
  160. /// <param name="header"> = {
  161. /// "x-nonce-str": "123456",
  162. /// "x-timestamp": "456789",
  163. /// "x-roomid": "268",
  164. /// "x-msg-type": "live_gift",
  165. /// } </param>
  166. /// <param name="bodyStr"> = "abc123你好"</param>
  167. /// <param name="secret"> = "oumuamua410"</param>
  168. /// <returns>PDcKhdlsrKEJif6uMKD2dw==</returns>
  169. public static string Signature(Dictionary<string, string> header, string bodyStr, string secret)
  170. {
  171. List<string> keyList = new List<string>(4);
  172. keyList.AddRange(header.Select(keyValuePair => keyValuePair.Key));
  173. keyList.Sort();
  174. List<string> kvList = new List<string>(4);
  175. kvList.AddRange(keyList.Select(key => key + "=" + header[key]));
  176. string urlParams = string.Join("&", kvList);
  177. string rawData = MD5Helper.StringMD5(urlParams + bodyStr + secret);
  178. byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes(rawData);
  179. return Convert.ToBase64String(bytes);
  180. }
  181. }
  182. }