| | |
| | | DWORD PowerEx; //额外固定战力
|
| | | };
|
| | |
|
| | |
|
| | | //连续签到奖励表
|
| | |
|
| | | struct tagContineSignAward
|
| | | {
|
| | | BYTE _ContineDay; //连续签到天数
|
| | | list ItemID; //奖励物品ID |
| | | BYTE IsBind; //物品是否绑定 |
| | | list ItemNum; //物品奖励最小值
|
| | | list JobItemList; //职业物品列表
|
| | | };
|
| | |
|
| | | //签到奖励表
|
| | |
|
| | | struct tagSignAward
|
| | | struct SignIn
|
| | | {
|
| | | BYTE _RewardID; //奖励ID
|
| | | list ItemID; //奖励物品ID
|
| | | BYTE IsBind; //物品是否绑定 |
| | | BYTE VipLv; //vip等级
|
| | | list OrdinaryNum; //奖励物品数量
|
| | | BYTE VipMultiple; //奖励倍率 |
| | | BYTE _SignDay; //签到天
|
| | | list AwardItemList; //奖励列表
|
| | | };
|
| | |
|
| | | //VIP礼包表
|
| | |
| | |
|
| | | Def_PDict_ItemUseCntToday = "ItemUseCntToday_%s" # 物品今日使用次数, 参数为物品ID
|
| | |
|
| | | Def_PDict_DayLoginSignIsMulti = "SignIsMulti" # 是否第二月以后
|
| | | Def_PDict_DayLoginSignNum = "DayLoginSignNum" # 本轮已签到次数
|
| | | Def_PDict_TotalSignNum = "TotalSignNum" # 累计已签到次数
|
| | | Def_PDict_DayLoginSignState = "DayLoginSignState" # 当天登陆签到状态
|
| | | Def_PDict_DayLoginSignStartTime = "SignStartTime" # 本轮签到开始时间
|
| | |
|
| | | Def_PDict_GodWeaponLV = "GodWeaponLV_%s" # 神器等级, 参数神器索引
|
| | | Def_PDict_GodWeaponExp = "GodWeaponExp_%s" # 神器等级对应祝福值经验, 参数神器索引
|
| | | Def_PDict_GodWeaponState = "GodWeaponState" # 神器是否已经激活, 按索引位存储神器是否激活
|
| | |
| | | Def_PDict_DropCountToday = "DropCountToday_%s" # 今日物品已掉落次数,参数(物品ID)
|
| | | Def_PDict_DropColorToday = "DropColorToday_%s" # 今日装备品质已掉落次数,参数(装备品质)
|
| | |
|
| | | # 签到
|
| | | Def_PDict_SignInState = "SignInState_%s" # 按位记录每日签到状态,参数(key编号),状态:0-不可签到;1-已签到;2-可补签;3-已领取
|
| | | Def_PDict_SignInLastDay = "SignInLastDay" # 最后一次签到是第x天
|
| | |
|
| | | # 跑环
|
| | | Def_PDict_RunTaskAwardState = "RunTaskAwardState_%s" # 是否已领取跑环本轮结束奖励 参数任务类型
|
| | | Def_PDict_RunTaskAwardRecord = "RunTaskAwardRecord_%s" # 跑环本轮结束奖励记录 参数任务类型
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #A5 09 玩家签到 #tagCMDaySign
|
| | | #A5 09 玩家签到领奖 #tagCSDaySign
|
| | |
|
| | | class tagCMDaySign(Structure):
|
| | | class tagCSDaySign(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("Day", c_ubyte), #默认0表示当日签到,可扩展做补签用
|
| | | ("Day", c_ubyte), # 第x天,从1开始
|
| | | ]
|
| | |
|
| | | def __init__(self):
|
| | |
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagCMDaySign)
|
| | | return sizeof(tagCSDaySign)
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''//A5 09 玩家签到 //tagCMDaySign:
|
| | | DumpString = '''//A5 09 玩家签到领奖 //tagCSDaySign:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | Day:%d
|
| | |
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagCMDaySign=tagCMDaySign()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCMDaySign.Cmd,m_NAtagCMDaySign.SubCmd))] = m_NAtagCMDaySign
|
| | | m_NAtagCSDaySign=tagCSDaySign()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagCSDaySign.Cmd,m_NAtagCSDaySign.SubCmd))] = m_NAtagCSDaySign
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | |
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | | #A3 0D 玩家签到信息记录 # tagMCDaySignInfo
|
| | | #A3 0D 玩家签到信息记录 # tagSCDaySignInfo
|
| | |
|
| | | class tagMCDaySignInfo(Structure):
|
| | | _pack_ = 1
|
| | | _fields_ = [
|
| | | ("Cmd", c_ubyte),
|
| | | ("SubCmd", c_ubyte),
|
| | | ("DaySignCount", c_ubyte), #已经签到天数
|
| | | ("ReplenishSignCount", c_ubyte), # 可以补签天数
|
| | | ("IsSign", c_ubyte), #当天是否已经签到,发送0和1
|
| | | ("IsFrist", c_ubyte), #是否是第一个月
|
| | | ("TotalSignCount", c_ushort), #累计总签到天数
|
| | | ]
|
| | | class tagSCDaySignInfo(Structure):
|
| | | Head = tagHead()
|
| | | Count = 0 #(BYTE Count)
|
| | | SignStateList = list() #(vector<BYTE> SignStateList)//每日签到状态记录列表 [第1天状态, ...] 状态:0-不可签到;1-已签到;2-可补签;3-已领取
|
| | | data = None
|
| | |
|
| | | def __init__(self):
|
| | | self.Clear()
|
| | | self.Cmd = 0xA3
|
| | | self.SubCmd = 0x0D
|
| | | self.Head.Cmd = 0xA3
|
| | | self.Head.SubCmd = 0x0D
|
| | | return
|
| | |
|
| | | def ReadData(self, stringData, _pos=0, _len=0):
|
| | | def ReadData(self, _lpData, _pos=0, _Len=0):
|
| | | self.Clear()
|
| | | memmove(addressof(self), stringData[_pos:], self.GetLength())
|
| | | return _pos + self.GetLength()
|
| | | _pos = self.Head.ReadData(_lpData, _pos)
|
| | | self.Count,_pos = CommFunc.ReadBYTE(_lpData, _pos)
|
| | | for i in range(self.Count):
|
| | | value,_pos=CommFunc.ReadBYTE(_lpData,_pos)
|
| | | self.SignStateList.append(value)
|
| | | return _pos
|
| | |
|
| | | def Clear(self):
|
| | | self.Cmd = 0xA3
|
| | | self.SubCmd = 0x0D
|
| | | self.DaySignCount = 0
|
| | | self.ReplenishSignCount = 0
|
| | | self.IsSign = 0
|
| | | self.IsFrist = 0
|
| | | self.TotalSignCount = 0
|
| | | self.Head = tagHead()
|
| | | self.Head.Clear()
|
| | | self.Head.Cmd = 0xA3
|
| | | self.Head.SubCmd = 0x0D
|
| | | self.Count = 0
|
| | | self.SignStateList = list()
|
| | | return
|
| | |
|
| | | def GetLength(self):
|
| | | return sizeof(tagMCDaySignInfo)
|
| | | length = 0
|
| | | length += self.Head.GetLength()
|
| | | length += 1
|
| | | length += 1 * self.Count
|
| | |
|
| | | return length
|
| | |
|
| | | def GetBuffer(self):
|
| | | return string_at(addressof(self), self.GetLength())
|
| | | data = ''
|
| | | data = CommFunc.WriteString(data, self.Head.GetLength(), self.Head.GetBuffer())
|
| | | data = CommFunc.WriteBYTE(data, self.Count)
|
| | | for i in range(self.Count):
|
| | | data = CommFunc.WriteBYTE(data, self.SignStateList[i])
|
| | | return data
|
| | |
|
| | | def OutputString(self):
|
| | | DumpString = '''//A3 0D 玩家签到信息记录 // tagMCDaySignInfo:
|
| | | Cmd:%s,
|
| | | SubCmd:%s,
|
| | | DaySignCount:%d,
|
| | | ReplenishSignCount:%d,
|
| | | IsSign:%d,
|
| | | IsFrist:%d,
|
| | | TotalSignCount:%d
|
| | | DumpString = '''
|
| | | Head:%s,
|
| | | Count:%d,
|
| | | SignStateList:%s
|
| | | '''\
|
| | | %(
|
| | | self.Cmd,
|
| | | self.SubCmd,
|
| | | self.DaySignCount,
|
| | | self.ReplenishSignCount,
|
| | | self.IsSign,
|
| | | self.IsFrist,
|
| | | self.TotalSignCount
|
| | | self.Head.OutputString(),
|
| | | self.Count,
|
| | | "..."
|
| | | )
|
| | | return DumpString
|
| | |
|
| | |
|
| | | m_NAtagMCDaySignInfo=tagMCDaySignInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagMCDaySignInfo.Cmd,m_NAtagMCDaySignInfo.SubCmd))] = m_NAtagMCDaySignInfo
|
| | | m_NAtagSCDaySignInfo=tagSCDaySignInfo()
|
| | | ChNetPackDict[eval("0x%02x%02x"%(m_NAtagSCDaySignInfo.Head.Cmd,m_NAtagSCDaySignInfo.Head.SubCmd))] = m_NAtagSCDaySignInfo
|
| | |
|
| | |
|
| | | #------------------------------------------------------
|
| | |
| | | import GameWorld
|
| | | import ShareDefine
|
| | | import GameWorldEvent
|
| | | import PlayerSignDay
|
| | | import DBDataMgr
|
| | | import ChPlayer
|
| | |
|
| | |
| | | MixDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_MixServerDay) + 1
|
| | | OpenWeekday = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_OpenServerWeekday)
|
| | | GameWorld.DebugAnswer(curPlayer, '开服星期%s, 天数:%s 是否合服:%s, 合服天数:%s' % (OpenWeekday, ServerDay, IsMixServer, MixDay))
|
| | | PlayerSignDay.ResetDaySign(curPlayer)
|
| | |
|
| | | # 暂时同步GameServer,之后可去除
|
| | | return True
|
| | |
| | | #
|
| | | ##@package GM.Commands.SetSignDay
|
| | | #
|
| | | # @todo:设置签到
|
| | | # @todo:签到
|
| | | # @author hxp
|
| | | # @date 2018-03-29
|
| | | # @date 2025-10-09
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 设置签到
|
| | | # 详细描述: 签到
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2018-03-29 11:00"""
|
| | | #"""Version = 2025-10-09 16:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import PlayerControl
|
| | | import PlayerSignDay
|
| | | import GameWorld
|
| | | import PlayerSignDay
|
| | | import ChConfig
|
| | |
|
| | | import datetime
|
| | | import time
|
| | | #---------------------------------------------------------------------
|
| | | ## 设置每日签到
|
| | | # @param curPlayer 玩家实例
|
| | | # @param cmdList 参数列表
|
| | | # @return None
|
| | | # @remarks |
| | | def OnExec(curPlayer, cmdList):
|
| | | if len(cmdList) == 1 and cmdList[0] == 0:
|
| | | PlayerSignDay.ResetDaySign(curPlayer)
|
| | | PlayerSignDay.Sync_SignDayInfo(curPlayer)
|
| | | |
| | | startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignStartTime) # 开始时间
|
| | | GameWorld.DebugAnswer(curPlayer, "重置签到OK!%s" % GameWorld.ChangeTimeNumToStr(startTime))
|
| | | PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
|
| | | return
|
| | |
|
| | | if not cmdList:
|
| | | GameWorld.DebugAnswer(curPlayer, "设置:SetSignDay 已签次数 可补次数 是否次月 累计签到次数")
|
| | | GameWorld.DebugAnswer(curPlayer, "重置:SetSignDay 0")
|
| | | GameWorld.DebugAnswer(curPlayer, "重置签到: SetSignDay 0")
|
| | | GameWorld.DebugAnswer(curPlayer, "设置签到: SetSignDay 天 状态")
|
| | | GameWorld.DebugAnswer(curPlayer, "状态:1-已签到;2-可补签;3-已领取")
|
| | | return
|
| | |
|
| | | signNum = cmdList[0]
|
| | | canAddSignNum = cmdList[1] if len(cmdList) > 1 else 0
|
| | | isMulti = cmdList[2] if len(cmdList) > 2 else 0
|
| | | totalSignNum = cmdList[3] if len(cmdList) > 3 else signNum
|
| | | value = cmdList[0]
|
| | | if value <= 0:
|
| | | GameWorld.DebugAnswer(curPlayer, "重置签到")
|
| | | PlayerSignDay.ResetDaySign(curPlayer)
|
| | | return
|
| | |
|
| | | curTime = int(time.time())
|
| | | curDateTime = GameWorld.ChangeTimeNumToDatetime(curTime)
|
| | | |
| | | startDateTime = curDateTime - datetime.timedelta(days=(signNum + canAddSignNum))
|
| | | startTimeStr = str(startDateTime)
|
| | | startTime = GameWorld.ChangeTimeStrToNum(startTimeStr)
|
| | | |
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignState, 0) # 默认当前未签到
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignNum, signNum)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TotalSignNum, totalSignNum)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignIsMulti, isMulti)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignStartTime, startTime)
|
| | | day = value
|
| | | state = cmdList[1] if len(cmdList) > 1 else 0
|
| | | GameWorld.DebugAnswer(curPlayer, "设置签到: 天:%s, 状态:%s" % (day, state))
|
| | | GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_SignInState, day - 1, state, False)
|
| | | PlayerSignDay.Sync_SignDayInfo(curPlayer)
|
| | | |
| | | PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
|
| | | GameWorld.DebugAnswer(curPlayer, "设置已签次数:%s,可补次数:%s,是否次月:%s" % (signNum, canAddSignNum, isMulti))
|
| | | GameWorld.DebugAnswer(curPlayer, "本轮开始签到时间:%s" % (startTimeStr))
|
| | | return
|
| | |
|
| | |
| | | ("DWORD", "PowerEx", 0),
|
| | | ),
|
| | |
|
| | | "ContineSignAward":(
|
| | | ("BYTE", "ContineDay", 1),
|
| | | ("list", "ItemID", 0),
|
| | | ("BYTE", "IsBind", 0),
|
| | | ("list", "ItemNum", 0),
|
| | | ("list", "JobItemList", 0),
|
| | | ),
|
| | |
|
| | | "SignAward":(
|
| | | ("BYTE", "RewardID", 1),
|
| | | ("list", "ItemID", 0),
|
| | | ("BYTE", "IsBind", 0),
|
| | | ("BYTE", "VipLv", 0),
|
| | | ("list", "OrdinaryNum", 0),
|
| | | ("BYTE", "VipMultiple", 0),
|
| | | "SignIn":(
|
| | | ("BYTE", "SignDay", 1),
|
| | | ("list", "AwardItemList", 0),
|
| | | ),
|
| | |
|
| | | "VIPAward":(
|
| | |
| | | def GetUnLockSkill(self): return self.attrTuple[4] # 解锁的技能 list
|
| | | def GetPowerEx(self): return self.attrTuple[5] # 额外固定战力 DWORD |
| | | |
| | | # 连续签到奖励表 |
| | | class IPY_ContineSignAward(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetContineDay(self): return self.attrTuple[0] # 连续签到天数 BYTE
|
| | | def GetItemID(self): return self.attrTuple[1] # 奖励物品ID list
|
| | | def GetIsBind(self): return self.attrTuple[2] # 物品是否绑定 BYTE
|
| | | def GetItemNum(self): return self.attrTuple[3] # 物品奖励最小值 list
|
| | | def GetJobItemList(self): return self.attrTuple[4] # 职业物品列表 list |
| | | |
| | | # 签到奖励表 |
| | | class IPY_SignAward(): |
| | | class IPY_SignIn(): |
| | | |
| | | def __init__(self): |
| | | self.attrTuple = None |
| | | return |
| | | |
| | | def GetRewardID(self): return self.attrTuple[0] # 奖励ID BYTE
|
| | | def GetItemID(self): return self.attrTuple[1] # 奖励物品ID list
|
| | | def GetIsBind(self): return self.attrTuple[2] # 物品是否绑定 BYTE
|
| | | def GetVipLv(self): return self.attrTuple[3] # vip等级 BYTE
|
| | | def GetOrdinaryNum(self): return self.attrTuple[4] # 奖励物品数量 list
|
| | | def GetVipMultiple(self): return self.attrTuple[5] # 奖励倍率 BYTE |
| | | def GetSignDay(self): return self.attrTuple[0] # 签到天 BYTE
|
| | | def GetAwardItemList(self): return self.attrTuple[1] # 奖励列表 list |
| | | |
| | | # VIP礼包表 |
| | | class IPY_VIPAward(): |
| | |
| | | self.__LoadFileData("TongTianTask", onlyCheck)
|
| | | self.__LoadFileData("Treasure", onlyCheck)
|
| | | self.__LoadFileData("TreasureUp", onlyCheck)
|
| | | self.__LoadFileData("ContineSignAward", onlyCheck)
|
| | | self.__LoadFileData("SignAward", onlyCheck)
|
| | | self.__LoadFileData("SignIn", onlyCheck)
|
| | | self.__LoadFileData("VIPAward", onlyCheck)
|
| | | self.__LoadFileData("AuctionItem", onlyCheck)
|
| | | self.__LoadFileData("VipPrivilege", onlyCheck)
|
| | |
| | | self.CheckLoadData("TreasureUp") |
| | | return self.ipyTreasureUpCache[index]
|
| | | |
| | | def GetContineSignAwardCount(self): |
| | | self.CheckLoadData("ContineSignAward") |
| | | return self.ipyContineSignAwardLen
|
| | | def GetContineSignAwardByIndex(self, index): |
| | | self.CheckLoadData("ContineSignAward") |
| | | return self.ipyContineSignAwardCache[index]
|
| | | |
| | | def GetSignAwardCount(self): |
| | | self.CheckLoadData("SignAward") |
| | | return self.ipySignAwardLen
|
| | | def GetSignAwardByIndex(self, index): |
| | | self.CheckLoadData("SignAward") |
| | | return self.ipySignAwardCache[index]
|
| | | def GetSignInCount(self): |
| | | self.CheckLoadData("SignIn") |
| | | return self.ipySignInLen
|
| | | def GetSignInByIndex(self, index): |
| | | self.CheckLoadData("SignIn") |
| | | return self.ipySignInCache[index]
|
| | | |
| | | def GetVIPAwardCount(self): |
| | | self.CheckLoadData("VIPAward") |
| | |
| | |
|
| | | curPlayer.SetDict(ChConfig.Def_PlayerKey_MixServerFirstLogin, 1)
|
| | |
|
| | | PlayerSignDay.ResetDaySign(curPlayer) # 重置签到
|
| | | |
| | | # 重置首充双倍
|
| | | PlayerCoin.DoResetCTGCount(curPlayer, "MixServer")
|
| | |
|
| | |
| | | import ShareDefine
|
| | | import IpyGameDataPY
|
| | | import PlayerControl
|
| | | import PlayerSignDay
|
| | | import PlayerActBuyCountGift
|
| | | import PlayerActLoginNew
|
| | | import PlayerActTask
|
| | |
| | |
|
| | | # 功能开启需执行的函数{功能ID:执行函数, ...} 函数需返回是否激活成功, 功能开启有需要处理功能逻辑的这里增加函数调用配置即可
|
| | | FuncOpenLogicDict = {
|
| | | ShareDefine.GameFuncID_SignDay:lambda curObj:PlayerSignDay.DoSignDayOpen(curObj),
|
| | | ShareDefine.GameFuncID_Arena:lambda curObj:PlayerArena.DoArenaOpen(curObj),
|
| | | }
|
| | |
|
| | |
| | |
|
| | | def SendMailByKey(mailTypeKey, playerID, itemList, paramList=[], limitDays=7):
|
| | | ## 发送个人邮件魔板
|
| | | # @param itemList: 元素支持字典{itemID:itemCount, ...} 或列表 [itemID, itemCount, 可选是否拍品, 物品UserData]
|
| | | if not mailTypeKey:
|
| | | mailTypeKey = ShareDefine.DefaultLackSpaceMailType
|
| | | title = "<T>%s</T>" % mailTypeKey
|
| | |
| | |
|
| | | def SendMail(playerID, title, text, itemList=None, limitDays=7, mailType=0):
|
| | | ## 发送个人邮件
|
| | | # @param itemList: 元素支持字典{itemID:itemCount, ...} 或列表 [itemID, itemCount, 可选是否拍品, 物品UserData]
|
| | | if itemList == None:
|
| | | itemList = []
|
| | | |
| | | if isinstance(itemList, dict):
|
| | | itemList = [[itemID, itemCount] for itemID, itemCount in itemList.items()]
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailMax = IpyGameDataPY.GetFuncCfg("PersonalMail", 1)
|
| | | mailCnt = mailMgr.GetPersonalMailCount(playerID)
|
| | |
| | | def SendSeverMail(guid, title, text, itemList=None, limitDays=7, mailType=0, limitLV=0, limitLVType=0, checkState=0):
|
| | | '''发送全服邮件
|
| | | @param guid: 可传入空,则系统自动生成guid
|
| | | @param itemList: 元素支持字典{itemID:itemCount, ...} 或列表 [itemID, itemCount, 可选是否拍品, 物品UserData]
|
| | | @param limitLV: 限制可领的最低等级
|
| | | @param limitLVType: 等级达到后是否可领,默认不可
|
| | | @param checkState: 是否需要审核,默认不需要
|
| | | @return: None - 发送失败; mailObj - 成功发送的邮件实例
|
| | | '''
|
| | | if itemList == None:
|
| | | itemList = []
|
| | | if isinstance(itemList, dict):
|
| | | itemList = [[itemID, itemCount] for itemID, itemCount in itemList.items()]
|
| | | mailMgr = DBDataMgr.GetMailMgr()
|
| | | mailObj = mailMgr.AddServerMail(guid, title, text, itemList, limitDays, mailType)
|
| | | if not mailObj:
|
| | |
| | | #!/usr/bin/python
|
| | | # -*- coding: GBK -*-
|
| | | #
|
| | | #
|
| | | ##@package PlayerSignDay
|
| | | #
|
| | | # @todo: 每日签到
|
| | | #
|
| | | # @author jiang
|
| | | # @date 2012-03-23
|
| | | # @version 1.8
|
| | | # @note:
|
| | | # @change: "2013-03-13 17:00" wdb 删除封包
|
| | | # @change: "2013-10-31 11:00" hxp 修改每日签到逻辑
|
| | | # @change: "2013-11-05 20:20" hxp 增加过天通知签到记录情况
|
| | | # @change: "2014-04-03 22:00" xmnathan 每日签到逻辑修改,增加VIP补签
|
| | | # @change: "2015-06-16 15:40" ljd 修改成类登陆奖励,补登
|
| | | # @change: "2015-08-03 16:40" ljd 补签次数从VIP 挪到 贵族
|
| | | # @change: "2015-08-24 14:40" zqx 增加签到成就
|
| | | # @change: "2016-10-26 11:00" hxp 签到逻辑修改
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2016-10-26 11:00"""
|
| | | #
|
| | | ##@package Player.PlayerSignDay
|
| | | #
|
| | | # @todo:签到
|
| | | # @author hxp
|
| | | # @date 2025-10-09
|
| | | # @version 1.0
|
| | | #
|
| | | # 详细描述: 签到
|
| | | #
|
| | | #-------------------------------------------------------------------------------
|
| | | #"""Version = 2025-10-09 16:30"""
|
| | | #-------------------------------------------------------------------------------
|
| | |
|
| | | import ObjPool
|
| | | import DBDataMgr
|
| | | import PlayerMail
|
| | | import ShareDefine
|
| | | import NetPackCommon
|
| | | import IPY_GameWorld
|
| | | import ItemControler
|
| | | import DataRecordPack
|
| | | import ChPyNetSendPack
|
| | | import PlayerTongTianLing
|
| | | import PlayerActTask
|
| | | import PlayerPet
|
| | | import PlayerControl
|
| | | import IpyGameDataPY
|
| | | import GameWorld
|
| | | import ChConfig
|
| | | import GameFuncComm
|
| | | import IpyGameDataPY
|
| | | import ItemCommon
|
| | |
|
| | | import time
|
| | | #===============================================================================
|
| | | #//A5 09 玩家签到 #tagCMDaySign
|
| | | # struct tagCMDaySign
|
| | | SignInState_None = 0
|
| | | SignInState_Sign = 1 # 已签到
|
| | | SignInState_Supplement = 2 # 可补签
|
| | | SignInState_Got = 3 # 已领取
|
| | |
|
| | | #//A5 09 玩家签到领奖 #tagCSDaySign
|
| | | #
|
| | | #struct tagCSDaySign
|
| | | #{
|
| | | # tagHead Head;
|
| | | # BYTE Day; //默认0表示当日签到,从1表示补签。
|
| | | # BYTE Day; // 第x天,从1开始
|
| | | # };
|
| | | #===============================================================================
|
| | | ## 玩家签到封包入口
|
| | | # @param index: 玩家索引
|
| | | # @param clientData: 封包结构体
|
| | | # @param tick: 时间戳
|
| | | # @return: None
|
| | | def OnSignDay(index, clientData, tick):
|
| | | # 跨服服务器功能限制
|
| | | if GameWorld.IsCrossServer():
|
| | | return
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | #功能开启判断
|
| | | if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_SignDay):
|
| | | GameWorld.DebugLog("玩家等级不足,未开启签到功能 PlayerLv=%s" % curPlayer.GetLV())
|
| | | signDay = clientData.Day
|
| | | |
| | | bit = signDay - 1
|
| | | state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_SignInState, bit, False)
|
| | | if state == SignInState_Got:
|
| | | GameWorld.DebugLog("该天已签到领奖过了! signDay=%s" % signDay)
|
| | | return
|
| | |
|
| | | curPlayer = GameWorld.GetPlayerManager().GetPlayerByIndex(index)
|
| | | signDay = clientData.Day # 0-正常签到;1-补签
|
| | | isAddLogin = 1 if signDay else 0 # 是否补签
|
| | | |
| | | if not isAddLogin:
|
| | | #是否今天已经签到
|
| | | signState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignState)
|
| | | if signState:
|
| | | GameWorld.DebugLog("今日已签到过!")
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("SignIn", signDay)
|
| | | if not ipyData:
|
| | | return
|
| | | signCost = 0
|
| | | else:
|
| | | #本轮累计可补签次数
|
| | | canAddSignNum = GetCanAddSignNum(curPlayer)
|
| | | #是否有剩余补签次数
|
| | | if canAddSignNum <= 0:
|
| | | GameWorld.DebugLog("已经没有补签次数,补签失败!canAddSignNum=%s" % canAddSignNum)
|
| | | return
|
| | | #获取需要消耗玩家仙玉 |
| | | signCost = IpyGameDataPY.GetFuncCfg("SignConsumption")
|
| | | if not PlayerControl.HaveMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, signCost, True):
|
| | | GameWorld.DebugLog("补签所需货币不足! signCost=%s" % signCost)
|
| | | awardItemList = ipyData.GetAwardItemList()
|
| | | if not awardItemList:
|
| | | return
|
| | |
|
| | | #获得签到天数
|
| | | curSignNum = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignNum) + 1
|
| | | totalSignNum = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TotalSignNum) + 1
|
| | | |
| | | #获得签到累计奖励表某日信息 |
| | | awardInfo = IpyGameDataPY.GetIpyGameData("SignAward", curSignNum)
|
| | | if not awardInfo:
|
| | | GameWorld.DebugLog("找不到签到奖励! 签到第(%s)次" % curSignNum)
|
| | | moneyType, moneyValue = 0, 0
|
| | | # 补签
|
| | | if state == SignInState_Supplement:
|
| | | moneyType, moneyValue = IpyGameDataPY.GetFuncEvalCfg("SignInSet", 1)
|
| | | if not PlayerControl.HaveMoney(curPlayer, moneyType, moneyValue):
|
| | | return
|
| | | elif state != SignInState_Sign:
|
| | | GameWorld.DebugLog("当前天签到状态不可领取签到奖励! signDay=%s,state=%s" % (signDay, state))
|
| | | return
|
| | |
|
| | | #获得列信息
|
| | | itemIDList = awardInfo.GetItemID()
|
| | | ordinaryNumList = awardInfo.GetOrdinaryNum()
|
| | | isBind = awardInfo.GetIsBind()
|
| | | vipLv = awardInfo.GetVipLv()
|
| | | vipMultiple = awardInfo.GetVipMultiple()
|
| | | #判断是否是第二月以后
|
| | | isMulti = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignIsMulti)
|
| | | if not isMulti:
|
| | | itemID = itemIDList[0]
|
| | | ordinaryNum = ordinaryNumList[0]
|
| | | else:
|
| | | itemID = itemIDList[1]
|
| | | ordinaryNum = ordinaryNumList[1] |
| | | #判断是否需要Vip多倍 |
| | | curVipLV = curPlayer.GetVIPLv()
|
| | | if curVipLV >= vipLv:
|
| | | ordinaryNum *= vipMultiple
|
| | | if moneyType and moneyValue:
|
| | | PlayerControl.PayMoney(curPlayer, moneyType, moneyValue, ChConfig.Def_Cost_AddSignDay)
|
| | | befValue, updValue = GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_SignInState, bit, SignInState_Got, False)
|
| | | GameWorld.DebugLog("签到领奖: signDay=%s,state=%s,befValue=%s,updValue=%s" % (signDay, state, befValue, updValue))
|
| | |
|
| | | #记录签到信息
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignNum, curSignNum)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TotalSignNum, totalSignNum)
|
| | | if not isAddLogin:
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignState, 1)
|
| | | |
| | | #支付仙玉
|
| | | if signCost > 0:
|
| | | PlayerControl.PayMoney(curPlayer, IPY_GameWorld.TYPE_Price_Gold_Money, signCost, ChConfig.Def_Cost_AddSignDay)
|
| | | |
| | | #签到奖励信息
|
| | | awardInfoList = [[itemID, ordinaryNum, isBind]]
|
| | | |
| | | #给予签到奖励物品
|
| | | __GivePlayerItemByItemInfoList(curPlayer, awardInfoList, "SignToPlayer")
|
| | | |
| | | #累计签到奖励信息
|
| | | contineAwardInfoList = []
|
| | | |
| | | #获得连续签到奖励表信息
|
| | | contineAwardInfo = IpyGameDataPY.GetIpyGameData("ContineSignAward", curSignNum)
|
| | | if not contineAwardInfo:
|
| | | GameWorld.DebugLog("找不到连续签到奖励! 签到第(%s)次" % curSignNum)
|
| | | else:
|
| | | jobItemList = contineAwardInfo.GetJobItemList()
|
| | | itemIDList = contineAwardInfo.GetItemID()
|
| | | itemNumList = contineAwardInfo.GetItemNum()
|
| | | awardIndex = 1 if (len(itemIDList) > 1 and isMulti) else 0
|
| | | itemID = itemIDList[awardIndex]
|
| | | itemCount = itemNumList[awardIndex]
|
| | | if itemID in jobItemList and curPlayer.GetJob() <= len(jobItemList):
|
| | | itemID = jobItemList[curPlayer.GetJob() - 1]
|
| | | contineAwardInfoList = [[itemID, itemCount, contineAwardInfo.GetIsBind()]]
|
| | | #for index in xrange(len(itemIDList)): |
| | | # contineAwardInfoList.append([itemIDList[index], itemNumList[index], itemIsBind])
|
| | | |
| | | #给予累计奖励物品 |
| | | __GivePlayerItemByItemInfoList(curPlayer, contineAwardInfoList, "ContineSignToPlayer")
|
| | | PlayerControl.NotifyCode(curPlayer, 'SignInText')
|
| | | #同步客户端 |
| | | ItemControler.GivePlayerItemOrMail(curPlayer, awardItemList, event=["SignDay", False, {}])
|
| | | Sync_SignDayInfo(curPlayer)
|
| | | |
| | | addDataDict = {"signNum":curSignNum, "vipLV":curVipLV, "itemInfo":str(awardInfoList + contineAwardInfoList),
|
| | | "isAddSign":isAddLogin, "CostMoney":str([IPY_GameWorld.TYPE_Price_Gold_Money, signCost])}
|
| | | DataRecordPack.DR_FuncGiveItem(curPlayer, "DayLoginSignAward", addDataDict)
|
| | | GameWorld.DebugLog("%s: %s" % ("补签" if isAddLogin else "签到", addDataDict), curPlayer.GetPlayerID())
|
| | | ItemControler.NotifyGiveAwardInfo(curPlayer, awardInfoList + contineAwardInfoList, "SignDay")
|
| | | |
| | | # 刷签到附加功能属性
|
| | | PlayerPet.CalcPetItemAddPlayerAttr(curPlayer)
|
| | | PlayerControl.PlayerControl(curPlayer).RefreshPlayerAttrState()
|
| | | |
| | | petLearnSkillList, petPassiveSkillList = PlayerPet.GetPetLearnSkill(curPlayer)
|
| | | if ChConfig.Def_SkillID_PetSignDay in petPassiveSkillList:
|
| | | signDayAttrSkill = GameWorld.GetGameData().GetSkillBySkillID(ChConfig.Def_SkillID_PetSignDay)
|
| | | if signDayAttrSkill:
|
| | | curEffect = signDayAttrSkill.GetEffect(0)
|
| | | PlayerControl.NotifyCode(curPlayer, "SignInText2", [ChConfig.Def_SkillID_PetSignDay, curEffect.GetEffectID(), curEffect.GetEffectValue(0)])
|
| | | |
| | | PlayerTongTianLing.AddTongTianTaskValue(curPlayer, ChConfig.TTLTaskType_Sign, 1)
|
| | | PlayerActTask.AddActTaskValue(curPlayer, ChConfig.ActTaskType_Sign)
|
| | | return
|
| | |
|
| | | ## 签到总奖励天数
|
| | | def GetSignAwardCountMax(): return IpyGameDataPY.IPY_Data().GetSignAwardCount()
|
| | |
|
| | | def DoSignDayOpen(curPlayer):
|
| | | ResetDaySign(curPlayer)
|
| | | return
|
| | | def GetSignAwardCountMax(): return IpyGameDataPY.IPY_Data().GetSignInCount()
|
| | |
|
| | | def SignDayOnLogin(curPlayer):
|
| | | ''' 玩家上线 '''
|
| | | #功能开启判断
|
| | | if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_SignDay):
|
| | | #GameWorld.DebugLog("玩家未开启签到功能 PlayerLv=%s" % curPlayer.GetLV())
|
| | | return |
| | | Sync_SignDayInfo(curPlayer)
|
| | | __doAutoSingIn(curPlayer)
|
| | | return
|
| | |
|
| | | def SignDayOnDay(curPlayer):
|
| | | ''' 玩家过天 '''
|
| | | #功能开启判断
|
| | | if not GameFuncComm.GetFuncCanUse(curPlayer, ShareDefine.GameFuncID_SignDay):
|
| | | GameWorld.DebugLog("玩家攻击不足,未开启签到功能 PlayerLv=%s" % curPlayer.GetLV())
|
| | | return |
| | | curSignNum = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignNum)
|
| | | #签到天数已满最大值,刷新榜单
|
| | | if curSignNum >= GetSignAwardCountMax():
|
| | | GameWorld.DebugLog("累计签到天数满重置! curSignNum=%s" % curSignNum)
|
| | | ResetDaySign(curPlayer, 1)
|
| | | __doAutoSingIn(curPlayer)
|
| | | return
|
| | |
|
| | | #刷新是否签到记录
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignState, 0)
|
| | | Sync_SignDayInfo(curPlayer)
|
| | | def ResetDaySign(curPlayer):
|
| | | ## 重置签到
|
| | | |
| | | signInMax = GetSignAwardCountMax()
|
| | | GameWorld.DebugLog("重置签到: signInMax=%s" % (signInMax), curPlayer.GetPlayerID())
|
| | | |
| | | #补发未领取奖励
|
| | | mailItemDict = {}
|
| | | for day in range(1, 1 + signInMax):
|
| | | state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_SignInState, day - 1, False)
|
| | | if state != SignInState_Sign: # 已签到未领取的
|
| | | continue
|
| | | ipyData = IpyGameDataPY.GetIpyGameData("SignIn", day)
|
| | | if not ipyData:
|
| | | break
|
| | | awardItemList = ipyData.GetAwardItemList()
|
| | | for itemInfo in awardItemList:
|
| | | itemID, itemCount = itemInfo[:2]
|
| | | mailItemDict[itemID] = mailItemDict.get(itemID, 0) + itemCount
|
| | | GameWorld.DebugLog("签到未领取奖励补发: day=%s,awardItemList=%s,%s" % (day, awardItemList, mailItemDict), curPlayer.GetPlayerID())
|
| | | if mailItemDict:
|
| | | PlayerMail.SendMailByKey("SignDay", curPlayer.GetPlayerID(), mailItemDict)
|
| | | |
| | | keyNumMax = signInMax / 9 + 1 # 每个可以记录9天的状态
|
| | | for num in range(keyNumMax):
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_SignInState % num, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_SignInLastDay, 0)
|
| | | __doAutoSingIn(curPlayer)
|
| | | return
|
| | |
|
| | | def ResetDaySign(curPlayer, isMulti=0):
|
| | | ''' 重置签到 |
| | | @param isMulti: 是否次月起
|
| | | '''
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignIsMulti, isMulti)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignNum, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignState, 0)
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_DayLoginSignStartTime, int(time.time()))
|
| | | if isMulti:
|
| | | Sync_SignDayInfo(curPlayer)
|
| | | def __doAutoSingIn(curPlayer):
|
| | | ## 执行自动签到,仅做签到标记,非领奖
|
| | | |
| | | signInMax = GetSignAwardCountMax()
|
| | | lastDay = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_SignInLastDay)
|
| | | |
| | | isMixServer = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_IsMixServer)
|
| | | if isMixServer:
|
| | | serverDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_MixServerDay) + 1
|
| | | else:
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_TotalSignNum, 0)
|
| | | serverDay = DBDataMgr.GetEventTrigMgr().GetValue(ShareDefine.Def_ServerDay) + 1
|
| | | |
| | | if lastDay:
|
| | | signInRound = (serverDay - 1) / signInMax
|
| | | signInRoundLast = (lastDay - 1) / signInMax
|
| | | if signInRound != signInRoundLast:
|
| | | ResetDaySign(curPlayer)
|
| | | return
|
| | |
|
| | | def GetCanAddSignNum(curPlayer):
|
| | | ## 获取可补签天数
|
| | | curTime = int(time.time())
|
| | | startTime = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignStartTime) # 开始时间
|
| | | if not startTime:
|
| | | return 0
|
| | | if curTime < startTime:
|
| | | return 0
|
| | | signNumMax = GetSignAwardCountMax()
|
| | | signNumMax = min(GameWorld.GetDiff_Day(curTime, startTime) + 1, signNumMax) # 最大可签到次数
|
| | | signState = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignState) # 今日是否已签到
|
| | | signCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignNum) # 已签到次数
|
| | | signNumRemain = signNumMax - signCount # 剩余可签到次数
|
| | | if not signState:
|
| | | signNumRemain -= 1
|
| | | signNumRemain = max(0, signNumRemain)
|
| | | #GameWorld.DebugLog("最大可签到次数=%s,已签到次数=%s,今天是否已签到=%s,可补签次数=%s" |
| | | # % (signNumMax, signCount, signState, signNumRemain), curPlayer.GetPlayerID())
|
| | | return signNumRemain
|
| | | canSignInMax = (serverDay - 1) % signInMax + 1
|
| | | for day in range(1, 1 + canSignInMax):
|
| | | bit = day - 1
|
| | | if GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_SignInState, bit, False):
|
| | | continue
|
| | | state = SignInState_Sign if day == canSignInMax else SignInState_Supplement
|
| | | GameWorld.SetDictValueByBit(curPlayer, ChConfig.Def_PDict_SignInState, bit, state, False)
|
| | | GameWorld.DebugLog("更新签到状态: day=%s/%s,state=%s,isMixServer=%s,serverDay=%s" % (day, signInMax, state, isMixServer, serverDay))
|
| | |
|
| | | ## 通知签到次数奖励领取情况
|
| | | # @param curPlayer: 玩家实例
|
| | | # @return: None
|
| | | PlayerControl.NomalDictSetProperty(curPlayer, ChConfig.Def_PDict_SignInLastDay, serverDay)
|
| | | Sync_SignDayInfo(curPlayer)
|
| | | return True
|
| | |
|
| | | def Sync_SignDayInfo(curPlayer):
|
| | | signInfo = ChPyNetSendPack.tagMCDaySignInfo()
|
| | | signInfo.Clear()
|
| | | signInfo.DaySignCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignNum)
|
| | | signInfo.ReplenishSignCount = GetCanAddSignNum(curPlayer)
|
| | | signInfo.IsSign = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignState)
|
| | | isFrist = 0 if curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_DayLoginSignIsMulti) else 1
|
| | | signInfo.IsFrist = isFrist
|
| | | signInfo.TotalSignCount = curPlayer.NomalDictGetProperty(ChConfig.Def_PDict_TotalSignNum)
|
| | | NetPackCommon.SendFakePack(curPlayer, signInfo)
|
| | | signInMax = GetSignAwardCountMax()
|
| | | clientPack = ObjPool.GetPoolMgr().acquire(ChPyNetSendPack.tagSCDaySignInfo)
|
| | | clientPack.SignStateList = []
|
| | | for bit in range(signInMax):
|
| | | state = GameWorld.GetDictValueByBit(curPlayer, ChConfig.Def_PDict_SignInState, bit, False)
|
| | | clientPack.SignStateList.append(state)
|
| | | clientPack.Count = len(clientPack.SignStateList)
|
| | | NetPackCommon.SendFakePack(curPlayer, clientPack)
|
| | | return
|
| | |
|
| | | ##给予玩家物品
|
| | | def __GivePlayerItemByItemInfoList(curPlayer, awardInfoList, mailTypeKey): |
| | | signCount = len(awardInfoList)
|
| | | |
| | | packSpace = ItemCommon.GetItemPackSpace(curPlayer, IPY_GameWorld.rptItem, signCount)
|
| | | if packSpace >= signCount:
|
| | | for awardInfo in awardInfoList:
|
| | | ItemControler.GivePlayerItem(curPlayer, awardInfo[0], awardInfo[1], 0, [IPY_GameWorld.rptItem]) |
| | | else: |
| | | GameWorld.DebugLog("背包已满 邮件发送物品")
|
| | | PlayerControl.SendMailByKey(mailTypeKey, [curPlayer.GetPlayerID()], awardInfoList)
|
| | | return
|
| | |
|
| | |
|
| | |
| | | # 游戏功能ID定义,需确保唯一,与PyGameFuncControl.txt中FuncId一致
|
| | | GameFuncID_Official = 12 # 官爵,境界
|
| | | GameFuncID_Family = 15 # 战盟,仙盟
|
| | | GameFuncID_SignDay = 81 # 签到
|
| | | GameFuncID_Arena = 195 # 竞技场
|
| | |
|
| | | # 以下为暂时无用的
|