You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1011 lines
44 KiB

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<SSGameReportRealmlistRes> resList = new List<SSGameReportRealmlistRes>();
public List<ClassSSGameReportRealmlistRes> resList = new List<ClassSSGameReportRealmlistRes>();
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<ClassSSRealmBriefRes> resList = new List<ClassSSRealmBriefRes>();
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<long, long> s_sessionSendAreaServerIpDict = new Dictionary<long, long>();
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<long> needDeleteSession = new List<long>();
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<CSGameListReq>();
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<AreaRealm> 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<SSGameReportRealmlistReq>();
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<GameGateInfo> 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);
}
}
}
/// <summary>
/// 返回全部服务器
/// </summary>
/// <param name="remoteAppID"></param>
/// <param name="packet"></param>
public static void OnRealmBriefReq(uint remoteAppID, StructPacket packet)
{
ref var req = ref packet.GetMessage<SSRealmBriefReq>();
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);
}
}
}
/// <summary>
/// 返回全部服务器
/// </summary>
/// <param name="remoteAppID"></param>
/// <param name="packet"></param>
public static void OnRealmAllBriefReq(uint remoteAppID, StructPacket packet)
{
ref var req = ref packet.GetMessage<SSRealmAllBriefReq>();
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);
}
/// <summary>
/// 查询服务器最大bigrealmid
/// </summary>
public static void OnAllRealmReq(uint remoteAppID, StructPacket packet)
{
ref var req = ref packet.GetMessage<SSAllRealmReq>();
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);
}
}
/// <summary>
/// 新增服务器
/// </summary>
public static void OnSsAddRealmReq(uint serverID, StructPacket packet)
{
RealmlistServerConfig serverConfig = RealmlistServerUtils.GetServerConfig();
ref SSAddRealmReq req = ref packet.GetMessage<SSAddRealmReq>();
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<string> lines = File.ReadAllLines(filePathName).ToList();
var addLines = new List<string>();
var newLines = new List<string>();
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<SSRealmOperationReq>();
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<SSRealmNewPlayer>();
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<AreaRealm> list)
{
foreach(var iarea in list)
{
if(iarea.areaName == area.areaName)
{
return true;
}
}
return false;
}
//获取区域的ip和timezone
public static List<AreaRealm> GetAllAreaServerIPList(ref CSGameListReq req, string ip, string deviceId, bool checkNewUserInvisibleAreaRule)
{
List<AreaRealm> visiableAreaList = new List<AreaRealm>();
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<AreaRealm> 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);
}
}
}