def _fish_w_up(self, player, iid, num, qt): """ 白色鱼饵起杆 """ left_num = self._mgr.get_white_chum_max_sett() - self.data.wn if left_num < num: return False, errcode.FISH_NOT_ENOUGH t_list = [] for i in range(num): t_rs_item = self._fish_up(player, iid, qt) for t_d in t_rs_item: t_list.append(t_d) if not bool(t_list): self.data.wn += num self.data.flt = common.current_time() self.data.update_attr(player) player.pub(MSG_FISH_UP, num, 0) return True, {} #添加到待收物品 oWaitItem = self.player.wait_bag.add_waitItem(WAITBAG_TYPE_FISHING, t_list) player.pub(MSG_FISH_UP, num, 0) self.data.wn += num self.data.flt = common.current_time() self.data.update_attr(player) rs = self.player.pack_msg_data(waits=[oWaitItem]) return True, rs
def del_expire_mail(self): """ 每日凌晨4点删除过期的邮件 """ four = cur_day_hour_time(4) ct = current_time() sleep_time = four-ct if ct<four else MailMgr.SLEEP_TIME-(ct-four) log.info("del_expire_mail sleep %s times", sleep_time) sleep(sleep_time) store = Game.rpc_store while 1: #计算段数 limit = MailMgr.LIMIT a_n = store.count(Mail.TABLE_NAME, {'_id':{FOP_NE:0}}) u_n = a_n/limit+1 if a_n%limit else a_n/limit sections = [i for i in xrange(u_n)] sections.append(u_n) sections.sort(reverse=True) ct = current_time() onls = Game.rpc_player_mgr.get_online_ids() del_time = ct - MailMgr.EXPIRE_TIME querys = {'pid':{FOP_NIN:onls}, 'ct':{FOP_LTE:del_time}} for section in sections: mails = store.query_loads(Mail.TABLE_NAME, querys=querys, limit=limit, skip=section*limit) for m_d in mails: self._del_mail(m_d, store) sleep(MailMgr.SLEEP_TIME)
def _fish_w_up(self, player, iid, num, qt): """ 白色鱼饵起杆 """ left_num = self._mgr.get_white_chum_max_sett() - self.data.wn if left_num < num: return False, errcode.FISH_NOT_ENOUGH t_list = [] for i in range(num): t_rs_item = self._fish_up(player, iid, qt) for t_d in t_rs_item: t_list.append(t_d) if not bool(t_list): self.data.wn += num self.data.flt = common.current_time() self.data.update_attr(player) player.pub(MSG_FISH_UP, num, 0) return True, {} #添加到待收物品 oWaitItem = self.player.wait_bag.add_waitItem(WAITBAG_TYPE_FISHING, t_list) player.pub(MSG_FISH_UP, num, 0) self.data.wn += num self.data.flt = common.current_time() self.data.update_attr(player) rs = self.player.pack_msg_data(waits=[oWaitItem]) return True, rs
def _w_boos(self): """ 世界boos开启提前广播(判断时间是否到达) """ res_starts = self.fetch_start_time while 1: min_sec = 0 common.current_time() now_sec = self.get_today_seconds time_keys = res_starts.keys() time_keys.sort() for start_sec, res_blid in res_starts.iteritems(): if self.w_start_boss: continue boss_id = self.w_bosses[res_blid] #setting表的改动后建立新的boss数据 if boss_id: w_boss = self.bosses.get(boss_id) else: w_boss = self._new_world_boss(res_blid) l_sec = start_sec - now_sec rs, data = w_boss.handle_start_time(l_sec, min_sec) w_boss.set_start_type(time_keys.index(start_sec)) if rs: w_boss.start(data) self.w_start_boss = w_boss else: min_sec = data #还有多久通知min_sec if min_sec <= 0: min_sec = self.fetch_notice_start sleep(min_sec)
def need_refurbish(self): """ 处理超过一天(超过则更新数据) """ curt = common.current_time() if curt - self.shopData.st > PlayShop.REFURBISH_TIME: self.shopData = ShopData() self.shopData.st = curt return True
def gem_enter(self): """进入珠宝商店""" nt = self.gem_next_time() if nt - self.gemShopData.t >= 3600*6: self._new_gem_items() return True, dict(n = self.gemShopData.n, sids = self.gemShopData.sids, t = nt - common.current_time(), rc = self.gemShopData.rc)
def gem_reset(self): """珠宝商店重置""" d_cost = self.player._game.setting_mgr.setdefault(GEM_SHOP_RESET_COST, GEM_SHOP_RESET_COST_V) if d_cost is None: return False, errcode.EC_VALUE if not common.is_today(self.gemShopData.rt): self.gemShopData.rc = 0 self.gemShopData.rt = common.current_time() d_cost = common.str2dict2(d_cost) cost = 0 for k, v in d_cost.iteritems(): start, end = int(v[0]), int(v[1]) cs = 0 if start <= self.gemShopData.rc + 1 <= end: index = range(start, end + 1).index(self.gemShopData.rc + 1) + 1 cost = int(k) * index + cs break cs += int(k) * end if not self.player.enough_coin_ex(0, aCoin3=cost): return False, errcode.EC_COST_ERR self.player.cost_coin_ex(aCoin3=cost) self.gemShopData.rc += 1 self.gemShopData.sids = self.player._game.res_mgr.get_gem_shop_by_rate(self.gemShopData.n) nt = self.gem_next_time() return True, dict(n = self.gemShopData.n, sids = self.gemShopData.sids, t=nt - common.current_time(), data = self.player.pack_msg_data(coin=True), rc = self.gemShopData.rc)
def pre_exchange(self, strcode, uid, pid): """ 领取之前的检测 """ t_lis = Game.rpc_res_store.query_loads(ExchangeCode.TABLE_NAME, dict(code=strcode)) if not t_lis: return False, errcode.EC_CODE_EXCHANGE_INVALID if len(t_lis) > 1: log.error("the exchange code :%s must exit only one but exit %s", strcode, len(t_lis)) #特定服 _obj = ExchangeCode(t_lis[0]) if _obj.data.num <= 0: return False, errcode.EC_CODE_EXCHANGE_INVALID if common.current_time() > _obj.data.et: return False, errcode.EC_CODE_EXCHANGE_PASS if _obj.is_one: lis = CodeLog.find(_obj.data.name, uid, pid) if lis: return False, errcode.EC_CODE_EXCHANGE_NOMORE self.codes[strcode] = _obj rid = _obj.data.rid return True, rid
def _save_report(self, news): """ 保存高伤害值的战报 """ pid = self.player.data.id file = 'boss_%d_%d' % (pid, common.current_time()) fid = self.player._game.rpc_report_mgr.save( REPORT_WBOSS_HURTS, [pid], news, url=[REPORT_BOSS_URL, file]) log.debug('world—boss-fid %d, %s', fid, file)
def dismiss(self, pid): """ 解散同盟 """ assist_obj = self.assist_objs.get(pid) if assist_obj.data.duty != ALLY_MAIN: return False, errcode.EC_NO_RIGHT if common.current_time() - self.data.tNew < ONE_DAY_TIME: return False, errcode.EC_QUIT_TIME_ERR params = dict(name=self.main_name()) pids = [] for assist_obj in self.assist_objs.itervalues(): assist_obj.remove_member(self.rpc_store) self._mgr.detach_ally(assist_obj.data.pid) pids.append(assist_obj.data.pid) #玩家如果在线解除玩家的ally属性 rpc_players = self._mgr.rpc_player_mgr.get_rpc_players(pids) for rpc_player in rpc_players: rpc_player.detach_ally(self.pack_msg(kick=True)) #邮件通知所有同盟玩家 self.mail_mgr.send_mails(pids, MAIL_REWARD, language.ALLY_DISMISS_TITLE, language.ALLY_DISMISS_CONTENT % params, [], notify_mgr=False) self.delete(self.rpc_store) for log_obj in self.log_objs: log_obj.delete(self.rpc_store) return True, ALLY_OP_SUCCEED
def join(self, pid): """ 加入房间 """ if self.is_war: return False, errcode.EC_ALLY_WAR_ING if len(self.pids) >= self.res_warstart_config.mplayer: return False, errcode.EC_ALLY_WAR_ROOMMAX if pid in self.pids: return False, errcode.EC_ALLY_WAR_ENTERED self.pids.append(pid) _, glory = Game.rpc_ally_mgr.get_glory_by_pid(pid) if not self.books: books = common.str2dict2(self.res_warstart_config.books) for bid, (num, emax) in books.iteritems(): self.books[bid] = int(num) self.ebooks[bid] = int(emax) now = common.current_time() rtime = self.res_warstart_config.rtime - (now - self.b_time) if not self.tname: self.tname = self.get_change_tname data = dict(rnum=self.id, rtime=rtime, pnum=len(self.pids), asid=self.res_warstart_config.id, glory=glory, books=self.books, tname=self.tname) self.join_broad(pid) return True, data
def pre_exchange(self, strcode, uid, pid): """ 领取之前的检测 """ t_lis = Game.rpc_res_store.query_loads(ExchangeCode.TABLE_NAME, dict(code=strcode)) if not t_lis: return False, errcode.EC_CODE_EXCHANGE_INVALID if len(t_lis) > 1: log.error("the exchange code :%s must exit only one but exit %s", strcode, len(t_lis)) #特定服 _obj = ExchangeCode(t_lis[0]) if _obj.data.num <= 0: return False, errcode.EC_CODE_EXCHANGE_INVALID if common.current_time() > _obj.data.et: return False, errcode.EC_CODE_EXCHANGE_PASS if _obj.is_one: lis = CodeLog.find(_obj.data.name, uid, pid) if lis: return False, errcode.EC_CODE_EXCHANGE_NOMORE self.codes[strcode] = _obj rid = _obj.data.rid return True, rid
def send_reward(self): res_tbox = Game.res_mgr.tboxs.get(self.bid) if res_tbox is None: log.error('ally_team(%s) res_tbox is None, pids(%s)', self.tid, self.pids) return rw = Game.reward_mgr.get(res_tbox.trid) items = rw.reward(None) if items is None: log.error('ally_team(%s) reward_items is None, pids(%s)', self.tid, self.pids) return rw_mail = Game.res_mgr.reward_mails.get(RW_MAIL_ATBOX) boss = Game.res_mgr.monsters.get(res_tbox.tmid) content = rw_mail.content % dict(name=boss.name) pids = [] for pid in self.pids: player = Game.rpc_player_mgr.get_rpc_player(pid) if player is None: player = Player.load_player(pid) if player is None: continue data = player.get_ally_tbox_data() if not is_today(data['t']): data['bids'] = [] data['cr'] = 0 if len(data['bids']) == 0: data['bids'].append(self.bid) data['t'] = current_time() pids.append(pid) if pid == self.lid: data['cr'] += 1 player.set_ally_tbox_data(data) Game.mail_mgr.send_mails(pids, MAIL_REWARD, rw_mail.title, content, items)
def send_reward(self): res_tbox = Game.res_mgr.tboxs.get(self.bid) if res_tbox is None: log.error('ally_team(%s) res_tbox is None, pids(%s)', self.tid, self.pids) return rw = Game.reward_mgr.get(res_tbox.trid) items = rw.reward(None) if items is None: log.error('ally_team(%s) reward_items is None, pids(%s)', self.tid, self.pids) return rw_mail = Game.res_mgr.reward_mails.get(RW_MAIL_ATBOX) boss = Game.res_mgr.monsters.get(res_tbox.tmid) content = rw_mail.content % dict(name = boss.name) pids = [] for pid in self.pids: player = Game.rpc_player_mgr.get_rpc_player(pid) if player is None: player = Player.load_player(pid) if player is None: continue data = player.get_ally_tbox_data() if not is_today(data['t']): data['bids'] = [] data['cr'] = 0 if len(data['bids']) == 0: data['bids'].append(self.bid) data['t'] = current_time() pids.append(pid) if pid == self.lid: data['cr'] += 1 player.set_ally_tbox_data(data) Game.mail_mgr.send_mails(pids, MAIL_REWARD, rw_mail.title, content, items)
def re_use(cls, gid, pid, duty, dic): assist_obj = cls(dic) data = assist_obj.data data.duty = duty data.gid = gid data.tJoin = common.current_time()#加入时间 return assist_obj
def new_apply_json(cls, pid, n, level, pvp): return { PID: pid, TIME: common.current_time(), NAME: n, LEVEL: level, PVP: pvp }
def get_start_activity(self, pid): """ 活动是否开启 """ ally = self._game.rpc_ally_mgr.get_ally_by_pid(pid) now_sec = common.current_time() - common.zero_day_time() if self.warstart_config and self.warstart_config.stime < now_sec and \ ally.data.level >= self.warstart_config.unlock: return True, self.warstart_config.type return False, None
def get_start_activity(self, pid): """ 活动是否开启 """ ally = self._game.rpc_ally_mgr.get_ally_by_pid(pid) now_sec = common.current_time() - common.zero_day_time() if self.warstart_config and self.warstart_config.stime < now_sec and \ ally.data.level >= self.warstart_config.unlock: return True, self.warstart_config.type return False, None
def save_data(self, is_win): """ boss数据的保存 """ #log.debug('boss--end--is_win %s', is_win) self.data.c += 1 if not is_win: self.save(Game.rpc_store, forced=True) return self.data.deads += 1 res_boss_level = Game.res_mgr.boss_level.get(self.data.blid) key = (res_boss_level.mid, res_boss_level.level + 1) res_boss_level_up = Game.res_mgr.boss_level_by_midlevel.get(key) log.debug('kill-time %s', common.current_time() - self.boss_start) if common.current_time() - self.boss_start < self.fetch_bosskill_time or\ self.data.deads >= res_boss_level_up.deads: self.data.blid = res_boss_level_up.id self.data.deads = 0 self.save(Game.rpc_store, forced=True)
def start_arena(self, rival_id): """ 开始挑战 """ self.pass_day() if not self.free_count: #检查费用 return 0, errcode.EC_COST_ERR self.data.t = current_time() self.rival_id = rival_id return 1, rival_id
def add_log(self, t, rid, rival_name, rk, fid): """ 添加战报 """ self.modified = True logs = self.data.logs logs.append(dict(ct=current_time(), t=t, n=rival_name, rk=rk, fid=fid)) #id=rid, while len(logs) > self.MAX_REPORT: logs.pop(0)
def kill_out_apply(self): """ 处理申请过期的申请者 """ cur_time = common.current_time() u_d = self.pid2applyjson.copy() for pid, js in u_d.iteritems(): if cur_time - js[TIME] >= ONE_DAY_TIME: self.del_apply_by_pid(pid) log.info("player :%s apply is out time was killed", pid)
def kill_out_apply(self): """ 处理申请过期的申请者 """ cur_time = common.current_time() u_d = self.pid2applyjson.copy() for pid, js in u_d.iteritems(): if cur_time - js[TIME] >= ONE_DAY_TIME: self.del_apply_by_pid(pid) log.info("player :%s apply is out time was killed", pid)
def new(cls, pid, gid, duty = ALLY_MEMBER): assist_obj = cls() d = assist_obj.data d.gid = gid #同盟id d.pid = pid #玩家id d.duty = duty #职责 d.tJoin = common.current_time()#加入时间 return assist_obj
def _over_handle(self, rpc_store): data = self.data data.finish += 1 data.t = common.current_time() tid = Game.setting_mgr.setdefault(DAYSIGN_OVERTASKID, DAYSIGN_OVERTASKID_V) self.player.task.add_task(tid, send_msg=True) self.save(rpc_store, forced=True) return True, None
def _over_handle(self, rpc_store): data = self.data data.finish += 1 data.t = common.current_time() tid = Game.setting_mgr.setdefault(DAYSIGN_OVERTASKID, DAYSIGN_OVERTASKID_V) self.player.task.add_task(tid, send_msg=True) self.save(rpc_store, forced=True) return True, None
def handle_pass_day(self): if self.player.no_game: return if common.is_pass_day(self.data_dict['t']): for obj in self.pass_days_objs: obj.pass_day(self, self.player) obj.updata_attr() self.data_dict['t'] = common.current_time() self.update_attr()
def deep_pass_day(self): """ 深渊数据根据每日凌晨清楚 """ if self.is_save_rank and common.is_pass_day(self.first_time): self.first_time = common.current_time() self.deep_floor_pids.clear() self.deep_pid_floor.clear() self.is_save_rank = False return True return False
def _loop_ready_war(self): """ 准备倒计时自动开战 """ while not self.is_war: now = common.current_time() if now >= self.b_time + self.res_warstart_config.rtime: Game.rpc_awar_mgr.start_war(self.pids[0]) self.is_war = 1 break sleep(1)
def handle_pass_day(self): if self.player.no_game: return if common.is_pass_day(self.data_dict['t']): for obj in self.pass_days_objs: obj.pass_day(self, self.player) obj.updata_attr() self.data_dict['t'] = common.current_time() self.update_attr()
def new(cls, pid, t, title, content, wid): o = cls() o.data.pid = pid o.data.ct = current_time() o.data.t = t o.data.title = title o.data.content = str(content) o.data.wid = wid return o
def _loop_war(self): """ 开战计时 """ while 1: now_time = common.current_time() use_time = now_time - self.war_data.stime if use_time > self.war_per_config.wtime + self.boat.gtime: self.war_result_borad(ALLY_WAR_FAIL_TIME) break sleep(1)
def _loop_war(self): """ 开战计时 """ while 1: now_time = common.current_time() use_time = now_time - self.war_data.stime if use_time > self.war_per_config.wtime + self.boat.gtime: self.war_result_borad(ALLY_WAR_FAIL_TIME) break sleep(1)
def gem_next_time(self): """珠宝商店下次刷新时间""" ct = common.current_time() t = common.zero_day_time() for i in xrange(4): t = t + 3600*6 if t >= ct: break return t
def connon_fire(self, pid, index): """ 开炮 """ rs = self.boat.is_use(index) if rs: return False, errcode.EC_ALLY_WAR_FIRED now = common.current_time() self.boat.set_cannon(index, (pid, now)) self.boat.cannon -= 1 self.connon_fire_braod(pid, index) return True, None
def pass_day(self): """ 玩家数据是否过期 """ if not is_pass_day(self.data.t): return self.modified = True self.rival_id = None self.data.coin1 = 0 self.data.train = 0 self.data.c = 0 self.data.t = current_time()
def connon_fire(self, pid, index): """ 开炮 """ rs = self.boat.is_use(index) if rs: return False, errcode.EC_ALLY_WAR_FIRED now = common.current_time() self.boat.set_cannon(index, (pid, now)) self.boat.cannon -= 1 self.connon_fire_braod(pid, index) return True, None
def is_use(self, index): """ 该炮是否能使用中 """ data = self.get_cannon(index) if data is None: return False _, use_time = data now = common.current_time() if now - use_time > self.ctime: self.connon2data.pop(index) return False return True
def is_use(self, index): """ 该炮是否能使用中 """ data = self.get_cannon(index) if data is None: return False _, use_time = data now = common.current_time() if now - use_time > self.ctime: self.connon2data.pop(index) return False return True
def new(cls, aid, type, n1, n2, v1, v2, rpc_store): log_obj = cls() log_obj.data.gid = aid log_obj.data.t = type #操作类型1=加入 2=退出 3=贡献 6=任职 7=踢人 log_obj.data.ct = common.current_time() log_obj.data.n1 = n1 log_obj.data.n2 = n2 log_obj.data.v1 = v1 log_obj.data.v2 = v2 log_obj.save(rpc_store) return log_obj
def _new_items(self, reset=False): """ 生成新物品 """ #获取活动中出现的商品id reward_sids = [] self.player.pub(MSG_REWARD_BUY, reward_sids) sids_tmp = {} fids_tmp = {} shop_item_num = self.shop_item_num #处理必然出现的物品 #活动必然出 for reward_sid in reward_sids: res_shop = self.player._game.res_mgr.shop_items.get(reward_sid) sids_tmp[(res_shop.t, res_shop.iid)] = res_shop.id if res_shop.t == SHOP_TYPE_FATE: self._handle_fate(res_shop, fids_tmp) if len(sids_tmp)==shop_item_num: break #本身商店必然出现的物品 must_shops = self.player._game.res_mgr.shop_items_must if not reset and must_shops: for must_shop in must_shops.itervalues(): if not (must_shop.start <= common.current_time() <= must_shop.end): continue sids_tmp[(must_shop.t, must_shop.iid)] = must_shop.id if must_shop.t == SHOP_TYPE_FATE: self._handle_fate(must_shop, fids_tmp) if len(sids_tmp)==shop_item_num: break while len(sids_tmp) < shop_item_num: shop_ret = self.player._game.res_mgr.get_shop_by_rate() if shop_ret.start and shop_ret.start\ and not (shop_ret.start <= common.current_time() <= shop_ret.end): continue if (shop_ret.t, shop_ret.iid) not in sids_tmp: sids_tmp[(shop_ret.t, shop_ret.iid)] = shop_ret.id if shop_ret.t == SHOP_TYPE_FATE: self._handle_fate(shop_ret, fids_tmp) self.shopData.sids = sids_tmp.values() self.shopData.fids = fids_tmp self.shopData.st = int(time.time())
def kick_out(self, pid1, name, pid2): """踢人""" if not pid1 in self.r_tick_out: return False, errcode.EC_NO_RIGHT assist_obj = self.assist_objs.get(pid2, None) if not assist_obj: return False, errcode.EC_PLAYER_NO if assist_obj.data.duty == ALLY_MAIN: return False, errcode.EC_NO_RIGHT if common.current_time() - assist_obj.data.tJoin < ONE_DAY_TIME: return False, errcode.EC_QUIT_TIME_ERR return self._kick_out(name, pid2)
def time_start(self): """ 根据当前时间和配置表数据对应开启活动 """ now_sec = common.current_time() - common.zero_day_time() for res_config in self.res_warstart_configs.itervalues(): notice_time = res_config.stime - res_config.ntime if notice_time <= now_sec < res_config.etime: self.warstart_config = res_config l_sec = now_sec - res_config.stime spawn(self._notice, l_sec) log.debug('start----- %s, %s', res_config.stime, res_config.type) return True return False
def loop_connon(self): """ 处理打炮 """ if not self.connon2data or self.war_mgr.war_data.war_end: return log.debug('loop_connon----------- %s', self.connon2data) now = common.current_time() hurt_pids = [] for index, (pid, use_time) in self.connon2data.items(): if now < use_time + self.ctime: continue hurt_pids.append(pid) self.connon2data.pop(index) return hurt_pids
def save_data(self, is_win): """ boss数据的保存 """ #log.debug('boss--end--is_win %s', is_win) self.data.c += 1 if not is_win: self.save(Game.rpc_store, forced=True) #挑战世界boss失败广播 if not self.data.aid: self.handle_horn(HORN_TYPE_WORLDBOSSFAIL) else: self.handle_horn(HORN_TYPE_ALLYBOSSFAIL, aid=self.aid) return self.data.deads += 1 res_boss_level = Game.res_mgr.boss_level.get(self.data.blid) key = (res_boss_level.mid, res_boss_level.level+1) res_boss_level_up = Game.res_mgr.boss_level_by_midlevel.get(key) log.debug('kill-time %s',common.current_time() - self.boss_start) if common.current_time() - self.boss_start < self.fetch_bosskill_time or\ self.data.deads >= res_boss_level_up.deads: self.data.blid = res_boss_level_up.id self.data.deads = 0 self.save(Game.rpc_store, forced=True)
def _loop_war(self): """ 开战计时 """ is_use_boattime = False while 1: now_time = common.current_time() use_time = now_time - self.war_data.stime if use_time > self.war_per_config.wtime + self.boat.gtime: self.war_result_borad(ALLY_WAR_FAIL_TIME) break elif not is_use_boattime and use_time > self.war_per_config.wtime: is_use_boattime = True self.record_uboattimes() sleep(1)
def exchange(self, uid, pid): """ 奖励完成保存要保存的数据 """ d = self.data d.num = d.num - 1 if d.num > 0 else 0 c_log = CodeLog() data ={} data['gt'] = common.current_time() data['code'] = self.data.code data['uid'] = uid data['pid'] = pid data['name'] = self.data.name c_log.new(data) self.save(Game.rpc_res_store, forced = True)
def _loop_war(self): """ 活动开启提前通知 """ while 1: now_sec = common.current_time() - common.zero_day_time() #开启的活动结束 if self.warstart_config and now_sec > self.warstart_config.etime: if self.time_start(): #本次开启活动时清楚上一次的数据 self.stop_activity() #未开启活动时 elif self.warstart_config is None: self.time_start() sleep(1)
def load(self): """ 获取数据 """ data = Game.rpc_status_mgr.get(STATUS_RANK) if data: #深渊 self.first_time = data.get(STATUS_RANK_FT) self._load_deep_data(data.get(STATUS_RANK_DEEP)) #世界boss boss_data = data.get(STATUS_RANK_BOSS) boss_data = self._change_data_type(boss_data, int) self.handle_boss_rank(boss_data, None) else: self.first_time = common.current_time()