| | |
| | | # @return 返回值无意义
|
| | | # @remarks 重新加载脚本
|
| | | def ReloadScript(scriptPath, importDir):
|
| | | gameWorld = GetGameWorld()
|
| | | tick = gameWorld.GetTick()
|
| | | |
| | | #未到刷新间隔
|
| | | if tick - gameWorld.GetTickByType(ChConfig.TYPE_Map_Tick_ReloadScript) < \
|
| | | ChConfig.TYPE_Map_Tick_Time[ChConfig.TYPE_Map_Tick_ReloadScript]:
|
| | | return
|
| | | |
| | | gameWorld.SetTickByType(ChConfig.TYPE_Map_Tick_ReloadScript, tick)
|
| | | |
| | | if __GetPsycoIsOpen():
|
| | | #Psyco开启
|
| | | PsycoReload(tick)
|
| | | return
|
| | | # gameWorld = GetGameWorld()
|
| | | # tick = gameWorld.GetTick()
|
| | | # |
| | | # #未到刷新间隔
|
| | | # if tick - gameWorld.GetTickByType(ChConfig.TYPE_Map_Tick_ReloadScript) < \
|
| | | # ChConfig.TYPE_Map_Tick_Time[ChConfig.TYPE_Map_Tick_ReloadScript]:
|
| | | # return
|
| | | # |
| | | # gameWorld.SetTickByType(ChConfig.TYPE_Map_Tick_ReloadScript, tick)
|
| | | # |
| | | # if __GetPsycoIsOpen():
|
| | | # #Psyco开启
|
| | | # PsycoReload(tick)
|
| | | # return
|
| | |
|
| | | #Psyco关闭
|
| | | __ReloadScript()
|
| | | #__ReloadScript() 不再调用,c++会触发多个Reload,py默认只在 ReloadEvent 调用一次
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | # @remarks
|
| | | def __ReloadScript():
|
| | | #重新加载已经预存的脚本
|
| | | Log("=============================== ReloadScript Begin ===============================")
|
| | | for name, reloadPath in sys.modules.items():
|
| | | try:
|
| | | pathStr = str(reloadPath)
|
| | | if "\\Lib\\" in pathStr or "\\DLLs\\" in pathStr:
|
| | | #DebugLog("Py库脚本不重读,会引起类继承出现问题导致报错! %s, %s" % (name, reloadPath))
|
| | | continue
|
| | | if name in ["PyGameData"]:
|
| | | DebugLog("%s 模块不重读!" % name)
|
| | | continue
|
| | | reload(reloadPath)
|
| | | except Exception:
|
| | | continue
|
| | |
|
| | | Log("Reload Begin : time = %s"%GetCurrentDataTimeStr())
|
| | | |
| | | import DataRecordPack
|
| | | DataRecordPack.DR_Reload("script")
|
| | | Log("=============================== ReloadScript End ===============================")
|
| | | ReadChConfig.OnReloadConfig()
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | # @return 返回值. 是否通过检查
|
| | | # @remarks 概率相关, 这个事件是否能够出现
|
| | | def CanHappen(rate, maxRate=ShareDefine.Def_MaxRateValue):
|
| | | if random.randint(0, maxRate -1) < rate:
|
| | | if rate <= 0:
|
| | | return 0
|
| | | if rate >= maxRate or random.randint(0, maxRate -1) < rate:
|
| | | return 1
|
| | |
|
| | | return 0
|
| | |
| | | return False
|
| | | #if not curPlayer.GetInitOK():
|
| | | # return False
|
| | | if IsMirrorPlayer(curPlayer):
|
| | | return False
|
| | | #if IsMirrorPlayer(curPlayer):
|
| | | # return False
|
| | | return True
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
| | | return
|
| | |
|
| | | return
|
| | |
|
| | | ## 获得指定的时间格式
|
| | | # @param timeStr 时间列表
|
| | | # @param timeFormat 指定的转换格式
|
| | | # @return 时间datetime格式
|
| | | # @remarks 获得指定的时间格式
|
| | | def GetDateTimeByFormatStr(timeStr, timeFormat):
|
| | | timeStr = timeStr.strip().split(".")[0]
|
| | | try:
|
| | | return datetime.datetime.strptime(timeStr, timeFormat)
|
| | | except BaseException , e :
|
| | | Log("%s : %s"%(e, timeStr))
|
| | | return
|
| | |
|
| | | return
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##获得与现实时间差距的小时数
|
| | | # @param dateTimeStr 比较时间字符 如"2010-05-26 11:21:25"
|
| | |
| | | dateTimeB = ChangeTimeNumToDatetime(timeB)
|
| | | dateTimeB = datetime.datetime(dateTimeB.year, dateTimeB.month, dateTimeB.day, 0, 0, 0)
|
| | | return (dateTimeA - dateTimeB).days
|
| | |
|
| | | def GetEndTimeByZeroTime(startTime, addDays):
|
| | | ## 获取结束时间,根据0点结束计算
|
| | | # @param startTime: 起始时间戳
|
| | | # @param addDays: 增加的天数,如果是1天实际为当天,即1代表当天
|
| | | startDate = ChangeTimeNumToDatetime(startTime)
|
| | | startZeroDate = datetime.datetime(startDate.year, startDate.month, startDate.day, 23, 59, 59)
|
| | | startZeroTime = int(time.mktime(startZeroDate.timetuple()))
|
| | | endTime = startTime + (startZeroTime - startTime) + max(addDays - 1, 0) * 24 * 3600
|
| | | return endTime
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##获取与当前时间相差天数的datetime格式数据
|
| | |
| | | LogUI.Msg('%s\t%s\tPyDebug:%s'%(par, playerID, msg))
|
| | | return
|
| | |
|
| | | def DebugLogEx(logFormat, *args):
|
| | | ## DEBUG调试输出信息,只传入日志格式跟参数,非debug下不进行日志内容格式化
|
| | | # @param logFormat: 日志内容格式,也可以直接传入完整的日志内容
|
| | | # @param args: 日志参数,最后一个参数可以多传一个参数作为playerID用
|
| | | if not __GameWorld.GetDebugLevel():
|
| | | return
|
| | | par = 0
|
| | | playerID = 0
|
| | | try:
|
| | | msg = logFormat % args
|
| | | except:
|
| | | msg = logFormat % args[:-1]
|
| | | playerID = args[-1]
|
| | | LogUI.Msg('%s\t%s\tPyDebug:%s'%(par, playerID, msg))
|
| | | return True
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | | ##获得当前服务器跨服ID
|
| | | # @param 无
|
| | |
| | | def GetServerVersion():
|
| | | return GetGameWorld().GetServerVersion()
|
| | |
|
| | | def GetServerGroupID():
|
| | | ## 服务器组ID,必须唯一,代表这台物理服务器
|
| | | return ToIntDef(ReadChConfig.GetPyMongoConfig("platform", "GroupID"), 0)
|
| | | def IsCrossServer():
|
| | | ## 是否跨服服务器,跨服中心跟常规跨服都算跨服
|
| | | return GetServerType() in [ShareDefine.serverType_Cross, ShareDefine.serverType_CrossCenter]
|
| | |
|
| | | def IsCrossCenter():
|
| | | ## 是否跨服中心服务器
|
| | | return GetServerType() == ShareDefine.serverType_CrossCenter
|
| | |
|
| | | def CheckCrossCenterUniquenessErr():
|
| | | ## 检查跨服中心唯一性
|
| | | # @return: 是否异常
|
| | | if not IsCrossCenter():
|
| | | return
|
| | | serverCnt = 0
|
| | | serverDict = ReadChConfig.GetServerConfigDict()
|
| | | for serverInfo in serverDict.values():
|
| | | serverType = serverInfo[ShareDefine.serverCfgIndex_ServerType]
|
| | | if serverType == ShareDefine.serverType_CrossCenter:
|
| | | serverCnt += 1
|
| | | if serverCnt > 1:
|
| | | SendGameErrorEx("CrossCenterUniquenessErr", "跨服中心只允许配置一台", isRaiseErr=True)
|
| | | return
|
| | | return
|
| | |
|
| | | def IsMainServer():
|
| | | ## 是否游戏服
|
| | | return GetServerType() == ShareDefine.serverType_Main
|
| | |
|
| | | def IsBattleServer():
|
| | | ## 是否战斗服务器
|
| | | return GetServerType() == ShareDefine.serverType_Battle
|
| | |
|
| | | def GetServerType():
|
| | | ## 本服服务器类型
|
| | | ServerType = IpyGameDataPY.GetConfigEx("ServerType")
|
| | | if ServerType == None:
|
| | | ServerType = 0
|
| | | serverDict = ReadChConfig.GetServerConfigDict()
|
| | | serverID = GetGameWorld().GetServerID()
|
| | | if serverID in serverDict:
|
| | | serverInfo = serverDict[serverID]
|
| | | ServerType = serverInfo[ShareDefine.serverCfgIndex_ServerType]
|
| | | DebugLog("加载本服服务器类型: serverID=%s,ServerType=%s,serverInfo=%s" % (serverID, ServerType, serverInfo))
|
| | | IpyGameDataPY.SetConfigEx("ServerType", ServerType)
|
| | | return ServerType
|
| | |
|
| | | def GetServerGroupName():
|
| | | ## 服务器组名,取 ServersRoute 中的配置
|
| | | return ReadChConfig.GetServersRouteConfig("platform", "GroupName")
|
| | |
|
| | | def GetMixServerDict():
|
| | | ## 获取合服信息
|
| | | # @return: {主服ID:[主服ID, 子服ID, ...], ...}
|
| | | return # 待处理,以后有合服需要再写
|
| | | #MixServerDict = IpyGameDataPY.GetConfigEx("MixServerDict")
|
| | | #if MixServerDict == None:
|
| | | # MixServerDict = {}
|
| | | # MainServerDict = {} # 所属主服ID {子服ID:主服ID, ...}
|
| | | # groupName = GetServerGroupName()
|
| | | # serverDict = ReadChConfig.GetServerConfigDict()
|
| | | # for serverInfo in serverDict.values():
|
| | | # groupName = serverInfo[ShareDefine.serverCfgIndex_GroupName]
|
| | | # serverMapID = serverInfo[ShareDefine.serverCfgIndex_MapID]
|
| | | # serverType = serverInfo[ShareDefine.serverCfgIndex_ServerType]
|
| | | # IpyGameDataPY.SetConfigEx("MixServerDict", MixServerDict)
|
| | | # IpyGameDataPY.SetConfigEx("MainServerDict", MainServerDict)
|
| | | #return MixServerDict
|
| | |
|
| | | def GetMainServerID(serverID):
|
| | | ## 获取服务器ID所属主服ID
|
| | | ServerIDMainServerDict = IpyGameDataPY.GetConfigEx("ServerIDMainServerDict")
|
| | | if ServerIDMainServerDict == None:
|
| | | filePath = ChConfig.GetServerConfigPath() + ("\\MixServerMap_%s.json" % GetPlatform())
|
| | | if not os.path.isfile(filePath):
|
| | | SendGameErrorEx("GetMainServerIDError", "file can not found. %s" % filePath)
|
| | | else:
|
| | | fileObj = open(filePath, 'rb')
|
| | | content = fileObj.read()
|
| | | fileObj.close()
|
| | | MixServerMapDict = eval(content)
|
| | | |
| | | ServerIDMainServerDict = {}
|
| | | for mainServerIDStr, serverIDList in MixServerMapDict.items():
|
| | | mainServerID = int(mainServerIDStr)
|
| | | for sID in serverIDList:
|
| | | ServerIDMainServerDict[sID] = mainServerID
|
| | | IpyGameDataPY.SetConfigEx("ServerIDMainServerDict", ServerIDMainServerDict)
|
| | | Log("加载 ServerIDMainServerDict=%s" % ServerIDMainServerDict)
|
| | | |
| | | if not ServerIDMainServerDict:
|
| | | return serverID
|
| | | return ServerIDMainServerDict.get(serverID, serverID)
|
| | |
|
| | | def GetPlatformServerNum(platform):
|
| | | # 获取服务器的平台编号
|
| | | platformNumDict = ReadChConfig.GetDBEvalChConfig("DBPlatformNum")
|
| | | #===========================================================================
|
| | | # if platform not in platformNumDict:
|
| | | # ErrLog("DBPlatformNum没有配置该服务器平台所对应的编号!platfrom=%s" % platform)
|
| | | # raise Exception("DBPlatformNum没有配置该服务器平台所对应的编号!platfrom=%s" % platform)
|
| | | #===========================================================================
|
| | | return platformNumDict.get(platform, 0)
|
| | | return serverID
|
| | | #GetMixServerDict()
|
| | | #MainServerDict = IpyGameDataPY.GetConfigEx("MainServerDict")
|
| | | #if not MainServerDict or serverID not in MainServerDict:
|
| | | # return serverID
|
| | | #return MainServerDict[serverID]
|
| | |
|
| | | ##获得当前服务器平台
|
| | | # @param 无
|
| | |
| | | def GetPlatform():
|
| | | return ReadChConfig.GetPyMongoConfig("platform", "PlatformName")
|
| | |
|
| | | #===============================================================================
|
| | | # ##获得当前服务器ID
|
| | | # # @param 无
|
| | | # # @return
|
| | | # def GetServerID():
|
| | | # return ToIntDef(GetServerSID()[1:], 0)
|
| | | #===============================================================================
|
| | | def GetAppID():
|
| | | ## 获取渠道ID
|
| | | return ReadChConfig.GetPyMongoConfig("platform", "AppID")
|
| | |
|
| | | #===============================================================================
|
| | | # def GetServerSID():
|
| | | # ##获得当前服务器ID, 带s的
|
| | | # return ReadChConfig.GetPyMongoConfig("platform", "ServerID")
|
| | | #===============================================================================
|
| | | def IsTestPlatform(platform): return platform in ["test", "yun"]
|
| | |
|
| | | def GetCreateRoleDays(curPlayer):
|
| | | # 获取创角第几天
|
| | |
| | | infoList = accID.split(Def_AccID_Split_Sign)
|
| | | return "" if len(infoList) < 3 else infoList[-1]
|
| | |
|
| | | def GetPlayerMainServerID(accIDPlatform):
|
| | | # 玩家合服后所属主服ID
|
| | | # @param accIDPlatform: 玩家账号所属的平台
|
| | | mainServerID = ToIntDef(ReadChConfig.GetPyMongoConfig("platform", "%sMainServerID" % accIDPlatform), None)
|
| | | if mainServerID != None:
|
| | | return mainServerID
|
| | | return 0
|
| | |
|
| | | def GetDBPlayerAccIDByID(playerID):
|
| | | ## 获取玩家表账号ID - 根据玩家ID, 可用于判断是否本服玩家
|
| | | return PyGameData.g_dbPlayerIDMap.get(playerID, "")
|
| | |
|
| | | def CheckServerIDInList(serverID, serverIDList):
|
| | | if serverIDList == None:
|
| | | return False
|
| | | if not serverIDList:
|
| | | return True
|
| | | for serverIDInfo in serverIDList:
|
| | | if (isinstance(serverIDInfo, (list, tuple)) and len(serverIDInfo) == 2 and serverIDInfo[0] <= serverID <= serverIDInfo[1]) \
|
| | | or (isinstance(serverIDInfo, int) and serverIDInfo == serverID):
|
| | | return True
|
| | | return False
|
| | |
|
| | | #===============================================================================
|
| | | # ƽ̨ID = appid
|
| | |
| | |
|
| | | ##获取玩家所属平台
|
| | | def GetPlayerPlatform(curPlayer):
|
| | | return curPlayer.GetAccountData().GetOperator()
|
| | | appID = curPlayer.GetAccountData().GetOperator()
|
| | | if not appID:
|
| | | appID = GetAppIDByAccID(curPlayer.GetAccID())
|
| | | return appID
|
| | |
|
| | | ##获取平台账号
|
| | | def GetPlatformAccID(gameAccID):
|
| | |
| | | paInfoList = infoList[:-2]
|
| | | platformAccID = Def_AccID_Split_Sign.join(paInfoList)
|
| | | return platformAccID
|
| | | def GetAppIDByAccID(gameAccID):
|
| | | ## 根据账号获取appID
|
| | | infoList = gameAccID.split(Def_AccID_Split_Sign)
|
| | | return infoList[-2]
|
| | |
|
| | | def GetSessionID(curPlayer):
|
| | | return md5.md5(curPlayer.GetAccID() + curPlayer.GetAccountData().GetLastLoginTime() +'mobile').hexdigest()
|
| | |
| | | randList = []
|
| | | weight = 0
|
| | | for info in weightList:
|
| | | if not info[0]:
|
| | | continue
|
| | | weight += info[0]
|
| | | randList.append([weight, info[1] if len(info) == 2 else info[1:]])
|
| | | if not randList:
|
| | |
| | |
|
| | | return inputText
|
| | |
|
| | | def IsCrossServer():
|
| | | ## 是否跨服服务器
|
| | | return ToIntDef(ReadChConfig.GetPyMongoConfig("Merge", "IsMergeServer"), 0)
|
| | |
|
| | | def GetCrossZoneName():
|
| | | ## 跨服服务器分区名,标记一起跨服分区的名字,配置在跨服服务器,子服不用配置,由跨服服务器同步
|
| | | if IsCrossServer():
|
| | | return ReadChConfig.GetPyMongoConfig("Merge", "CrossZoneName")
|
| | | return PyGameData.g_crossZoneName
|
| | |
|
| | | def GetCrossServerTimeStr():
|
| | | ## 跨服服务器时间
|
| | | if IsCrossServer():
|
| | | return GetCurrentDataTimeStr()
|
| | | lastCrossServerTime, lastServerTime, _ = PyGameData.g_crossServerTimeInfo
|
| | | if not lastCrossServerTime:
|
| | | return GetCurrentDataTimeStr()
|
| | | curTime = int(time.time())
|
| | | crossServerTime = lastCrossServerTime + (curTime - lastServerTime)
|
| | | return ChangeTimeNumToStr(crossServerTime)
|
| | |
|
| | | ## 时间格式转换成数值时间,可参考datetime.datetime.fromtimestamp(102645645)
|
| | | # @param timeNum
|
| | | # @return 时间数值 1970年起
|
| | |
| | | numValue += pow(10, dataIndex)*(dataValue - lastTagLV)
|
| | | return numValue
|
| | |
|
| | | def GetValue(dataValue, fromRight, bits):
|
| | | '''获取某个数值中,从右往左数第x位开始,截图n位得到的数据
|
| | | @param dataValue: 原始数值
|
| | | @param fromRight: 从右往左数第x位开始,从1开始
|
| | | @param bits: 截取n位
|
| | | @return: 数值value
|
| | | '''
|
| | | lPow = pow(10, fromRight)
|
| | | rPow = pow(10, fromRight - bits)
|
| | | curValue = dataValue % lPow / rPow
|
| | | return curValue
|
| | |
|
| | | def SetValue(dataValue, fromRight, bits, updValue):
|
| | | '''修改某个数值,从右往左数第x位开始,截图n位得到的数据,替换为具体数值
|
| | | @param dataValue: 原始数值
|
| | | @param fromRight: 从右往左数第x位开始,从1开始
|
| | | @param bits: 截取n位
|
| | | @param updValue: 替换值
|
| | | @return: 修改后的value值
|
| | | '''
|
| | | lPow = pow(10, fromRight)
|
| | | rPow = pow(10, fromRight - bits)
|
| | | leftValue = dataValue / lPow * lPow
|
| | | rightValue = dataValue % rPow
|
| | | return leftValue + updValue * rPow + rightValue
|
| | | |
| | | def GetBitValue(dataValue, index):
|
| | | """ 得到某个字节值中某一位(Bit)的值
|
| | | @param dataValue: 待取值的字节值
|
| | |
| | |
|
| | |
|
| | | def DebugAnswer(curPlayer, text):
|
| | | '''转码后再发DebugAnswer'''
|
| | | '''转码后再发DebugAnswer
|
| | | @param curPlayer: 跨服服务器时支持直接传入 crossPlayer
|
| | | '''
|
| | | #===========================================================================
|
| | | # if not GetGameWorld().GetDebugLevel():
|
| | | # return
|
| | | #===========================================================================
|
| | | |
| | | DebugLog(text, curPlayer.GetPlayerID())
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | if IsCrossServer():
|
| | | crossPlayer = curPlayer
|
| | | mainServerID = crossPlayer.GetMainServerID()
|
| | | if not mainServerID:
|
| | | return
|
| | | import CrossMsg
|
| | | CrossMsg.SendToClientServer(ShareDefine.C2S_GMDebugAnswer, {"text":text}, [mainServerID], playerID)
|
| | | return
|
| | | DebugLog(text, playerID)
|
| | | text = text.decode(ShareDefine.Def_Game_Character_Encoding).encode(GetCharacterEncoding())
|
| | | curPlayer.DebugAnswer(text)
|
| | | return
|
| | |
|
| | | def C2S_GMDebugAnswer(dataMsg, playerID):
|
| | | text = dataMsg["text"]
|
| | | curPlayer = GetPlayerManager().FindPlayerByID(playerID)
|
| | | if curPlayer:
|
| | | DebugAnswer(curPlayer, text)
|
| | | return
|
| | |
|
| | | def RaiseException(errorMsg, playerID=0):
|
| | |
| | | SendGameError("MapServerRaiseException", errorMsg)
|
| | | return
|
| | |
|
| | | def SendGameErrorEx(errType, msgInfo="", playerID=0):
|
| | | def SendGameErrorEx(errType, msgInfo="", playerID=0, isRaiseErr=False):
|
| | | ErrLog("SendGameErrorEx: %s -> %s" % (errType, msgInfo), playerID)
|
| | | SendGameError(errType, msgInfo)
|
| | | #if GetGameWorld().GetDebugLevel():
|
| | | # raise Exception("%s -> %s" % (errType, msgInfo))
|
| | | if isRaiseErr or GetGameWorld().GetDebugLevel():
|
| | | raise Exception("%s -> %s" % (errType, msgInfo))
|
| | | return
|
| | |
|
| | | def SendGameError(errType, msgInfo=""):
|
| | |
| | | @param msgInfo: 错误信息,可选
|
| | | '''
|
| | | getUrl = ReadChConfig.GetPyMongoConfig("EventReport", "OpenStateUrl")
|
| | | groupID = ReadChConfig.GetPyMongoConfig("platform", "GroupID")
|
| | | groupName = GetServerGroupName()
|
| | | userDBName = ReadChConfig.GetPyMongoConfig("connect", "USER_DB_NAME")
|
| | | getUrl = getUrl + "?Type=%s&groupID=%s&userDBName=%s&mapID=%s"%(errType, groupID, userDBName, GetMap().GetMapID())
|
| | | getUrl = getUrl + "?Type=%s&groupID=%s&userDBName=%s&mapID=%s"%(errType, groupName, userDBName, GetMap().GetMapID())
|
| | | if msgInfo:
|
| | | getUrl = getUrl + "&MsgInfo=%s" % urllib.quote_plus(msgInfo)
|
| | | GetGameWorld().EventReport_EventReport("", "", "", "", 0, getUrl)
|