using System; using System.Collections.Generic; using System.Linq; using System.Text; using Newtonsoft.Json.Linq; namespace ET.Server { [FriendOf(typeof (GameDouyinComponent))] public static class GameDouyinComponentSystem { public class GameDouyinComponentAwakeSystem: AwakeSystem { protected override void Awake(GameDouyinComponent self) { Log.Info($"创建抖音组件..."); self.InitAccessToken(); } } public class GameDouyinComponentDestroySystem: DestroySystem { protected override void Destroy(GameDouyinComponent self) { } } public class GameDouyinComponentUpdateSystem: UpdateSystem { protected override void Update(GameDouyinComponent self) { if (TimeHelper.ClientNow() <= self.AccessTokenTime) { return; } self.InitAccessToken(); } } /// /// 初始化抖音接口调用凭证 /// /// public static void InitAccessToken(this GameDouyinComponent self) { // 请求头 Dictionary head = new Dictionary(); // 参数 JObject param = new JObject(); param.Add("appid", DouyinConst.Appid); param.Add("secret", DouyinConst.Secret); param.Add("grant_type", "client_credential"); string str = HttpHelper.PostRequestByDouyin(DouyinConst.GetAccessTokenUrl, head, param); if (string.IsNullOrEmpty(str)) { Log.Error($"InitAccessToken - GetAccessTokenUrl请求失败...返回为null"); return; } JObject jObject = JObject.Parse(str); int errNo = Convert.ToInt32(jObject.SelectToken("err_no")); if (errNo != 0) { string errTips = Convert.ToString(jObject.SelectToken("err_tips")); Log.Error($"InitAccessToken - GetAccessTokenUrl请求成功...返回错误:{errNo}, 错误信息:{errTips}"); return; } self.AccessToken = Convert.ToString(jObject.SelectToken("data").SelectToken("access_token")); long time = Convert.ToInt64(jObject.SelectToken("data").SelectToken("expires_in")); self.AccessTokenTime = TimeHelper.ClientNow() + time * 1000; Log.Info($"AccessToken刷新完成, AccessToken:{self.AccessToken}, AccessTokenTime:{self.AccessTokenTime}"); } /// /// 获取抖音直播信息 /// /// /// /// public static JObject GetRoomInfo(this GameDouyinComponent self, string token) { if (string.IsNullOrEmpty(self.AccessToken.Trim())) { Log.Error($"InitRoomId...AccessToken为null"); return null; } // 请求头 Dictionary head = new Dictionary(); head.Add("X-Token", self.AccessToken.Trim()); // 参数 JObject param = new JObject(); param.Add("token", token); string str = HttpHelper.PostRequestByDouyin(DouyinConst.GetLiveInfoUrl, head, param); if (string.IsNullOrEmpty(str)) { Log.Error($"InitRoomId - GetLiveInfoUrl请求失败...返回为null"); return null; } JObject jObject = JObject.Parse(str); int errNo = Convert.ToInt32(jObject.SelectToken("errcode")); if (errNo != 0) { // 容错处理 if (errNo == 40004) { Log.Debug($"InitRoomId - 40004 容错处理:AccessToken不合法,下一秒重新刷新"); self.AccessTokenTime = 0; } else { Log.Error($"InitRoomId - GetLiveInfoUrl请求成功...返回错误:{errNo}"); } return null; } return jObject; } /// /// 礼物置顶 /// /// /// public static void TopGifts(this GameDouyinComponent self, long roomId) { if (string.IsNullOrEmpty(self.AccessToken.Trim())) { Log.Error($"TopGifts...AccessToken为null"); return; } // 礼物参数 JArray item = new JArray(); foreach (string itemKey in DouyinItem.GiftHash.Keys) { item.Add(itemKey); } // 请求头 Dictionary head = new Dictionary(); head.Add("x-token", self.AccessToken.Trim()); // 参数 JObject param = new JObject(); param.Add("room_id", roomId.ToString()); param.Add("app_id", DouyinConst.Appid); param.Add("sec_gift_id_list", item); string str = HttpHelper.PostRequestByDouyin(DouyinConst.TopGiftUrl, head, param); if (string.IsNullOrEmpty(str)) { Log.Error($"TopGifts - TopGiftUrl请求失败...返回为null"); return; } JObject jObject = JObject.Parse(str); int errNo = Convert.ToInt32(jObject.SelectToken("errcode")); if (errNo != 0) { if (errNo == 40004) { Log.Debug($"TopGifts - 40004 容错处理:AccessToken不合法,下一秒重新刷新"); self.AccessTokenTime = 0; } else { Log.Error($"TopGifts - TopGiftUrl请求成功...返回错误:{errNo}, str={str}"); } } } /// /// 签名验证 /// /// = { /// "x-nonce-str": "123456", /// "x-timestamp": "456789", /// "x-roomid": "268", /// "x-msg-type": "live_gift", /// } /// = "abc123你好" /// = "oumuamua410" /// PDcKhdlsrKEJif6uMKD2dw== public static string Signature(Dictionary header, string bodyStr, string secret) { List keyList = new List(4); keyList.AddRange(header.Select(keyValuePair => keyValuePair.Key)); keyList.Sort(); List kvList = new List(4); kvList.AddRange(keyList.Select(key => key + "=" + header[key])); string urlParams = string.Join("&", kvList); string rawData = MD5Helper.StringMD5(urlParams + bodyStr + secret); byte[] bytes = Encoding.GetEncoding("UTF-8").GetBytes(rawData); return Convert.ToBase64String(bytes); } } }