using System; using System.Collections.Generic; using System.Linq; using Sog; using ProtoCSStruct; using System.IO; using System.Diagnostics; namespace Realmlist { public class ClassSSGameReportRealmlistRes { public SSGameReportRealmlistRes structRes; } public class SSGameReportRealmlistResList { //c#里不允许数组里的struct大小超过64K //public List resList = new List(); public List resList = new List(); public string calcMd5; public void CalcMd5() { MemoryStream ms = new MemoryStream(); for (int i = 0; i < resList.Count; i++) { ref SSGameReportRealmlistRes res = ref resList[i].structRes; int size = res.CalculateSize(); byte[] data = new byte[size]; CodedOutputStream ouput = new CodedOutputStream(data); res.WriteTo(ouput); ms.Write(data); } calcMd5 = HashHelper.MD5Bytes(ms.GetBuffer()); } } public class ClassSSRealmBriefRes { public SSRealmBriefRes structRes; } public class SSRealmBriefResList { public List resList = new List(); public string calcMd5; public void CalcMd5() { MemoryStream ms = new MemoryStream(); for (int i = 0; i < resList.Count; i++) { ref SSRealmBriefRes res = ref resList[i].structRes; int size = res.CalculateSize(); byte[] data = new byte[size]; CodedOutputStream ouput = new CodedOutputStream(data); res.WriteTo(ouput); ms.Write(data); } calcMd5 = HashHelper.MD5Bytes(ms.GetBuffer()); } } public static class RealmInfoHandler { //account sessionId, time second static Dictionary s_sessionSendAreaServerIpDict = new Dictionary(); static long lastCheckDeleteSessionDictTime = 0; const int SendRealmMaxCountOnce = 128; private static void TryDeleteSessionDictByTime() { long now = RealmlistServerUtils.GetTimeSecond(); //1分钟一次 if (now - lastCheckDeleteSessionDictTime < 60) { return; } lastCheckDeleteSessionDictTime = now; List needDeleteSession = new List(); foreach(var pair in s_sessionSendAreaServerIpDict) { //删除超过10分钟的 if(now - pair.Value > 300) { needDeleteSession.Add(pair.Key); } } foreach(var session in needDeleteSession) { s_sessionSendAreaServerIpDict.Remove(session); } TraceLog.Debug("RealmInfoHandler.TryDeleteSessionDictByTime s_sessionSendAreaServerIpDict new count {0} after delete count {1}" , s_sessionSendAreaServerIpDict.Count, needDeleteSession.Count); } public static void OnClientGameListReq(uint remoteAppID, StructPacket packet) { ref CSGameListReq req = ref packet.GetMessage(); string accountID = req.AccountID.GetString(); string ip = req.Ip.ToString(); string deviceId = req.DeviceId.ToString(); bool isInWhiteList = LimitIPList.IsInWhiteList(ip, deviceId); TraceLog.Trace("RealmInfoHandler.OnClientGameListReq accountType {0} accountId {1} ip {2} deviceId {3} isInWhiteList {4}" , req.AccountType, accountID, ip, deviceId, isInWhiteList); List visiableAreas = null; //表示是客户端来的 if (req.FromAccountSession != 0 && s_sessionSendAreaServerIpDict.ContainsKey(req.FromAccountSession) == false) { visiableAreas = GetAllAreaServerIPList(ref req, ip, deviceId, true); } PlayerRealmInfo player = RealmlistServerUtils.GetCreatePlayerInfo(req.AccountType, accountID); AreaRealm area = null; string reqArea = req.AreaName.ToString(); // 客户端指定大区 if (! string.IsNullOrEmpty(reqArea)) { if (! RealmlistSvc.areaDict.TryGetValue(reqArea, out area)) { // 增加默认大区, 方便渠道包登录内网服务器 if (string.IsNullOrEmpty(RealmlistServerUtils.GetServerConfig().defaultAreaName)) { TraceLog.Error("RealmInfoHandler.OnClientGameListReq area {0} no data", reqArea); return; } reqArea = RealmlistServerUtils.GetServerConfig().defaultAreaName; if (! RealmlistSvc.areaDict.TryGetValue(reqArea, out area)) { TraceLog.Error("RealmInfoHandler.OnClientGameListReq default area {0} no data", reqArea); return; } } } else { // 没有登录过, 先根据ip选择,再选客户端所在时区最近的大区 if (req.LastLoginRealm == 0) { area = RecommendRealmByIP.GetAreaByIP(ip); TraceLog.Trace("RealmInfoHandler.OnClientGameListReq GetAreaByIP {0} area {1}", ip, area == null ? "null" : area.areaName); //如果强制配置成ip白名单可见,那么不在名单里的肯定不可见 if (area != null && area.visibleOnlyWhiteList == 1 && !LimitIPList.IsInWhiteList(ip, deviceId)) { area = null; } if (area == null) { area = RealmlistSvc.GetAreaByTimezone(req.CltTimezone, ip, deviceId); TraceLog.Trace("RealmInfoHandler.OnClientGameListReq GetAreaByTimezone {0} area {1}", req.CltTimezone, area == null ? "null" : area.areaName); } } else//已经登录过,选最近登录大区 { area = RealmlistSvc.GetAreaByRealmId(req.LastLoginRealm); TraceLog.Trace("RealmInfoHandler.OnClientGameListReq GetAreaByRealmId {0} area {1}", req.LastLoginRealm, area == null ? "null" : area.areaName); } if (area == null) { TraceLog.Trace("RealmInfoHandler.OnClientGameListReq 1 area is null, clt timezone {0} lastLogin {1}" , req.CltTimezone, req.LastLoginRealm); area = RealmlistSvc.GetAreaByTimezone(req.CltTimezone, ip, deviceId); TraceLog.Trace("RealmInfoHandler.OnClientGameListReq GetAreaByTimezone by default {0} area {1}", req.CltTimezone, area == null ? "null" : area.areaName); if (area == null) { TraceLog.Error("RealmInfoHandler.OnClientGameListReq 2 area is null, clt timezone {0} lastLogin {1}" , req.CltTimezone, req.LastLoginRealm); return; } } } if(visiableAreas != null) { //这种情况是: 比如开了美区,设置了推荐美区的新用户的号屏蔽了其他区,但是美区又不可见(比如开白名单), //这种情况非常少见,但还是需要处理,要不然玩家一个区都看不见了 if (area != null && visiableAreas.Contains(area) == false) { TraceLog.Debug("RealmInfoHandler.OnClientGameListReq find area {0} but not in visiableAreas", area.areaName); visiableAreas = GetAllAreaServerIPList(ref req, ip, deviceId, false); } SendAllAreaServerIPList(visiableAreas, remoteAppID, packet.ObjectID); s_sessionSendAreaServerIpDict.Add(req.FromAccountSession, RealmlistServerUtils.GetTimeSecond()); TryDeleteSessionDictByTime(); } var res = new CSGameListRes { CurrPage = req.ReqPage, RealmPerPage = RealmlistSvc.realmNumPerPage, TotalPage = RealmlistSvc.GetTotalRealmPage(area), AccountType = req.AccountType, FromGameSvr = req.FromGameSvr, FromWorldSvr = req.FromWorldSvr, FromAccountSession = req.FromAccountSession, FromUid = req.FromUid }; res.AccountID.SetString(req.AccountID.GetPtr()); res.AreaName.SetString(area.areaName); // 0号页签是推荐页签, 包含一个最新realm和这个大区所有已创建角色的realm if (req.ReqPage <= 0) { RealmInfo recommendRealm = RealmlistSvc.GetRecommendRealm(area, req.ClientVer.GetString(), ip, req.LastLoginRealm == 0, deviceId); if (recommendRealm != null) { RealmlistSvc.FillCSRealmInfo(area, recommendRealm, player, ref res.RecommendRealm, isInWhiteList); } else { // 没有推荐服, 只有一种情况就是所有服务器当前都不可见 TraceLog.Error("RealmInfoHandler.OnClientGameListReq area {0} lastlogin {1} no recommend realm" , area.areaName, req.LastLoginRealm); } // 加入属于这个大区的已创建角色realm for (int i = 0; i < req.CreateRoleRealms.Count; i++) { var realm = RealmlistSvc.GetRealm(area, req.CreateRoleRealms[i]); //共享显示大区 if(realm == null && area.shareShowAreaRealm != null) { realm = RealmlistSvc.GetRealm(area.shareShowAreaRealm, req.CreateRoleRealms[i]); } if (realm != null) { var csrealm = new CSRealmInfo(); RealmlistSvc.FillCSRealmInfo(area, realm, player, ref csrealm, isInWhiteList); res.Realms.Add(ref csrealm); } } RealmlistServerUtils.GetPacketSender().SendToServerByID( remoteAppID, (int)CSMsgID.GameListRes, ref res, packet.ObjectID); return; } TraceLog.Trace("RealmInfoHandler.OnClientGameListReq area {0} lastlogin {1} no recommend realm" , area.areaName, req.LastLoginRealm); WorldInfo worldInfo = null; int thisAreaRealmsCount = area.sortedRealms.Count; int totalRealmsCount = thisAreaRealmsCount; //加上要显示的共享大区的区服数量 if (area.shareShowAreaRealm != null) { totalRealmsCount += area.shareShowAreaRealm.sortedRealms.Count; TraceLog.Trace("RealmInfoHandler.OnClientGameListReq area {0} share count {1} totalRealmsCount {2} thisAreaRealmsCount {3}" , area.areaName, area.shareShowAreaRealm.sortedRealms.Count, totalRealmsCount, thisAreaRealmsCount); } int startIdx = (req.ReqPage - 1) * RealmlistSvc.realmNumPerPage; int endIdx = startIdx + RealmlistSvc.realmNumPerPage - 1; if (endIdx >= totalRealmsCount) { endIdx = totalRealmsCount - 1; } TraceLog.Trace("RealmInfoHandler.OnClientGameListReq area {0} startIdx {1} endIdx {2}" , area.areaName, startIdx, endIdx); // 倒序发给客户端 for (int i = endIdx; i >= startIdx; i--) { if (res.Realms.Count >= res.Realms.GetMaxCount()) { break; } RealmInfo realm = null; if(i < thisAreaRealmsCount) { realm = area.sortedRealms[i]; } else { realm = area.shareShowAreaRealm.sortedRealms[i - thisAreaRealmsCount]; } //检查版本和ip白名单 if (RealmlistSvc.CheckCanVisibleRealmByClintVerIp(realm, req.ClientVer.GetString(), ip, deviceId) == false) { continue; } //如果未到可见时间(可见时间可以配置成比开服时间晚,方便自己人进去测试),那么只有ip白名单的人可以看见 if (! RealmlistServerUtils.CheckRealmCanVisible(realm) && !LimitIPList.IsInWhiteList(ip, deviceId)) { continue; } if (worldInfo == null || worldInfo.worldId != realm.worldId) { area.areaWorldDict.TryGetValue(realm.worldId, out worldInfo); if(worldInfo == null) { area.shareShowAreaRealm.areaWorldDict.TryGetValue(realm.worldId, out worldInfo); } } if (worldInfo == null) { TraceLog.Error("RealmInfoHandler.OnClientGameListReq area {0} worldId {1} no worldinfo" , area.areaName, realm.worldId); continue; } CSRealmInfo csrealmInfo = new CSRealmInfo(); RealmlistSvc.FillCSRealmInfo(worldInfo, realm, player, ref csrealmInfo, i >= thisAreaRealmsCount, isInWhiteList); res.Realms.Add(ref csrealmInfo); } RealmlistServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSMsgID.GameListRes, ref res, packet.ObjectID); } public static void OnGameWorldReport(uint serverID, StructPacket packet) { ref SSGameReportRealmlistReq req = ref packet.GetMessage(); int worldID = (int)ServerIDUtils.GetWorldID(req.WorldSvrid); string worldSvrId = ServerIDUtils.IDToString(req.WorldSvrid); TraceLog.Trace("RealmInfoHandler.OnGameWorldReport world {0} online {1}", worldSvrId, req.OnlinePlayer); // 这里找不到world先不返回, 至少先更新全局的gateOnlineDict RealmlistSvc.worldDict.TryGetValue(worldID, out WorldInfo worldInfo); var svrData = RealmlistServerUtils.GetRealmlistServerData(); for (int i = 0; i < req.Gates.Count; i++) { ref GameGateSvrInfo gate = ref req.Gates[i]; // 更新全局的gateOnlineDict if (! svrData.gateOnlineDict.TryGetValue(gate.GateSvrid, out int online)) { svrData.gateOnlineDict.Add(gate.GateSvrid, gate.OnlinePlayer); } else { svrData.gateOnlineDict[gate.GateSvrid] = gate.OnlinePlayer; } // 更新worldInfo中的gate在线数据 if (worldInfo != null) { List gatelist; int serverType = ServerIDUtils.GetServerType(gate.GateSvrid); if (serverType == (int) ServerType.GameGate) { gatelist = worldInfo.gameGates; } else { gatelist = worldInfo.chatGates; } for (int j = 0; j < gatelist.Count; j++) { if (gatelist[j].gatesvrId == gate.GateSvrid) { gatelist[j].online = gate.OnlinePlayer; break; } } } } if (worldInfo == null) { TraceLog.Error("RealmInfoHandler.OnGameWorldReport world {0} {1} no worldInfo", worldSvrId, worldID); return; } // 回包时同步world所有可登录的realm SSGameReportRealmlistResList resListForCheck = new SSGameReportRealmlistResList(); ClassSSGameReportRealmlistRes classResForCheck = new ClassSSGameReportRealmlistRes(); ref SSGameReportRealmlistRes resForCheck = ref classResForCheck.structRes; int resMsgIndexFrom1 = 1; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; foreach (RealmInfo realm in worldInfo.worldRealms.Values) { if (!RealmlistServerUtils.CheckRealmOpen(realm)) { continue; } var brief = new CSRealmBrief(); RealmlistSvc.FillCSRealmBrief(worldInfo.areaName, realm, ref brief); resForCheck.RealmList.Add(brief); if (resForCheck.RealmList.Count >= resForCheck.RealmList.GetMaxCount() || resForCheck.RealmList.Count >= SendRealmMaxCountOnce) { resListForCheck.resList.Add(classResForCheck); classResForCheck = new ClassSSGameReportRealmlistRes(); resForCheck = ref classResForCheck.structRes; resMsgIndexFrom1++; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; } } if (resForCheck.RealmList.Count > 0) { resListForCheck.resList.Add(classResForCheck); } //最后发一个结束包 classResForCheck = new ClassSSGameReportRealmlistRes(); resForCheck = ref classResForCheck.structRes; resMsgIndexFrom1++; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; resListForCheck.resList.Add(classResForCheck); //计算md5 resListForCheck.CalcMd5(); TraceLog.Trace("RealmInfoHandler.OnGameWorldReport world {0} req md5 {1} res md5 {2}", worldSvrId, req.RealmListMd5.GetString(), resListForCheck.calcMd5); if (resListForCheck.calcMd5 != req.RealmListMd5.GetString()) { for (int i = 0; i < resListForCheck.resList.Count; i++) { ref SSGameReportRealmlistRes res = ref resListForCheck.resList[i].structRes; if (i == resListForCheck.resList.Count - 1) { res.RealmListMd5.SetString(resListForCheck.calcMd5); } RealmlistServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSMsgID.GameReportRealmlistRes, ref res, 0, req.WorldSvrid); } } } /// /// 返回全部服务器 /// /// /// public static void OnRealmBriefReq(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); SSRealmBriefResList resListForCheck = new SSRealmBriefResList(); ClassSSRealmBriefRes classResForCheck = new ClassSSRealmBriefRes(); ref SSRealmBriefRes resForCheck = ref classResForCheck.structRes; resForCheck.GameSvrId = req.GameSvrId; resForCheck.WorldSvrId = req.WorldSvrId; int resMsgIndexFrom1 = 1; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; foreach (var area in RealmlistSvc.areaDict.Values) { foreach (RealmInfo realm in area.sortedRealms) { if (!RealmlistServerUtils.CheckRealmOpen(realm)) { continue; } var brief = new CSRealmBrief(); RealmlistSvc.FillCSRealmBrief(area.areaName, realm, ref brief, area.timezone); resForCheck.RealmList.Add(ref brief); if (resForCheck.RealmList.Count >= resForCheck.RealmList.GetMaxCount() || resForCheck.RealmList.Count >= SendRealmMaxCountOnce) { resListForCheck.resList.Add(classResForCheck); classResForCheck = new ClassSSRealmBriefRes(); resForCheck = ref classResForCheck.structRes; resForCheck.GameSvrId = req.GameSvrId; resForCheck.WorldSvrId = req.WorldSvrId; resMsgIndexFrom1++; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; } } } if (resForCheck.RealmList.Count > 0) { resListForCheck.resList.Add(classResForCheck); } //最后发一个结束包 classResForCheck = new ClassSSRealmBriefRes(); resForCheck = ref classResForCheck.structRes; resForCheck.GameSvrId = req.GameSvrId; resForCheck.WorldSvrId = req.WorldSvrId; resMsgIndexFrom1++; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; resListForCheck.resList.Add(classResForCheck); //计算md5 resListForCheck.CalcMd5(); TraceLog.Trace("RealmInfoHandler.OnRealmBriefReq remote {0} game {1} world {2} req md5 {3} res md5 {4}", ServerIDUtils.IDToString(remoteAppID), ServerIDUtils.IDToString(req.GameSvrId), ServerIDUtils.IDToString(req.WorldSvrId), req.RealmListMd5.GetString(), resListForCheck.calcMd5); if (resListForCheck.calcMd5 != req.RealmListMd5.GetString()) { for (int i = 0; i < resListForCheck.resList.Count; i++) { ref SSRealmBriefRes res = ref resListForCheck.resList[i].structRes; if (i == resListForCheck.resList.Count - 1) { res.RealmListMd5.SetString(resListForCheck.calcMd5); } RealmlistServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSMsgID.RealmBriefRes, ref res, 0); } } } /// /// 返回全部服务器 /// /// /// public static void OnRealmAllBriefReq(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); SSRealmAllBriefRes resForCheck = new SSRealmAllBriefRes(); resForCheck.Guid = req.Guid; resForCheck.GameSvrId = req.GameSvrId; resForCheck.WorldSvrId = req.WorldSvrId; int resMsgIndexFrom1 = 1; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; foreach (var area in RealmlistSvc.areaDict.Values) { foreach (RealmInfo realm in area.sortedRealms) { var brief = new CSRealmBrief(); RealmlistSvc.FillCSRealmBrief(area.areaName, realm, ref brief, area.timezone); resForCheck.RealmList.Add(ref brief); resMsgIndexFrom1++; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; if(resForCheck.RealmList.Count == 500) { TraceLog.Trace("RealmInfoHandler.OnRealmAllBriefReq remote {0} game {1} world {2}", ServerIDUtils.IDToString(remoteAppID), ServerIDUtils.IDToString(req.GameSvrId), ServerIDUtils.IDToString(req.WorldSvrId)); RealmlistServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSMsgID.RealmAllbriefRes, ref resForCheck, 0); resForCheck.RealmList.Clear(); } } } //最后发一个结束包 resMsgIndexFrom1++; resForCheck.MsgIndexFrom1 = resMsgIndexFrom1; resForCheck.IsEnd = 1; TraceLog.Trace("RealmInfoHandler.OnRealmAllBriefReq remote {0} game {1} world {2}", ServerIDUtils.IDToString(remoteAppID), ServerIDUtils.IDToString(req.GameSvrId), ServerIDUtils.IDToString(req.WorldSvrId)); RealmlistServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSMsgID.RealmAllbriefRes, ref resForCheck, 0); } /// /// 查询服务器最大bigrealmid /// public static void OnAllRealmReq(uint remoteAppID, StructPacket packet) { ref var req = ref packet.GetMessage(); var res = new SSAllRealmRes { GameSvrId = req.GameSvrId, WorldSvrId = req.WorldSvrId }; ServerApp m_app = RealmlistServerUtils.GetApp(); RealmlistServerConfig serverConfig = RealmlistServerUtils.GetServerConfig(); string svnRealmListVersion = ""; if (serverConfig.enableModifykRealmListOpen && req.UpdateSvnFlag) { string svnFileName = m_app.GetCluster().GetAppConfigPath() + "/" + "svn.sh"; string svnInfo = Bash(svnFileName + " update"); if (svnInfo != null) { string[] info = svnInfo.Split("\n"); for (int i = 0; i < info.Length; i++) { if (info[i].Contains("At revision")) { svnRealmListVersion = info[i]; } } } } res.SvnRealmListVersion.SetString(svnRealmListVersion); res.Guid = req.Guid; foreach (var area in RealmlistSvc.areaDict.Values) { foreach (RealmInfo realm in area.sortedRealms) { var brief = new CSRealmBrief(); RealmlistSvc.FillCSRealmBrief(area.areaName, realm, ref brief, area.timezone); res.RealmList.Add(ref brief); if (res.RealmList.Count >= res.RealmList.GetMaxCount()) { RealmlistServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSMsgID.AllRealmRes, ref res, 0); res.RealmList.Clear(); } } } if (res.RealmList.Count > 0) { RealmlistServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)SSMsgID.AllRealmRes, ref res, 0); } } /// /// 新增服务器 /// public static void OnSsAddRealmReq(uint serverID, StructPacket packet) { RealmlistServerConfig serverConfig = RealmlistServerUtils.GetServerConfig(); ref SSAddRealmReq req = ref packet.GetMessage(); var res = new SSAddRealmRes { Code = 0 }; res.Msg.SetString("成功"); res.Id = req.Id; if (!serverConfig.enableModifykRealmListOpen) { res.Code = 1; res.Msg.SetString("更新svn开关未打开"); RealmlistServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSMsgID.SsAddRealmRes, ref res, 0); return; } try { ServerApp m_app = RealmlistServerUtils.GetApp(); string newVersion = req.SvnRealmListVersion.ToString(); string filePathName = m_app.GetCluster().GetAppConfigPath() + "/" + serverConfig.realmListFile; string svnFileName = m_app.GetCluster().GetAppConfigPath() + "/" + "svn.sh"; //svn更新本地realmlist文件 string svnInfo = Bash(svnFileName + " update"); if (string.IsNullOrEmpty(svnInfo)) { string[] info = svnInfo.Split("\n"); for (int i = 0; i < info.Length; i++) { if (info[i].Contains("At revision")) { newVersion = info[i]; } } } if (newVersion == req.SvnRealmListVersion.ToString()) { List lines = File.ReadAllLines(filePathName).ToList(); var addLines = new List(); var newLines = new List(); string areaName = ""; int worldId = 0; int beginRealmId = int.MaxValue; for (int i = 0; i < lines.Count; i++) { if (lines[i].Contains("\"areaName\"")) { areaName = lines[i].Split(":")[1].Replace("\"", "").Replace("\t", "").Replace(",", ""); newLines.Add(lines[i]); } else if (lines[i].Contains("\"worldId\"")) { worldId = int.Parse(lines[i].Split(":")[1].Replace("\"", "").Replace("\t", "").Replace(",", "")); newLines.Add(lines[i]); } else if (lines[i].Contains("\"realmList\"")) { for (int j = 0; j < req.RealmList.Count; j++) { string res111 = req.RealmList[j].ToString(); if (req.RealmList[j].AreaName.ToString() == areaName && req.RealmList[j].WorldId == worldId) { beginRealmId = (beginRealmId < req.RealmList[j].RealmId) ? beginRealmId : req.RealmList[j].RealmId; int k = 1; int startRealmId = 0; int startRealmIdUnit = 0; while (!lines[i + k].Contains("}")) { string[] temp = new string[2]; if (lines[i + k].Replace("\t", "").StartsWith("//")) { addLines.Add(lines[i + k]); } else if (lines[i + k].Contains("realmId")) { temp = lines[i + k].Split(':'); startRealmId = Convert.ToInt32(temp[1].Replace("/t", "").Replace(",", "").Replace("\"", "")); startRealmIdUnit = startRealmId % 1000; addLines.Add(temp[0] + ":" + temp[temp.Length - 1].Replace(startRealmId.ToString(), req.RealmList[j].RealmId.ToString())); } else if (lines[i + k].Contains("name")) { temp = lines[i + k].Split(':'); int num = req.RealmList[j].RealmId % 1000; addLines.Add(temp[0] + ":" + temp[temp.Length - 1].Replace(startRealmIdUnit.ToString(), num.ToString())); } else if (lines[i + k].Contains("showSeq")) { temp = lines[i + k].Split(':'); int num = req.RealmList[j].RealmId % 1000; addLines.Add(temp[0] + ":" + temp[temp.Length - 1].Replace(startRealmIdUnit.ToString(), num.ToString())); } else if (lines[i + k].Contains("bdcName")) { temp = lines[i + k].Split(':'); addLines.Add(temp[0] + ":" + temp[temp.Length - 1].Replace(startRealmId.ToString(), req.RealmList[j].RealmId.ToString())); } else if (lines[i + k].Contains("openTime")) { temp = lines[i + k].Split(':'); addLines.Add(temp[0] + ": \"" + AppTime.ConvertUnixTimeToDateTime((long)(req.RealmList[j].OpenTime) * 1000).ToString("yyyy-MM-dd HH:mm:ss") + "\"" + (temp[temp.Length - 1].EndsWith(",") ? "," : "")); } else if (lines[i + k].Contains("visibleTime")) { temp = lines[i + k].Split(':'); addLines.Add(temp[0] + ": \"" + AppTime.ConvertUnixTimeToDateTime((long)(req.RealmList[j].VisibleTime) * 1000).ToString("yyyy-MM-dd HH:mm:ss") + "\"" + (temp[temp.Length - 1].EndsWith(",") ? "," : "")); } else if (lines[i + k].Contains("bigRealmId")) { temp = lines[i + k].Split(':'); addLines.Add(temp[0] + ":" + req.RealmList[j].BigRealmId + (temp[temp.Length - 1].EndsWith(",") ? "," : "")); } else addLines.Add(lines[i + k]); k++; } addLines.Add(lines[i + k]); } } if (addLines.Count > 0) { addLines[addLines.Count - 1] = addLines[addLines.Count-1].Replace(",", ""); } newLines.Add(lines[i]); } else if (lines[i].Contains("\"realmId\"")) { int realmId = Convert.ToInt32(lines[i].Split(':')[1].Replace("\t", "").Replace(",", "")); if (realmId == beginRealmId) { for (int m = 1; m < addLines.Count; m++) { newLines.Add(addLines[m]); } while (!lines[i].Contains("]")) i++; newLines.Add(lines[i]); //插入完成后清理addLines addLines.Clear(); beginRealmId = int.MaxValue; } else { newLines.Add(lines[i]); } } else { newLines.Add(lines[i]); } } string[] resLines = new string[newLines.Count]; for (int i = 0; i < newLines.Count; i++) { resLines[i] = newLines[i]; } TraceLog.Trace("filePathName = " + filePathName + "当前版本 = " + newVersion + "查询版本 = " + req.SvnRealmListVersion.ToString()); //更新到配置文件中 File.WriteAllLines(filePathName, resLines); //读取游戏服务器开服列表 RealmlistSvc.ReadRealmListConfig(m_app, filePathName); RecommendRealmByIP.OnReloadConfig(); //上传到svn Bash(svnFileName + " upload"); } else { TraceLog.Trace("filePathName = " + filePathName + "当前版本 = " + newVersion + "查询版本 = " + req.SvnRealmListVersion.ToString()); res.Code = 1; res.Msg.SetString("本地版本与svn版本不一致,修改失败"); } } catch (Exception ex) { TraceLog.Exception(ex); res.Code = 1; res.Msg.SetString("失败"); } finally { RealmlistServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSMsgID.SsAddRealmRes, ref res, 0); } } public static void OnRealmOperationReq(uint serverID, StructPacket packet) { var realmValues = RealmlistSvc.areaDict.Values; ref SSRealmOperationReq req = ref packet.GetMessage(); SSRealmOperationRes res = new SSRealmOperationRes(); res.Id = req.Id; switch (req.OpType) { case (int)OpRealmType.Add: res.Code = RealmlistDBSvc.AddNewRealmFromOp2Cache(ref req); break; case (int)OpRealmType.Update: res.Code = RealmlistDBSvc.UpdateNewRealmFromOp2Cache(ref req); break; default: break; } if(res.Code != 0) { RealmlistServerUtils.GetPacketSender().SendToServerByID(serverID, (int)SSMsgID.SsRealmOperationRes, ref res, 0); } } public static void SsRealmNewPlayer(uint serverID, StructPacket packet) { var realmValues = RealmlistSvc.areaDict.Values; ref SSRealmNewPlayer req = ref packet.GetMessage(); if (RealmlistServerUtils.GetRealmlistServerData().dbRealmConfigs.ContainsKey(req.ReamlId)) { var cfg = RealmlistServerUtils.GetRealmlistServerData().dbRealmConfigs[req.ReamlId]; cfg.RegNum++; RealmlistServerUtils.GetRealmlistServerData().dbRealmConfigs[req.ReamlId] = cfg; SSRealmSavePlayerNum savePlayerNum = new SSRealmSavePlayerNum(); savePlayerNum.RegNum = cfg.RegNum; savePlayerNum.RealmId = cfg.RealmId; int instId = (int)ServerIDUtils.GetInstanceID(RealmlistServerUtils.GetApp().ServerID); uint DBServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Db, instId); RealmlistServerUtils.GetPacketSender().SendToServerByID(DBServerID, (int)SSMsgID.SsRealmSavePlayernum, ref savePlayerNum, 0); } } public static string Bash(this string cmd) { var escapedArgs = cmd.Replace("\"", "\\\""); var process = new Process() { StartInfo = new ProcessStartInfo { FileName = "/bin/bash", Arguments = $"-c \"{escapedArgs}\"", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true, } }; process.Start(); string result = process.StandardOutput.ReadToEnd(); process.WaitForExit(); process.Close(); return result; } private static bool HasRoleInArea(ref CSGameListReq req, AreaRealm area) { for (int i = 0; i < req.CreateRoleRealms.Count; i++) { int realmId = req.CreateRoleRealms[i]; if (area.realmIndex.ContainsKey(realmId)) { return true; } } return false; } private static bool AreaInInvisiableArea(AreaRealmList area, List list) { foreach(var iarea in list) { if(iarea.areaName == area.areaName) { return true; } } return false; } //获取区域的ip和timezone public static List GetAllAreaServerIPList(ref CSGameListReq req, string ip, string deviceId, bool checkNewUserInvisibleAreaRule) { List visiableAreaList = new List(); bool invisibleAreaForNewUser = false; var recommendarea = RecommendRealmByIP.GetAreaByIP(ip); if(checkNewUserInvisibleAreaRule && recommendarea != null && recommendarea.invisibleAreaForNewUserList.Count > 0) { //规则,有任一屏蔽区有角色,则所有区都不屏蔽 bool hasRoleInInvisibleArea = false; foreach (var invisiblearea in recommendarea.invisibleAreaForNewUserList) { if (HasRoleInArea(ref req, invisiblearea)) { hasRoleInInvisibleArea = true; break; } } if(hasRoleInInvisibleArea == false) { invisibleAreaForNewUser = true; } } foreach (AreaRealmList area in RealmlistSvc.realmListConfig.areaRealmList) { //如果配置了特殊版本 if (string.IsNullOrEmpty(area.visibleOnlyCliVersion) == false && area.visibleOnlyCliVersion != ip) { continue; } //如果强制配置成ip白名单可见,那么不在名单里的肯定不可见 if (area.visibleOnlyWhiteList == 1 && !LimitIPList.IsInWhiteList(ip, deviceId)) { continue; } //在不可见列表里? if(invisibleAreaForNewUser && AreaInInvisiableArea(area, recommendarea.invisibleAreaForNewUserList)) { continue; } var areaRealm = RealmlistSvc.areaDict[area.areaName]; visiableAreaList.Add(areaRealm); } return visiableAreaList; } public static void SendAllAreaServerIPList(List visiableAreaList, uint remoteAppID, long objectId) { CSGameAreaServerIPRes res = new CSGameAreaServerIPRes(); foreach (var area in visiableAreaList) { CSAreaServerIPInfo info = new CSAreaServerIPInfo(); info.AreaName.SetString(area.areaName); //info.AreaIP.SetString(area.areaIP); info.Timezone = area.timezone; if (area.sortedRealms.Count > 0) { info.MinRealmId = area.sortedRealms[0].realmId; info.MaxRealmId = area.sortedRealms.Last().realmId; } res.AreaInfo.Add(ref info); } RealmlistServerUtils.GetPacketSender().SendToServerByID(remoteAppID, (int)CSMsgID.GameareaServeripRes, ref res, objectId); } } }