hch
2024-10-14 e3da0cc2f9c808c617b030a4c9e698b4a82f5799
ServerPython/CoreServerGroup/GameServer/Script/GameWorldLogic/CrossLuckyCloudBuy.py
@@ -60,8 +60,11 @@
value5:lotteryTime       开奖时间
StrValue1:luckyPlayerName    中奖玩家名
StrValue2:templateID    使用模板ID
StrValue3:lotteryInfo        分区信息|大奖信息|中奖玩家账号
'''
Def_SyncBuyRec_Count = 50
class LuckyCloudBuyNum():
    ''' 幸运云购购买号码记录
@@ -103,11 +106,12 @@
        self.serverIDRangeList = [] # 分区信息
        self.superItemInfo = [] # 大奖信息
        self.luckyPlayerAccID = "" # 中奖玩家账号
        self.templateID = 0 # 使用模板ID
        return
    
    def GetString(self):
        return {"idTime":self.idTime, "cfgID":self.cfgID, "zoneID":self.zoneID, "roundNum":self.roundNum, "luckyPlayerID":self.luckyPlayerID, 
                "lotteryNum":self.lotteryNum, "lotteryTime":self.lotteryTime, "luckyPlayerName":self.luckyPlayerName,
                "lotteryNum":self.lotteryNum, "lotteryTime":self.lotteryTime, "luckyPlayerName":self.luckyPlayerName, "templateID":self.templateID,
                "serverIDRangeList":self.serverIDRangeList, "superItemInfo":self.superItemInfo, "luckyPlayerAccID":self.luckyPlayerAccID}
        
    def SetAttrByDict(self, attrDict):
@@ -168,6 +172,7 @@
        lotteryRec.lotteryTime = recData.GetValue5()
        
        lotteryRec.luckyPlayerName = recData.GetStrValue1()
        lotteryRec.templateID = GameWorld.ToIntDef(recData.GetStrValue2())
        strValue3 = recData.GetStrValue3()
        lotteryRec.serverIDRangeList, lotteryRec.superItemInfo, lotteryRec.luckyPlayerAccID = [], [], ""
        if strValue3:
@@ -227,6 +232,7 @@
            recData.SetValue5(lotteryRec.lotteryTime)
            
            recData.SetStrValue1(lotteryRec.luckyPlayerName)
            recData.SetStrValue2("%s" % lotteryRec.templateID)
            recData.SetStrValue3("%s|%s|%s" % (str(lotteryRec.serverIDRangeList).replace(" ", ""), 
                                               str(lotteryRec.superItemInfo).replace(" ", ""), 
                                               lotteryRec.luckyPlayerAccID))
@@ -238,6 +244,7 @@
        return
    
    Sync_LuckyCloudBuyRoundInfo(curPlayer)
    Sync_LuckyCloudBuyNumRecInfo(curPlayer)
    __LoginNotifyMapCloudBuyNumInfo(curPlayer)
    return
@@ -263,41 +270,6 @@
                                   % (lotteryRec.lotteryNum, crossServerTime, GameWorld.ChangeTimeNumToStr(crossServerTime), 
                                      lotteryRec.lotteryTime, GameWorld.ChangeTimeNumToStr(lotteryRec.lotteryTime), passTime, MaxTime))
            
    if not GameWorld.IsCrossServer():
        return
    maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
    doLotteryBuyCountPer = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 3)
    doLotteryBuyCount = int(math.ceil(maxBuyCount * doLotteryBuyCountPer / 100.0))
    zoneLotteryInfo = {}
    for zoneID, lotteryRecList in PyGameData.g_luckyCloudBuyLotteryDict.items():
        if not lotteryRecList:
            continue
        lastLotteryRec = lotteryRecList[-1] # 取最后一个为最新一期
        cfgID = lastLotteryRec.cfgID
        if lastLotteryRec.lotteryNum:
            GameWorld.Log("OnDay已开奖进入新一天第一轮! cfgID=%s,zoneID=%s" % (cfgID, zoneID))
            DoStartNewRoundLuckyCloudBuy(cfgID, 1)
            continue
        buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
        buyCount = len(buyRecList)
        if len(buyRecList) >= doLotteryBuyCount:
            GameWorld.Log("OnDay未开奖但购买份数超过开奖保底份数! cfgID=%s,zoneID=%s,buyCount=%s >= %s" % (cfgID, zoneID, buyCount, doLotteryBuyCount))
            DoLuckyCloudBuyLottery(lastLotteryRec, True, "OnDay")
            continue
        GameWorld.Log("已购买份数不足开奖保底份数,重置为新一天的第一轮! cfgID=%s,zoneID=%s,buyCount=%s < %s" % (cfgID, zoneID, buyCount, doLotteryBuyCount))
        lastLotteryRec.roundNum = 1
        dataDict = {"Type":"ResetRound"}
        dataDict.update(lastLotteryRec.GetString())
        DataRecordPack.SendEventPack("LuckyCloudBuyLottery", dataDict)
        zoneLotteryInfo[zoneID] = [lastLotteryRec.GetString()]
    # 广播子服轮次信息变更
    if zoneLotteryInfo:
        dataMsg = {"syncType":"Update", "zoneLotteryInfo":zoneLotteryInfo}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyLottery, dataMsg)
    return
def DoLuckyCloudBuyLottery(lotteryRec, resetRound=False, sign=""):
@@ -382,21 +354,9 @@
    zoneLotteryInfo = {zoneID:[lotteryRec.GetString()]}
    dataMsg = {"syncType":"Update", "zoneLotteryInfo":zoneLotteryInfo}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyLottery, dataMsg)
    actInfoDict = CrossActionControl.GetCrossActInfoByCfgID(ShareDefine.CrossActName_LuckyCloudBuy, cfgID)
    if not actInfoDict or not actInfoDict[ShareDefine.ActKey_State]:
        GameWorld.Log("    不在活动中了,不开下一轮! cfgID=%s" % cfgID)
        return
    if roundNum >= IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 1):
        GameWorld.Log("    当日已达每日云购轮数上限,不开下一轮! roundNum=%s" % roundNum)
        return
    
    nextRoundNum = 1 if resetRound else (roundNum + 1)
    GameWorld.Log("幸运云购开启下一轮! cfgID=%s,zoneID=%s,roundNum=%s,resetRound=%s,nextRoundNum=%s"
                  % (cfgID, zoneID, roundNum, resetRound, nextRoundNum))
    # 开始下一轮
    return DoStartNewRoundLuckyCloudBuy(cfgID, nextRoundNum)
    return DoStartNewRoundLuckyCloudBuy(cfgID, resetRound, roundNum)
def GetMailBuyNums(buyNumList):
    buyNumList.sort()
@@ -426,58 +386,81 @@
        
    return buyNums
def OnLuckyCloudBuyReset(ipyData, state):
    ## 云购重置
def OnLuckyCloudBuyStateChange(ipyData, actIDChange, state):
    ## 云购状态变更
    cfgID = ipyData.GetCfgID()
    zoneID = ipyData.GetZoneID()
    
    startNewLottery = False
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    lastLotteryRec = None if not lotteryRecList else lotteryRecList[-1]
    # 最后一场未开奖
    if lastLotteryRec and not lastLotteryRec.lotteryNum:
        GameWorld.Log("幸运云购重置,当前轮次未开奖,直接开奖! cfgID=%s,zoneID=%s" % (lastLotteryRec.cfgID, zoneID))
        startNewLottery = DoLuckyCloudBuyLottery(lastLotteryRec, True, "Reset")
        buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
        if buyRecList:
            GameWorld.Log("幸运云购重置,当前轮次未开奖,直接开奖! cfgID=%s,zoneID=%s" % (lastLotteryRec.cfgID, zoneID))
            startNewLottery = DoLuckyCloudBuyLottery(lastLotteryRec, True, "Reset")
        else:
            GameWorld.Log("幸运云购重置,当前轮次无购买记录,不开奖! cfgID=%s,zoneID=%s,%s" % (lastLotteryRec.cfgID, zoneID, lastLotteryRec.GetString()))
            popLotteryRec = lotteryRecList.pop(-1)
            if popLotteryRec:
                GameWorld.Log("移除无效轮次信息 %s" % popLotteryRec.GetString())
    # 变更为活动中且未开启新轮次
    if state and not startNewLottery:
        GameWorld.Log("幸运云购重置,当前没有未开奖的轮次,直接开启新一轮! cfgID=%s,zoneID=%s" % (cfgID, zoneID))
        DoStartNewRoundLuckyCloudBuy(cfgID, 1)
        GameWorld.Log("幸运云购重置,当前没有未开奖的轮次,直接开启新一轮! cfgID=%s,zoneID=%s,state=%s" % (cfgID, zoneID, state))
        DoStartNewRoundLuckyCloudBuy(cfgID, True)
        
    return
def DoStartNewRoundLuckyCloudBuy(cfgID, roundNum):
def DoStartNewRoundLuckyCloudBuy(cfgID, resetRound, roundNum=0):
    # 开启新一轮云购
    actInfoDict = CrossActionControl.GetCrossActInfoByCfgID(ShareDefine.CrossActName_LuckyCloudBuy, cfgID)
    if not actInfoDict or not actInfoDict[ShareDefine.ActKey_State]:
        GameWorld.ErrLog("幸运云购非活动中,无法开启! cfgID=%s, roundNum=%s" % (cfgID, roundNum))
        GameWorld.ErrLog("幸运云购非活动中,无法开启新轮次! cfgID=%s, roundNum=%s" % (cfgID, roundNum))
        return
    state = actInfoDict[ShareDefine.ActKey_State]
    
    actIpyData = IpyGameDataPY.GetIpyGameData("CrossActLuckyCloudBuy", cfgID)
    if not actIpyData:
        return
    zoneID = actIpyData.GetZoneID()
    serverIDRangeList = actIpyData.GetServerIDRangeList()
    roundMaxList = actIpyData.GetRoundMaxList()
    templateIDList = actIpyData.GetTemplateIDList()
    if not templateIDList:
    if not roundMaxList or not templateIDList:
        return
    
    dayIndex = actInfoDict.get(ShareDefine.ActKey_DayIndex, 0)
    templateID = templateIDList[dayIndex] if len(templateIDList) > dayIndex else templateIDList[-1]
    sIndex = state - 1
    roundMax = roundMaxList[sIndex] if len(roundMaxList) > sIndex else roundMaxList[-1]
    if not resetRound and roundMax and roundNum >= roundMax:
        GameWorld.Log("    已达云购轮数上限,不开下一轮! cfgID=%s,state=%s,roundNum=%s" % (cfgID, state, roundNum))
        return
    templateID = templateIDList[sIndex] if len(templateIDList) > sIndex else templateIDList[-1]
    templateIpyData = IpyGameDataPY.GetIpyGameData("CrossActLuckyCloudBuyTemplate", templateID)
    if not templateIpyData:
        return
    
    if resetRound:
        nextRoundNum = 1
    else:
        nextRoundNum = roundNum + 1
    superItemWeightInfo = templateIpyData.GetSuperItemWeightInfo()
    superItemInfo = GameWorld.GetResultByWeightList(superItemWeightInfo)
    if not superItemInfo or len(superItemInfo) < 3:
        GameWorld.ErrLog("幸运云购生成大奖失败! zoneID=%s,roundNum=%s,superItemInfo=%s" % (zoneID, roundNum, superItemInfo))
        GameWorld.ErrLog("幸运云购生成大奖失败! cfgID=%s,zoneID=%s,nextRoundNum=%s,superItemInfo=%s" % (cfgID, zoneID, nextRoundNum, superItemInfo))
        return
    
    lotteryRec = LuckyCloudBuyLottery()
    lotteryRec.idTime = int(time.time())
    lotteryRec.cfgID = cfgID
    lotteryRec.zoneID = zoneID
    lotteryRec.roundNum = roundNum
    lotteryRec.roundNum = nextRoundNum
    lotteryRec.templateID = templateID
    
    lotteryRec.serverIDRangeList = serverIDRangeList
    lotteryRec.superItemInfo = superItemInfo
@@ -487,16 +470,21 @@
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict[zoneID]
    lotteryRecList.append(lotteryRec)
    
    PyGameData.g_luckyCloudBuyNumDict[zoneID] = [] # 新一轮情况购买记录
    PyGameData.g_luckyCloudBuyNumDict[zoneID] = [] # 新一轮清空购买记录
    
    dataDict = {"Type":"NewRound"}
    dataDict.update(lotteryRec.GetString())
    DataRecordPack.SendEventPack("LuckyCloudBuyLottery", dataDict)
    GameWorld.Log("幸运云购开启新轮次! cfgID=%s,zoneID=%s,state=%s,nextRoundNum=%s,superItemInfo=%s" % (cfgID, zoneID, state, nextRoundNum, superItemInfo))
    
    # 广播子服开奖信息
    zoneLotteryInfo = {zoneID:[lotteryRec.GetString()]}
    dataMsg = {"syncType":"New", "zoneLotteryInfo":zoneLotteryInfo}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyLottery, dataMsg)
    maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
    dataMsg = {"syncType":"All", "zoneID":zoneID, "zoneBuyNumList":[], "remainCount":maxBuyCount}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyNum, dataMsg)
    return True
def Sync_LuckyCloudBuyDataToClientServer(tick, serverGroupID=0):
@@ -517,10 +505,12 @@
    for zoneID in PyGameData.g_luckyCloudBuyLotteryDict.keys():
        zoneBuyNumList = []
        buyRecList = PyGameData.g_luckyCloudBuyNumDict.get(zoneID, [])
        for buyRec in buyRecList:
        for buyRec in buyRecList[-Def_SyncBuyRec_Count:]:
            zoneBuyNumList.append(buyRec.GetString())
            
        dataMsg = {"syncType":"All", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList}
        maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
        remainCount = max(0, maxBuyCount - len(buyRecList))
        dataMsg = {"syncType":"All", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList, "remainCount":remainCount}
        CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyNum, dataMsg)
        
    return
@@ -673,11 +663,12 @@
    DataRecordPack.SendEventPack("LuckyCloudBuyNum", dataDict)
    
    # 通知子服
    dataMsg = {"syncType":"New", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList, "buyPlayer":[serverGroupID, playerID, roundID, buyCount]}
    remainCount -= buyCount
    dataMsg = {"syncType":"New", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList, "buyPlayer":[serverGroupID, playerID, roundID, buyCount], "remainCount":remainCount}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyNum, dataMsg)
    
    # 结算开奖
    if remainCount == buyCount:
    if remainCount <= 0:
        DoLuckyCloudBuyLottery(lotteryRec, False, "SoldOut")
        
    return
@@ -728,11 +719,12 @@
        zoneBuyNumList.append(buyRec.GetString())
        
    # 通知子服
    dataMsg = {"syncType":"New", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList}
    remainCount -= buyCount
    dataMsg = {"syncType":"New", "zoneID":zoneID, "zoneBuyNumList":zoneBuyNumList, "remainCount":remainCount}
    CrossRealmMsg.SendMsgToClientServer(ShareDefine.CrossServerMsg_LuckyCloudBuyNum, dataMsg)
    
    # 结算开奖
    if remainCount == buyCount:
    if remainCount <= 0:
        DoLuckyCloudBuyLottery(lotteryRec, False, "SoldOut")
    return
@@ -742,6 +734,7 @@
    syncType = msgData["syncType"] # All New
    zoneID = msgData["zoneID"]
    zoneBuyNumList = msgData["zoneBuyNumList"]
    remainCount = msgData["remainCount"]
    
    curServerGroupID = GameWorld.GetServerGroupID()
    actInfo = CrossActionControl.GetCrossActInfoByServerGroupID(ShareDefine.CrossActName_LuckyCloudBuy, curServerGroupID)
@@ -756,6 +749,8 @@
        GameWorld.DebugLog("不是本服务器分区的云购记录不处理! curServerGroupID=%s,serverZoneID(%s) != zoneID(%s)" 
                           % (curServerGroupID, serverZoneID, zoneID))
        return
    PyGameData.g_luckyCloudBuyRemainCountDict[zoneID] = remainCount
    
    if syncType == "All":
        PyGameData.g_luckyCloudBuyNumDict = {}
@@ -782,12 +777,11 @@
    if serverGroupID != curServerGroupID:
        return
    
    templateIDList = ipyDataInfo.get("TemplateIDList")
    if not templateIDList:
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    lotteryRec = None if not lotteryRecList else lotteryRecList[-1] # 取最新一期的
    if not lotteryRec:
        return
    dayIndex = actInfo.get(ShareDefine.ActKey_DayIndex, 0)
    templateID = templateIDList[dayIndex] if len(templateIDList) > dayIndex else templateIDList[-1]
    templateID = lotteryRec.templateID
    templateIpyData = IpyGameDataPY.GetIpyGameData("CrossActLuckyCloudBuyTemplate", templateID)
    if not templateIpyData:
        return
@@ -872,31 +866,37 @@
    actInfo = CrossActionControl.GetCrossActInfoByServerGroupID(ShareDefine.CrossActName_LuckyCloudBuy, serverGroupID)
    if not actInfo:
        return
    state = actInfo.get(ShareDefine.ActKey_State)
    #state = actInfo.get(ShareDefine.ActKey_State)
    ipyDataInfo = actInfo.get(ShareDefine.ActKey_IpyDataInfo)
    if not state or not ipyDataInfo:
    if not ipyDataInfo:
        return
    zoneID = ipyDataInfo.get("ZoneID")
    if not zoneID:
        return
    
    templateIDList = ipyDataInfo.get("TemplateIDList")
    if not templateIDList:
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    lotteryRec = None if not lotteryRecList else lotteryRecList[-1] # 取最新一期的
    if not lotteryRec:
        return
    templateID = lotteryRec.templateID
    
    dayIndex = actInfo.get(ShareDefine.ActKey_DayIndex, 0)
    templateID = templateIDList[dayIndex] if len(templateIDList) > dayIndex else templateIDList[-1]
    templateIpyData = IpyGameDataPY.GetIpyGameData("CrossActLuckyCloudBuyTemplate", templateID)
    if not templateIpyData:
        return
    baseAwardInfo = templateIpyData.GetBaseAwardInfo()
    randAwardWeightInfo = templateIpyData.GetRandAwardWeightInfo()
    
    lotteryRecList = PyGameData.g_luckyCloudBuyLotteryDict.get(zoneID, [])
    lotteryRec = None if not lotteryRecList else lotteryRecList[-1] # 取最新一期的
    if not lotteryRec:
        return
    roundTimeList = []
    StartTimeList = ipyDataInfo.get("StartTimeList")
    EndTimeList = ipyDataInfo.get("EndTimeList")
    RoundMaxList = ipyDataInfo.get("RoundMaxList")
    for i, startTime in enumerate(StartTimeList):
        roundTime = ChPyNetSendPack.tagGCLuckyCloudBuyRoundTime()
        roundTime.StartTime = startTime
        roundTime.EndtTime = EndTimeList[i] if len(EndTimeList) > i else ""
        roundTime.RoundMax = RoundMaxList[i] if len(RoundMaxList) > i else 0
        roundTimeList.append(roundTime)
    superItemInfo = lotteryRec.superItemInfo + [0, 0, 0, 0, 0]
    superItemID, superItemCount, _, moneyType, moneyValue = superItemInfo[:5]
    clientPack = ChPyNetSendPack.tagGCLuckyCloudBuyRoundInfo()
@@ -904,6 +904,8 @@
    clientPack.StartDate = ipyDataInfo.get("StartDate", "")
    clientPack.EndtDate = ipyDataInfo.get("EndDate", "")
    clientPack.LVLimit = ipyDataInfo.get("LVLimit", 0)
    clientPack.RoundTimeList = roundTimeList
    clientPack.RoundTimeCount = len(clientPack.RoundTimeList)
    clientPack.RoundID = lotteryRec.idTime
    clientPack.RoundNum = lotteryRec.roundNum
    clientPack.SuperItemID = superItemID
@@ -956,12 +958,10 @@
        lotteryRec = None if not lotteryRecList else lotteryRecList[-1] # 取最新一期的
        if not lotteryRec:
            return
        syncRecList = buyRecList[-50:]
    maxBuyCount = IpyGameDataPY.GetFuncCfg("LuckyCloudBuySet", 2)
        syncRecList = buyRecList[-Def_SyncBuyRec_Count:]
        
    clientPack = ChPyNetSendPack.tagGCLuckyCloudBuyNumRecInfo()
    clientPack.RemainCount = max(0, maxBuyCount - len(buyRecList))
    clientPack.RemainCount = PyGameData.g_luckyCloudBuyRemainCountDict.get(zoneID, 0)
    clientPack.BuyNumRecList = []
    for buyRec in syncRecList:
        buyNumInfo = ChPyNetSendPack.tagGCLuckyCloudBuyNumRec()