Browse Source

【增加】抖音接口数据接入和推送协议

johnclot69 1 năm trước cách đây
mục cha
commit
4d519113c9
38 tập tin đã thay đổi với 1234 bổ sung294 xóa
  1. 11 1
      Config/Proto/InnerMessage_S_20001.proto
  2. 12 0
      Config/Proto/OuterMessage_C_10001.proto
  3. 186 0
      DotNet/Hotfix/Helper/DouyinCallBackHelper.cs
  4. 105 2
      DotNet/Hotfix/Helper/HttpHelper.cs
  5. 2 3
      DotNet/Hotfix/Helper/MapHelper.cs
  6. 2 2
      DotNet/Hotfix/Helper/PlayerHelper.cs
  7. 4 2
      DotNet/Hotfix/Helper/SceneFactory.cs
  8. 146 0
      DotNet/Hotfix/Scenes/Game/GameDouyinComponentSystem.cs
  9. 1 1
      DotNet/Hotfix/Scenes/Game/GameMapComponentSystem.cs
  10. 1 2
      DotNet/Hotfix/Scenes/Game/Handler/C2G_AddUnitsToMapHandler.cs
  11. 20 29
      DotNet/Hotfix/Scenes/Game/Handler/C2G_BattleNotifyHandler.cs
  12. 12 9
      DotNet/Hotfix/Scenes/Game/Handler/C2G_LoginGameHandler.cs
  13. 27 25
      DotNet/Hotfix/Scenes/Game/Handler/R2G_AddLevelHandler.cs
  14. 11 6
      DotNet/Hotfix/Scenes/Game/Handler/R2G_AddUnitsToMapHandler.cs
  15. 38 0
      DotNet/Hotfix/Scenes/Game/Handler/R2G_GiveGiftHandler.cs
  16. 179 0
      DotNet/Hotfix/Scenes/Game/Map/MapDouyinLiveCommentComponentSystem.cs
  17. 179 0
      DotNet/Hotfix/Scenes/Game/Map/MapDouyinLiveLikeComponentSystem.cs
  18. 11 14
      DotNet/Hotfix/Scenes/Game/Map/MapEventComponentSystem.cs
  19. 3 3
      DotNet/Hotfix/Scenes/Game/Map/MapRankComponentSystem.cs
  20. 16 13
      DotNet/Hotfix/Scenes/Game/Map/MapReliveTimeComponentSystem.cs
  21. 50 52
      DotNet/Hotfix/Scenes/Game/Map/MapSystem.cs
  22. 1 1
      DotNet/Hotfix/Scenes/Game/Player/PlayerSystem.cs
  23. 4 6
      DotNet/Hotfix/Scenes/Game/Session/SessionPlayerComponentSystem.cs
  24. 1 1
      DotNet/Hotfix/Scenes/Realm/Handler/C2R_LoginHandler.cs
  25. 32 85
      DotNet/Hotfix/Scenes/Router/HttpDouyinApiCallbackHandler.cs
  26. 1 1
      DotNet/Hotfix/Scenes/Router/HttpGetRouterHandler.cs
  27. 18 0
      DotNet/Model/Const/ConstGame.cs
  28. 27 11
      DotNet/Model/Const/Struct.cs
  29. 26 1
      DotNet/Model/Generate/Message/InnerMessage_S_20001.cs
  30. 27 7
      DotNet/Model/Generate/Message/OuterMessage_C_10001.cs
  31. 5 1
      DotNet/Model/Scenes/Game/DBEntity/PlayerInfo.cs
  32. 11 0
      DotNet/Model/Scenes/Game/GameDouyinComponent.cs
  33. 12 10
      DotNet/Model/Scenes/Game/Map/Map.cs
  34. 13 0
      DotNet/Model/Scenes/Game/Map/MapDouyinLiveCommentComponent.cs
  35. 13 0
      DotNet/Model/Scenes/Game/Map/MapDouyinLiveLikeComponent.cs
  36. 0 2
      DotNet/Model/Scenes/Game/Map/MapReliveTimeComponent.cs
  37. 1 4
      DotNet/Model/Scenes/Game/Session/SessionPlayerComponent.cs
  38. 26 0
      Unity/Assets/Scripts/Codes/Model/Client/Generate/Message/OuterMessage_C_10001.cs

+ 11 - 1
Config/Proto/InnerMessage_S_20001.proto

@@ -172,5 +172,15 @@ message R2G_AddLevel // IActorMessage
 {
 	string OpenId = 1;
 	int64 RoomId = 2;
-	int32 Likes = 3;
+	int64 Likes = 3;
+}
+
+message R2G_GiveGift // IActorMessage
+{
+	string OpenId = 1;
+	int64 RoomId = 2;
+	string NickName = 3;
+	string GiftId = 4;
+	int64 GiftNum = 5;		// 送出的礼物数量
+	int64 GiftValue = 6;	// 礼物总价值,单位分
 }

+ 12 - 0
Config/Proto/OuterMessage_C_10001.proto

@@ -363,4 +363,16 @@ message G2C_BattleNotify // IResponse
 	int32 RpcId = 1;
 	int32 Error = 2;
 	string Message = 3;
+}
+
+message G2C_LikeInfoPush // IActorMessage
+{
+	int64 TotalNum = 1;		// 点赞总数量
+	int64 ConfigNum = 2;	// 到达多少值后,总数量减少,然后累加
+}
+
+message G2C_GiftInfoPush // IActorMessage
+{
+	string NickName = 1;	// 昵称
+	int64 GiftNum = 2;		// 数量
 }

+ 186 - 0
DotNet/Hotfix/Helper/DouyinCallBackHelper.cs

@@ -0,0 +1,186 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using Newtonsoft.Json.Linq;
+
+namespace ET.Server
+{
+    /// <summary>
+    /// 抖音回调帮助类
+    /// </summary>
+    public static class DouyinCallBackHelper
+    {
+        /// <summary>
+        /// 评论加入玩家
+        /// </summary>
+        /// <param name="domain"></param>
+        /// <param name="context"></param>
+        /// <param name="roomId"></param>
+        public static async void LiveComment(Entity domain, HttpListenerContext context, long roomId)
+        {
+            HttpDouyinApiCallbackResponse response = new HttpDouyinApiCallbackResponse();
+
+            string bodyStr = await HttpHelper.GetBodyParameter(context);
+            // 判断body是否为空
+            if (string.IsNullOrEmpty(bodyStr))
+            {
+                response.Error = ErrorCode.ERR_ParameterError;
+                response.Message = "参数错误";
+                HttpHelper.Response(context, response);
+                return;
+            }
+
+            JArray jsonArray = JArray.Parse(bodyStr);
+
+            foreach (JToken jToken in jsonArray)
+            {
+                JObject jsonObject = (JObject)jToken;
+                string msgId = (string)jsonObject["msg_id"];
+                string secOpenId = (string)jsonObject["sec_openid"];
+                string content = (string)jsonObject["content"];
+                string avatarUrl = (string)jsonObject["avatar_url"];
+                string nickname = (string)jsonObject["nickname"];
+                long timestamp = (long)jsonObject["timestamp"];
+
+                Log.Debug($"body参数: openid={secOpenId}, roomId={roomId}, content={content}");
+                // 判断参数
+                if (string.IsNullOrEmpty(secOpenId) || roomId <= 0)
+                {
+                    response.Error = ErrorCode.ERR_ParameterError;
+                    response.Message = "参数错误";
+                    HttpHelper.Response(context, response);
+                    return;
+                }
+
+                List<StartSceneConfig> list = RealmGateAddressHelper.GetAllGame(1);
+
+                foreach (StartSceneConfig config in list.Where(config => config is { Id: 10001 }))
+                {
+                    MessageHelper.SendActor(config.InstanceId, new R2G_AddUnitsToMap() { OpenId = secOpenId, RoomId = roomId});
+                    break;
+                }
+
+                HttpHelper.Response(context, response);
+            }
+            await ETTask.CompletedTask;
+        }
+
+        /// <summary>
+        /// 刷礼物
+        /// </summary>
+        /// <param name="domain"></param>
+        /// <param name="context"></param>
+        /// <param name="roomId"></param>
+        public static async void LiveGift(Entity domain, HttpListenerContext context, long roomId)
+        {
+            HttpDouyinApiCallbackResponse response = new HttpDouyinApiCallbackResponse();
+
+            string bodyStr = await HttpHelper.GetBodyParameter(context);
+
+            if (string.IsNullOrEmpty(bodyStr))
+            {
+                response.Error = ErrorCode.ERR_ParameterError;
+                response.Message = "参数错误";
+                HttpHelper.Response(context, response);
+                return;
+            }
+
+            JArray jsonArray = JArray.Parse(bodyStr);
+
+            foreach (JToken jToken in jsonArray)
+            {
+                JObject jsonObject = (JObject)jToken;
+                string msgId = (string)jsonObject["msg_id"];
+                string secOpenId = (string)jsonObject["sec_openid"];
+                // 加密的礼物id
+                string secGiftId = (string)jsonObject["sec_gift_id"];
+                // 送出的礼物数量
+                long giftNum = (long)jsonObject["gift_num"];
+                // 礼物总价值,单位分
+                long giftValue = (long)jsonObject["gift_value"];
+                string avatarUrl = (string)jsonObject["avatar_url"];
+                string nickname = (string)jsonObject["nickname"];
+                long timestamp = (long)jsonObject["timestamp"];
+
+                Log.Debug($"body参数: openid={secOpenId}, roomId={roomId}, secGiftId={secGiftId}, giftNum={giftNum}, giftValue={giftValue}");
+                // 判断参数
+                if (string.IsNullOrEmpty(secOpenId) || roomId <= 0)
+                {
+                    response.Error = ErrorCode.ERR_ParameterError;
+                    response.Message = "参数错误";
+                    HttpHelper.Response(context, response);
+                    return;
+                }
+
+                List<StartSceneConfig> list = RealmGateAddressHelper.GetAllGame(1);
+
+                foreach (StartSceneConfig config in list.Where(config => config is { Id: 10001 }))
+                {
+                    MessageHelper.SendActor(config.InstanceId, new R2G_GiveGift() { OpenId = secOpenId, RoomId = roomId, NickName = nickname, GiftId = secGiftId, GiftNum = giftNum, GiftValue = giftValue});
+                    break;
+                }
+
+                HttpHelper.Response(context, response);
+            }
+
+            await ETTask.CompletedTask;
+        }
+
+        /// <summary>
+        /// 点赞10次增加等级
+        /// </summary>
+        /// <param name="domain"></param>
+        /// <param name="context"></param>
+        /// <param name="roomId"></param>
+        public static async void LiveLike(Entity domain, HttpListenerContext context, long roomId)
+        {
+            HttpDouyinApiCallbackResponse response = new HttpDouyinApiCallbackResponse();
+
+            string bodyStr = await HttpHelper.GetBodyParameter(context);
+
+            if (string.IsNullOrEmpty(bodyStr))
+            {
+                response.Error = ErrorCode.ERR_ParameterError;
+                response.Message = "参数错误";
+                HttpHelper.Response(context, response);
+                return;
+            }
+
+            JArray jsonArray = JArray.Parse(bodyStr);
+
+            foreach (JToken jToken in jsonArray)
+            {
+                JObject jsonObject = (JObject)jToken;
+                string msgId = (string)jsonObject["msg_id"];
+                string secOpenId = (string)jsonObject["sec_openid"];
+                long likeNum = (long)jsonObject["like_num"];
+                string avatarUrl = (string)jsonObject["avatar_url"];
+                string nickname = (string)jsonObject["nickname"];
+                long timestamp = (long)jsonObject["timestamp"];
+
+                Log.Debug($"body参数: openid={secOpenId}, roomId={roomId}, likes={likeNum}");
+                // 判断参数
+                if (string.IsNullOrEmpty(secOpenId) || roomId <= 0 || likeNum < 0)
+                {
+                    response.Error = ErrorCode.ERR_ParameterError;
+                    response.Message = "参数错误";
+                    HttpHelper.Response(context, response);
+                    return;
+                }
+
+                List<StartSceneConfig> list = RealmGateAddressHelper.GetAllGame(1);
+
+                foreach (StartSceneConfig config in list.Where(config => config is { Id: 10001 }))
+                {
+                    MessageHelper.SendActor(config.InstanceId, new R2G_AddLevel() { OpenId = secOpenId, RoomId = roomId, Likes = likeNum});
+                    break;
+                }
+
+                HttpHelper.Response(context, response);
+            }
+
+            await ETTask.CompletedTask;
+        }
+    }
+}

+ 105 - 2
DotNet/Hotfix/Helper/HttpHelper.cs

@@ -1,6 +1,13 @@
-using System.IO;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
 using System.Net;
+using System.Net.Http;
 using System.Text;
+using Microsoft.Extensions.Primitives;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
 
 namespace ET.Server
 {
@@ -19,5 +26,101 @@ namespace ET.Server
             context.Response.ContentLength64 = bytes.Length;
             context.Response.OutputStream.Write(bytes, 0, bytes.Length);
         }
+
+        /// <summary>
+        /// post请求抖音接口
+        /// </summary>
+        /// <param name="url"></param>
+        /// <param name="heads"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public static string PostRequestByDouyin(string url, Dictionary<string, string> heads, JObject param)
+        {
+            if (string.IsNullOrEmpty(url) || param is not { Count: > 0 })
+            {
+                return null;
+            }
+
+            using HttpClient httpClient = new HttpClient();
+            httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
+            // 设置请求头
+            if (heads is { Count: >= 0 })
+            {
+                foreach (var head in heads)
+                {
+                    httpClient.DefaultRequestHeaders.Add(head.Key, head.Value);
+                }
+            }
+
+            // post
+            HttpContent content = new StringContent(JsonConvert.SerializeObject(param), Encoding.UTF8, "application/json");
+            // response
+            HttpResponseMessage response = httpClient.PostAsync(new Uri(url), content).Result;
+
+            if (response.IsSuccessStatusCode)
+            {
+                return response.Content.ReadAsStringAsync().Result;
+            }
+
+            string statusCode = response.StatusCode.ToString();
+            Log.Debug($"http请求错误...statusCode:{statusCode}, url:{url}");
+            return null;
+        }
+
+        /// <summary>
+        /// get请求抖音接口
+        /// </summary>
+        /// <param name="baseUrl"></param>
+        /// <param name="heads"></param>
+        /// <param name="param"></param>
+        /// <returns></returns>
+        public static string GetRequestByDouyin(string baseUrl, Dictionary<string, string> heads, Dictionary<string, string> param)
+        {
+            if (string.IsNullOrEmpty(baseUrl) || param is not { Count: > 0 })
+            {
+                return null;
+            }
+
+            using HttpClient httpClient = new HttpClient();
+            httpClient.DefaultRequestHeaders.Accept.TryParseAdd("application/json");
+            // 设置请求头
+            if (heads is { Count: >= 0 })
+            {
+                foreach (var head in heads)
+                {
+                    httpClient.DefaultRequestHeaders.Add(head.Key, head.Value);
+                }
+            }
+
+            StringBuilder url = new StringBuilder(baseUrl);
+
+            if (param is { Count: >= 0 })
+            {
+                url.Append('?');
+
+                List<string> keyList = new List<string>(param.Keys);
+
+                for (int i = 0; i < param.Count; i++)
+                {
+                    url.Append(keyList[i]).Append('=').Append(param[keyList[i]]);
+
+                    if (i < param.Count)
+                    {
+                        url.Append('&');
+                    }
+                }
+            }
+
+            HttpResponseMessage response = httpClient.GetAsync(new Uri(url.ToString())).Result;
+
+            if (response.IsSuccessStatusCode)
+            {
+                return response.Content.ReadAsStringAsync().Result;
+            }
+
+            string statusCode = response.StatusCode.ToString();
+            Log.Debug($"http请求错误...statusCode:{statusCode}, url:{url}");
+            return null;
+        }
     }
-}
+}

+ 2 - 3
DotNet/Hotfix/Helper/MapHelper.cs

@@ -226,13 +226,12 @@ namespace ET.Server
         {
             Scene scene = player.DomainScene();
 
-            Map map = scene.GetComponent<GameMapComponent>().AddChildWithId<Map, JObject>(instanceId, data);
+            Map map = scene.GetComponent<GameMapComponent>().AddChildWithId<Map, JObject, WNPlayer>(instanceId, data, player);
             if (map != null)
             {
                 Log.Info($"创建Area场景:{map.MapId}, instanceId:{instanceId}, srvId:" + map.LogicServerId);
                 map.BindBattleServer(player, bsServerId);
-                // todo 测试用roomId
-                scene.GetComponent<GameMapComponent>().Add(map, 10098);
+                scene.GetComponent<GameMapComponent>().Add(map.RoomId, map);
             }
             else
             {

+ 2 - 2
DotNet/Hotfix/Helper/PlayerHelper.cs

@@ -15,7 +15,7 @@
             return new PlayerBasic()
             {
                 id = playerInfo.Id,
-                roomId = playerInfo.RoomId,
+                roomId = playerInfo.RoomId.ToString(),
                 name = playerInfo.Name,
                 level = playerInfo.Level,
                 exp = playerInfo.Exp,
@@ -32,7 +32,7 @@
             return new Player()
             {
                 id = player.GetId(),
-                roomId = player.GetRoomId(),
+                roomId = player.GetRoomId().ToString(),
                 name = player.GetName(),
                 level = player.GetLevel(),
                 exp = player.GetExp(),

+ 4 - 2
DotNet/Hotfix/Helper/SceneFactory.cs

@@ -40,7 +40,9 @@ namespace ET.Server
                     scene.AddComponent<GameTokenInfoComponent>();
                     scene.AddComponent<GamePlayerComponent>();
                     scene.AddComponent<GameMapComponent>();
-                    //战斗服的Ice会话组件
+                    // 抖音组件
+                    scene.AddComponent<GameDouyinComponent>();
+                    // 战斗服的Ice会话组件
                     scene.AddComponent<BattleIceAgentComponent>();
                     scene.AddComponent<ObjectWait>();
                     break;
@@ -52,7 +54,7 @@ namespace ET.Server
                     break;
                 case SceneType.BenchmarkServer:
                     scene.AddComponent<BenchmarkServerComponent>();
-                    scene.AddComponent<NetServerComponent, IPEndPoint, NetworkProtocol>(startSceneConfig.OuterIPPort, NetworkProtocol.KCP);
+                    scene.AddComponent<NetServerComponent, IPEndPoint, NetworkProtocol>(startSceneConfig.InnerIPOutPort, NetworkProtocol.KCP);
                     break;
                 case SceneType.BenchmarkClient:
                     scene.AddComponent<BenchmarkClientComponent>();

+ 146 - 0
DotNet/Hotfix/Scenes/Game/GameDouyinComponentSystem.cs

@@ -0,0 +1,146 @@
+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<GameDouyinComponent>
+        {
+            protected override void Awake(GameDouyinComponent self)
+            {
+                // 初始化数据
+                self.InitAccessToken();
+            }
+        }
+
+        public class GameDouyinComponentDestroySystem: DestroySystem<GameDouyinComponent>
+        {
+            protected override void Destroy(GameDouyinComponent self)
+            {
+                Log.Info($"销毁session玩家抖音组件");
+            }
+        }
+
+        public class GameDouyinComponentUpdateSystem: UpdateSystem<GameDouyinComponent>
+        {
+            protected override void Update(GameDouyinComponent self)
+            {
+                if (TimeHelper.ClientNow() >= self.AccessTokenTime)
+                {
+                    Log.Info($"刷新AccessToken...");
+                    self.InitAccessToken();
+                    Log.Info($"AccessToken刷新完成, AccessToken:{self.AccessToken}, AccessTokenTime:{self.AccessTokenTime}");
+                }
+            }
+        }
+
+        /// <summary>
+        /// 初始化抖音接口调用凭证
+        /// </summary>
+        /// <param name="self"></param>
+        private static void InitAccessToken(this GameDouyinComponent self)
+        {
+            // 请求头
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            // 参数
+            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;
+        }
+
+        /// <summary>
+        /// 获取抖音直播信息
+        /// </summary>
+        /// <param name="self"></param>
+        /// <param name="token"></param>
+        /// <returns></returns>
+        public static JObject GetRoomInfo(this GameDouyinComponent self, string token)
+        {
+            if (string.IsNullOrEmpty(self.AccessToken))
+            {
+                Log.Error($"InitRoomId...AccessToken为null");
+                return null;
+            }
+            // 请求头
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            head.Add("X-Token", self.AccessToken);
+            // 参数
+            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)
+            {
+                Log.Error($"InitRoomId - GetLiveInfoUrl请求成功...返回错误:{errNo}");
+                return null;
+            }
+
+            return jObject;
+        }
+
+        /// <summary>
+        /// 签名验证
+        /// </summary>
+        /// <param name="header"> = {
+        ///                             "x-nonce-str": "123456",
+        ///                             "x-timestamp": "456789",
+        ///                             "x-roomid":    "268",
+        ///                             "x-msg-type":  "live_gift",
+        ///                         } </param>
+        /// <param name="bodyStr"> = "abc123你好"</param>
+        /// <param name="secret"> = "oumuamua410"</param>
+        /// <returns>PDcKhdlsrKEJif6uMKD2dw==</returns>
+        public static string Signature(Dictionary<string, string> header, string bodyStr, string secret)
+        {
+            List<string> keyList = new List<string>(4);
+            keyList.AddRange(header.Select(keyValuePair => keyValuePair.Key));
+            keyList.Sort();
+
+            List<string> kvList = new List<string>(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);
+        }
+    }
+}

+ 1 - 1
DotNet/Hotfix/Scenes/Game/GameMapComponentSystem.cs

@@ -29,7 +29,7 @@ namespace ET.Server
             }
         }
 
-        public static void Add(this GameMapComponent self, Map map, long roomId)
+        public static void Add(this GameMapComponent self, long roomId, Map map)
         {
             self.allMaps.TryAdd(map.Id, map);
             // 映射一下roomId与instanceId的关系

+ 1 - 2
DotNet/Hotfix/Scenes/Game/Handler/C2G_AddUnitsToMapHandler.cs

@@ -55,8 +55,7 @@ namespace ET.Server
             // 临时openId
             string _openId = player.GetComponent<PlayerDataComponent>().Data.Id.ToString();
 
-            player.Map.AddUnitObjId(_openId, objId);
-            player.Map.AddUnitPlayer(_openId, request.UnitId);
+            player.Map.AddUnitPlayer(_openId, request.UnitId, objId, 0);
 
             reply();
         }

+ 20 - 29
DotNet/Hotfix/Scenes/Game/Handler/C2G_BattleNotifyHandler.cs

@@ -29,46 +29,37 @@ namespace ET.Server
                 return;
             }
 
-            //甜甜圈礼物功能示例
-            /*if(eventname = "甜甜圈")
-            {
-                player.GetXmdsManager().notifyBattleServer(player.Map.Id.ToString(), NotifyBSName.TriggerEvent,
-                    JsonSerializer.Serialize(new Struct.TriggerEventNotify() { message = BattleNotify.TiktokGift_52.ToString() }));
-                return;
-            }*/
-
-            Struct.TriggerEventNotify notifyMsg = new Struct.TriggerEventNotify() { message = request.Message };
             //TODO:从玩家的openid换取在战场中的objectID
             int objid = 7;
-            if (request.Message == BattleNotify.TiktokGift_1.ToString())
+
+            //甜甜圈礼物功能示例
+            if(request.Message == BattleNotify.TiktokGift_52.ToString())//eventname = "甜甜圈")
             {
-			    //仙女棒特殊处理示例
-                var hp = player.GetZoneManager().getUnitHP(player.Map.Id.ToString(), objid);
-                if(hp <= 0)
+                //TODO: 游戏服记录单位level,初始level为1,level=3为顶级
+                int level = 1;
+                if (level < 3)
                 {
-                    //如果自己不是dead状态,则随机复活他人
-                    notifyMsg.message = BattleNotify.TiktokGift_1_ext.ToString();
+                    player.GetXmdsManager().notifyBattleServer(player.Map.Id.ToString(), NotifyBSName.TriggerEvent,
+                        JsonSerializer.Serialize(new Struct.TriggerEventNotify() { message = BattleNotify.TiktokGift_52.ToString(), TriggerUnits = objid.ToString() }));
                 }
                 else
                 {
-                    //送礼物的人的objectid填入到TriggerUnits中,有多个用半角逗号隔开
-                    notifyMsg.TriggerUnits = objid.ToString();
+                    //已经升到顶级的单位,触发其它甜甜圈效果
+                    player.GetXmdsManager().notifyBattleServer(player.Map.Id.ToString(), NotifyBSName.TriggerEvent,
+                        JsonSerializer.Serialize(new Struct.TriggerEventNotify() { message = BattleNotify.TiktokGift_52_ext.ToString(), TriggerUnits = objid.ToString() }));
                 }
+                return;
+            }
+
+            Struct.TriggerEventNotify notifyMsg = new Struct.TriggerEventNotify() { message = request.Message };
+            if (request.Message == BattleNotify.TiktokGift_1.ToString() )    //仙女棒
+            {
+                //礼物的效果如果专门针对送礼人自己,则需要把送礼人的objectid填入到TriggerUnits中
+                notifyMsg.TriggerUnits = objid.ToString();
             }
             else if(request.Message == BattleNotify.TiktokGift_10.ToString())
             {
-                //能力药丸特殊处理示例
-                var hp = player.GetZoneManager().getUnitHP(player.Map.Id.ToString(), objid);
-                if (hp <= 0)
-                {
-                    //如果自己不是dead状态,则随机复活他人
-                    notifyMsg.message = BattleNotify.TiktokGift_10_ext.ToString();
-                }
-                else
-                {
-                    //送礼物的人的objectid填入到TriggerUnits中,有多个用半角逗号隔开
-                    notifyMsg.TriggerUnits = objid.ToString();
-                }
+                notifyMsg.TriggerUnits = objid.ToString();
             }
 
             // 通知战斗服

+ 12 - 9
DotNet/Hotfix/Scenes/Game/Handler/C2G_LoginGameHandler.cs

@@ -1,4 +1,5 @@
 using System;
+using Newtonsoft.Json.Linq;
 
 namespace ET.Server
 {
@@ -30,24 +31,26 @@ namespace ET.Server
 
             // 移除session自动超时组件
             session.RemoveComponent<SessionAcceptTimeoutComponent>();
-            // 添加session组件,用于绑定角色
-            session.AddComponent<SessionPlayerComponent>().RoomId = request.Token.Trim();
-            session.AddComponent<MailBoxComponent, MailboxType>(MailboxType.GateSession);
 
             Scene scene = session.DomainScene();
+
+            JObject roomInfo = scene.GetComponent<GameDouyinComponent>().GetRoomInfo(request.Token.Trim());
+
             // 预先创建数据
-            long _id = IdGenerater.Instance.GenerateUnitId(scene.DomainZone());
             PlayerInfo playerInfo = new PlayerInfo();
-            playerInfo.Id = _id;
-            playerInfo.RoomId = session.GetComponent<SessionPlayerComponent>().RoomId;
-            playerInfo.Name = "主播-" + _id;
+            playerInfo.Id = IdGenerater.Instance.GenerateUnitId(scene.DomainZone());
+            playerInfo.RoomId = Convert.ToInt64(roomInfo.SelectToken("data").SelectToken("info").SelectToken("room_id"));
+            playerInfo.AnchorOpenId = Convert.ToString(roomInfo.SelectToken("data").SelectToken("info").SelectToken("anchor_open_id"));
+            playerInfo.AvatarUrl = Convert.ToString(roomInfo.SelectToken("data").SelectToken("info").SelectToken("avatar_url"));
+            playerInfo.Name = Convert.ToString(roomInfo.SelectToken("data").SelectToken("info").SelectToken("nick_name"));
             playerInfo.Sex = 0;
             playerInfo.Pro = (int)PlayerProType.CANG_LANG;
             playerInfo.Level = 1;
             playerInfo.Exp = 0;
 
-            session.GetComponent<SessionPlayerComponent>().PlayerId = _id;
-            session.GetComponent<SessionPlayerComponent>().PlayerInfo = playerInfo;
+            // 添加session组件,用于绑定角色
+            session.AddComponent<SessionPlayerComponent, PlayerInfo>(playerInfo);
+            session.AddComponent<MailBoxComponent, MailboxType>(MailboxType.GateSession);
 
             response.Player = PlayerHelper.PlayerInfoToPlayerBasicProto(playerInfo);
 

+ 27 - 25
DotNet/Hotfix/Scenes/Game/Handler/R2G_AddLevelHandler.cs

@@ -1,4 +1,6 @@
-namespace ET.Server
+using System.Text.Json;
+
+namespace ET.Server
 {
     /// <summary>
     /// 抖音api http回调, 点赞10次增加等级
@@ -18,35 +20,21 @@
             }
 
             // 数据是否存在
-            if (map.GetUnitTemplateId(request.OpenId) == 0)
-            {
-                Log.Debug($"未找到单位玩家数据...openId={request.OpenId}");
-                return;
-            }
-
-            // 总点赞数
-            int totelLikes = 0;
+            Struct.UnitPlayerData unitPlayerData = map.GetUnitPlayerData(request.OpenId) ?? map.AddUnitPlayer(request.OpenId, 0, 0, request.Likes);
 
             // 累计增加点赞数
-            if (map.UnitPlayerLikes.TryGetValue(request.OpenId, out int likes))
-            {
-                totelLikes = likes + request.Likes;
-                map.UnitPlayerLikes[request.OpenId] = totelLikes;
-            }
-            else
-            {
-                totelLikes = request.Likes;
-                map.UnitPlayerLikes.Add(request.OpenId, totelLikes);
-            }
+            unitPlayerData.Likes += request.Likes;
+            map.TotalLikeNum += request.Likes;
 
             int initialLevel = 1; // 初始等级
             int maxLevel = 3; // 等级上限
+            int configNum = 1000;   //到达多少值后,总数量减去这个值,然后继续累加
             int level = initialLevel; // 玩家等级
 
-            int levelUpCount = totelLikes / 10; // 计算升级次数
+            long levelUpCount = unitPlayerData.Likes / 10; // 计算升级次数
 
             // 根据升级次数更新等级
-            for (int i = 0; i < levelUpCount; i++)
+            for (long i = 0; i < levelUpCount; i++)
             {
                 level++; // 等级加1
 
@@ -59,13 +47,13 @@
             }
 
             // 模板id
-            int oldTemplateId = map.GetUnitTemplateId(request.OpenId);
+            int oldTemplateId = unitPlayerData.TemplateId;
             int newTemplateId = ((oldTemplateId / 10) * 10) + level;
 
             if (oldTemplateId != newTemplateId)
             {
                 // 当前战斗服objId
-                int curObjId = map.GetUnitObjId(request.OpenId);
+                int curObjId = unitPlayerData.ObjId;
                 // 移除原单位
                 await map.RemovePointUnit(curObjId);
 
@@ -80,8 +68,22 @@
 
                 curObjId = await map.AddUnits(unit, true);
 
-                map.AddUnitObjId(request.OpenId, curObjId);
-                map.AddUnitPlayer(request.OpenId, newTemplateId);
+                map.AddUnitPlayer(request.OpenId, newTemplateId, curObjId, unitPlayerData.Likes);
+            }
+
+            // 推送客户端
+            if (map.Player != null)
+            {
+                MessageHelper.SendToClient(map.Player, new G2C_LikeInfoPush{ TotalNum = map.TotalLikeNum, ConfigNum = configNum});
+            }
+
+            // 点赞>=ConfigNum时, 通知战斗服
+            if (map.TotalLikeNum >= configNum)
+            {
+                Struct.TriggerEventNotify notify = new Struct.TriggerEventNotify();
+                notify.message = BattleNotify.TiktokLike_energy.ToString();
+                notify.TriggerUnits = unitPlayerData.ObjId.ToString();
+                map.GetXmdsManager().notifyBattleServer(map.Id.ToString(), NotifyBSName.TriggerEvent, JsonSerializer.Serialize(notify));
             }
 
             await ETTask.CompletedTask;

+ 11 - 6
DotNet/Hotfix/Scenes/Game/Handler/R2G_AddUnitsToMapHandler.cs

@@ -8,10 +8,11 @@
     {
         protected override async ETTask Run(Scene scene, R2G_AddUnitsToMap request)
         {
-            // 初始模板id
-            int[] units = new int[] { 101, 111, 121, 131 };
-
-            int templateId = RandomGenerator.RandomArray(units);
+            if (string.IsNullOrEmpty(request.OpenId))
+            {
+                Log.Debug($"未找到openId...");
+                return;
+            }
 
             // 房间是否存在
             Map map = scene.GetComponent<GameMapComponent>().GetMapByRoomId(request.RoomId);
@@ -22,6 +23,11 @@
                 return;
             }
 
+            // 初始模板id
+            int[] units = new int[] { 101, 111, 121, 131 };
+
+            int templateId = RandomGenerator.RandomArray(units);
+
             string[] pos = map.GetCurXY().Split(";");
 
             Struct.MonsterUnit unit = new Struct.MonsterUnit();
@@ -33,8 +39,7 @@
 
             int objId = await map.AddUnits(unit, true);
 
-            map.AddUnitObjId(request.OpenId, objId);
-            map.AddUnitPlayer(request.OpenId, templateId);
+            map.AddUnitPlayer(request.OpenId, templateId, objId, 0);
 
             await ETTask.CompletedTask;
         }

+ 38 - 0
DotNet/Hotfix/Scenes/Game/Handler/R2G_GiveGiftHandler.cs

@@ -0,0 +1,38 @@
+namespace ET.Server
+{
+    /// <summary>
+    /// 抖音api http回调, 送礼物
+    /// </summary>
+    [ActorMessageHandler(SceneType.Game)]
+    public class R2G_GiveGiftHandler: AMActorHandler<Scene, R2G_GiveGift>
+    {
+        protected override async ETTask Run(Scene scene, R2G_GiveGift request)
+        {
+            // 房间是否存在
+            Map map = scene.GetComponent<GameMapComponent>().GetMapByRoomId(request.RoomId);
+
+            if (map == null)
+            {
+                Log.Debug($"未找到房间...roomId={request.RoomId}");
+                return;
+            }
+
+            Struct.UnitPlayerData unitPlayerData = map.GetUnitPlayerData(request.OpenId);
+
+            // 数据是否存在
+            if (unitPlayerData == null)
+            {
+                Log.Debug($"未找到单位玩家数据...openId={request.OpenId}");
+                return;
+            }
+
+            // 推送客户端
+            if (map.Player != null)
+            {
+                MessageHelper.SendToClient(map.Player, new G2C_GiftInfoPush{ NickName = request.NickName, GiftNum = request.GiftNum});
+            }
+
+            await ETTask.CompletedTask;
+        }
+    }
+}

+ 179 - 0
DotNet/Hotfix/Scenes/Game/Map/MapDouyinLiveCommentComponentSystem.cs

@@ -0,0 +1,179 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+
+namespace ET.Server
+{
+    [FriendOf(typeof (MapDouyinLiveCommentComponent))]
+    public static class MapDouyinLiveCommentComponentSystem
+    {
+        public class MapDouyinLiveCommentEventComponentAwakeSystem: AwakeSystem<MapDouyinLiveCommentComponent>
+        {
+            protected override void Awake(MapDouyinLiveCommentComponent self)
+            {
+                Log.Info($"创建抖音直播评论任务组件...");
+                // self.StartTask();
+            }
+        }
+
+        public class MapDouyinLiveCommentEventComponentDestroySystem: DestroySystem<MapDouyinLiveCommentComponent>
+        {
+            protected override void Destroy(MapDouyinLiveCommentComponent self)
+            {
+                Log.Info($"销毁抖音直播评论任务组件");
+                self.StopTask();
+            }
+        }
+
+        public class MapDouyinLiveCommentEventComponentU: UpdateSystem<MapDouyinLiveCommentComponent>
+        {
+            protected override void Update(MapDouyinLiveCommentComponent self)
+            {
+                // 运行中状态
+                if (self.Status == 3)
+                {
+                    return;
+                }
+
+                Log.Debug($"检查抖音直播评论任务状态...Status={self.Status}");
+
+                self.Status = self.CheckTaskStatus();
+
+                switch (self.Status)
+                {
+                    case -1:
+                    {
+                        // 接口请求出错
+                        Log.Debug($"检查抖音直播评论任务状态 - 抖音接口请求出错");
+                        break;
+                    }
+                    case 1:
+                    {
+                        // 数据推送回调任务不存在
+                        Log.Debug($"检查抖音直播评论任务状态 - 任务已经被删除,可能是因为主播取消挂载/已关播");
+                        break;
+                    }
+                    case 2:
+                    {
+                        // 数据推送回调任务未启动则启动
+                        self.StartTask();
+                        break;
+                    }
+                    case 3:
+                        // 数据推送回调任务运行中,不处理
+                        break;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 启动评论推送任务
+        /// </summary>
+        /// <param name="self"></param>
+        private static void StartTask(this MapDouyinLiveCommentComponent self)
+        {
+            // 请求头
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            head.Add("access-token", self.GetParent<Map>().AccessToken);
+            // 参数
+            JObject param = new JObject();
+            param.Add("roomid", self.GetParent<Map>().RoomId.ToString());
+            param.Add("appid", DouyinConst.Appid);
+            param.Add("msg_type", "live_comment");
+
+            string str = HttpHelper.PostRequestByDouyin(DouyinConst.StartTaskUrl, head, param);
+
+            if (string.IsNullOrEmpty(str))
+            {
+                Log.Error($"启动评论推送任务 - StartTaskUrl 请求失败...返回为null");
+                return;
+            }
+
+            JObject jObject = JObject.Parse(str);
+
+            int errNo = Convert.ToInt32(jObject.SelectToken("err_no"));
+
+            if (errNo != 0)
+            {
+                Log.Error($"启动评论推送任务 - StartTaskUrl 请求成功...返回错误:{errNo}");
+                return;
+            }
+
+            self.LogId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("logid"));
+            self.TaskId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("task_id"));
+        }
+
+        /// <summary>
+        /// 停止评论推送任务
+        /// </summary>
+        /// <param name="self"></param>
+        private static void StopTask(this MapDouyinLiveCommentComponent self)
+        {
+            // 请求头
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            head.Add("access-token", self.GetParent<Map>().AccessToken);
+            // 参数
+            JObject param = new JObject();
+            param.Add("roomid", self.GetParent<Map>().RoomId.ToString());
+            param.Add("appid", DouyinConst.Appid);
+            param.Add("msg_type", "live_comment");
+
+            string str = HttpHelper.PostRequestByDouyin(DouyinConst.StopTaskUrl, head, param);
+
+            if (string.IsNullOrEmpty(str))
+            {
+                Log.Error($"停止评论推送任务 - StopTaskUrl 请求失败...返回为null");
+                return;
+            }
+
+            JObject jObject = JObject.Parse(str);
+
+            int errNo = Convert.ToInt32(jObject.SelectToken("err_no"));
+
+            if (errNo != 0)
+            {
+                Log.Error($"停止评论推送任务 - StopTaskUrl 请求成功...返回错误:{errNo}");
+                return;
+            }
+
+            self.LogId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("logid"));
+        }
+
+        /// <summary>
+        /// 检查点赞推送任务状态 (1-任务不存在, 2-任务未启动, 3-任务运行中)
+        /// </summary>
+        /// <param name="self"></param>
+        /// <returns></returns>
+        private static int CheckTaskStatus(this MapDouyinLiveCommentComponent self)
+        {
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            head.Add("access-token", self.GetParent<Map>().AccessToken);
+            // 参数
+            Dictionary<string, string> param = new Dictionary<string, string>();
+            param.Add("roomid", self.GetParent<Map>().RoomId.ToString());
+            param.Add("appid", DouyinConst.Appid);
+            param.Add("msg_type", "live_comment");
+
+            string str = HttpHelper.GetRequestByDouyin(DouyinConst.CheckTaskUrl, head, param);
+
+            if (string.IsNullOrEmpty(str))
+            {
+                Log.Error($"检查评论推送任务状态 - CheckTaskUrl 请求失败...返回为null");
+                return -1;
+            }
+
+            JObject jObject = JObject.Parse(str);
+
+            int errNo = Convert.ToInt32(jObject.SelectToken("err_no"));
+
+            if (errNo != 0)
+            {
+                Log.Error($"检查评论推送任务状态 - CheckTaskUrl 请求成功...返回错误:{errNo}");
+                return -1;
+            }
+
+            self.LogId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("logid"));
+            return Convert.ToInt32(jObject.SelectToken("data").SelectToken("status"));
+        }
+    }
+}

+ 179 - 0
DotNet/Hotfix/Scenes/Game/Map/MapDouyinLiveLikeComponentSystem.cs

@@ -0,0 +1,179 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json.Linq;
+
+namespace ET.Server
+{
+    [FriendOf(typeof (MapDouyinLiveLikeComponent))]
+    public static class MapDouyinLiveLikeComponentSystem
+    {
+        public class MapDouyinLiveLikeComponentAwakeSystem: AwakeSystem<MapDouyinLiveLikeComponent>
+        {
+            protected override void Awake(MapDouyinLiveLikeComponent self)
+            {
+                Log.Info($"创建抖音直播点赞任务组件...");
+                // self.StartTask();
+            }
+        }
+
+        public class MapDouyinLiveLikeComponentDestroySystem: DestroySystem<MapDouyinLiveLikeComponent>
+        {
+            protected override void Destroy(MapDouyinLiveLikeComponent self)
+            {
+                Log.Info($"销毁抖音直播点赞任务组件");
+                self.StopTask();
+            }
+        }
+
+        public class MapDouyinLiveLikeComponentUpdateSystem: UpdateSystem<MapDouyinLiveLikeComponent>
+        {
+            protected override void Update(MapDouyinLiveLikeComponent self)
+            {
+                // 运行中状态
+                if (self.Status == 3)
+                {
+                    return;
+                }
+
+                Log.Debug($"检查抖音直播点赞任务状态...Status={self.Status}");
+
+                self.Status = self.CheckTaskStatus();
+
+                switch (self.Status)
+                {
+                    case -1:
+                    {
+                        // 接口请求出错
+                        Log.Debug($"检查抖音直播点赞任务状态 - 抖音接口请求出错");
+                        break;
+                    }
+                    case 1:
+                    {
+                        // 数据推送回调任务不存在
+                        Log.Debug($"检查抖音直播点赞任务状态 - 任务已经被删除,可能是因为主播取消挂载/已关播");
+                        break;
+                    }
+                    case 2:
+                    {
+                        // 数据推送回调任务未启动则启动
+                        self.StartTask();
+                        break;
+                    }
+                    case 3:
+                        // 数据推送回调任务运行中,不处理
+                        break;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 启动点赞推送任务
+        /// </summary>
+        /// <param name="self"></param>
+        private static void StartTask(this MapDouyinLiveLikeComponent self)
+        {
+            // 请求头
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            head.Add("access-token", self.GetParent<Map>().AccessToken);
+            // 参数
+            JObject param = new JObject();
+            param.Add("roomid", self.GetParent<Map>().RoomId.ToString());
+            param.Add("appid", DouyinConst.Appid);
+            param.Add("msg_type", "live_like");
+
+            string str = HttpHelper.PostRequestByDouyin(DouyinConst.StartTaskUrl, head, param);
+
+            if (string.IsNullOrEmpty(str))
+            {
+                Log.Error($"启动点赞推送任务 - StartTaskUrl 请求失败...返回为null");
+                return;
+            }
+
+            JObject jObject = JObject.Parse(str);
+
+            int errNo = Convert.ToInt32(jObject.SelectToken("err_no"));
+
+            if (errNo != 0)
+            {
+                Log.Error($"启动点赞推送任务 - StartTaskUrl 请求成功...返回错误:{errNo}");
+                return;
+            }
+
+            self.LogId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("logid"));
+            self.TaskId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("task_id"));
+        }
+
+        /// <summary>
+        /// 停止点赞推送任务
+        /// </summary>
+        /// <param name="self"></param>
+        private static void StopTask(this MapDouyinLiveLikeComponent self)
+        {
+            // 请求头
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            head.Add("access-token", self.GetParent<Map>().AccessToken);
+            // 参数
+            JObject param = new JObject();
+            param.Add("roomid", self.GetParent<Map>().RoomId.ToString());
+            param.Add("appid", DouyinConst.Appid);
+            param.Add("msg_type", "live_like");
+
+            string str = HttpHelper.PostRequestByDouyin(DouyinConst.StopTaskUrl, head, param);
+
+            if (string.IsNullOrEmpty(str))
+            {
+                Log.Error($"停止点赞推送任务 - StopTaskUrl 请求失败...返回为null");
+                return;
+            }
+
+            JObject jObject = JObject.Parse(str);
+
+            int errNo = Convert.ToInt32(jObject.SelectToken("err_no"));
+
+            if (errNo != 0)
+            {
+                Log.Error($"停止点赞推送任务 - StopTaskUrl 请求成功...返回错误:{errNo}");
+                return;
+            }
+
+            self.LogId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("logid"));
+        }
+
+        /// <summary>
+        /// 检查点赞推送任务状态 (1-任务不存在, 2-任务未启动, 3-任务运行中)
+        /// </summary>
+        /// <param name="self"></param>
+        /// <returns></returns>
+        private static int CheckTaskStatus(this MapDouyinLiveLikeComponent self)
+        {
+            Dictionary<string, string> head = new Dictionary<string, string>();
+            head.Add("access-token", self.GetParent<Map>().AccessToken);
+            // 参数
+            Dictionary<string, string> param = new Dictionary<string, string>();
+            param.Add("roomid", self.GetParent<Map>().RoomId.ToString());
+            param.Add("appid", DouyinConst.Appid);
+            param.Add("msg_type", "live_like");
+
+            string str = HttpHelper.GetRequestByDouyin(DouyinConst.CheckTaskUrl, head, param);
+
+            if (string.IsNullOrEmpty(str))
+            {
+                Log.Error($"检查点赞推送任务状态 - CheckTaskUrl 请求失败...返回为null");
+                return -1;
+            }
+
+            JObject jObject = JObject.Parse(str);
+
+            int errNo = Convert.ToInt32(jObject.SelectToken("err_no"));
+
+            if (errNo != 0)
+            {
+                Log.Error($"检查点赞推送任务状态 - CheckTaskUrl 请求成功...返回错误:{errNo}");
+                return -1;
+            }
+
+            self.LogId = Convert.ToInt64(jObject.SelectToken("data").SelectToken("logid"));
+            return Convert.ToInt32(jObject.SelectToken("data").SelectToken("status"));
+        }
+    }
+}

+ 11 - 14
DotNet/Hotfix/Scenes/Game/Map/MapEventComponentSystem.cs

@@ -83,24 +83,21 @@ namespace ET.Server
 
             map.IsGameOver = true;
 
-            if (map.Players is not { Count: > 0 })
+            if (map.Player == null)
             {
                 return;
             }
 
-            foreach (WNPlayer player in map.Players.Values.Where(player => player != null))
-            {
-                // 记录玩家历史
-                map.SyncPlayerHistoryData(player);
-                // 战斗服场景玩家离开
-                map.PlayerLeaveRequest(player, false);
-                // 本地场景移除玩家
-                map.RemovePlayer(player, false);
-                // 战斗服结束场景
-                map.GetZoneManager().destroyZoneRequest(map.Id.ToString());
-
-                player.Map = null;
-            }
+            // 记录玩家历史
+            map.SyncPlayerHistoryData(map.Player);
+            // 战斗服场景玩家离开
+            map.PlayerLeaveRequest(map.Player, false);
+            // 本地场景移除玩家
+            map.RemovePlayer(map.Player, false);
+            // 战斗服结束场景
+            map.GetZoneManager().destroyZoneRequest(map.Id.ToString());
+
+            map.Player.Map = null;
         }
 
         /// <summary>

+ 3 - 3
DotNet/Hotfix/Scenes/Game/Map/MapRankComponentSystem.cs

@@ -97,10 +97,10 @@ namespace ET.Server
             }
 
             self.LastInfoListProto = infoListProto;
-
-            foreach (WNPlayer player in map.Players.Values)
+            // 推送客户端
+            if (map.Player != null)
             {
-                MessageHelper.SendToClient(player, new G2C_RankNotify() { InfoList = infoListProto });
+                MessageHelper.SendToClient(map.Player, new G2C_RankNotify() { InfoList = infoListProto });
             }
         }
 

+ 16 - 13
DotNet/Hotfix/Scenes/Game/Map/MapReliveTimeComponentSystem.cs

@@ -11,7 +11,6 @@ namespace ET.Server
             protected override void Awake(MapReliveTimeComponent self)
             {
                 Log.Info($"创建单位玩家复活组件...");
-                self.ReliveDatas = new List<Struct.UnitPlayerReliveData>();
             }
         }
 
@@ -19,38 +18,42 @@ namespace ET.Server
         {
             protected override void Update(MapReliveTimeComponent self)
             {
-                if (self.ReliveDatas.Count <= 0)
+                Map map = self.GetParent<Map>();
+
+                if (map.UnitPlayers.Count <= 0)
                 {
                     return;
                 }
 
-                for (int i = self.ReliveDatas.Count - 1; i >= 0; i--)
+                long now = TimeHelper.ServerNow();
+
+                foreach (Struct.UnitPlayerData data in map.UnitPlayers.Values)
                 {
-                    Struct.UnitPlayerReliveData data = self.ReliveDatas[i];
                     if (data == null)
                     {
                         continue;
                     }
-
-                    if (TimeHelper.ServerNow() < data.ReliveTime)
+                    // 过滤一下纯点赞或刷礼物的玩家
+                    if (data.TemplateId <= 0 || data.ObjId <= 0)
+                    {
+                        continue;
+                    }
+                    // 过滤一下已复活的玩家
+                    if (data.ReliveTime <= 0 || now < data.ReliveTime)
                     {
                         continue;
                     }
-
                     // 复活(添加一个单位)
                     Struct.MonsterUnit unit = new Struct.MonsterUnit();
-                    unit.id = data.ID;
+                    unit.id = data.TemplateId;
                     unit.force = 1;
                     unit.x = data.x;
                     unit.y = data.y;
                     unit.autoGuard = true;
 
-                    int objId = data.Map.AddUnits(unit, true).GetResult();
-
-                    data.Map.AddUnitObjId(data.OpenId, objId);
-                    data.Map.AddUnitPlayer(data.OpenId, data.ID);
+                    data.ObjId = data.Map.AddUnits(unit, true).GetResult();
 
-                    self.ReliveDatas.Remove(data);
+                    data.ReliveTime = 0;
                 }
             }
         }

+ 50 - 52
DotNet/Hotfix/Scenes/Game/Map/MapSystem.cs

@@ -10,27 +10,33 @@ namespace ET.Server
     [FriendOf(typeof (BattleIceAgentComponent))]
     public static class MapSystem
     {
-        public class MapAwakeSystem: AwakeSystem<Map, JObject>
+        public class MapAwakeSystem: AwakeSystem<Map, JObject, WNPlayer>
         {
-            protected override void Awake(Map self, JObject opts)
+            protected override void Awake(Map self, JObject opts, WNPlayer player)
             {
-                self.createTime = TimeHelper.ServerNow();
-
                 Log.Debug($"create area opts:{JsonConvert.SerializeObject(opts, Formatting.Indented)}");
+
+                GameDouyinComponent gameDouyinComponent = player.DomainScene().GetComponent<GameDouyinComponent>();
+                self.AccessToken = gameDouyinComponent.AccessToken;
+                self.RoomId = player.GetRoomId();
+                self.createTime = TimeHelper.ServerNow();
                 self.LogicServerId = opts.SelectToken("logicServerId") != null? Convert.ToInt32(opts.SelectToken("logicServerId")) : 0;
                 self.MapId = Convert.ToInt32(opts.SelectToken("areaId"));
                 self.Prop = MapConfigCategory.Instance.Get(self.MapId);
                 self.Type = self.Prop.Type;
-                self.UnitPlayers = new Dictionary<string, int>();
-                self.UnitObjIds = new Dictionary<string, int>();
-                self.UnitPlayerLikes = new Dictionary<string, int>();
+                self.Player = player;
+                self.UnitPlayers = new Dictionary<string, Struct.UnitPlayerData>();
 
                 // 战斗服事件组件
                 self.AddComponent<MapEventComponent>();
                 // 场景复活组件
-                self.AddComponent<MapReliveTimeComponent>();
+                // self.AddComponent<MapReliveTimeComponent>();
                 // 场景排行榜组件
                 self.AddComponent<MapRankComponent>();
+                // 场景抖音直播评论组件
+                self.AddComponent<MapDouyinLiveCommentComponent>();
+                // 场景抖音直播点赞组件
+                self.AddComponent<MapDouyinLiveLikeComponent>();
             }
         }
 
@@ -82,7 +88,7 @@ namespace ET.Server
         /// <returns></returns>
         public static WNPlayer GetPlayer(this Map self, long playerId)
         {
-            return self.Players.TryGetValue(playerId, out WNPlayer player) ? player : null;
+            return self.Player;
         }
 
         /// <summary>
@@ -107,7 +113,7 @@ namespace ET.Server
             WNPlayer actorPlayer = self.GetPlayer(player.GetId());
             if (actorPlayer != null)
             {
-                self.Players.Remove(player.GetId());
+                // self.Players.Remove(player.GetId());
             }
             // 重置进入场景标识
             player.GetComponent<PlayerTempDataComponent>().MapData.ready = false;
@@ -148,9 +154,9 @@ namespace ET.Server
         public static void AddPlayer(this Map self, WNPlayer player)
         {
             Log.Info($"addPlayer: playerId={player.GetId()}, mapId={self.MapId}, ip={player.Session.RemoteAddress}");
-            self.SetForce(player);
-            self.Players.TryAdd(player.GetId(), player);
             player.Map = self;
+            self.SetForce(player);
+            self.Player = player;
         }
 
         /// <summary>
@@ -285,56 +291,48 @@ namespace ET.Server
         }
 
         /// <summary>
-        /// 增加单位玩家
+        /// 增加单位玩家本地数据
         /// </summary>
         /// <param name="self"></param>
         /// <param name="openId"></param>
+        /// <param name="templateId"></param>
         /// <param name="objId"></param>
-        public static void AddUnitObjId(this Map self, string openId, int objId)
+        /// <param name="likes"></param>
+        public static Struct.UnitPlayerData AddUnitPlayer(this Map self, string openId, int templateId, int objId, long likes)
         {
-            if (objId <= 0 || self.IsGameOver())
+            if (string.IsNullOrEmpty(openId) || templateId <= 0 || objId <= 0 || self.IsGameOver())
             {
-                return;
+                return null;
             }
 
-            if (!self.UnitObjIds.TryAdd(openId, objId))
-            {
-                self.UnitObjIds[openId] = objId;
-            }
-        }
+            Struct.UnitPlayerData unitPlayerData = null;
 
-        /// <summary>
-        /// 获取单位玩家objId
-        /// </summary>
-        /// <param name="self"></param>
-        /// <param name="openId"></param>
-        public static int GetUnitObjId(this Map self, string openId)
-        {
-            if (self.UnitObjIds.TryGetValue(openId, out int objId))
+            if (self.UnitPlayers.ContainsKey(openId))
             {
-                return objId;
-            }
-
-            return 0;
-        }
+                unitPlayerData = self.UnitPlayers[openId];
+                unitPlayerData.TemplateId = templateId;
+                unitPlayerData.ObjId = objId;
+                unitPlayerData.Map = self;
 
-        /// <summary>
-        /// 添加单位玩家
-        /// </summary>
-        /// <param name="self"></param>
-        /// <param name="openId"></param>
-        /// <param name="templateId"></param>
-        public static void AddUnitPlayer(this Map self, string openId, int templateId)
-        {
-            if (templateId <= 0 || self.IsGameOver())
-            {
-                return;
+                self.UnitPlayers[openId] = unitPlayerData;
             }
-
-            if (!self.UnitPlayers.TryAdd(openId, templateId))
+            else
             {
-                self.UnitPlayers[openId] = templateId;
+                unitPlayerData = new Struct.UnitPlayerData();
+                unitPlayerData.OpenId = openId;
+                unitPlayerData.TemplateId = templateId;
+                unitPlayerData.ObjId = objId;
+                unitPlayerData.Level = 1;
+                unitPlayerData.Likes = 0;
+                unitPlayerData.ReliveTime = 0;
+                unitPlayerData.x = 0;
+                unitPlayerData.y = 0;
+                unitPlayerData.Map = self;
+
+                self.UnitPlayers.TryAdd(openId, unitPlayerData);
             }
+
+            return unitPlayerData;
         }
 
         /// <summary>
@@ -343,14 +341,14 @@ namespace ET.Server
         /// <param name="self"></param>
         /// <param name="openId"></param>
         /// <returns></returns>
-        public static int GetUnitTemplateId(this Map self, string openId)
+        public static Struct.UnitPlayerData GetUnitPlayerData(this Map self, string openId)
         {
-            if (self.UnitPlayers.TryGetValue(openId, out int templateId))
+            if (self.UnitPlayers.TryGetValue(openId, out Struct.UnitPlayerData unitPlayer))
             {
-                return templateId;
+                return unitPlayer;
             }
 
-            return 0;
+            return null;
         }
 
         /// <summary>

+ 1 - 1
DotNet/Hotfix/Scenes/Game/Player/PlayerSystem.cs

@@ -71,7 +71,7 @@ namespace ET.Server
         /// </summary>
         /// <param name="self"></param>
         /// <returns></returns>
-        public static string GetRoomId(this WNPlayer self)
+        public static long GetRoomId(this WNPlayer self)
         {
             return self.GetComponent<PlayerDataComponent>().Data.RoomId;
         }

+ 4 - 6
DotNet/Hotfix/Scenes/Game/Session/SessionPlayerComponentSystem.cs

@@ -6,15 +6,13 @@ namespace ET.Server
     [FriendOf(typeof (SessionPlayerComponent))]
 	public static class SessionPlayerComponentSystem
 	{
-        public class SessionPlayerComponentAwakeSystem: AwakeSystem<SessionPlayerComponent>
+        public class SessionPlayerComponentAwakeSystem: AwakeSystem<SessionPlayerComponent, PlayerInfo>
         {
-            /// <summary>
-            /// session玩家组件创建
-            /// </summary>
-            /// <param name="self"></param>
-            protected override void Awake(SessionPlayerComponent self)
+            protected override void Awake(SessionPlayerComponent self, PlayerInfo playerInfo)
             {
                 Log.Info($"创建session玩家绑定组件...");
+                self.PlayerInfo = playerInfo;
+                self.PlayerId = playerInfo.Id;
             }
         }
 

+ 1 - 1
DotNet/Hotfix/Scenes/Realm/Handler/C2R_LoginHandler.cs

@@ -41,7 +41,7 @@ namespace ET.Server
 
                 foreach (StartSceneConfig config in gameList)
                 {
-                    response.Address.Add(config.InnerIPOutPort.ToString());
+                    response.Address.Add(config.OuterIPPort.ToString());
                 }
             }
 

+ 32 - 85
DotNet/Hotfix/Scenes/Router/HttpDouyinApiCallbackHandler.cs

@@ -1,113 +1,60 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using Newtonsoft.Json.Linq;
+using System.Net;
 
 namespace ET.Server
 {
     /// <summary>
-    /// 抖音api回调, 评论添加玩家
+    /// 抖音推送数据, http回调
     /// </summary>
-    [HttpHandler(SceneType.RouterManager, "/addPlayer")]
+    [HttpHandler(SceneType.RouterManager, "/tk")]
     public class HttpCommentHandler: IHttpHandler
     {
         public async ETTask Handle(Entity domain, HttpListenerContext context)
         {
-            Log.Debug($"收到http 评论添加玩家回调...");
+            string xroomId = context.Request.Headers["x-roomid"];
 
-            HttpDouyinApiCallbackResponse response = new HttpDouyinApiCallbackResponse();
-
-            string bodyStr = await HttpHelper.GetBodyParameter(context);
-            // 判断body是否为空
-            if (string.IsNullOrEmpty(bodyStr))
+            if (string.IsNullOrEmpty(xroomId))
             {
-                response.Error = ErrorCode.ERR_ParameterError;
-                response.Message = "参数错误";
-                HttpHelper.Response(context, response);
+                Log.Error($"抖音推送数据http回调 找不到请求头:x-roomid");
                 return;
             }
 
-            JObject parameter = JObject.Parse(bodyStr);
-
-            string openId = Convert.ToString(parameter.SelectToken("openId"));
-            long roomId = Convert.ToInt64(parameter.SelectToken("roomId"));
-            int serverId = Convert.ToInt32(parameter.SelectToken("serverId"));
+            string msgType = context.Request.Headers["x-msg-type"];
 
-            Log.Debug($"body参数: openid={openId}, roomId={roomId}, serverId={serverId}");
-            // 判断参数
-            if (string.IsNullOrEmpty(openId) || roomId <= 0 || serverId <= 0)
+            if (string.IsNullOrEmpty(msgType))
             {
-                response.Error = ErrorCode.ERR_ParameterError;
-                response.Message = "参数错误";
-                HttpHelper.Response(context, response);
+                Log.Error($"抖音推送数据http回调 找不到请求头:x-msg-type");
                 return;
             }
 
-            List<StartSceneConfig> list = RealmGateAddressHelper.GetAllGame(1);
+            long roomId = long.Parse(xroomId);
 
-            foreach (StartSceneConfig config in list.Where(config => config != null && config.Id == serverId))
+            switch (msgType)
             {
-                MessageHelper.SendActor(config.InstanceId, new R2G_AddUnitsToMap() { OpenId = openId, RoomId = roomId});
-                break;
+                case "live_comment":
+                {
+                    // 直播间评论
+                    Log.Debug($"收到抖音推送http回调 评论添加玩家回调...");
+                    DouyinCallBackHelper.LiveComment(domain, context, roomId);
+                    break;
+                }
+                case "live_gift":
+                {
+                    // 直播间送礼
+                    Log.Debug($"收到抖音推送http回调 直播间刷礼物回调...");
+                    DouyinCallBackHelper.LiveGift(domain, context, roomId);
+                    break;
+                }
+                case "live_like":
+                {
+                    // 直播间点赞
+                    Log.Debug($"收到抖音推送http回调 点赞10次增加等级回调...");
+                    DouyinCallBackHelper.LiveLike(domain, context, roomId);
+                    break;
+                }
             }
 
-            HttpHelper.Response(context, response);
             await ETTask.CompletedTask;
         }
     }
 
-    /// <summary>
-    /// 抖音api回调, 点赞10次增加等级
-    /// </summary>
-    [HttpHandler(SceneType.RouterManager, "/like")]
-    public class HttpLikeHandler: IHttpHandler
-    {
-        public async ETTask Handle(Entity domain, HttpListenerContext context)
-        {
-            Log.Debug($"收到http 点赞10次增加等级回调...");
-
-            HttpDouyinApiCallbackResponse response = new HttpDouyinApiCallbackResponse();
-
-            string bodyStr = await HttpHelper.GetBodyParameter(context);
-
-            if (string.IsNullOrEmpty(bodyStr))
-            {
-                response.Error = ErrorCode.ERR_ParameterError;
-                response.Message = "参数错误";
-                HttpHelper.Response(context, response);
-                return;
-            }
-
-            JObject parameter = JObject.Parse(bodyStr);
-
-            string openId = Convert.ToString(parameter.SelectToken("openId"));
-            long roomId = Convert.ToInt64(parameter.SelectToken("roomId"));
-            int serverId = Convert.ToInt32(parameter.SelectToken("serverId"));
-            // 点赞数
-            int likes = Convert.ToInt32(parameter.SelectToken("likes"));
-            likes = 30;
-
-            Log.Debug($"body参数: openid={openId}, roomId={roomId}, serverId={serverId}, likes={likes}");
-            // 判断参数
-            if (string.IsNullOrEmpty(openId) || roomId <= 0 || serverId <= 0 || likes < 0)
-            {
-                response.Error = ErrorCode.ERR_ParameterError;
-                response.Message = "参数错误";
-                HttpHelper.Response(context, response);
-                return;
-            }
-
-            List<StartSceneConfig> list = RealmGateAddressHelper.GetAllGame(1);
-
-            foreach (StartSceneConfig config in list.Where(config => config != null && config.Id == serverId))
-            {
-                MessageHelper.SendActor(config.InstanceId, new R2G_AddLevel() { OpenId = openId, RoomId = roomId, Likes = likes});
-                break;
-            }
-
-            HttpHelper.Response(context, response);
-            await ETTask.CompletedTask;
-        }
-    }
 }

+ 1 - 1
DotNet/Hotfix/Scenes/Router/HttpGetRouterHandler.cs

@@ -15,7 +15,7 @@ namespace ET.Server
             response.Routers = new List<string>();
             foreach (StartSceneConfig startSceneConfig in StartSceneConfigCategory.Instance.Realms)
             {
-                response.Realms.Add(startSceneConfig.InnerIPOutPort.ToString());
+                response.Realms.Add(startSceneConfig.OuterIPPort.ToString());
             }
             foreach (StartSceneConfig startSceneConfig in StartSceneConfigCategory.Instance.Routers)
             {

+ 18 - 0
DotNet/Model/Const/ConstGame.cs

@@ -21,6 +21,24 @@ namespace ET.Server
         public const int maxNum = 4; // 最多角色数量
     }
 
+    public static class DouyinConst
+    {
+        /** 小程序 ID **/
+        public const string Appid = "tt1f2a69978016076d10";
+        /** 小程序的 APP Secret,可以在开发者后台获取 **/
+        public const string Secret = "0a2d84c09dcab30b26a82da1c93da78544ad6f6e";
+        /** POST 获取开放能力接口的调用凭证 **/
+        public const string GetAccessTokenUrl = "https://developer.toutiao.com/api/apps/v2/token";
+        /** POST 获取直播间信息 **/
+        public const string GetLiveInfoUrl = "https://webcast.bytedance.com/api/webcastmate/info";
+        /** POST 启动抖音推送回调任务 **/
+        public const string StartTaskUrl = "https://webcast.bytedance.com/api/live_data/task/start";
+        /** POST 停止抖音推送回调任务 **/
+        public const string StopTaskUrl = "https://webcast.bytedance.com/api/live_data/task/stop";
+        /** GET 获取任务状态 **/
+        public const string CheckTaskUrl = "https://webcast.bytedance.com/api/live_data/task/get";
+    }
+
     /** 通知战斗事件信息 */
     public static class NotifyBSName
     {

+ 27 - 11
DotNet/Model/Const/Struct.cs

@@ -250,18 +250,24 @@
         }
 
         /// <summary>
-        /// 玩家单位复活数据
+        /// 玩家单位数据
         /// </summary>
-        public class UnitPlayerReliveData
+        public class UnitPlayerData
         {
-            /** 复活场景 **/
-            public Map Map { get; set; }
-
-            /** 复活的openId **/
+            /** 玩家单位的openId **/
             public string OpenId { get; set; }
 
-            /** 复活单位模板id **/
-            public int ID { get; set; }
+            /** 玩家单位模板id **/
+            public int TemplateId { get; set; }
+
+            /** 战斗服objId **/
+            public int ObjId { get; set; }
+
+            /** 等级 (最大为3) **/
+            public int Level { get; set; }
+
+            /** 点赞数 **/
+            public long Likes { get; set; }
 
             /** 复活时间 **/
             public long ReliveTime { get; set; }
@@ -272,18 +278,28 @@
             /** 复活位置y **/
             public int y { get; set; }
 
-            public UnitPlayerReliveData()
+            /** 场景 **/
+            public Map Map { get; set; }
+
+            public UnitPlayerData()
             {
             }
 
-            public UnitPlayerReliveData(Map map, string openId, int id, long time, int x, int y)
+            public UnitPlayerData(string openId, int objId, Map map)
             {
+                this.OpenId = openId;
+                this.ObjId = objId;
                 this.Map = map;
+            }
+
+            public UnitPlayerData(string openId, int templateId, long time, int x, int y, Map map)
+            {
                 this.OpenId = openId;
-                this.ID = id;
+                this.TemplateId = templateId;
                 this.ReliveTime = time;
                 this.x = x;
                 this.y = y;
+                this.Map = map;
             }
         }
 

+ 26 - 1
DotNet/Model/Generate/Message/InnerMessage_S_20001.cs

@@ -364,7 +364,31 @@ namespace ET
 		public long RoomId { get; set; }
 
 		[ProtoMember(3)]
-		public int Likes { get; set; }
+		public long Likes { get; set; }
+
+	}
+
+	[Message(InnerMessage.R2G_GiveGift)]
+	[ProtoContract]
+	public partial class R2G_GiveGift: ProtoObject, IActorMessage
+	{
+		[ProtoMember(1)]
+		public string OpenId { get; set; }
+
+		[ProtoMember(2)]
+		public long RoomId { get; set; }
+
+		[ProtoMember(3)]
+		public string NickName { get; set; }
+
+		[ProtoMember(4)]
+		public string GiftId { get; set; }
+
+		[ProtoMember(5)]
+		public long GiftNum { get; set; }
+
+		[ProtoMember(6)]
+		public long GiftValue { get; set; }
 
 	}
 
@@ -394,5 +418,6 @@ namespace ET
 		 public const ushort M2M_UnitTransferResponse = 20023;
 		 public const ushort R2G_AddUnitsToMap = 20024;
 		 public const ushort R2G_AddLevel = 20025;
+		 public const ushort R2G_GiveGift = 20026;
 	}
 }

+ 27 - 7
DotNet/Model/Generate/Message/OuterMessage_C_10001.cs

@@ -1,4 +1,4 @@
-using ET;
+using ET;
 using ProtoBuf;
 using System.Collections.Generic;
 namespace ET
@@ -350,9 +350,6 @@ namespace ET
 		[ProtoMember(1)]
 		public int RpcId { get; set; }
 
-		[ProtoMember(2)]
-		public string RoomId { get; set; }
-
 	}
 
 	[Message(OuterMessage.R2C_Login)]
@@ -368,9 +365,6 @@ namespace ET
 		[ProtoMember(3)]
 		public string Message { get; set; }
 
-		[ProtoMember(4)]
-		public string Token { get; set; }
-
 // 服务器列表
 		[ProtoMember(5)]
 		public List<string> Address { get; set; }
@@ -755,6 +749,30 @@ namespace ET
 
 	}
 
+	[Message(OuterMessage.G2C_LikeInfoPush)]
+	[ProtoContract]
+	public partial class G2C_LikeInfoPush: ProtoObject, IActorMessage
+	{
+		[ProtoMember(1)]
+		public long TotalNum { get; set; }
+
+		[ProtoMember(2)]
+		public long ConfigNum { get; set; }
+
+	}
+
+	[Message(OuterMessage.G2C_GiftInfoPush)]
+	[ProtoContract]
+	public partial class G2C_GiftInfoPush: ProtoObject, IActorMessage
+	{
+		[ProtoMember(1)]
+		public string NickName { get; set; }
+
+		[ProtoMember(2)]
+		public long GiftNum { get; set; }
+
+	}
+
 	public static class OuterMessage
 	{
 		 public const ushort HttpGetRouterResponse = 10002;
@@ -808,5 +826,7 @@ namespace ET
 		 public const ushort HttpGetVersionResponse = 10050;
 		 public const ushort C2G_BattleNotify = 10051;
 		 public const ushort G2C_BattleNotify = 10052;
+		 public const ushort G2C_LikeInfoPush = 10053;
+		 public const ushort G2C_GiftInfoPush = 10054;
 	}
 }

+ 5 - 1
DotNet/Model/Scenes/Game/DBEntity/PlayerInfo.cs

@@ -6,7 +6,7 @@ namespace ET.Server
     public class PlayerInfo: Entity, IAwake
     {
         /** 直播间id **/
-        public string RoomId { get; set; }
+        public long RoomId { get; set; }
         /** 服务器id **/
         public int LogicServerId { get; set; }
         /** 创建时间 **/
@@ -19,6 +19,10 @@ namespace ET.Server
         /** 玩家类型 0-正常玩家 1-ai **/
         public int PlayerType { get; set; }
 
+        /** openId **/
+        public string AnchorOpenId { get; set; }
+        /** 头像 **/
+        public string AvatarUrl { get; set; }
         /** 名称 **/
         public string Name { get; set; }
         /** 性别 **/

+ 11 - 0
DotNet/Model/Scenes/Game/GameDouyinComponent.cs

@@ -0,0 +1,11 @@
+namespace ET.Server
+{
+    [ComponentOf(typeof (Scene))]
+    public class GameDouyinComponent: Entity, IAwake, IDestroy, IUpdate
+    {
+        /** 抖音接口全局唯一调用凭据 **/
+        public string AccessToken { get; set; }
+        /** 有效时间 (时间戳) **/
+        public long AccessTokenTime { get; set; }
+    }
+}

+ 12 - 10
DotNet/Model/Scenes/Game/Map/Map.cs

@@ -7,8 +7,12 @@ namespace ET.Server
     /// 游戏场景实体
     /// </summary>
     [ChildOf(typeof(GameMapComponent))]
-    public class Map: Entity, IAwake<JObject>, IDestroy
+    public class Map: Entity, IAwake<JObject, WNPlayer>, IDestroy
     {
+        /** 房间id **/
+        public long RoomId { get; set; }
+        /** 抖音接口全局唯一调用凭据 **/
+        public string AccessToken { get; set; }
         /** 地图id **/
         public int MapId { get; set; }
         /** 场景玩法类型 **/
@@ -21,15 +25,13 @@ namespace ET.Server
         public int LogicServerId { get; set; }
         /** 副本创建时间 **/
         public long createTime { get; set; }
-        /** 场景里的角色(主播) [key:playerId, value:主播玩家实体] **/
-        [StaticField]
-        public Dictionary<long, WNPlayer> Players = new Dictionary<long, WNPlayer>();
-        /** 场景里的单位玩家 [key:openId, value:模板id] **/
-        public Dictionary<string, int> UnitPlayers { get; set; }
-        /** 场景中单位玩家objId列表 [key:openId, value:战斗服objId] **/
-        public Dictionary<string, int> UnitObjIds { get; set; }
-        /** 场景中单位玩家点赞数 [key:openId, value:点赞数] **/
-        public Dictionary<string, int> UnitPlayerLikes { get; set; }
+        /** 场景里的角色(主播) **/
+        public WNPlayer Player { get; set; }
+        /** 场景里的单位玩家 [key:openId, value:单位玩家数据] **/
+        public Dictionary<string, Struct.UnitPlayerData> UnitPlayers { get; set; }
+        /** 总点赞数 **/
+        public long TotalLikeNum { get; set; }
+
         /** 死亡的单位(塔) **/
         [StaticField]
         public List<int> DeadUnits = new List<int>();

+ 13 - 0
DotNet/Model/Scenes/Game/Map/MapDouyinLiveCommentComponent.cs

@@ -0,0 +1,13 @@
+namespace ET.Server
+{
+    [ComponentOf(typeof (Map))]
+    public class MapDouyinLiveCommentComponent: Entity, IAwake, IDestroy, IUpdate
+    {
+        /** 任务id **/
+        public long TaskId { get; set; }
+        /** 请求链路id, 用于出问题时提供给开平具体定位 **/
+        public long LogId { get; set; }
+        /** 任务运行状态 **/
+        public int Status { get; set; }
+    }
+}

+ 13 - 0
DotNet/Model/Scenes/Game/Map/MapDouyinLiveLikeComponent.cs

@@ -0,0 +1,13 @@
+namespace ET.Server
+{
+    [ComponentOf(typeof (Map))]
+    public class MapDouyinLiveLikeComponent: Entity, IAwake, IDestroy, IUpdate
+    {
+        /** 任务id **/
+        public long TaskId { get; set; }
+        /** 请求链路id, 用于出问题时提供给开平具体定位 **/
+        public long LogId { get; set; }
+        /** 任务运行状态 **/
+        public int Status { get; set; }
+    }
+}

+ 0 - 2
DotNet/Model/Scenes/Game/Map/MapReliveTimeComponent.cs

@@ -5,7 +5,5 @@ namespace ET.Server
     [ComponentOf(typeof (Map))]
     public class MapReliveTimeComponent: Entity, IAwake, IUpdate
     {
-        /** 单位玩家复活数据 **/
-        public List<Struct.UnitPlayerReliveData> ReliveDatas { get; set; }
     }
 }

+ 1 - 4
DotNet/Model/Scenes/Game/Session/SessionPlayerComponent.cs

@@ -3,11 +3,8 @@
 namespace ET.Server
 {
     [ComponentOf(typeof (Session))]
-    public class SessionPlayerComponent: Entity, IAwake, IDestroy
+    public class SessionPlayerComponent: Entity, IAwake<PlayerInfo>, IDestroy
     {
-        /** 直播间id **/
-        public string RoomId { get; set; }
-
         /** 角色id **/
         public long PlayerId { get; set; }
 

+ 26 - 0
Unity/Assets/Scripts/Codes/Model/Client/Generate/Message/OuterMessage_C_10001.cs

@@ -749,6 +749,30 @@ namespace ET
 
 	}
 
+	[Message(OuterMessage.G2C_LikeInfoPush)]
+	[ProtoContract]
+	public partial class G2C_LikeInfoPush: ProtoObject, IActorMessage
+	{
+		[ProtoMember(1)]
+		public long TotalNum { get; set; }
+
+		[ProtoMember(2)]
+		public long ConfigNum { get; set; }
+
+	}
+
+	[Message(OuterMessage.G2C_GiftInfoPush)]
+	[ProtoContract]
+	public partial class G2C_GiftInfoPush: ProtoObject, IActorMessage
+	{
+		[ProtoMember(1)]
+		public string NickName { get; set; }
+
+		[ProtoMember(2)]
+		public long GiftNum { get; set; }
+
+	}
+
 	public static class OuterMessage
 	{
 		 public const ushort HttpGetRouterResponse = 10002;
@@ -802,5 +826,7 @@ namespace ET
 		 public const ushort HttpGetVersionResponse = 10050;
 		 public const ushort C2G_BattleNotify = 10051;
 		 public const ushort G2C_BattleNotify = 10052;
+		 public const ushort G2C_LikeInfoPush = 10053;
+		 public const ushort G2C_GiftInfoPush = 10054;
 	}
 }