def run(cfg): _show_head_line("开始核心逻辑") start_time = datetime.datetime.now() if cfg.common.enable_multiprocessing: logger.info(f"已开启多进程模式({cfg.get_pool_size()}),将并行运行~") get_pool().starmap( do_run, [ (_idx + 1, account_config, cfg.common) for _idx, account_config in enumerate(cfg.account_configs) if account_config.is_enabled() ], ) else: for idx, account_config in enumerate(cfg.account_configs): idx += 1 if not account_config.is_enabled(): logger.info(f"第{idx}个账号({account_config.name})未启用,将跳过") continue do_run(idx, account_config, cfg.common) used_time = datetime.datetime.now() - start_time _show_head_line(f"处理总计{len(cfg.account_configs)}个账户 共耗时 {used_time}")
def check_all_skey_and_pskey(cfg, check_skey_only=False): if not has_any_account_in_normal_run(cfg): return _show_head_line("启动时检查各账号skey/pskey/openid是否过期") if cfg.common.enable_multiprocessing and cfg.is_all_account_auto_login(): logger.info(color("bold_yellow") + f"已开启多进程模式({cfg.get_pool_size()}),并检测到所有账号均使用自动登录模式,将开启并行登录模式") QQLogin(cfg.common).extract_portable_chrome_ahead() get_pool().starmap(do_check_all_skey_and_pskey, [(_idx + 1, _idx + 1, account_config, cfg.common, check_skey_only) for _idx, account_config in enumerate(cfg.account_configs) if account_config.is_enabled()]) logger.info("全部账号检查完毕") return # 串行登录 qq2index = {} for _idx, account_config in enumerate(cfg.account_configs): idx = _idx + 1 djcHelper = do_check_all_skey_and_pskey(idx, 1, account_config, cfg.common, check_skey_only) if djcHelper is None: continue qq = uin2qq(djcHelper.cfg.account_info.uin) if qq in qq2index: msg = f"第{idx}个账号的实际登录QQ {qq} 与第{qq2index[qq]}个账号的qq重复,是否重复扫描了?\n\n点击确认后,程序将清除本地登录记录,并退出运行。请重新运行并按顺序登录正确的账号~" logger.error(color("fg_bold_red") + msg) win32api.MessageBox(0, msg, "重复登录", win32con.MB_ICONINFORMATION) clear_login_status() sys.exit(-1) qq2index[qq] = idx
def check_all_skey_and_pskey(cfg): if not has_any_account_in_normal_run(cfg): return _show_head_line("启动时检查各账号skey/pskey/openid是否过期") QQLogin(cfg.common).check_and_download_chrome_ahead() if cfg.common.enable_multiprocessing and cfg.is_all_account_auto_login(): logger.info(color("bold_yellow") + f"已开启多进程模式({cfg.get_pool_size()}),并检测到所有账号均使用自动登录模式,将开启并行登录模式") get_pool().starmap( do_check_all_skey_and_pskey, [ (_idx + 1, account_config, cfg.common) for _idx, account_config in enumerate(cfg.account_configs) if account_config.is_enabled() ], ) logger.info("全部账号检查完毕") else: for _idx, account_config in enumerate(cfg.account_configs): idx = _idx + 1 if not account_config.is_enabled(): # 未启用的账户的账户不走该流程 continue do_check_all_skey_and_pskey(idx, account_config, cfg.common)
def show_accounts_status(cfg, ctx): if not has_any_account_in_normal_run(cfg): return _show_head_line(ctx) # 获取数据 rows = [] if cfg.common.enable_multiprocessing: logger.warning(f"已开启多进程模式({cfg.get_pool_size()}),将开始并行拉取数据,请稍后") for row in get_pool().starmap(get_account_status, [(_idx + 1, account_config, cfg.common) for _idx, account_config in enumerate(cfg.account_configs) if account_config.is_enabled()]): rows.append(row) else: logger.warning("拉取数据中,请稍候") for _idx, account_config in enumerate(cfg.account_configs): idx = _idx + 1 if not account_config.is_enabled(): # 未启用的账户的账户不走该流程 continue rows.append(get_account_status(idx, account_config, cfg.common)) # 打印结果 heads = ["序号", "账号名", "启用状态", "聚豆余额", "聚豆历史总数", "心悦类型", "成就点", "勇士币", "心悦组队", "赛利亚", "心悦G分", "编年史", "年史碎片", "引导石"] colSizes = [4, 12, 8, 8, 12, 8, 6, 6, 16, 12, 8, 14, 8, 6] logger.info(tableify(heads, colSizes)) for row in rows: logger.info(color("fg_bold_green") + tableify(row, colSizes, need_truncate=True))
def auto_send_cards(cfg: Config): if not has_any_account_in_normal_run(cfg): return _show_head_line("运行完毕自动赠送卡片") target_qqs = cfg.common.auto_send_card_target_qqs if len(target_qqs) == 0: logger.warning("未定义自动赠送卡片的对象QQ数组,将跳过本阶段") return # 统计各账号卡片数目 logger.info("拉取各账号的卡片数据中,请耐心等待...") account_data = [] if cfg.common.enable_multiprocessing: logger.info(f"已开启多进程模式({cfg.get_pool_size()}),将并行拉取数据~") for data in get_pool().starmap(query_account_ark_lottery_info, [(_idx + 1, len(cfg.account_configs), account_config, cfg.common) for _idx, account_config in enumerate(cfg.account_configs) if account_config.is_enabled()]): account_data.append(data) else: for _idx, account_config in enumerate(cfg.account_configs): idx = _idx + 1 if not account_config.is_enabled(): # 未启用的账户的账户不走该流程 continue account_data.append(query_account_ark_lottery_info(idx, len(cfg.account_configs), account_config, cfg.common)) account_data = remove_none_from_list(account_data) qq_to_card_name_to_counts = {} qq_to_prize_counts = {} qq_to_djcHelper = {} for card_name_to_counts, prize_counts, djcHelper in account_data: qq = uin2qq(djcHelper.cfg.account_info.uin) qq_to_card_name_to_counts[qq] = card_name_to_counts qq_to_prize_counts[qq] = prize_counts qq_to_djcHelper[qq] = djcHelper # 赠送卡片 for idx, target_qq in enumerate(target_qqs): if target_qq in qq_to_djcHelper: left_times = qq_to_djcHelper[target_qq].ark_lottery_query_left_times(target_qq) name = qq_to_djcHelper[target_qq].cfg.name logger.warning(color("fg_bold_green") + f"第{idx + 1}/{len(target_qqs)}个赠送目标账号 {name}({target_qq}) 今日仍可被赠送 {left_times} 次卡片") # 最多赠送目标账号今日仍可接收的卡片数 for i in range(left_times): send_card(target_qq, qq_to_card_name_to_counts, qq_to_prize_counts, qq_to_djcHelper, target_qqs) # 赠送卡片完毕后尝试领取奖励和抽奖 djcHelper = qq_to_djcHelper[target_qq] lr = djcHelper.fetch_pskey() if lr is not None: logger.info("赠送完毕,尝试领取奖励和抽奖") qa = QzoneActivity(djcHelper, lr) qa.take_ark_lottery_awards(print_warning=False) qa.try_lottery_using_cards(print_warning=False)
def update_pool(): leaderboard = fetch_leaderboard() pool = get_pool() pool_standings = [] for member in pool: member = get_player_scores(leaderboard, member) score = calculate_member_score(member) pool_standings.append({'pool_member': member, 'score': score}) return sorted(pool_standings, key=lambda member: member['score'])
def show_lottery_status(ctx, cfg: Config, need_show_tips=False): if not has_any_account_in_normal_run(cfg): return _show_head_line(ctx) logger.info(get_not_ams_act_desc("集卡")) lottery_zzconfig = zzconfig() card_info_map = parse_card_group_info_map(lottery_zzconfig) order_map = {} # 卡片编码 => 名称 for name, card_info in card_info_map.items(): order_map[card_info.index] = name # 奖励展示名称 => 实际名称 groups = [ lottery_zzconfig.prizeGroups.group1, lottery_zzconfig.prizeGroups.group2, lottery_zzconfig.prizeGroups.group3, lottery_zzconfig.prizeGroups.group4, ] prizeDisplayTitles = [] for group in groups: displayTitle = group.title if len(displayTitle) > 4 and "礼包" in displayTitle: # 将 全民竞速礼包 这种名称替换为 全民竞速 displayTitle = displayTitle.replace("礼包", "") order_map[displayTitle] = group.title prizeDisplayTitles.append(displayTitle) heads = [] colSizes = [] baseHeads = ["序号", "账号名"] baseColSizes = [4, 12] heads.extend(baseHeads) colSizes.extend(baseColSizes) card_indexes = ["1-1", "1-2", "1-3", "1-4", "2-1", "2-2", "2-3", "2-4", "3-1", "3-2", "3-3", "3-4"] card_width = 3 heads.extend(card_indexes) colSizes.extend([card_width for i in card_indexes]) prize_indexes = [*prizeDisplayTitles] heads.extend(prize_indexes) colSizes.extend([printed_width(name) for name in prize_indexes]) # 获取数据 logger.warning("开始获取数据,请耐心等待~") rows = [] if cfg.common.enable_multiprocessing: logger.info(f"已开启多进程模式({cfg.get_pool_size()}),将并行拉取数据~") for row in get_pool().starmap(query_lottery_status, [(_idx + 1, account_config, cfg.common, card_indexes, prize_indexes, order_map) for _idx, account_config in enumerate(cfg.account_configs) if account_config.is_enabled()]): rows.append(row) else: for _idx, account_config in enumerate(cfg.account_configs): idx = _idx + 1 if not account_config.is_enabled(): # 未启用的账户的账户不走该流程 continue rows.append(query_lottery_status(idx, account_config, cfg.common, card_indexes, prize_indexes, order_map)) rows = remove_none_from_list(rows) # 计算概览 summaryCols = [1, "总计", *[0 for card in card_indexes], *[count_with_color(0, "bold_green", show_width=printed_width(prize_index)) for prize_index in prize_indexes]] for row in rows: summaryCols[0] += 1 for i in range(2, 2 + 12): summaryCols[i] += row[i] for cardIdx in range(len(card_indexes)): idx = len(baseHeads) + cardIdx summaryCols[idx] = colored_count(len(cfg.account_configs), summaryCols[idx], cfg.common.ark_lottery_summary_show_color or "fg_thin_cyan") # 计算可以开启抽奖卡片的账号 accounts_that_should_enable_cost_card_to_lottery = [] for row in rows: has_any_card = False has_any_left_gift = False for i in range(2, 2 + 12): if row[i] > 0: has_any_card = True for i in range(14, 14 + 4): if row[i] > 0: has_any_left_gift = True if has_any_card and not has_any_left_gift: accounts_that_should_enable_cost_card_to_lottery.append(row[1]) # 给每一行上色 for row in rows[:-1]: idx = row[0] name = row[1] for i in range(2, 2 + 12): row[i] = colored_count(idx, row[i], cfg.get_account_config_by_name(name).ark_lottery.show_color) for i in range(14, 14 + 4): row[i] = count_with_color(row[i], "bold_green", show_width=printed_width(prize_indexes[i - 14])) # 打印卡片情况 logger.info(tableify(heads, colSizes)) for row in rows: logger.info(tableify(row, colSizes)) logger.info(tableify(summaryCols, colSizes)) # 打印提示 if need_show_tips and len(accounts_that_should_enable_cost_card_to_lottery) > 0: accounts = ', '.join(accounts_that_should_enable_cost_card_to_lottery) msg = f"账户({accounts})仍有剩余卡片,但已无任何可领取礼包,建议开启消耗卡片来抽奖的功能" logger.warning(color("fg_bold_yellow") + msg)
def get_pool(id): pl = pool.get_pool(id) serializer = PoolSerializer(pl) return serializer.data