16 卡牌服务端(GMT命令:GMT_AddPayCoin、GMT_CTG)
| | |
| | | def SendGameErrorEx(errType, msgInfo="", playerID=0):
|
| | | ErrLog("SendGameErrorEx: %s -> %s" % (errType, msgInfo), playerID)
|
| | | SendGameError(errType, msgInfo)
|
| | | #if GetGameWorld().GetDebugLevel():
|
| | | # raise Exception("%s -> %s" % (errType, msgInfo))
|
| | | if GetGameWorld().GetDebugLevel():
|
| | | raise Exception("%s -> %s" % (errType, msgInfo))
|
| | | return
|
| | |
|
| | | def SendGameError(errType, msgInfo=""):
|
| | |
| | | import IPY_ServerDefine
|
| | | import CommFunc
|
| | | from PyMongoDB import RecvPackToMapDB
|
| | | import PyMongoMain
|
| | | import PlayerTalk
|
| | |
|
| | | import datetime
|
| | |
| | | pass
|
| | |
|
| | | else:
|
| | | PyMongoMain.GetUserCtrlDB().OnPlayerLogin(curPlayer)
|
| | | PlayerMail.OnPlayerLogin(curPlayer)
|
| | | PlayerChatBox.OnPlayerLogin(curPlayer)
|
| | | PlayerFace.OnPlayerLogin(curPlayer)
|
| | |
| | | import PlayerFlashGiftbag
|
| | | import PlayerDailyGiftbag
|
| | | import PlayerFairyCeremony
|
| | | import PlayerOfflineSupport
|
| | | import PlayerNewFairyCeremony
|
| | | import PlayerActHorsePetFeast
|
| | | import PlayerFeastRedPacket
|
| | |
| | |
|
| | | def DoLogic_OnDay(tick):
|
| | | GameWorld.Log("MapServer -> OnDay!")
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | #处理所有玩家信件的onday事件, 把存在时间+1
|
| | | playerManager.ProcessAllPlayerMailOnDay()
|
| | | |
| | | #副本OnDay事件响应
|
| | | FBLogic.OnDay(tick)
|
| | |
|
| | | #删除所有的任务发布
|
| | | missionPubManager = GameWorld.GetGameWorld().GetDBMissionPubManager()
|
| | | missionPubManager.Clear()
|
| | | #仙盟
|
| | | PlayerFamily.FamilyOnDay()
|
| | |
|
| | | PlayerOfflineSupport.OnDay()
|
| | | playerManager = GameWorld.GetPlayerManager()
|
| | | for i in xrange(playerManager.GetPlayerCount()):
|
| | | curPlayer = playerManager.GetPlayerByIndex(i)
|
| | |
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package Player.PlayerOfflineSupport
|
| | | #
|
| | | # @todo:玩家离线支持能力
|
| | | # @author hxp
|
| | | # @date 2025-06-03
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 主要用于处理离线玩家相关支持的能力
|
| | | # 典型应用:
|
| | | # 1. 后台GM工具命令,玩家不在线支持,规避后台操作一定要玩家在线的限制;
|
| | | # 2. 跨服通知的玩家相关操作信息
|
| | | # 由于子服跨服通讯有一定的延迟,所以确保某些通过跨服修改玩家相关信息命令在子服玩家离线时能在上线后执行
|
| | | # 如扣物品、货币或者给奖励等,防止由玩家离线后才收到消息引起的少扣或少给
|
| | | # 3. 其他
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-06-03 14:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import DBDataMgr
|
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import traceback
|
| | | import time
|
| | |
|
| | | def AddOfflineUnprocessed(playerID, eventName, eventData, outtimeDays=7):
|
| | | '''添加玩家离线未处理的事件
|
| | | @param eventName: 事件名
|
| | | @param eventData: 事件数据,由功能自定定义,任意格式
|
| | | @param outtimeDays: 过期天数,0-永久, >0-指定天数, 默认30天
|
| | | '''
|
| | | gameRecMgr = DBDataMgr.GetGameRecMgr()
|
| | | recIDMgr = gameRecMgr.GetRecTypeIDMgr(ShareDefine.Def_GameRecType_PlayerOfflineUnprocessed, playerID)
|
| | | recData = recIDMgr.AddRecData()
|
| | | recData.SetValue1(outtimeDays)
|
| | | recData.GetUserDict().update({"eventName":eventName, "eventData":eventData})
|
| | | GameWorld.Log("添加玩家离线未处理的事件: %s, %s, %s" % (eventName, outtimeDays, eventData), playerID)
|
| | | return
|
| | |
|
| | | def DoOfflineUnprocessed(curPlayer, eventName, dofunc):
|
| | | '''执行处理玩家离线未处理的事件
|
| | | @param dofunc: 执行函数,参数[curPlayer, recData, eventName, eventData]
|
| | | '''
|
| | | if not dofunc:
|
| | | return
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | recIDMgr = DBDataMgr.GetGameRecMgr().GetRecTypeIDMgr(ShareDefine.Def_GameRecType_PlayerOfflineUnprocessed, playerID)
|
| | | # 必须按添加顺序执行,不然可能导致异常,如,先加1000金币,再扣除500,如果不按顺序执行可能导致最后金币与预期不符合
|
| | | |
| | | delRecDataList = []
|
| | | try:
|
| | | for index in range(recIDMgr.GetCount()):
|
| | | recData = recIDMgr.At(index)
|
| | | recDict = recData.GetUserDict()
|
| | | if recDict.get("eventName") != eventName:
|
| | | continue
|
| | | eventData = recDict.get("eventData")
|
| | | GameWorld.Log("执行玩家上次离线前未处理事件: %s, %s" % (eventName, eventData), playerID)
|
| | | dofunc(curPlayer, recData, eventName, eventData)
|
| | | delRecDataList.append(recData)
|
| | | except:
|
| | | accID = curPlayer.GetAccID()
|
| | | msgInfo = "eventName=%s,accID=%s, %s" % (eventName, accID, traceback.format_exc())
|
| | | GameWorld.SendGameErrorEx("DoOfflineUnprocessed", msgInfo, playerID)
|
| | | |
| | | # 执行完后再统一删除
|
| | | for recData in delRecDataList:
|
| | | recIDMgr.DelRecData(recData)
|
| | | |
| | | return
|
| | |
|
| | | def DelOfflineUnprocessed(eventName):
|
| | | ## 删除所有玩家某种离线未处理的事件
|
| | | # @param eventName: 事件名
|
| | | |
| | | delCnt = 0
|
| | | recTypeMgr = DBDataMgr.GetGameRecMgr().GetRecTypeMgr(ShareDefine.Def_GameRecType_PlayerOfflineUnprocessed)
|
| | | for recID in recTypeMgr.GetRecIDList():
|
| | | recIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
| | | for index in range(recIDMgr.GetCount())[::-1]:
|
| | | recData = recIDMgr.At(index)
|
| | | if recData.GetUserDict().get("eventName") != eventName:
|
| | | continue
|
| | | recIDMgr.DelRecData(recData)
|
| | | delCnt += 1
|
| | | |
| | | GameWorld.DebugLog("删除玩家离线未处理的事件: %s, delCnt=%s" % (eventName, delCnt))
|
| | | return
|
| | |
|
| | | def DelOuttimeOfflineUnprocessed():
|
| | | ## 删除过期玩家离线未处理的事件
|
| | | curTime = int(time.time())
|
| | | recTypeMgr = DBDataMgr.GetGameRecMgr().GetRecTypeMgr(ShareDefine.Def_GameRecType_PlayerOfflineUnprocessed)
|
| | | for recID in recTypeMgr.GetRecIDList():
|
| | | recIDMgr = recTypeMgr.GetRecIDMgr(recID)
|
| | | for index in range(recIDMgr.GetCount())[::-1]:
|
| | | recData = recIDMgr.At(index)
|
| | | recTime = recData.GetTime()
|
| | | outtimeDays = recData.GetValue1()
|
| | | if not outtimeDays:
|
| | | continue
|
| | | diffDays = GameWorld.GetDiff_Day(curTime, recTime) + 1
|
| | | if diffDays <= outtimeDays:
|
| | | continue
|
| | | recIDMgr.DelRecData(recData)
|
| | | GameWorld.DebugLog("删除玩家离线未处理的过期事件: %s, %s" % (outtimeDays, recData.GetUserData()), recID)
|
| | | return
|
| | |
|
| | | def OnDay():
|
| | | DelOuttimeOfflineUnprocessed()
|
| | | return
|
New file |
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | ##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_AddPayCoin
|
| | | #
|
| | | # @todo:GM工具命令 - 发放代币
|
| | | # @author hxp
|
| | | # @date 2025-06-03
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: GM工具命令 - 发放代币
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-06-03 14:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GMCommon
|
| | | import ShareDefine
|
| | | import DataRecordPack
|
| | | import PlayerControl
|
| | | import GameWorld
|
| | |
|
| | | ## 执行逻辑
|
| | | # @param curPlayer 当前玩家
|
| | | # @param gmCmdDict: 命令字典
|
| | | # @return None
|
| | | # @remarks 函数详细说明.
|
| | | def OnExec(gmCmdDict):
|
| | | errorMsg = ""
|
| | | from GMToolLogicProcess import ProjSpecialProcess
|
| | | Result, curPlayer = ProjSpecialProcess.GMCmdPlayerValidation(gmCmdDict)
|
| | | if Result != GMCommon.Def_Success:
|
| | | return Result, errorMsg
|
| | | if not curPlayer:
|
| | | return Result, "玩家不在线,上线后处理"
|
| | | |
| | | # 玩家在线,可处理
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | Result = GMCommon.Def_Unknow
|
| | | GMT_Name = gmCmdDict.get(GMCommon.Def_GMKey_Type, '') |
| | | |
| | | value = GameWorld.ToIntDef(gmCmdDict.get('value', ''))
|
| | | PlayerControl.GiveMoney(curPlayer, ShareDefine.TYPE_Price_PayCoin, value, "GMTAdd")
|
| | | |
| | | resultDict = {"value":value, "nowPayCoin":PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_PayCoin)}
|
| | | #流向 记录
|
| | | DataRecordPack.DR_ToolGMOperate(playerID, curPlayer.GetPlayerName(), curPlayer.GetAccID(), GMT_Name, resultDict)
|
| | | return GMCommon.Def_Success, resultDict
|
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #---------------------------------------------------------------------
|
| | | #-------------------------------------------------------------------------------
|
| | | #
|
| | | #---------------------------------------------------------------------
|
| | | ##@package GMT_CTG
|
| | | # GM命令CTG
|
| | | ##@package PyMongoDB.GMToolLogicProcess.Commands.GMT_CTG
|
| | | #
|
| | | # @author whx
|
| | | # @date 2012-08-27 13:59
|
| | | # @todo:GM工具命令 - CTG充值
|
| | | # @author hxp
|
| | | # @date 2025-06-03
|
| | | # @version 1.0
|
| | | #
|
| | | # @note
|
| | | #---------------------------------------------------------------------
|
| | | """Version = 2012-08-27 13:59"""
|
| | | #---------------------------------------------------------------------
|
| | | #导入
|
| | | # 详细描述: GM工具命令 - CTG充值
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-06-03 14:00"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import GMCommon
|
| | | from MangoDBCommon import fix_incomingText
|
| | | import GameWorld
|
| | | from Player import (PlayerControl, PlayerCoin)
|
| | | import IpyGameDataPY
|
| | | import IPY_GameWorld
|
| | | import ShareDefine
|
| | | import DataRecordPack
|
| | | import ShareDefine
|
| | | import ChConfig
|
| | | from PyMongoDB.GMToolLogicProcess import GMToolPyInterface
|
| | | import json
|
| | | #---------------------------------------------------------------------
|
| | | #全局变量
|
| | |
|
| | | #---------------------------------------------------------------------
|
| | |
|
| | | ## 收到gm命令执行
|
| | | # @param gmCmdDict:gm命令字典
|
| | | # @return None
|
| | | def OnExec(gmCmdDict):
|
| | | queryType = gmCmdDict.get(GMCommon.Def_GMKey_QueryType, '')
|
| | | playerFind = gmCmdDict.get(GMCommon.Def_GMKey_PlayerFind, '')
|
| | | Result = GMCommon.Def_ParamErr
|
| | | |
| | | errorMsg = ""
|
| | | |
| | | if queryType not in [GMCommon.Def_GMKey_PlayerAccID, GMCommon.Def_GMKey_PlayerName]:
|
| | | from GMToolLogicProcess import ProjSpecialProcess
|
| | | Result, curPlayer = ProjSpecialProcess.GMCmdPlayerValidation(gmCmdDict)
|
| | | if Result != GMCommon.Def_Success:
|
| | | return Result, errorMsg
|
| | | if not curPlayer:
|
| | | return Result, "玩家不在线,上线后处理"
|
| | |
|
| | | if len(playerFind) <= 0:
|
| | | return Result, errorMsg
|
| | | |
| | | curPlayer = None
|
| | | if queryType == GMCommon.Def_GMKey_PlayerName:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByName(playerFind)
|
| | | else:
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByAccID(playerFind)
|
| | | |
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | Result = GMCommon.Def_Success
|
| | | # 不在线
|
| | | return Result, errorMsg
|
| | |
|
| | | # 玩家在线,可处理
|
| | | playerID = curPlayer.GetPlayerID()
|
| | | |
| | | Result = GMCommon.Def_Unknow
|
| | |
|
| | | GMT_Name = gmCmdDict.get(GMCommon.Def_GMKey_Type, '') |
| | | |
| | | value = gmCmdDict.get('value', '')
|
| | | appID = gmCmdDict.get('appID', '')
|
| | | isAddBourseMoney = GameWorld.ToIntDef(gmCmdDict.get('isAddBourseMoney', ''), 0)
|
| | |
| | | changeCoinPointBefore = curPlayer.GetChangeCoinPointTotal()
|
| | | bourseMoneyBefore = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_BourseMoney)
|
| | |
|
| | |
|
| | | orderInfoIpyData = None
|
| | | if appID:
|
| | | orderInfoIpyData = IpyGameDataPY.GetIpyGameDataNotLog("OrderInfo", value, appID)
|
| | |
| | | "bourseMoney":[bourseMoneyBefore, bourseMoneyAfter]}
|
| | |
|
| | | #流向 增加金额记录
|
| | | DataRecordPack.DR_ToolGMOperate(playerID, curPlayer.GetPlayerName(), curPlayer.GetAccID(), 'GMT_CTG', resultDict)
|
| | | DataRecordPack.DR_ToolGMOperate(playerID, curPlayer.GetPlayerName(), curPlayer.GetAccID(), GMT_Name, resultDict)
|
| | |
|
| | | return Result, resultDict
|
| | | |
| | | |
| | | |
| | |
| | | from Common import (CommFuncEx, mylog)
|
| | |
|
| | | from Protocol import (MMORPGPack, RecvPackProtocol, SendPackProtocol, MergeServerRecvProtocol, MergeServerSendProtocol)
|
| | | import PlayerOfflineSupport
|
| | | import PyGameData
|
| | | import GameWorld
|
| | |
|
| | | ##################################################################
|
| | | ####### python逻辑入口 #######
|
| | |
| | |
|
| | | ##################################################################
|
| | |
|
| | | def GMCmdPlayerValidation(gmCmdDict, offlineSupport=True):
|
| | | '''后台GM工具玩家命令通用验证
|
| | | @param gmCmdDict: 命令参数字典
|
| | | @param offlineSupport: 离线玩家是否支持该命令,默认支持,当玩家离线时,会在上线后执行该命令
|
| | | @return: GMCommon.Def_xxx, curPlayer
|
| | | 非 Def_Success 的错误类型 - 代表错误,可直接返回给后台
|
| | | Def_Success, curPlayer - curPlayer为空时代表玩家离线状态
|
| | | '''
|
| | | |
| | | queryType = gmCmdDict.get(GMCommon.Def_GMKey_QueryType, '')
|
| | | playerFind = gmCmdDict.get(GMCommon.Def_GMKey_PlayerFind, '')
|
| | | |
| | | if len(playerFind) <= 0:
|
| | | return GMCommon.Def_ParamErr, None
|
| | | |
| | | # 玩家姓名
|
| | | if queryType == GMCommon.Def_GMKey_PlayerName:
|
| | | rec = PyGameData.g_usrCtrlDB.findDBPlayerByName(playerFind)
|
| | | elif queryType == GMCommon.Def_GMKey_PlayerAccID:
|
| | | rec = PyGameData.g_usrCtrlDB.findDBPlayerByAccID(playerFind)
|
| | | else:
|
| | | return GMCommon.Def_ParamErr, None
|
| | | |
| | | if not rec:
|
| | | # db找不到就是不存在该玩家
|
| | | return GMCommon.Def_NoTag, None
|
| | | |
| | | playerID = rec.get(u'PlayerID', 0)
|
| | | curPlayer = GameWorld.GetPlayerManager().FindPlayerByID(playerID)
|
| | | if not curPlayer or curPlayer.IsEmpty():
|
| | | # 离线处理
|
| | | if offlineSupport:
|
| | | PlayerOfflineSupport.AddOfflineUnprocessed(playerID, "GMToolCMD", gmCmdDict)
|
| | | return GMCommon.Def_Success, None
|
| | | return GMCommon.Def_PlayerOfLine, None
|
| | | |
| | | return GMCommon.Def_Success, curPlayer
|
| | |
|
| | | def GMCmdPlayerLogin(curPlayer):
|
| | | PlayerOfflineSupport.DoOfflineUnprocessed(curPlayer, "GMToolCMD", __doOfflineGMToolCMD)
|
| | | return
|
| | |
|
| | | def __doOfflineGMToolCMD(curPlayer, recData, eventName, eventData):
|
| | | gmCmdDict = eventData
|
| | | if not gmCmdDict or not isinstance(gmCmdDict, dict):
|
| | | return
|
| | | funcName = gmCmdDict.get(GMCommon.Def_GMKey_Type, '') |
| | | callFunc = GetExecFunc(Commands, "%s.%s" % (funcName, "OnExec"))
|
| | | if callFunc != None:
|
| | | callFunc(gmCmdDict)
|
| | | return
|
| | |
|
| | |
|
| | | ## gm命令执行
|
| | | #
|
| | |
| | | return
|
| | |
|
| | | def findDBPlayer(self, playerID):
|
| | | '''根据玩家ID查找dbPlayer
|
| | | @return: None or tagDBPlayer
|
| | | '''
|
| | | col = self.db[UCN_DBPlayer]
|
| | | dbPlayer = DataServerPlayerData.tagDBPlayer()
|
| | | dbPlayer.IsDeleted = 0
|
| | | if not dbPlayer.adoLoadCEx(col, {"PlayerID":playerID}):
|
| | | return
|
| | | return dbPlayer
|
| | | |
| | | def findDBPlayerByName(self, playerName, backDBPlayer=False):
|
| | | '''根据玩家名查找dbPlayer
|
| | | @param backDBPlayer: 可指定返回 tagDBPlayer 实例,默认false,直接返回db数据字典
|
| | | @return: None or db数据字典{k:v, ...} or tagDBPlayer
|
| | | '''
|
| | | collection = self.db[UCN_DBPlayer]
|
| | | rec = collection.find_one({'PlayerName':fix_incomingText(playerName), 'IsDeleted':0})
|
| | | if not rec:
|
| | | return
|
| | | if backDBPlayer:
|
| | | dbPlayer = DataServerPlayerData.tagDBPlayer()
|
| | | dbPlayer.readRecord(rec)
|
| | | return dbPlayer
|
| | | return rec
|
| | | |
| | | def findDBPlayerByAccID(self, accID, backDBPlayer=False):
|
| | | '''根据玩家账号查找dbPlayer
|
| | | @param backDBPlayer: 可指定返回 tagDBPlayer 实例,默认false,直接返回db数据字典
|
| | | @return: None or db数据字典{k:v, ...} or tagDBPlayer
|
| | | '''
|
| | | collection = self.db[UCN_DBPlayer]
|
| | | rec = collection.find_one({'AccID':fix_incomingText(accID), 'IsDeleted':0})
|
| | | if not rec:
|
| | | return
|
| | | if backDBPlayer:
|
| | | dbPlayer = DataServerPlayerData.tagDBPlayer()
|
| | | dbPlayer.readRecord(rec)
|
| | | return dbPlayer
|
| | | return rec
|
| | |
|
| | | def requestLogicProcess(self, pack):
|
| | | db = self.db
|
| | |
| | | self.packSend(sessionID, 0, 0, CommonDefine.atMergeLogic, MMORPGPack.stGame,
|
| | | MMORPGPack.stData, sendPack.GetBuffer())
|
| | |
|
| | |
|
| | | def OnPlayerLogin(self, curPlayer):
|
| | | ProjSpecialProcess.GMCmdPlayerLogin(curPlayer)
|
| | | return
|
| | | |
| | | def OnGMToolCommand(self, db, pack):
|
| | |
|
| | | if CommonDefine.IsDebug():
|
| | |
| | | Def_GameRecType_FamilyGCZJoinMember, # 仙盟攻城战参与成员信息, zoneID 304
|
| | | Def_GameRecType_FamilyGCZCityWall, # 仙盟攻城战城池信息, zoneID 305
|
| | | Def_GameRecType_TalkCache, # 聊天缓存,频道 306
|
| | | ) = range(300, 1 + 306)
|
| | | Def_GameRecType_PlayerOfflineUnprocessed, # 离线玩家待处理事件,playerID 307
|
| | | ) = range(300, 1 + 307)
|
| | | #通用信息记录新 - 字典key配置,如果有配置,则可额外按对应记录Value值存储字典,方便快速取值,可配置Value编号 1~8,配空默认 Value1
|
| | | Def_GameRecValueKeyDict = {
|
| | | Def_GameRecType_Xiangong:[1],
|