def cb(ret): for marryRow in ret.result: marryId = long(marryRow[0]) marryTotalInfo = MarryTotalInfo(marryId) marryTotalInfo.assginFromDB(marryRow) #定时举行婚礼 if marryTotalInfo.flagWeding == MsgDef.WeddingFlagCmd.WEDDING_APPLYED: leftSec = ffext.getTime() - marryTotalInfo.tmWedding if leftSec <= 0 or marryTotalInfo.tmWedding == 0: leftSec = 30 #ffext.dump('timer wedding', leftSec, marryTotalInfo) def cb(): handleTimerWedding(marryId) ffext.timer(leftSec*1000, cb) #如果和谐离婚,定时离婚 if marryTotalInfo.tmEndWedding != 0 and marryTotalInfo.getInfoByGender(Base.Gender.MALE).status == MsgDef.MarryStatusCmd.MARRY_STATUS_DIVORCING and \ marryTotalInfo.getInfoByGender(Base.Gender.FEMAIL).status == MsgDef.MarryStatusCmd.MARRY_STATUS_DIVORCING: leftSec = marryTotalInfo.tmEndWedding - ffext.getTime() if leftSec <= 0: leftSec = 10 def cbDiv(): handleTimerDivorce(marryId) #ffext.timer(leftSec*1000, cbDiv) #ffext.dump('marry divorcing left sec', leftSec, marryId) #如果婚礼未举行 self.allMarryInfo[marryTotalInfo.marryId] = marryTotalInfo #ffext.dump('load marryTotalInfo', marryTotalInfo) #ffext.dump('load self.allMarryInfo', len(self.allMarryInfo)) return
def processLogout(session): print(__name__, session.player) player = session.player if not player: return #发消息通知 mapObj = player.mapObj if mapObj: mapObj.playerLeaveMap(player) #如果地图属性配置了下线后踢到某地图,那么改一下地图和坐标 cfg = mapObj.cfg if cfg.offlineMap != None: player.mapname = cfg.offlineMap.mapname player.x = cfg.offlineMap.x player.y = cfg.offlineMap.y ffext.info('logout name=%s, offlineMap=%s, x=%d, y=%d' % (player.name, player.mapname, player.x, player.y)) elif player.isDeath() and cfg.reviveMap != None: player.mapname = cfg.reviveMap.mapname player.x = cfg.reviveMap.x player.y = cfg.reviveMap.y ffext.info('logout name=%s, reviveMap=%s, x=%d, y=%d' % (player.name, player.mapname, player.x, player.y)) #下线计算本次在线时长 player.gametime = player.gametime + (ffext.getTime() - player.logintime) player.last_logout = ffext.getTime() DbService.getPlayerService().updatePlayer(player) #DbService.getPlayerService().updatePlayer(player) from handler import MarryHandler MarryHandler.processOffline(session) #MARRY_OFFLINE TeamHandler.processTeamOps( session, MsgDef.TeamMsgReq(MsgDef.TeamClientCmd.QUIT_TEAM, 0)) TeamHandler.processBrotherDownline(session)
def onWeeklyNightEvent(self): ffext.dump( "***************** New Week Process Begin ... ******************:", ffext.getTime()) #所有在线玩家对象,每日refresh ffext.getSessionMgr().foreach(self.weeklyRefresh4Session) ffext.dump( "***************** New Week Process End ... ******************:", ffext.getTime()) return True
def addGuild(self, guildid, guildname, guildchiefname): now = ffext.datetime_to_str(ffext.datetime_from_time(ffext.getTime())) sql = "insert into guildinfo (guildid, guildname, guildimage, guildnotice, guildlevel, guildexp, guildchiefname, lastdatecontribution, lastdate) \ values ('%d', '%s', '', '', 1, 0, '%s', 0, '%s') " % ( guildid, guildname, guildchiefname, now) DbServiceBase.getDB().query(sql) return True
def exe(self, owner, skill, objDest, param): #TODO from model import PlayerModel newX = owner.x + 2 newY = owner.y + 2 if not owner.mapObj.canMove(newX, newY): newX = owner.x newY = owner.y player = PlayerModel.Player() player.forkFrom(owner, self.paramPropRate) player.arenaCtrl.destPlayerRef = weakref.ref(objDest) player.session = owner.session owner.mapObj.playerEnterMap(player, newX, newY) from model import ArenaModel player.fsm.changeState(ffext.singleton(ArenaModel.ArenaStateAttack)) beginTm = ffext.getTime() def cb(): if ffext.getTime() - beginTm >= 20 or player.isDeath(): player.mapObj.playerLeaveMap(player) player.session = None else: try: player.fsm.update(player, ffext.getTimeMs()) except: pass ffext.timer(1000, cb) ffext.timer(1000, cb) return
def initTimer(self): nowSec = ffext.getTime() secondUtilMiddleNight = SECONDS_PER_DAY - (nowSec % SECONDS_PER_DAY) nowTm = ffext.datetime_now() weekDay = nowTm.weekday() if weekDay == 0: weekDay = 7 nowCompVal = weekDay * 10000 + nowTm.hour * 100 + nowTm.minute for wd, tmInfo in CITYWAR_START_TM_LIST.iteritems(): tmCompVal_1 = wd * 10000 + tmInfo[0] tmCompVal_2 = wd * 10000 + tmInfo[1] if nowCompVal >= tmCompVal_1: # 目前配置时间点已经过了,算到本周日结束的时间 secondUtilWeekEnd = secondUtilMiddleNight + ( 7 - weekDay) * SECONDS_PER_DAY tm2 = secondUtilWeekEnd + (wd - 1) * SECONDS_PER_DAY + ( tmInfo[0] / 100) * 3600 + (tmInfo[0] % 100) * 60 ffext.timer(tm2 * 1000, onCityWarStart) else: # 目前配置时间还没来,还可以再打一场 tm1 = nowSec % SECONDS_PER_DAY tm2 = (tmInfo[0] / 100) * 3600 + (tmInfo[0] % 100) * 60 ffext.timer((tm2 - tm1) * 1000, onCityWarStart) pass return True
def onMiddleNightEvent(self): ffext.dump( "***************** New Day Process Begin ... ******************:", ffext.getTime()) #添加每日凌晨更新时间到这里,依次处理 self.updateRefreshTime() #每日排行榜刷新 RankModel.getRankMgr().dailyRefresh() #所有在线玩家对象,每日refresh ffext.getSessionMgr().foreach(self.dailyRefresh4Session) ffext.dump( "***************** New Day Process End ... ******************:", ffext.getTime()) return True
def __init__(self, owner): self.ownerref = weakref.ref(owner) self.uid = 0 self.level = 1 self.exp = 0 self.createTime = ffext.getTime() self.cfg = None
def updateBuffMsg(self, uid=None): nowTm = ffext.getTime() for k, v in self.buffCtrl.allBuff.iteritems(): v.endTime -= nowTm retMsg = MsgDef.UpdateBuffRet(self.buffCtrl.allBuff, uid) self.broadcast(MsgDef.ServerCmd.UPDATE_BUFF, retMsg) for k, v in self.buffCtrl.allBuff.iteritems(): v.endTime += nowTm
def update(self, monster, nowMs): if monster.hp <= 0: monster.lastAttackObjRef = None if nowMs < monster.nextMoveTm + 10*1000: return True else: if nowMs - monster.tmpInfo.get('_killedtm_', 0) <= 2000:#2秒内不要消失 return True #先从地图上消失.,再出现 mapObj = monster.mapObj oldMon = mapObj.monsterLeaveMap(monster) #ffext.dump('monster leave map start reborn', monster.name) def reborn(): oldMon.hp = oldMon.hpMax oldMon.x = oldMon.bornX oldMon.y = oldMon.bornY mapObj.monsterEnterMap(oldMon, oldMon.x, oldMon.y) if mapObj.copyMapHandler == None and oldMon.rebornSec > 0: ffext.timer(1000*oldMon.rebornSec, reborn) #ffext.dump('monster reborn', monster.name) return True if nowMs < monster.nextMoveTm: if monster.lastAttackObjRef != None: targetObj = monster.lastAttackObjRef() if targetObj != None:#直接进入攻击模式 ffext.dump(monster.name, 'find target', targetObj.name) monster.fsm.changeState(ffext.singleton(StateAttack)) return True #回血 if monster.hp < monster.hpMax: nowTm = ffext.getTime() nAddHP = int((nowTm - monster.lastRecoverHPTM) * monster.hpMax / 100) if nAddHP > 0: monster.addHPMsg(nAddHP) # 如果仇恨列表中有敌人在线,那么切换到战斗状态 if monster.aiFlag == 0:#被动攻击 if monster.lastAttackObjRef != None: targetObj = monster.lastAttackObjRef() if targetObj != None:#直接进入攻击模式 ffext.dump(monster.name, 'find target', targetObj.name) monster.fsm.changeState(ffext.singleton(StateAttack)) return True enemyObj = monster.selectEnemy() if enemyObj: monster.fsm.changeState(ffext.singleton(StateAttack)) return True #先朝一个方向走,走到头,再随机选一个方向 curDir = monster.direction if Base.distance(monster.x, monster.y, monster.bornX, monster.bornY) >= monster.calMaxReachEnemyDistance(): curDir = int((curDir + 4 ) % 8) desrDir= Base.MOVE_HELP_DIRECTION[curDir] curDir = desrDir[random.randint(0, len(desrDir) - 1)] monster.direction = curDir x, y = Base.getPosByDirection(monster.x, monster.y, curDir) monster.nextMoveTm = nowMs + random.randint(5000, 10000) monster.mapObj.moveMonster(monster, x, y) return True
def cb(): if ffext.getTime() - beginTm >= 20 or player.isDeath(): player.mapObj.playerLeaveMap(player) player.session = None else: try: player.fsm.update(player, ffext.getTimeMs()) except: pass ffext.timer(1000, cb)
def openCopyMap(self, player): guildInfo = player.guildCtrl.guildInfo mapObj = self.guildName2CoypMap.get(guildInfo.guildID) if mapObj: return mapObj mapObj = GuildCopy.create( guildInfo) #MapMgr.getMapMgr().allocMap('10002')# if mapObj: self.guildName2CoypMap[guildInfo.guildID] = mapObj guildInfo.copymapEndTm = ffext.getTime() + 30 return mapObj
def onStart(self, mapObj): if not mapObj: return False # 1. 清理战场先(以防万一) if self.statueMonster: MonsterModel.destroyMonster(self.statueMonster) self.statueMonster = None # 2. spawn雕像 retMon = MonsterModel.genMonsterById(mapObj.mapname, CITYWAR_STATUE_ID, CITYWAR_STATUE_X, CITYWAR_STATUE_Y, 1, 2) if len(retMon) >= 1: self.statueMonster = retMon[0] # 3. 通知双方行会 inform_msg = MsgDef.GuildCityWarOpsMsgRet() inform_msg.opstype = MsgDef.GuildCityWarOpsCmd.CITYWAR_START inform_msg.tmStart = ffext.getTime() self.startTime = ffext.getTime() self.attackGuild.sendMsg2OnlineMember(MsgDef.ServerCmd.GUILD_CITYWAR_MSG, inform_msg) if self.defendGuild: self.defendGuild.sendMsg2OnlineMember(MsgDef.ServerCmd.GUILD_CITYWAR_MSG, inform_msg) # 4. 通知全服? return True
def handleTimer(self, mapObj): #ffext.dump('CopyMapHandler handleTimer', len(mapObj.allPlayer)) n = ffext.getTime() if n - self.createTime >= LIMIT_SEC: self.onEnd() if self.autoPlayerRef != None: player = self.autoPlayerRef() if player and player.mapObj: nowMs = ffext.getTimeMs() player.fsm.update(player, nowMs) else: self.autoPlayerRef = None return True
def createNewMail(player, type, title, msg, listAtt = None): mail = Mail() mail.id = idtool.allocId() mail.type = type if player: mail.sender = playerToMailPlayer(player) else: mail.sender = None mail.title = title mail.msg = msg mail.sendTime = ffext.getTime() if listAtt == None: listAtt = [] mail.listAttach = listAtt return mail
def checkTimeAfterInit(self): ffext.dump("last_logout:", self.last_logout, " gametime", self.gametime) if self.last_logout == 0: return True now = ffext.getTime() if ffext.tmIsSameDay(now, self.last_logout): #跨天了 self.dailyRefresh() #是否跨周 nowTm = ffext.datetime_now() if nowTm.weekday() == 0: self.weeklyRefresh() pass return True
def processPetEggStartReq(session, msg): player = session.player petCtrl = player.petCtrl petEgg = petCtrl.petEgg item = player.itemCtrl.getItem(msg.uid) if not item: retErr = Base.lang('道具不存在!') session.sendMsg(MsgDef.ServerCmd.ERROR_MSG, buildErrMsg(MsgDef.ClientCmd.PET_EGG_START, retErr)) return item = player.itemCtrl.delItem(msg.uid) petEgg.eggItemCfgId = item.itemCfg.cfgId petEgg.starttm = ffext.getTime() petEgg.needsec = 10 processQueryPet(session) return
def completeEgg(self): #完成孵化 nowtm = ffext.getTime() if self.petEgg.eggItemCfgId == 0: return False if nowtm < self.petEgg.starttm + self.petEgg.needsec: return False player = self.ownerref() pet = Pet(player) pet.uid = idtool.allocUid() cfgid = 1 pet.cfg = getPetMgr().getCfgById(cfgid) self.allPet[pet.uid] = pet DbService.getPlayerService().addPet(player, pet) self.petEgg.eggItemCfgId = 0 self.petEgg.starttm = 0 self.petEgg.needsec = 0 return pet
def checkOnInit(self): nowTime = ffext.getTime() nowTm = ffext.datetime_now() if self.last_refresh_time > 0: if ffext.tmIsSameDay(self.last_refresh_time, nowTime): #服务器重启时,跨越了凌晨 self.onMiddleNightEvent() # 是否跨周 if nowTm.weekday() == 0: self.onWeeklyNightEvent() pass # 计算出到达午夜的时间,启动定时器 secondUtilMiddleNight = SECONDS_PER_DAY - (nowTime % SECONDS_PER_DAY) ffext.timer(secondUtilMiddleNight * 1000, self.onMiddleNightEvent) # 计算到达下一个周(一)午夜的时间,启动定时器 secondUtilNextWeek = secondUtilMiddleNight + ( 6 - nowTm.weekday()) * SECONDS_PER_DAY ffext.timer(secondUtilNextWeek * 1000, self.onWeeklyNightEvent) return
def recoverHpMp(session): player = session.player if player.getSinType() != PkSinType.WHITE: curTm = ffext.getTime() #跟随在线时间罪恶值会消掉,罪恶值累计在线时间4小时减少100罪恶值。 lastTm = player.tmpInfo.get('_lastCheckSin_', 0) if lastTm == 0: player.tmpInfo['_lastCheckSin_'] = curTm elif curTm - lastTm > 2 * 60: #TODO player.tmpInfo['_lastCheckSin_'] = curTm player.pkSinValue -= 10 #TODO 100 if player.pkSinValue < 0: player.pkSinValue = 0 #更新pk罪恶值 session.sendMsg(MsgDef.ServerCmd.PK_SIN_UPDATE_OPS, MsgDef.PkSinUpdateRet(0, player.pkSinValue)) #TODO if player.mapObj == None or player.hp == 0 or player.hp >= player.hpMax: return player.addHPMsg(int(player.hpMax / 100))
def acceptTask(self, taskId): task = self.allTask.get(taskId) if not task: return Base.lang('任务不存在') if task.status != TaskStatus.INIT: return Base.lang('无法接受任务') task.status = TaskStatus.ACCEPT task.acceptTm = ffext.getTime() #for k, item in self.owner.itemCtrl.allItem.iteritems(): #if task.object == item.itemCfg.cfgId: #task.value = self.owner.itemCtrl.countItemNumbyCfgId(task.object) #ffext.dump('Value', task.value) self.owner.sendMsg( ServerCmd.UPDATE_TASK_STATUS, MsgDef.UpdateTaskStatusRet(task.taskId, task.status, task.value)) if task.taskCfg.action == Base.Action.CHAT_NPC: task.status = TaskStatus.DONE DbService.getPlayerService().updateTask(self.owner, task) return None
def addBuff(self, buffId, buffSec=0, buffEffect=0, fromSkillId=0): curBuff = self.allBuff.get(buffId) if curBuff: return False endTime = 0 if buffSec > 0: endTime = ffext.getTime() + buffSec owner = self.ownerref def cb(): player = owner() if not player or player.mapObj == None: return player.buffCtrl.delBuff(buffId) player.updateBuffMsg() ffext.timer(buffSec * 1000, cb) newBuff = MsgDef.BuffStatus(endTime, {1: buffEffect}, fromSkillId) self.allBuff[buffId] = newBuff player = self.ownerref() return
def handleObjDie(self, mapObj, obj): playerOther = None bWin = True if self.autoPlayerRef != None: playerOther = self.autoPlayerRef() def cb(): playerOther.mapObj.playerLeaveMap(playerOther) if playerOther: ffext.timer(100, cb) if obj.uid != playerOther.uid: bWin = False self.autoPlayerRef =None #self.onEnd() for k, v in mapObj.allPlayer.iteritems(): if v.uid != playerOther.uid: v.sendMsg(MsgDef.ServerCmd.COPYMAP_END, MsgDef.CopymapEndRet(1, AWARD_EXP, GOLD_ADD, [])) v.AddScoreArena(getScoreBytimes(v.arenaCtrl.usedTimes)) #v.taskCtrl.trigger(Base.Action.COPY_MAP, int(mapObj.mapname), 1) #5秒后关闭副本 self.createTime = ffext.getTime() + 5 - LIMIT_SEC return True
def fromData(self, result): # 从DB获取的数据初始化邮件 if not result or len(result) <= 0: createMailRecrodAtFirstTime(self.owner.uid) return row = result[0] mailDataStr = row[1] if not mailDataStr or mailDataStr == '': return # [{}] # [{}, {"d":1}] mailDataObj = json.loads(mailDataStr) for mailNodeObj in mailDataObj: if len(mailNodeObj) <= 0: continue newM = Mail() newM.initFromJson(mailNodeObj) mLastTm = ffext.getTime() - newM.sendTime # load时发现邮件超过30天,删除 if mLastTm >= MAIL_DELETE_ELAPSE_TIME_30DAY: continue self.addMail(newM, False, False) pass return
def updateRefreshTime(self): self.last_refresh_time = ffext.getTime() + 1 DbService.getPlayerService().updateGlobalOfRefreshTime( GLOBAL_RECORD_INDEX, self.last_refresh_time) return True
def handleTimer(self, mapObj): #ffext.dump('CityWarCopy handleTimer', mapObj.getPlayerNum()) n = ffext.getTime() if n - self.createTime >= CITYWAR_LIMIT_SEC: self.onEnd(mapObj) return True
def handleTimer(self, mapObj): #ffext.dump('CopyMapHandler handleTimer', len(mapObj.allPlayer)) n = ffext.getTime() if n - self.createTime >= LIMIT_SEC: self.onEnd() return True
def dailyRefresh(self): self.logintime = ffext.getTime() self.gametime = 0 self.loginActCtrl.dailyRefresh() return True
def getGameTime(self): now = ffext.getTime() return self.gametime + (now - self.logintime)
def __init__(self, dbRow=None): Player.NUM += 1 ffext.dump('Player new', Player.NUM) #各个模块增加的属性 self.allPropByModule = {} self.mapObj = None self.session = None self.last_move_tm = time.time() self.friendCtrl = FriendModel.FriendCtrl() self.teamCtrl = TeamModel.PersonTeamCtrl(self) self.guildCtrl = GuildModel.PersonGuildCtrl(self) self.skillCtrl = SkillModel.SkillCtrl(self) self.taskCtrl = TaskModel.TaskCtrl(self) self.itemCtrl = ItemModel.ItemCtrl(self) self.buffCtrl = MonsterModel.BuffCtrl(self) self.petCtrl = PetModel.PetCtrl(self) self.brotherCtrl = TeamModel.PersonBrotherCtrl() self.mailCtrl = MailModel.MailCtrl(self) self.loginActCtrl = LoginRewardModel.LoginActCtrl(self) #竞技场相关的 self.arenaCtrl = ArenaCtrl() self.marriageCtrl = MarryModel.PersonMarryCtrl(self) self.moneyBankCtrl = MoneyBankCtrl() self.tmpInfo = {} #临时数据 self.uid = 0 self.name = '' self.job = 0 self.gender = 0 self.gold = 0 self.mapname = '' self.x = 0 self.y = 0 self.level = 1 self.exp = 0 self.direction = 0 #self.powerFight = 0#战斗力 实时计算 self.hp = 0 self.mp = 0 self.hpMax = 0 self.mpMax = 0 self.physicAttackMin = 0 #最小物理攻击 self.physicAttackMax = 0 #最大物理攻击 #法术攻击 self.magicAttackMin = 0 #最小法术攻击 self.magicAttackMax = 0 #最大法术攻击 #物理防御 self.physicDefendMin = 0 #最小物理防御 self.physicDefendMax = 0 #最大物理防御 #法术防御 self.magicDefendMin = 0 #最小法术防御 self.magicDefendMax = 0 #最大法术防御 #暴击 self.crit = 0 #暴击 影响暴击的概率 浮点数 self.hit = 0 #命中 影响攻击时的命中率 浮点数 self.avoid = 0 #躲避 被攻击时,影响降低被命中的概率 浮点数 self.attackSpeed = 0 #攻击速度 self.attackSing = 0 #攻击吟唱时间 影响释放攻击动作前的吟唱时间 吟唱时间内被攻击,有50%概率被打断,打断后需要重新吟唱,单位:秒 精确到毫秒 self.attackInterval = 0 #两次攻击之间间隔时间,单位:秒 精确到毫秒 self.attackDistance = 0 #攻击距离 以单位为中心的圆内可以攻击,近战标准值:100,远程值:600 self.moveSpeed = 0 #移动速度 影响地图上移动速度,标准值:100 精确到毫秒 self.hurtAbsorb = 0 #伤害吸收 受到伤害时,一定比例转换为生命值 百分比 self.hpAbsorb = 0 #吸血 当对敌人造成伤害时,吸取血量恢复自身生命值 百分比 self.pkSinValue = 0 #pk 罪恶值 即杀人数量 白:无杀人记录 橙:杀一个人后在线时间12小时内显示,被人杀死后0.1%掉落身上任一装备 红色:在线时间12小时内杀2个人以上,被人杀死后1%掉落身上任一装备 self.modeAttack = 0 #攻击模式 self.hurtAbsorbLimit = 0 #伤害吸收量 #战斗力 self.fightPower = 0 self.sumAngerTmp = 0 #技能累计怒气是小数 self.anger = 0 #怒气 self.angerMax = Base.MAX_ANGER #名字颜色 self.nameColor = 0 #NPC相关的 self.npcInfo = NpcInfo() #用于回调的函数容器 self.callbackFuncs = {} #记录当前切磋的目标玩家 self.ctrlQieCuo = QieCuoCtrl(self) self.last_logout = 0 #登出时间 #在线时间 self.logintime = ffext.getTime() #不存DB self.gametime = 0 #离线时计算,并存DB #状态机 self.fsm = None #MonsterAI.FSM(self) #if dbRow: self.assignFromDB(dbRow) #安全密码验证状态 self.isVerified = False