jeson_fxd 1 день назад
Родитель
Сommit
f867b1ff32

+ 46 - 39
server/src/server/OpenCards.Server.ArenaValor/ArenaManagerService.cs

@@ -1,25 +1,25 @@
 using DeepCore;
+using DeepCore.Protocol;
 using DeepCrystal.ORM;
 using DeepCrystal.ORM.Redis;
 using DeepCrystal.RPC;
+using OpenCards.Core.Data;
 using OpenCards.Core.ORM;
 using OpenCards.Server.Common;
 using OpenCards.Server.Common.Arena;
+using OpenCards.Server.Common.ORM;
+using OpenCards.Server.Common.RPC;
+using OpenCards.Server.Common.Statistic;
 using OpenCards.Server.Core;
+using OpenCards.Server.Core.ORM;
 using OpenCards.Server.Core.RPC;
+using OpenCards.Server.Core.Table;
+using OpenCards.Server.Core.Utils;
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
 using System.Threading.Tasks;
-using OpenCards.Server.Common.RPC;
-using OpenCards.Server.Core.Utils;
-using System.Diagnostics;
-using OpenCards.Server.Common.ORM;
-using OpenCards.Server.Core.Table;
-using OpenCards.Server.Common.Statistic;
-using OpenCards.Server.Core.ORM;
-using DeepCore.Protocol;
-using OpenCards.Core.Data;
 
 namespace OpenCards.Server.Arena
 {
@@ -111,16 +111,13 @@ namespace OpenCards.Server.Arena
                 config["OriginTime"] = createOriginTime.ToString();
                 config["RankActivityTime"] = rankActivityOriginTimeStr; //斗技场排名活动开始时间(兼容老服的老分组)
                 config["ArenaOriginTime"] = this.dataMapping.ArenaOriginTime.GetTimeStamp().ToString(); //斗技场管理服创服时间
-                var srv = await this.Provider.GetAsync(
-                    RpcUtils.GetArenaValorServiceAddress(ServerId, i, this.SelfAddress.ServiceNode));
+                var valorAddr = RpcUtils.GetArenaValorServiceAddress(ServerId, i, this.SelfAddress.ServiceNode);
+                var srv = await this.Provider.GetAsync(valorAddr);
                 if (srv != null)
                 {
-                    ServerUtils.StopServiceFunc?.Invoke(RpcUtils
-                        .GetArenaValorServiceAddress(ServerId, i, this.SelfAddress.ServiceNode).FullPath);
+                    ServerUtils.StopServiceFunc?.Invoke(valorAddr.FullPath);
                 }
-
-                await this.Provider.CreateAsync(
-                    RpcUtils.GetArenaValorServiceAddress(ServerId, i, this.SelfAddress.ServiceNode), config);
+                await this.Provider.CreateAsync(valorAddr, config);
             }
 
             if (this.dataMapping.ArenaValorCurrentID >= 1)
@@ -237,6 +234,10 @@ namespace OpenCards.Server.Arena
         {
             var rsp = new EnterArenaResponse();
 
+            bool pendingCreateService = false;
+            int pendingArenaID = 0;
+            DateTime pendingCreateNow = default;
+
             using (var lockasync = await _asyncDataLock.LockAsync())
             {
                 #region 斗技场
@@ -274,26 +275,11 @@ namespace OpenCards.Server.Arena
                             this.GetErrorCode($"ArenaValorGroupOriginTimeMap does contain arena valor id: {this.dataMapping.ArenaValorCurrentID} , createTime:{createOriginTime} !");
                         }
 
-                        var now = TimeUtils.Now;
-                        // 启动新赛区服务
-                        var config = new Dictionary<string, string>
-                        {
-                            ["OriginSeason"] = this.dataMapping.ArenaValorOriginSeason.ToString(),
-                            ["OriginTime"] = now.ToString(),
-                            ["ArenaID"] = this.dataMapping.ArenaValorCurrentID.ToString(),
-                            ["ServerID"] = this.ServerId,
-                            ["RankActivityTime"] = DateTime.MinValue.ToString(), //斗技场排名活动开始时间(兼容老服的老分组)
-                            ["ArenaOriginTime"] = this.dataMapping.ArenaOriginTime.GetTimeStamp().ToString(), //斗技场管理服创服时间
-                        };
-                        await this.Provider.CreateAsync(RpcUtils.GetArenaValorServiceAddress(this.ServerId, this.dataMapping.ArenaValorCurrentID, this.SelfAddress.ServiceNode), config);
-                        this.dataMapping.ArenaValorGroupOriginTimeMap.Put(this.dataMapping.ArenaValorCurrentID, now);
-
-                        //跟随斗技场服务,一同创建巅峰斗技场游戏服服务
-                        var arenaPinnacleConfig = new Dictionary<string, string>
-                        {
-                            ["ServerID"] = this.ServerId,
-                        };
-                        await this.Provider.CreateAsync(RpcUtils.GetArenaPinnacleServiceGameAddress(this.ServerId, this.SelfAddress.ServiceNode), arenaPinnacleConfig);
+                        pendingCreateNow = TimeUtils.Now;
+                        pendingCreateService = true;
+                        pendingArenaID = this.dataMapping.ArenaValorCurrentID;
+                        // 在锁内先更新数据映射
+                        this.dataMapping.ArenaValorGroupOriginTimeMap.Put(this.dataMapping.ArenaValorCurrentID, pendingCreateNow);
                     }
 
                     await this.dataMapping.SaveDataAsync();
@@ -319,13 +305,34 @@ namespace OpenCards.Server.Arena
                     await this.redis.HashSetAsync($"{PersistenceConstants.TYPE_ARENA_HIGHEND_TIER}{req.ServerID}", req.RoleUUID, value);
                     rsp.ArenaHighendTier = value;
                 }
-
                 #endregion
+            }
 
+            // 锁已释放,创建服务(避免在锁内执行 Provider.CreateAsync 导致RPC通信死锁)
+            if (pendingCreateService)
+            {
+                var config = new Dictionary<string, string>
+                {
+                    ["OriginSeason"] = this.dataMapping.ArenaValorOriginSeason.ToString(),
+                    ["OriginTime"] = pendingCreateNow.ToString(),
+                    ["ArenaID"] = pendingArenaID.ToString(),
+                    ["ServerID"] = this.ServerId,
+                    ["RankActivityTime"] = DateTime.MinValue.ToString(), //斗技场排名活动开始时间(兼容老服的老分组)
+                    ["ArenaOriginTime"] = this.dataMapping.ArenaOriginTime.GetTimeStamp().ToString(), //斗技场管理服创服时间
+                };
+                await this.Provider.CreateAsync(RpcUtils.GetArenaValorServiceAddress(this.ServerId, pendingArenaID, this.SelfAddress.ServiceNode), config);
+
+                //跟随斗技场服务,一同创建巅峰斗技场游戏服服务
+                var arenaPinnacleConfig = new Dictionary<string, string>
+                {
+                    ["ServerID"] = this.ServerId,
+                };
+                await this.Provider.CreateAsync(RpcUtils.GetArenaPinnacleServiceGameAddress(this.ServerId, this.SelfAddress.ServiceNode), arenaPinnacleConfig);
             }
+
             return rsp;
         }
-        
+
         [RpcHandler(typeof(HandleGMRequest), typeof(HandleGMResponse))]
         public async Task<HandleGMResponse> rpc_Handle(HandleGMRequest req)
         {
@@ -485,4 +492,4 @@ namespace OpenCards.Server.Arena
             return true;
         }
     }
-}
+}

+ 22 - 17
server/src/server/OpenCards.Server.ArenaValor/ArenaPinnacleBaseService.cs

@@ -30,6 +30,7 @@ using OpenCards.Server.Common.ORM;
 using OpenCards.Server.Core.ORM;
 using OpenCards.Server.Core.Table;
 using OpenCards.Server.Logic.Module;
+using static Org.BouncyCastle.Math.EC.ECCurve;
 
 namespace OpenCards.Server.Arena
 {
@@ -51,7 +52,7 @@ namespace OpenCards.Server.Arena
         private Action<int> afterGatherAction;
         private string fightPostUrl;
         private IAsyncLock _asyncDataLock;
-        protected bool useTest = false; //是否使用测试逻辑
+        protected bool useTest = true; //是否使用测试逻辑
         protected bool useOpenStateTest = false; //开关是否使用测试逻辑
         protected bool useParallel = true; //是否使用并行
         private static SemaphoreSlim distributionLock = new SemaphoreSlim(1);
@@ -440,7 +441,7 @@ namespace OpenCards.Server.Arena
             {
                 return rsp;
             }
-            
+
             rsp.SeasonState = await CheckSeaonDataRefresh(); //检测本赛区的赛季更新
             await CheckGatherContestants();
             var entranceState = await GetEntranceState();
@@ -456,7 +457,7 @@ namespace OpenCards.Server.Arena
             {
                 return rsp;
             }
-            
+
             rsp.WheelBattleTeamCount = regionDataMapping.WheelBattleTeamCount; //获取车轮战队伍数
             //获取上阵对数增加所需赛季数
             if (regionDataMapping.WheelBattleTeamCount >= ArenaUtils.WheelBattleTeamCountUpperLimit)
@@ -1499,7 +1500,7 @@ namespace OpenCards.Server.Arena
                         }
                         foreach (var competitionDataList in dataIEnumerable)
                         {
-                            foreach(var contestant in competitionDataList)
+                            foreach (var contestant in competitionDataList)
                             {
                                 if (contestant.LastestStage >= stage)
                                 {
@@ -1932,7 +1933,7 @@ namespace OpenCards.Server.Arena
             var groupContestantList = new List<RoleArenaPinnacleCompetitionData>();
             foreach (var item in dataIEnumerable)
             {
-                foreach(var data in item)
+                foreach (var data in item)
                 {
                     groupContestantList.Add(data);
                 }
@@ -2122,7 +2123,7 @@ namespace OpenCards.Server.Arena
                                     ServerID = role.ServerId,
                                 };
                                 uuidMap.TryAddOrUpdate(recordData.LeftRole.RoleData.RoleUUID, true);
-                                foreach(var hero in fightData.LeftRole.RoleHeroList)
+                                foreach (var hero in fightData.LeftRole.RoleHeroList)
                                 {
                                     ClientArenaPinnacleFightHeroData clientHeroData = new()
                                     {
@@ -2188,7 +2189,7 @@ namespace OpenCards.Server.Arena
                             for (int i = 0; i < rsp.RecordMap.Count; i++)
                             {
                                 var list = rsp.RecordMap[i];
-                                foreach(var data in list)
+                                foreach (var data in list)
                                 {
                                     var index = uuidList.FindIndex(uuid => uuid == data.LeftRole.RoleData.RoleUUID);
                                     var player = playerData.PlayerList[index];
@@ -2263,7 +2264,7 @@ namespace OpenCards.Server.Arena
             }
 
             var stage = GetStage();
-            if (stage == SyncClientPinnacleStageType.Vacuum 
+            if (stage == SyncClientPinnacleStageType.Vacuum
                 || stage == SyncClientPinnacleStageType.Offseason
                 || stage == SyncClientPinnacleStageType.CompetitionPrepare)
             {
@@ -3378,7 +3379,7 @@ namespace OpenCards.Server.Arena
                     {
                         var arenaPinnacleServerDataList = serverSplitList[i];
                         int regionId = lastestRegionData.RegionId + i + 1;
-                        foreach(var serverData in arenaPinnacleServerDataList)
+                        foreach (var serverData in arenaPinnacleServerDataList)
                         {
                             await RefreshRegionIdToCenterService(serverData.ServerId, regionId);
                             serverData.ObsoleteRegionId = serverData.RegionId;
@@ -3462,6 +3463,9 @@ namespace OpenCards.Server.Arena
 
             await this.dataMapping.FlushAsync();
 
+            if (regionID <= 0)
+                regionID = dataMapping.RegionDataMap.Values.First(r => r.Data.ServerList.Exists(s => s.ServerId == serverId)).RegionId;
+
             return regionID;
         }
 
@@ -3661,7 +3665,7 @@ namespace OpenCards.Server.Arena
 
                                     int tempServerCount = tempServerList.Count;
                                     //更新赛区id和老赛区id存储记录
-                                    foreach(var server in tempServerList)
+                                    foreach (var server in tempServerList)
                                     {
                                         server.ObsoleteRegionId = server.RegionId;
                                         server.RegionId = regionDataMap.RegionId;
@@ -3877,7 +3881,7 @@ namespace OpenCards.Server.Arena
                 if (emptyServerRegionIdList.Count > 0)
                 {
                     //移除分配完后已经空服务器的赛区
-                    foreach(var regionId in emptyServerRegionIdList)
+                    foreach (var regionId in emptyServerRegionIdList)
                     {
                         this.dataMapping.RegionDataMap.Remove(regionId);
                     }
@@ -4037,6 +4041,7 @@ namespace OpenCards.Server.Arena
                     var now = TimeUtils.CurrentTimeMs;
                     if (now >= gatherTimeStamp && now < GroupStartUTCTime.GetTimeStamp())
                     {
+                        this.dataMapping.GatherContestantsState = ContestantGatherStateType.NotStartGatherYet;
                         if (this.dataMapping.GatherContestantsState == ContestantGatherStateType.NotStartGatherYet)
                         {
                             this.dataMapping.GatherContestantsState = ContestantGatherStateType.IsGathering;
@@ -4148,7 +4153,7 @@ namespace OpenCards.Server.Arena
                                                                 }
                                                             }
                                                         }
-                                                        if(serverData == null || !serverData.HasValue)
+                                                        if (serverData == null || !serverData.HasValue)
                                                         {
                                                             this.GetErrorCode($"Server{serverId} gather arena  serviceType:{GetPinnacleServiceType()}   contestants to arena pinnacle server {serverId} in not in serverList!");
                                                         }
@@ -4167,7 +4172,7 @@ namespace OpenCards.Server.Arena
                                                                     log.Warn($"gathering {role.RoleUUID} deviceId is null or empty {role.DeviceID}!");
                                                                 }
 
-                                                                if(string.IsNullOrWhiteSpace(role.RoleUUID))
+                                                                if (string.IsNullOrWhiteSpace(role.RoleUUID))
                                                                 {
                                                                     this.GetErrorCode($"Region {regionDataMapping.RegionId} Server{serverId} gather arena  serverType:{GetPinnacleServiceType()} contestants to arena pinnacle has null or empty role {role.RoleUUID}!");
                                                                 }
@@ -4312,7 +4317,7 @@ namespace OpenCards.Server.Arena
                             var serverListRsp = await accountService.CallAsync<GetServerDataListResponse>(new GetServerDataListRequest());
                             if (Response.CheckSuccess(serverListRsp))
                             {
-                                foreach(var serverData in serverListRsp.ServerDataList)
+                                foreach (var serverData in serverListRsp.ServerDataList)
                                 {
                                     var connectorService = await RpcUtils.GetConnectorService(this.Provider, serverData.ID.ToString());
                                     if (connectorService != null)
@@ -4600,7 +4605,7 @@ namespace OpenCards.Server.Arena
         /// <returns></returns>
         private bool IsCompetitionStage(SyncClientPinnacleStageType stage)
         {
-            return stage > SyncClientPinnacleStageType.CompetitionPrepare;
+            return stage > SyncClientPinnacleStageType.CompetitionPrepare && stage <= SyncClientPinnacleStageType.ChampionshipFinals;
         }
 
         /// <summary>
@@ -5335,7 +5340,7 @@ namespace OpenCards.Server.Arena
 
                             int tempCount = 0;
                             int innerGroupId = 1;
-                            foreach(var groupMember in groupList)
+                            foreach (var groupMember in groupList)
                             {
                                 if (groupMember.LastestStage == SyncClientPinnacleStageType.Ro64)
                                 {
@@ -5479,7 +5484,7 @@ namespace OpenCards.Server.Arena
 
                             int tempCount = 0;
                             int innerGroupId = 1;
-                            foreach(var groupMember in groupList)
+                            foreach (var groupMember in groupList)
                             {
                                 if (groupMember.LastestStage == nextStageType)
                                 {

+ 16 - 15
server/src/server/OpenCards.Server.Common/Http/HttpServer.cs

@@ -323,23 +323,24 @@ namespace OpenCards.Server.Common.Http
             context.Response.StatusDescription = httpStatusDescription;
             context.Response.ContentEncoding = Encoding.UTF8;
 
-            var acceptsGzip = AcceptsGzip(context.Request);
-            if (!acceptsGzip)
-            {
-                byte[] buffer = Encoding.UTF8.GetBytes(data);
-                context.Response.ContentLength64 = buffer.Length;
-                await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
-                context.Response.OutputStream.Close();
-                context.Response.Close();
-            }
-            else
+           var acceptsGzip = AcceptsGzip(context.Request);
+           if (!acceptsGzip)
+           {
+                byte[] buffer = Encoding.UTF8.GetBytes(data ?? "");
+                context.Response.ContentLength64 = buffer.Length;
+                await context.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
+                context.Response.OutputStream.Close();
+                context.Response.Close();
+            }
+            else
             {
                 context.Response.AddHeader("Content-Encoding", "gzip");
-                using (GZipStream gzip = new GZipStream(context.Response.OutputStream, CompressionMode.Compress, true))
-                using (var writer = new StreamWriter(gzip, Encoding.UTF8, 4096, true))
-                {
-                    await writer.WriteAsync(data);
-                }
+                using (GZipStream gzip = new GZipStream(context.Response.OutputStream, CompressionMode.Compress, true))
+                using (var writer = new StreamWriter(gzip, Encoding.UTF8, 4096, true))
+                {
+                    data = data ?? "";
+                    await writer.WriteAsync(data);
+                }
             }
         }
 

+ 1 - 1
server/src/server/OpenCards.Server.Common/RPC/RpcUtils.cs

@@ -169,7 +169,7 @@ namespace OpenCards.Server.Common.RPC
         public static RemoteAddress GetArenaValorServiceAddress(string serverId, int id, string logicNode = "NODE_NAME")
         {
             if (UseNameServer)
-                return new RemoteAddress("ArenaValorService_" + serverId + "_" + id, logicNode, "ArenaValorService");
+                return new RemoteAddress("ArenaValorService_" + serverId + "_" + id, "", "");
             else
                 return new RemoteAddress($"ArenaValorService_{id}", logicNode, "OpenCards.Server.Arena.ArenaValorService");
         }

+ 11 - 0
server/src/server/OpenCards.Server.Common/ServerNames.cs

@@ -100,5 +100,16 @@ namespace OpenCards.Server.Common
                 return new RemoteAddress("StageRankService", null, "OpenCards.Service.StageRank.StageRankService");
 
         }
+
+        public static RemoteAddress GetArenaValorServiceAddress(string servreId = "")
+        {
+            if (RpcUtils.UseNameServer)
+            {
+                return new RemoteAddress("ArenaValorService_" + servreId, "", "");
+            }
+            else
+                return new RemoteAddress("ArenaValorService", null, "OpenCards.Server.Arena.ArenaValorService");
+
+        }
     }
 }

+ 6 - 1
server/src/server/OpenCards.Server.Logic/Module/FightModules.cs

@@ -616,7 +616,12 @@ namespace OpenCards.Server.Logic.Module
                             writer.Write(byteData, 0, length);
                             writer.Close();
                             var response = await request.GetResponseAsync() as HttpWebResponse;
-
+                            if (response.StatusCode != HttpStatusCode.OK)
+                            {
+                                this.GetErrorCode($"HttpWebResponse error:{c2s_FightMod} oppositeuuid:{c2s_OppositeRoleUUID}  response.StatusCode:{response.StatusCode}  err:{responseString} ");
+                                rsp.s2c_code = ClientArenaValorFightRandomSeedResponse.CODE_BATTLE_RETURN_ERROR;
+                                return rsp;
+                            }
                             responseString = new System.IO.StreamReader(response.GetResponseStream(), System.Text.Encoding.GetEncoding("utf-8")).ReadToEnd();
                             fightResp = JsonConvert.DeserializeObject<FightResultInfo>(responseString);
                             if (fightResp == null)