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.
 
 
 
 
 
 

626 lines
25 KiB

/*
Sog 游戏基础库
2016 by zouwei
*/
using System;
using System.Collections.Generic;
using Sog;
using Sog.Log;
using ProtoCSStruct;
namespace Realmlist
{
public class RealmlistDBSvc
{
public static List<OneDBRealmConfig> listCfg2DB = new List<OneDBRealmConfig>();
private static int GetAllRealm(Dictionary<int, RealmConfigOneForCheck> realmMap, Dictionary<int, RealmConfigOneForCheck> realmNewMap)
{
foreach (var area in RealmlistSvc.areaDict.Values)
{
if (area.areaWorldDict == null)
{
continue;
}
foreach (var world in area.areaWorldDict.Values)
{
if (world.worldRealms == null)
{
continue;
}
foreach (var realm in world.worldRealms.Values)
{
if (realmMap.ContainsKey(realm.realmId))
{
TraceLog.Error("realm id {0} repeated!", realm.realmId);
return -1;
}
RealmConfigOneForCheck configForCheck = new RealmConfigOneForCheck();
configForCheck.realmConfig = realm.config;
configForCheck.area = area.areaName;
configForCheck.worldId = world.worldId;
realmMap.Add(realm.realmId, configForCheck);
realmNewMap.Add(realm.realmId, configForCheck);
}
foreach (var dbcfgOne in listCfg2DB)
{
if(dbcfgOne.WorldId != world.worldId)
{
continue;
}
RealmConfigOne NewConfig = new RealmConfigOne()
{
realmId = dbcfgOne.RealmId,
name = dbcfgOne.RealmName.ToString(),
showSeq = dbcfgOne.ShowSeq,
status = dbcfgOne.Status,
bdcName = dbcfgOne.BdcName.ToString(),
openTime = dbcfgOne.OpenTime.ToString(),
visibleOnlyWhiteList = dbcfgOne.VisibleOnlyWhiteList,
visibleTime = dbcfgOne.VisibleTime.ToString(),
bigRealmId = dbcfgOne.BigRealmId,
logicWorldId = dbcfgOne.LogicWorldId,
regMax = dbcfgOne.RegMax,
};
RealmInfo realmInfo = new RealmInfo
{
realmId = dbcfgOne.RealmId,
logicWorldId = dbcfgOne.LogicWorldId,
worldId = dbcfgOne.WorldId,
config = NewConfig,
runtimeState = 1, // 初始都是open
openTimeSec = ConfigStringTimeParse.ParseConfigTimeWithTimeZone(
dbcfgOne.OpenTime.ToString(), AppTime.TimeZone, area.timezone),
visibleTimeSec = ConfigStringTimeParse.ParseConfigTimeWithTimeZone(
dbcfgOne.VisibleTime.ToString(), AppTime.TimeZone, area.timezone),
};
RealmConfigOneForCheck configForCheck = new RealmConfigOneForCheck();
configForCheck.realmConfig = realmInfo.config;
configForCheck.area = area.areaName;
configForCheck.worldId = world.worldId;
if (realmNewMap.ContainsKey(realmInfo.realmId))
{
realmNewMap.Remove(realmInfo.realmId);
}
realmNewMap.Add(realmInfo.realmId, configForCheck);
}
}
}
return 0;
}
private static int CheckRealmListConfig(out int allRealmCount)
{
allRealmCount = 0;
Dictionary<int, RealmConfigOneForCheck> realmMapOld = new Dictionary<int, RealmConfigOneForCheck>();
Dictionary<int, RealmConfigOneForCheck> realmMapNew = new Dictionary<int, RealmConfigOneForCheck>();
int ret = 0;
ret = GetAllRealm(realmMapOld, realmMapNew);
if (ret != 0)
{
TraceLog.Error("GetAllRealm old error {0}", ret);
return -1;
}
allRealmCount = realmMapNew.Count;
if (!RealmlistServerUtils.GetServerConfig().checkRealmListFile)
{
TraceLog.Debug("CheckRealmListConfig checkRealmListFile is false, need not to check");
return 0;
}
TraceLog.Debug("CheckRealmListConfig checkRealmListFile is true, need to check");
TraceLog.Debug("begin check realm ");
Dictionary<string, RealmConfigOneForCheck> nameMap = new Dictionary<string, RealmConfigOneForCheck>();
foreach (var realm in realmMapNew.Values)
{
if (nameMap.ContainsKey(realm.realmConfig.name))
{
TraceLog.Error("CheckRealmListConfig check name {0} repeated", realm.realmConfig.name);
return -1;
}
nameMap.Add(realm.realmConfig.name, realm);
}
//worldid, seq
Dictionary<int, Dictionary<int, RealmConfigOneForCheck>> worldMap = new Dictionary<int, Dictionary<int, RealmConfigOneForCheck>>();
foreach (var realm in realmMapNew.Values)
{
if (!worldMap.ContainsKey(realm.worldId))
{
Dictionary<int, RealmConfigOneForCheck> newworldRealms = new Dictionary<int, RealmConfigOneForCheck>();
worldMap.Add(realm.worldId, newworldRealms);
}
Dictionary<int, RealmConfigOneForCheck> worldRealms = worldMap[realm.worldId];
if (worldRealms.ContainsKey(realm.realmConfig.showSeq))
{
TraceLog.Error("CheckRealmListConfig check seq {0} repeated realmId {1} name {2}",
realm.realmConfig.showSeq, realm.realmConfig.realmId, realm.realmConfig.name);
return -1;
}
worldRealms.Add(realm.realmConfig.showSeq, realm);
}
List<RealmConfigOneForCheck> newRealList = new List<RealmConfigOneForCheck>();
foreach (var realm in realmMapNew)
{
if (realmMapOld.ContainsKey(realm.Key) == false)
{
newRealList.Add(realm.Value);
}
}
//这个是新添加的realm
foreach (var realmForCheck in newRealList)
{
var realm = realmForCheck.realmConfig;
if (realm.name.Contains(realm.showSeq.ToString()) == false)
{
TraceLog.Error("realm {0} {1} showSeq {2} must == name id", realm.realmId, realm.name, realm.showSeq);
return -1;
}
if (string.IsNullOrEmpty(realm.visibleTime))
{
TraceLog.Error("realm {0} {1} visibleTime must config", realm.realmId, realm.name);
return -1;
}
// string jp_openTime = "00:00:00";
// if (realm.openTime.Contains(jp_openTime) == false)
// {
// TraceLog.Error("realm {0} {1} openTime {2} must be {3}", realm.realmId, realm.name, realm.openTime, jp_openTime);
// return -1;
// }
long openTime = ConfigStringTimeParse.ParseConfigTime(realm.openTime);
long visiableTime = ConfigStringTimeParse.ParseConfigTime(realm.visibleTime);
if (visiableTime < openTime)
{
TraceLog.Error("realm {0} {1} openTime {2} must < visiableTime {3}", realm.realmId, realm.name, realm.openTime, realm.visibleTime);
return -1;
}
if (openTime == 0)
{
TraceLog.Error("realm {0} {1} openTime {2} invalid", realm.realmId, realm.name, realm.openTime);
return -1;
}
if (realm.bdcName != realm.realmId.ToString())
{
TraceLog.Error("realm {0} {1} bdcName {2} must == realmId", realm.realmId, realm.name, realm.bdcName);
return -1;
}
//新增加的realmId必须和worldId匹配,老的配置可以不管
if (realm.realmId / 1000 != realmForCheck.worldId)
{
TraceLog.Error("realm {0} {1} realmId must match worldId {2}", realm.realmId, realm.name, realmForCheck.worldId);
return -1;
}
//logicWorld配置有问题
if (realm.logicWorldId / 100 != realmForCheck.worldId)
{
TraceLog.Error("realm {0} {1} logicWorldId {2} error worldId {3}", realm.realmId, realm.name, realm.logicWorldId, realmForCheck.worldId);
return -1;
}
int minBigRealmId = 1000000;
if (realm.bigRealmId < minBigRealmId)
{
TraceLog.Error("realm {0} {1} bigRealmId {2} must > {3}", realm.realmId, realm.name, realm.bigRealmId, minBigRealmId);
return -1;
}
//判断一下开服时间,是不是最近才配置上的
bool newAddRealm = false;
if (RealmlistServerUtils.GetTimeSecond() - openTime < 3600 * 24)
{
newAddRealm = true;
}
//新加的bigrealmId必须符合规则,老的就算了
if (newAddRealm && realm.bigRealmId / 10000 != realmForCheck.worldId)
{
TraceLog.Error("realm {0} {1} bigRealmId must match worldId {2}", realm.realmId, realm.name, realmForCheck.worldId);
return -1;
}
}
//检查bigRealm
Dictionary<int, List<int>> bigRealmList = new Dictionary<int, List<int>>();
foreach (var it in realmMapNew)
{
if (!bigRealmList.ContainsKey(it.Value.realmConfig.bigRealmId))
{
bigRealmList.Add(it.Value.realmConfig.bigRealmId, new List<int>());
}
bigRealmList[it.Value.realmConfig.bigRealmId].Add(it.Value.realmConfig.realmId);
}
foreach (var oneBigRealmList in bigRealmList.Values)
{
int logicWorldId = 0;
int worldId = 0;
foreach (int oneRealmId in oneBigRealmList)
{
if (realmMapNew.ContainsKey(oneRealmId))
{
int tmpWorldId = realmMapNew[oneRealmId].worldId;
if (worldId == 0)
{
worldId = tmpWorldId;
}
if (tmpWorldId == 0 || worldId != tmpWorldId)
{
TraceLog.Error("Check BigRealm realm {0} error worldId {1} head worldId {2}", oneRealmId, tmpWorldId, worldId);
return -1;
}
int tmpLogicWorldId = realmMapNew[oneRealmId].realmConfig.logicWorldId;
if (logicWorldId == 0)
{
logicWorldId = tmpLogicWorldId;
}
if (tmpLogicWorldId == 0 || logicWorldId != tmpLogicWorldId)
{
TraceLog.Error("Check BigRealm realm {0} error logicWorldId {1} head logicWorldId {2}", oneRealmId, tmpLogicWorldId, logicWorldId);
return -1;
}
}
}
}
TraceLog.Debug("end check realm ");
return 0;
}
public static void Tick5Second(long nowSec)
{
var serverData = RealmlistServerUtils.GetRealmlistServerData();
if (serverData.HadGetDBRealmCfg == 0)
{
UpdateRelamConfigFromDB();
}
}
public static int AddNewRealmFromOp2Cache(ref SSRealmOperationReq req)
{
var serverData = RealmlistServerUtils.GetRealmlistServerData();
if (serverData.dbRealmConfigs == null)
{
serverData.dbRealmConfigs = new Dictionary<int, OneDBRealmConfig>();
}
int showSeq = req.ShowSeq;
if(req.ShowSeq == 0)
{
showSeq = req.RealmId % 1000;
}
//check 失败 -2
if (!CheckRealmDBCfg(ref req))
{
TraceLog.Error("AddNewRealmFromOp2Cache error,CheckRealmDBCfg error");
return -2;
}
if (serverData.dbRealmConfigs.ContainsKey(req.RealmId))
{
TraceLog.Error("AddNewRealmFromOp2Cache error,have create realmId{0}", req.RealmId);
return -1;
}
OneDBRealmConfig configOne = new OneDBRealmConfig()
{
//BusinessName = req.BusinessName,
AreaName = req.AreaName,
WorldId = req.WorldId,
RealmId = req.RealmId,
LogicWorldId = req.LogicWorldId,
RealmName = req.RealmName,
ShowSeq = showSeq,
Status = req.Status,
VisibleOnlyWhiteList = req.VisibleOnlyWhiteList,
BdcName = req.BdcName,
OpenTime = req.OpenTime,
VisibleTime = req.VisibleTime,
BigRealmId = req.BigRealmId,
RegMax = req.RegMax,
};
listCfg2DB.Add(configOne);
if(CheckRealmListConfig(out int allRealmCount) == 0)
{
if(req.End == 1)
{
listCfg2DB.Clear();
}
SSRealmDBSaveReq reqSave = new SSRealmDBSaveReq();
reqSave.Cfg = configOne;
reqSave.IsEnd = req.End;
reqSave.Id = req.Id;
int instId = (int)ServerIDUtils.GetInstanceID(RealmlistServerUtils.GetApp().ServerID);
uint DBServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Db, instId);
RealmlistServerUtils.GetPacketSender().SendToServerByID(DBServerID, (int)SSMsgID.SsRealmDbsaveReq, ref reqSave, 0);
}
else
{
return -3;
}
return 0;
}
public static int UpdateNewRealmFromOp2Cache(ref SSRealmOperationReq req)
{
var serverData = RealmlistServerUtils.GetRealmlistServerData();
if (serverData.dbRealmConfigs == null)
{
serverData.dbRealmConfigs = new Dictionary<int, OneDBRealmConfig>();
}
//check 失败 -2
if (!CheckRealmDBCfg(ref req))
{
TraceLog.Error("UpdateNewRealmFromOp2Cache error,CheckRealmDBCfg error");
return -2;
}
bool found = false;
if(serverData.dbRealmConfigs.ContainsKey(req.RealmId))
{
found = true;
}
RealmlistSvc.worldDict.TryGetValue(req.WorldId, out WorldInfo worldInfo);
if(worldInfo!=null && worldInfo.worldRealms.ContainsKey(req.RealmId))
{
found = true;
}
if (found)
{
int showSeq = req.ShowSeq;
if (req.ShowSeq == 0)
{
showSeq = req.RealmId % 1000;
}
var oconfig = RealmlistServerUtils.GetRealmlistServerData().dbRealmConfigs[req.RealmId];
OneDBRealmConfig configOne = new OneDBRealmConfig()
{
//BusinessName = req.BusinessName,
AreaName = req.AreaName,
WorldId = req.WorldId,
RealmId = req.RealmId,
LogicWorldId = req.LogicWorldId,
RealmName = req.RealmName,
ShowSeq = showSeq,
Status = req.Status,
VisibleOnlyWhiteList = req.VisibleOnlyWhiteList,
BdcName = req.BdcName,
OpenTime = req.OpenTime,
VisibleTime = req.VisibleTime,
BigRealmId = req.BigRealmId,
RegMax = req.RegMax,
RegNum = oconfig.RegNum
};
listCfg2DB.Add(configOne);
if (CheckRealmListConfig(out int allRealmCount) == 0)
{
if (req.End == 1)
{
listCfg2DB.Clear();
}
SSRealmDBSaveReq reqSave = new SSRealmDBSaveReq();
reqSave.Cfg = configOne;
reqSave.IsEnd = req.End;
reqSave.Id = req.Id;
int instId = (int)ServerIDUtils.GetInstanceID(RealmlistServerUtils.GetApp().ServerID);
uint DBServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Db, instId);
RealmlistServerUtils.GetPacketSender().SendToServerByID(DBServerID, (int)SSMsgID.SsRealmDbsaveReq, ref reqSave, 0);
}
else
{
return -1;
}
return 0;
}
else
{
return -1;
}
}
public static void AutoSaveRealmInFile(OneDBRealmConfig configOne)
{
SSRealmDBSaveReq reqSave = new SSRealmDBSaveReq();
reqSave.Cfg = configOne;
reqSave.Notreload = 1;
int instId = (int)ServerIDUtils.GetInstanceID(RealmlistServerUtils.GetApp().ServerID);
uint DBServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Db, instId);
RealmlistServerUtils.GetPacketSender().SendToServerByID(DBServerID, (int)SSMsgID.SsRealmDbsaveReq, ref reqSave, 0);
}
public static void UpdateRelamConfigFromDB()
{
int instId = (int)ServerIDUtils.GetInstanceID(RealmlistServerUtils.GetApp().ServerID);
uint DBServerID = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Db, instId);
SSRealmDBQueryReq req = new SSRealmDBQueryReq();
req.Seq = 0;
RealmlistServerUtils.GetPacketSender().SendToServerByID(DBServerID, (int)SSMsgID.SsRealmDbqueryReq, ref req, 0);
}
public static void OnRealmCfgDBQueryRes(uint serverID, StructPacket packet)
{
var serverData = RealmlistServerUtils.GetRealmlistServerData();
if (serverData.dbRealmConfigs == null)
{
serverData.dbRealmConfigs = new Dictionary<int, OneDBRealmConfig>();
}
ref SSRealmDBQueryRes res = ref packet.GetMessage<SSRealmDBQueryRes>();
if(res.Ret != 0)
{
return;
}
if(res.IsBegin == 1)
{
serverData.dbRealmConfigs.Clear();
}
for(int i=0;i<res.Configs.Count;i++)
{
serverData.dbRealmConfigs.Add(res.Configs[i].RealmId, res.Configs[i]);
}
if(res.IsEnd == 1)
{
ReadServerConfig();
serverData.HadGetDBRealmCfg = 1;
}
}
public static void ReadServerConfig()
{
var m_app = RealmlistServerUtils.GetApp();
//读取部分表格配置文件
GameConfigMgr.Instance.ReadOneConfig("CountryAreaNameMapDesc.bin");
RealmlistServer.TestConfigTimeWithTimeZone();
TraceLog.Debug("RealmlistServer.ReadServerConfig timezone {0}", AppTime.TimeZone);
//读取配置文件
string strLogicServerConfig = m_app.GetCluster().GetAppConfigPath() + "/" + m_app.AppParam.ServerConfig.configfile;
RealmlistServerConfig serverConfig = ServerConfigMgr.Instance.ReloadServerConfig<RealmlistServerConfig>(m_app, strLogicServerConfig);
//读取游戏服务器开服列表
var serverData = RealmlistServerUtils.GetRealmlistServerData();
string strRealmListFile = m_app.GetCluster().GetAppConfigPath() + "/" + serverConfig.realmListFile;
RealmlistSvc.ReadRealmListConfig(m_app, strRealmListFile);
RecommendRealmByIP.OnReloadConfig();
}
public static bool CheckRealmDBCfg(ref SSRealmOperationReq req)
{
if (string.IsNullOrEmpty(req.AreaName.ToString()))
{
TraceLog.Error("CheckRealmCfg error, areaName is null");
return false;
}
if (string.IsNullOrEmpty(req.RealmName.ToString()))
{
TraceLog.Error("CheckRealmCfg error, realmName is null");
return false;
}
if (string.IsNullOrEmpty(req.BdcName.ToString()))
{
TraceLog.Error("CheckRealmCfg error, BdcName is null");
return false;
}
if (string.IsNullOrEmpty(req.OpenTime.ToString()))
{
TraceLog.Error("CheckRealmCfg error, OpenTime is null");
return false;
}
if (string.IsNullOrEmpty(req.VisibleTime.ToString()))
{
TraceLog.Error("CheckRealmCfg error, VisibleTime is null");
return false;
}
if (req.WorldId == 0
|| req.RealmId == 0
|| req.BigRealmId == 0
|| req.LogicWorldId == 0)
{
TraceLog.Error("CheckRealmCfg error,WorldId {0} RealmId {1} BigRealmId {2} LogicWorldId {3} ShowSeq {4}", req.WorldId, req.RealmId, req.BigRealmId, req.LogicWorldId, req.ShowSeq);
return false;
}
// string jp_openTime = "00:00:00";
// if (req.OpenTime.GetString().Contains(jp_openTime) == false)
// {
// TraceLog.Error("realm {0} {1} openTime {2} must be {3}", req.RealmId, req.RealmName, req.OpenTime.GetString(), jp_openTime);
// return false;
// }
long nowSec = RealmlistServerUtils.GetTimeSecond();
long openTimeSec = ConfigStringTimeParse.ParseConfigTime(req.OpenTime.ToString());
long visibleTimeSec = ConfigStringTimeParse.ParseConfigTime(req.VisibleTime.ToString());
if(openTimeSec > visibleTimeSec)
{
return false;
}
return true;
}
public static void OnRealmDBCfgSaveRes(uint serverID, StructPacket packet)
{
//var realmValues = RealmlistSvc.areaDict.Values;
ref SSRealmDBSaveRes res = ref packet.GetMessage<SSRealmDBSaveRes>();
if (res.Ret == 0)
{
var svrData = RealmlistServerUtils.GetRealmlistServerData();
if (svrData.dbRealmConfigs.ContainsKey(res.Cfg.RealmId))
{
svrData.dbRealmConfigs.Remove(res.Cfg.RealmId);
}
svrData.dbRealmConfigs.Add(res.Cfg.RealmId, res.Cfg);
if(res.Notreload == 0)
{
ReadServerConfig();
}
}
{
SSRealmOperationRes opRes = new SSRealmOperationRes();
opRes.Id = res.Id;
opRes.Code = res.Ret;
opRes.End = res.IsEnd;
opRes.RealmId = res.Cfg.RealmId;
int instId = (int)ServerIDUtils.GetInstanceID(RealmlistServerUtils.GetApp().ServerID);
uint OPServer = ServerIDUtils.GetLevel0ServerIDByType((int)ServerType.Operation, instId);
RealmlistServerUtils.GetPacketSender().SendToServerByID(OPServer, (int)SSMsgID.SsRealmOperationRes, ref opRes, 0);
}
}
}
}