hxp
2025-06-03 4cdd576855c6e22d986ece4b18f7c80d82cefe38
16 卡牌服务端(GMT命令:GMT_AddPayCoin、GMT_CTG)
7个文件已修改
2个文件已删除
2个文件已添加
529 ■■■■ 已修改文件
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOfflineSupport.py 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTAddPayCoin.py 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTCTG.py 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddPayCoin.py 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CTG.py 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/GameWorld.py
@@ -2387,8 +2387,8 @@
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=""):
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/ChPlayer.py
@@ -172,6 +172,7 @@
import IPY_ServerDefine
import CommFunc
from PyMongoDB import RecvPackToMapDB
import PyMongoMain
import PlayerTalk
import datetime
@@ -872,6 +873,7 @@
        pass
    
    else:
        PyMongoMain.GetUserCtrlDB().OnPlayerLogin(curPlayer)
        PlayerMail.OnPlayerLogin(curPlayer)
        PlayerChatBox.OnPlayerLogin(curPlayer)
        PlayerFace.OnPlayerLogin(curPlayer)
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerEventCounter.py
@@ -96,6 +96,7 @@
import PlayerFlashGiftbag
import PlayerDailyGiftbag
import PlayerFairyCeremony
import PlayerOfflineSupport
import PlayerNewFairyCeremony
import PlayerActHorsePetFeast
import PlayerFeastRedPacket
@@ -137,19 +138,14 @@
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)
        
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/PlayerOfflineSupport.py
New file
@@ -0,0 +1,115 @@
#!/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
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTAddPayCoin.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/Player/RemoteQuery/GY_Query_GMTCTG.py
File was deleted
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_AddPayCoin.py
New file
@@ -0,0 +1,49 @@
#!/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
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/Commands/GMT_CTG.py
@@ -1,66 +1,47 @@
#!/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)
@@ -69,7 +50,6 @@
    changeCoinPointBefore = curPlayer.GetChangeCoinPointTotal()
    bourseMoneyBefore = PlayerControl.GetMoney(curPlayer, ShareDefine.TYPE_Price_BourseMoney)
    
    orderInfoIpyData = None
    if appID:
        orderInfoIpyData = IpyGameDataPY.GetIpyGameDataNotLog("OrderInfo", value, appID)
@@ -105,8 +85,7 @@
                  "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
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/GMToolLogicProcess/ProjSpecialProcess.py
@@ -41,6 +41,9 @@
from Common import (CommFuncEx, mylog)
from Protocol import (MMORPGPack, RecvPackProtocol, SendPackProtocol, MergeServerRecvProtocol, MergeServerSendProtocol)
import PlayerOfflineSupport
import PyGameData
import GameWorld
      
################################################################## 
                ####### python逻辑入口 ####### 
@@ -152,6 +155,58 @@
################################################################## 
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命令执行
#
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/PyMongoDB/LogicProcess/UserCtrlDB.py
@@ -415,12 +415,45 @@
        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
@@ -899,7 +932,10 @@
        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():
ServerPython/ZoneServerGroup/map1_8G/MapServer/MapServerData/Script/ShareDefine.py
@@ -1384,7 +1384,8 @@
                       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],